aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/ABI/stable/sysfs-devices-node7
-rw-r--r--Documentation/cpu-freq/pcc-cpufreq.txt207
-rw-r--r--Documentation/device-mapper/snapshot.txt44
-rw-r--r--Documentation/fault-injection/provoke-crashes.txt38
-rw-r--r--Documentation/feature-removal-schedule.txt6
-rw-r--r--Documentation/filesystems/00-INDEX2
-rw-r--r--Documentation/filesystems/logfs.txt241
-rw-r--r--Documentation/filesystems/nfs/nfs41-server.txt5
-rw-r--r--Documentation/filesystems/proc.txt53
-rw-r--r--Documentation/gpio.txt64
-rw-r--r--Documentation/hwmon/adt741142
-rw-r--r--Documentation/hwmon/adt747374
-rw-r--r--Documentation/hwmon/asc7621296
-rw-r--r--Documentation/hwmon/it8753
-rw-r--r--Documentation/hwmon/lm9022
-rw-r--r--Documentation/init.txt49
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--Documentation/power/runtime_pm.txt93
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/i2c.txt30
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt2
-rw-r--r--MAINTAINERS63
-rw-r--r--arch/alpha/kernel/osf_sys.c3
-rw-r--r--arch/cris/Kconfig6
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c2
-rw-r--r--arch/cris/arch-v32/mach-fs/arbiter.c2
-rw-r--r--arch/cris/kernel/time.c68
-rw-r--r--arch/frv/include/asm/pci.h37
-rw-r--r--arch/ia64/include/asm/elf.h48
-rw-r--r--arch/ia64/kernel/Makefile2
-rw-r--r--arch/ia64/kernel/elfcore.c80
-rw-r--r--arch/ia64/kernel/perfmon.c1
-rw-r--r--arch/ia64/mm/init.c2
-rw-r--r--arch/parisc/Kconfig.debug14
-rw-r--r--arch/parisc/include/asm/param.h23
-rw-r--r--arch/parisc/include/asm/system.h2
-rw-r--r--arch/parisc/include/asm/uaccess.h27
-rw-r--r--arch/parisc/include/asm/unistd.h4
-rw-r--r--arch/parisc/kernel/cache.c4
-rw-r--r--arch/parisc/kernel/syscall_table.S2
-rw-r--r--arch/parisc/kernel/time.c29
-rw-r--r--arch/parisc/kernel/unaligned.c14
-rw-r--r--arch/parisc/lib/memcpy.c3
-rw-r--r--arch/powerpc/mm/numa.c6
-rw-r--r--arch/s390/include/asm/qdio.h7
-rw-r--r--arch/s390/kernel/time.c10
-rw-r--r--arch/s390/lib/Makefile3
-rw-r--r--arch/s390/mm/cmm.c2
-rw-r--r--arch/sh/boards/mach-migor/setup.c16
-rw-r--r--arch/sh/boot/compressed/cache.c2
-rw-r--r--arch/sh/include/asm/cacheflush.h4
-rw-r--r--arch/sh/include/asm/dma-register.h51
-rw-r--r--arch/sh/include/asm/dma-sh.h88
-rw-r--r--arch/sh/include/asm/dmaengine.h93
-rw-r--r--arch/sh/include/asm/io.h23
-rw-r--r--arch/sh/include/asm/mmu.h31
-rw-r--r--arch/sh/include/asm/siu.h2
-rw-r--r--arch/sh/include/asm/topology.h2
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dma-register.h41
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dma.h27
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-register.h112
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-sh4a.h62
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma.h36
-rw-r--r--arch/sh/include/mach-migor/mach/migor.h1
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c190
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7724.c186
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c134
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c134
-rw-r--r--arch/sh/kernel/hw_breakpoint.c30
-rw-r--r--arch/sh/kernel/setup.c3
-rw-r--r--arch/sh/kernel/time.c6
-rw-r--r--arch/sh/lib/libgcc.h3
-rw-r--r--arch/sh/mm/ioremap.c70
-rw-r--r--arch/sh/mm/ioremap_fixed.c11
-rw-r--r--arch/sh/mm/numa.c3
-rw-r--r--arch/sh/mm/pmb.c412
-rw-r--r--arch/um/.gitignore3
-rw-r--r--arch/um/drivers/line.c4
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/asm/elf.h43
-rw-r--r--arch/um/sys-i386/elfcore.c83
-rw-r--r--arch/x86/Kconfig15
-rw-r--r--arch/x86/include/asm/apb_timer.h70
-rw-r--r--arch/x86/include/asm/hw_irq.h7
-rw-r--r--arch/x86/include/asm/i8259.h19
-rw-r--r--arch/x86/include/asm/io_apic.h7
-rw-r--r--arch/x86/include/asm/irq.h1
-rw-r--r--arch/x86/include/asm/mrst.h19
-rw-r--r--arch/x86/include/asm/numaq.h1
-rw-r--r--arch/x86/include/asm/olpc.h20
-rw-r--r--arch/x86/include/asm/pci.h9
-rw-r--r--arch/x86/include/asm/pci_x86.h22
-rw-r--r--arch/x86/include/asm/setup.h2
-rw-r--r--arch/x86/include/asm/visws/cobalt.h2
-rw-r--r--arch/x86/include/asm/x86_init.h15
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/acpi/boot.c4
-rw-r--r--arch/x86/kernel/apb_timer.c784
-rw-r--r--arch/x86/kernel/apic/apic.c8
-rw-r--r--arch/x86/kernel/apic/io_apic.c86
-rw-r--r--arch/x86/kernel/apic/nmi.c2
-rw-r--r--arch/x86/kernel/apic/numaq_32.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Kconfig14
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Makefile1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c620
-rw-r--r--arch/x86/kernel/cpu/perf_event.c2
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c2
-rw-r--r--arch/x86/kernel/i8259.c64
-rw-r--r--arch/x86/kernel/irqinit.c9
-rw-r--r--arch/x86/kernel/mrst.c216
-rw-r--r--arch/x86/kernel/olpc.c10
-rw-r--r--arch/x86/kernel/smpboot.c9
-rw-r--r--arch/x86/kernel/visws_quirks.c21
-rw-r--r--arch/x86/kernel/x86_init.c8
-rw-r--r--arch/x86/pci/Makefile2
-rw-r--r--arch/x86/pci/acpi.c7
-rw-r--r--arch/x86/pci/common.c6
-rw-r--r--arch/x86/pci/init.c8
-rw-r--r--arch/x86/pci/irq.c16
-rw-r--r--arch/x86/pci/legacy.c24
-rw-r--r--arch/x86/pci/mrst.c262
-rw-r--r--arch/x86/pci/numaq_32.c6
-rw-r--r--arch/x86/pci/olpc.c3
-rw-r--r--arch/x86/pci/visws.c6
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/base/power/Makefile1
-rw-r--r--drivers/base/power/generic_ops.c233
-rw-r--r--drivers/char/hvc_iucv.c6
-rw-r--r--drivers/char/virtio_console.c29
-rw-r--r--drivers/clocksource/Kconfig9
-rw-r--r--drivers/cpuidle/governors/menu.c2
-rw-r--r--drivers/dma/ioat/dma.c2
-rw-r--r--drivers/dma/shdma.c500
-rw-r--r--drivers/dma/shdma.h26
-rw-r--r--drivers/eisa/eisa-bus.c240
-rw-r--r--drivers/firmware/memmap.c57
-rw-r--r--drivers/gpio/Kconfig57
-rw-r--r--drivers/gpio/Makefile6
-rw-r--r--drivers/gpio/cs5535-gpio.c4
-rw-r--r--drivers/gpio/gpiolib.c58
-rw-r--r--drivers/gpio/it8761e_gpio.c231
-rw-r--r--drivers/gpio/max7300.c94
-rw-r--r--drivers/gpio/max7301.c293
-rw-r--r--drivers/gpio/max730x.c244
-rw-r--r--drivers/gpio/pca953x.c249
-rw-r--r--drivers/gpio/pl061.c2
-rw-r--r--drivers/gpio/sch_gpio.c295
-rw-r--r--drivers/gpio/timbgpio.c35
-rw-r--r--drivers/gpio/wm831x-gpio.c45
-rw-r--r--drivers/gpio/wm8350-gpiolib.c181
-rw-r--r--drivers/gpio/wm8994-gpio.c204
-rw-r--r--drivers/hwmon/Kconfig45
-rw-r--r--drivers/hwmon/Makefile3
-rw-r--r--drivers/hwmon/adcxx.c15
-rw-r--r--drivers/hwmon/adt7411.c366
-rw-r--r--drivers/hwmon/adt7473.c1180
-rw-r--r--drivers/hwmon/asc7621.c1255
-rw-r--r--drivers/hwmon/fschmd.c15
-rw-r--r--drivers/hwmon/g760a.c2
-rw-r--r--drivers/hwmon/it87.c939
-rw-r--r--drivers/hwmon/lm90.c89
-rw-r--r--drivers/hwmon/tmp401.c7
-rw-r--r--drivers/hwmon/tmp421.c24
-rw-r--r--drivers/hwmon/vt8231.c3
-rw-r--r--drivers/hwmon/w83793.c482
-rw-r--r--drivers/i2c/busses/Kconfig26
-rw-r--r--drivers/i2c/busses/Makefile2
-rw-r--r--drivers/i2c/busses/i2c-designware.c4
-rw-r--r--drivers/i2c/busses/i2c-imx.c1
-rw-r--r--drivers/i2c/busses/i2c-isch.c68
-rw-r--r--drivers/i2c/busses/i2c-mpc.c194
-rw-r--r--drivers/i2c/busses/i2c-nomadik.c959
-rw-r--r--drivers/i2c/busses/i2c-omap.c44
-rw-r--r--drivers/i2c/busses/i2c-pnx.c11
-rw-r--r--drivers/i2c/busses/i2c-xiic.c824
-rw-r--r--drivers/infiniband/core/mad.c21
-rw-r--r--drivers/input/misc/88pm860x_onkey.c155
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/touchscreen/88pm860x-ts.c236
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/mc13783_ts.c4
-rw-r--r--drivers/leds/Kconfig7
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-88pm860x.c325
-rw-r--r--drivers/md/dm-crypt.c3
-rw-r--r--drivers/md/dm-delay.c8
-rw-r--r--drivers/md/dm-ioctl.c24
-rw-r--r--drivers/md/dm-linear.c3
-rw-r--r--drivers/md/dm-log.c3
-rw-r--r--drivers/md/dm-mpath.c111
-rw-r--r--drivers/md/dm-raid1.c53
-rw-r--r--drivers/md/dm-snap.c34
-rw-r--r--drivers/md/dm-stripe.c3
-rw-r--r--drivers/md/dm-table.c12
-rw-r--r--drivers/md/dm-uevent.c7
-rw-r--r--drivers/md/dm.c25
-rw-r--r--drivers/md/dm.h4
-rw-r--r--drivers/mfd/88pm8607.c302
-rw-r--r--drivers/mfd/88pm860x-core.c740
-rw-r--r--drivers/mfd/88pm860x-i2c.c236
-rw-r--r--drivers/mfd/Kconfig72
-rw-r--r--drivers/mfd/Makefile8
-rw-r--r--drivers/mfd/ab3100-core.c54
-rw-r--r--drivers/mfd/ab3100-otp.c13
-rw-r--r--drivers/mfd/htc-egpio.c2
-rw-r--r--drivers/mfd/htc-i2cpld.c710
-rw-r--r--drivers/mfd/lpc_sch.c133
-rw-r--r--drivers/mfd/max8925-core.c656
-rw-r--r--drivers/mfd/max8925-i2c.c211
-rw-r--r--drivers/mfd/mc13783-core.c73
-rw-r--r--drivers/mfd/mfd-core.c5
-rw-r--r--drivers/mfd/sh_mobile_sdhi.c6
-rw-r--r--drivers/mfd/sm501.c7
-rw-r--r--drivers/mfd/t7l66xb.c4
-rw-r--r--drivers/mfd/tc6393xb.c2
-rw-r--r--drivers/mfd/twl-core.c41
-rw-r--r--drivers/mfd/twl4030-power.c52
-rw-r--r--drivers/mfd/ucb1x00-core.c1
-rw-r--r--drivers/mfd/wm831x-core.c51
-rw-r--r--drivers/mfd/wm8350-core.c35
-rw-r--r--drivers/mfd/wm8350-irq.c155
-rw-r--r--drivers/mfd/wm8994-core.c537
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/iwmc3200top/main.c2
-rw-r--r--drivers/misc/lkdtm.c472
-rw-r--r--drivers/misc/sgi-xp/xpnet.c2
-rw-r--r--drivers/mmc/core/core.c12
-rw-r--r--drivers/mmc/core/sdio.c64
-rw-r--r--drivers/mmc/core/sdio_io.c56
-rw-r--r--drivers/mmc/host/Kconfig15
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/at91_mci.c224
-rw-r--r--drivers/mmc/host/bfin_sdh.c10
-rw-r--r--drivers/mmc/host/davinci_mmc.c45
-rw-r--r--drivers/mmc/host/ricoh_mmc.c262
-rw-r--r--drivers/mmc/host/s3cmci.c4
-rw-r--r--drivers/mmc/host/sdhci-pci.c24
-rw-r--r--drivers/mmc/host/sdhci.c76
-rw-r--r--drivers/mmc/host/tmio_mmc.c13
-rw-r--r--drivers/mmc/host/tmio_mmc.h6
-rw-r--r--drivers/mtd/ubi/build.c133
-rw-r--r--drivers/mtd/ubi/debug.h4
-rw-r--r--drivers/mtd/ubi/io.c120
-rw-r--r--drivers/mtd/ubi/scan.c11
-rw-r--r--drivers/mtd/ubi/wl.c17
-rw-r--r--drivers/net/gianfar.c12
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c2
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c2
-rw-r--r--drivers/parisc/eisa_enumerator.c2
-rw-r--r--drivers/parisc/superio.c2
-rw-r--r--drivers/pci/pci.c43
-rw-r--r--drivers/pci/quirks.c85
-rw-r--r--drivers/power/Kconfig7
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/max8925_power.c534
-rw-r--r--drivers/power/wm8350_power.c26
-rw-r--r--drivers/regulator/88pm8607.c318
-rw-r--r--drivers/regulator/Kconfig8
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/max8925-regulator.c306
-rw-r--r--drivers/regulator/wm8350-regulator.c2
-rw-r--r--drivers/rtc/Kconfig10
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c1
-rw-r--r--drivers/rtc/rtc-at91sam9.c2
-rw-r--r--drivers/rtc/rtc-coh901331.c5
-rw-r--r--drivers/rtc/rtc-ep93xx.c71
-rw-r--r--drivers/rtc/rtc-max8925.c314
-rw-r--r--drivers/rtc/rtc-mc13783.c214
-rw-r--r--drivers/rtc/rtc-mxc.c7
-rw-r--r--drivers/rtc/rtc-pcf2123.c2
-rw-r--r--drivers/rtc/rtc-twl.c4
-rw-r--r--drivers/rtc/rtc-wm8350.c11
-rw-r--r--drivers/s390/block/dasd.c36
-rw-r--r--drivers/s390/block/dasd_3990_erp.c4
-rw-r--r--drivers/s390/block/dasd_devmap.c13
-rw-r--r--drivers/s390/block/dasd_diag.c6
-rw-r--r--drivers/s390/block/dasd_eckd.c27
-rw-r--r--drivers/s390/block/dasd_fba.c10
-rw-r--r--drivers/s390/block/dasd_genhd.c3
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_ioctl.c6
-rw-r--r--drivers/s390/cio/device.c5
-rw-r--r--drivers/s390/cio/qdio_debug.c1
-rw-r--r--drivers/s390/cio/qdio_main.c3
-rw-r--r--drivers/s390/net/Kconfig10
-rw-r--r--drivers/s390/net/Makefile1
-rw-r--r--drivers/s390/net/qeth_core_main.c3
-rw-r--r--drivers/s390/net/smsgiucv.c15
-rw-r--r--drivers/s390/net/smsgiucv.h8
-rw-r--r--drivers/s390/net/smsgiucv_app.c211
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c2
-rw-r--r--drivers/serial/Kconfig4
-rw-r--r--drivers/serial/sh-sci.c616
-rw-r--r--drivers/staging/Kconfig14
-rw-r--r--drivers/staging/Makefile8
-rw-r--r--drivers/staging/altpciechdma/Kconfig10
-rw-r--r--drivers/staging/altpciechdma/Makefile2
-rw-r--r--drivers/staging/altpciechdma/TODO15
-rw-r--r--drivers/staging/altpciechdma/altpciechdma.c1182
-rw-r--r--drivers/staging/arlan/Makefile2
-rw-r--r--drivers/staging/arlan/arlan.h136
-rw-r--r--drivers/staging/asus_oled/asus_oled.c21
-rw-r--r--drivers/staging/b3dfg/Kconfig10
-rw-r--r--drivers/staging/b3dfg/Makefile1
-rw-r--r--drivers/staging/b3dfg/TODO4
-rw-r--r--drivers/staging/b3dfg/b3dfg.c1100
-rw-r--r--drivers/staging/batman-adv/Kconfig6
-rw-r--r--drivers/staging/batman-adv/Makefile2
-rw-r--r--drivers/staging/batman-adv/README84
-rw-r--r--drivers/staging/batman-adv/TODO24
-rw-r--r--drivers/staging/batman-adv/aggregation.c13
-rw-r--r--drivers/staging/batman-adv/bitarray.c15
-rw-r--r--drivers/staging/batman-adv/compat.h75
-rw-r--r--drivers/staging/batman-adv/device.c53
-rw-r--r--drivers/staging/batman-adv/hard-interface.c209
-rw-r--r--drivers/staging/batman-adv/hard-interface.h4
-rw-r--r--drivers/staging/batman-adv/hash.c23
-rw-r--r--drivers/staging/batman-adv/hash.h5
-rw-r--r--drivers/staging/batman-adv/log.c179
-rw-r--r--drivers/staging/batman-adv/main.c55
-rw-r--r--drivers/staging/batman-adv/main.h46
-rw-r--r--drivers/staging/batman-adv/originator.c252
-rw-r--r--drivers/staging/batman-adv/originator.h (renamed from drivers/staging/batman-adv/log.h)19
-rw-r--r--drivers/staging/batman-adv/packet.h2
-rw-r--r--drivers/staging/batman-adv/proc.c508
-rw-r--r--drivers/staging/batman-adv/proc.h13
-rw-r--r--drivers/staging/batman-adv/routing.c1304
-rw-r--r--drivers/staging/batman-adv/routing.h21
-rw-r--r--drivers/staging/batman-adv/send.c172
-rw-r--r--drivers/staging/batman-adv/send.h5
-rw-r--r--drivers/staging/batman-adv/soft-interface.c96
-rw-r--r--drivers/staging/batman-adv/soft-interface.h3
-rw-r--r--drivers/staging/batman-adv/translation-table.c94
-rw-r--r--drivers/staging/batman-adv/translation-table.h1
-rw-r--r--drivers/staging/batman-adv/types.h14
-rw-r--r--drivers/staging/batman-adv/vis.c201
-rw-r--r--drivers/staging/batman-adv/vis.h13
-rw-r--r--drivers/staging/comedi/comedi_compat32.c1
-rw-r--r--drivers/staging/comedi/comedi_fops.c12
-rw-r--r--drivers/staging/comedi/drivers.c30
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c7
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_eeprom.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c12
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c121
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c2
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c6
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c6
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c66
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c21
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c4
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c122
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c46
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c16
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c57
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c28
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c12
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidio.c6
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c8
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c8
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c2
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c3
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c4
-rw-r--r--drivers/staging/comedi/drivers/das6402.c2
-rw-r--r--drivers/staging/comedi/drivers/das800.c6
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c5
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c33
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c89
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c2
-rw-r--r--drivers/staging/comedi/drivers/fl512.c72
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c2
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c49
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c73
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c32
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c34
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c24
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c276
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c83
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c29
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c26
-rw-r--r--drivers/staging/comedi/drivers/pcl725.c6
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c6
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c16
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c66
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c39
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c85
-rw-r--r--drivers/staging/comedi/drivers/pcm3730.c6
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c22
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c2
-rw-r--r--drivers/staging/comedi/drivers/poc.c14
-rw-r--r--drivers/staging/comedi/drivers/rti800.c61
-rw-r--r--drivers/staging/comedi/drivers/rti802.c8
-rw-r--r--drivers/staging/comedi/drivers/s626.c2
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c2
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c6
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c5
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c5
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c2
-rw-r--r--drivers/staging/crystalhd/Kconfig6
-rw-r--r--drivers/staging/crystalhd/Makefile6
-rw-r--r--drivers/staging/crystalhd/TODO16
-rw-r--r--drivers/staging/crystalhd/bc_dts_defs.h498
-rw-r--r--drivers/staging/crystalhd/bc_dts_glob_lnx.h299
-rw-r--r--drivers/staging/crystalhd/bc_dts_types.h121
-rw-r--r--drivers/staging/crystalhd/bcm_70012_regs.h757
-rw-r--r--drivers/staging/crystalhd/crystalhd_cmds.c1058
-rw-r--r--drivers/staging/crystalhd/crystalhd_cmds.h88
-rw-r--r--drivers/staging/crystalhd/crystalhd_fw_if.h369
-rw-r--r--drivers/staging/crystalhd/crystalhd_hw.c2395
-rw-r--r--drivers/staging/crystalhd/crystalhd_hw.h398
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.c765
-rw-r--r--drivers/staging/crystalhd/crystalhd_lnx.h96
-rw-r--r--drivers/staging/crystalhd/crystalhd_misc.c1030
-rw-r--r--drivers/staging/crystalhd/crystalhd_misc.h229
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c3
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c4
-rw-r--r--drivers/staging/cx25821/cx25821-video.c5
-rw-r--r--drivers/staging/dream/camera/Kconfig2
-rw-r--r--drivers/staging/dream/camera/Makefile1
-rw-r--r--drivers/staging/dream/camera/msm_camera.c69
-rw-r--r--drivers/staging/dream/camera/msm_vfe7x.c3
-rw-r--r--drivers/staging/dream/camera/s5k3e2fx.c30
-rw-r--r--drivers/staging/dream/include/linux/android_pmem.h80
-rw-r--r--drivers/staging/dream/include/linux/gpio_event.h154
-rw-r--r--drivers/staging/dream/include/linux/msm_adsp.h84
-rw-r--r--drivers/staging/dream/include/linux/msm_audio.h115
-rw-r--r--drivers/staging/dream/include/linux/msm_rpcrouter.h47
-rw-r--r--drivers/staging/dream/include/linux/wakelock.h91
-rw-r--r--drivers/staging/dream/include/mach/camera.h279
-rw-r--r--drivers/staging/dream/include/mach/msm_adsp.h112
-rw-r--r--drivers/staging/dream/include/mach/msm_rpcrouter.h179
-rw-r--r--drivers/staging/dream/include/mach/msm_smd.h107
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h94
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h70
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h914
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h318
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h256
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h85
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h176
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h127
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h376
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h177
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h82
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h80
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h235
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h107
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h212
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h910
-rw-r--r--drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h290
-rw-r--r--drivers/staging/dream/include/media/msm_camera.h388
-rw-r--r--drivers/staging/dream/pmem.c26
-rw-r--r--drivers/staging/dream/qdsp5/Makefile1
-rw-r--r--drivers/staging/dream/qdsp5/audio_mp3.c3
-rw-r--r--drivers/staging/dream/smd/Makefile1
-rw-r--r--drivers/staging/dream/smd/smd_rpcrouter.c2
-rw-r--r--drivers/staging/dt3155/Kconfig4
-rw-r--r--drivers/staging/dt3155/Makefile6
-rw-r--r--drivers/staging/dt3155/TODO10
-rw-r--r--drivers/staging/dt3155/allocator.README98
-rw-r--r--drivers/staging/dt3155/allocator.c295
-rw-r--r--drivers/staging/dt3155/allocator.h28
-rw-r--r--drivers/staging/dt3155/dt3155.h171
-rw-r--r--drivers/staging/dt3155/dt3155.sysvinit60
-rw-r--r--drivers/staging/dt3155/dt3155_drv.c1095
-rw-r--r--drivers/staging/dt3155/dt3155_drv.h45
-rw-r--r--drivers/staging/dt3155/dt3155_io.c175
-rw-r--r--drivers/staging/dt3155/dt3155_io.h358
-rw-r--r--drivers/staging/dt3155/dt3155_isr.c516
-rw-r--r--drivers/staging/dt3155/dt3155_isr.h77
-rw-r--r--drivers/staging/et131x/et1310_address_map.h617
-rw-r--r--drivers/staging/et131x/et1310_eeprom.c41
-rw-r--r--drivers/staging/et131x/et1310_eeprom.h103
-rw-r--r--drivers/staging/et131x/et1310_jagcore.h94
-rw-r--r--drivers/staging/et131x/et1310_mac.c104
-rw-r--r--drivers/staging/et131x/et1310_mac.h93
-rw-r--r--drivers/staging/et131x/et1310_phy.c7
-rw-r--r--drivers/staging/et131x/et1310_phy.h34
-rw-r--r--drivers/staging/et131x/et1310_pm.c6
-rw-r--r--drivers/staging/et131x/et1310_pm.h85
-rw-r--r--drivers/staging/et131x/et1310_rx.c301
-rw-r--r--drivers/staging/et131x/et1310_rx.h253
-rw-r--r--drivers/staging/et131x/et1310_tx.c10
-rw-r--r--drivers/staging/et131x/et1310_tx.h14
-rw-r--r--drivers/staging/et131x/et131x.h153
-rw-r--r--drivers/staging/et131x/et131x_adapter.h43
-rw-r--r--drivers/staging/et131x/et131x_config.h67
-rw-r--r--drivers/staging/et131x/et131x_initpci.c12
-rw-r--r--drivers/staging/et131x/et131x_initpci.h73
-rw-r--r--drivers/staging/et131x/et131x_isr.c34
-rw-r--r--drivers/staging/et131x/et131x_isr.h65
-rw-r--r--drivers/staging/et131x/et131x_netdev.c63
-rw-r--r--drivers/staging/et131x/et131x_netdev.h64
-rw-r--r--drivers/staging/et131x/et131x_version.h9
-rw-r--r--drivers/staging/frontier/alphatrack.c2
-rw-r--r--drivers/staging/frontier/tranzport.c2
-rw-r--r--drivers/staging/go7007/go7007-driver.c2
-rw-r--r--drivers/staging/go7007/go7007-usb.c4
-rw-r--r--drivers/staging/go7007/s2250-board.c2
-rw-r--r--drivers/staging/go7007/s2250-loader.c4
-rw-r--r--drivers/staging/go7007/saa7134-go7007.c1
-rw-r--r--drivers/staging/go7007/wis-ov7640.c2
-rw-r--r--drivers/staging/go7007/wis-saa7113.c2
-rw-r--r--drivers/staging/go7007/wis-saa7115.c2
-rw-r--r--drivers/staging/go7007/wis-sony-tuner.c2
-rw-r--r--drivers/staging/go7007/wis-tw2804.c2
-rw-r--r--drivers/staging/go7007/wis-tw9903.c2
-rw-r--r--drivers/staging/go7007/wis-uda1342.c2
-rw-r--r--drivers/staging/hv/Channel.c3
-rw-r--r--drivers/staging/hv/Hv.c205
-rw-r--r--drivers/staging/hv/Hv.h10
-rw-r--r--drivers/staging/hv/NetVscApi.h4
-rw-r--r--drivers/staging/hv/RingBuffer.c153
-rw-r--r--drivers/staging/hv/RndisFilter.c10
-rw-r--r--drivers/staging/hv/StorVsc.c3
-rw-r--r--drivers/staging/hv/StorVscApi.h5
-rw-r--r--drivers/staging/hv/VersionInfo.h22
-rw-r--r--drivers/staging/hv/Vmbus.c6
-rw-r--r--drivers/staging/hv/blkvsc_drv.c10
-rw-r--r--drivers/staging/hv/netvsc_drv.c29
-rw-r--r--drivers/staging/hv/storvsc_drv.c227
-rw-r--r--drivers/staging/hv/vmbus.h12
-rw-r--r--drivers/staging/hv/vmbus_drv.c68
-rw-r--r--drivers/staging/iio/industrialio-core.c35
-rw-r--r--drivers/staging/iio/ring_generic.h3
-rw-r--r--drivers/staging/iio/ring_sw.c3
-rw-r--r--drivers/staging/iio/trigger_consumer.h4
-rw-r--r--drivers/staging/line6/driver.c2
-rw-r--r--drivers/staging/line6/variax.c2
-rw-r--r--drivers/staging/mimio/Kconfig10
-rw-r--r--drivers/staging/mimio/Makefile1
-rw-r--r--drivers/staging/mimio/mimio.c914
-rw-r--r--drivers/staging/otus/80211core/cagg.c18
-rw-r--r--drivers/staging/otus/80211core/ccmd.c2
-rw-r--r--drivers/staging/otus/80211core/cfunc.c2
-rw-r--r--drivers/staging/otus/80211core/cmm.c4
-rw-r--r--drivers/staging/otus/80211core/cmmsta.c7
-rw-r--r--drivers/staging/otus/80211core/cpsmgr.c2
-rw-r--r--drivers/staging/otus/80211core/cscanmgr.c2
-rw-r--r--drivers/staging/otus/80211core/ctkip.c5
-rw-r--r--drivers/staging/otus/80211core/ctxrx.c8
-rw-r--r--drivers/staging/otus/80211core/ledmgr.c1
-rw-r--r--drivers/staging/otus/80211core/pub_zfi.h1
-rw-r--r--drivers/staging/otus/Kconfig2
-rw-r--r--drivers/staging/otus/apdbg.c53
-rw-r--r--drivers/staging/otus/hal/hpmain.c4
-rw-r--r--drivers/staging/otus/hal/hpreg.c133
-rw-r--r--drivers/staging/otus/hal/hprw.c1
-rw-r--r--drivers/staging/otus/ioctl.c16
-rw-r--r--drivers/staging/otus/usbdrv.c4
-rw-r--r--drivers/staging/otus/wrap_pkt.c10
-rw-r--r--drivers/staging/otus/zdusb.c2
-rw-r--r--drivers/staging/p9auth/Kconfig9
-rw-r--r--drivers/staging/p9auth/Makefile1
-rw-r--r--drivers/staging/p9auth/p9auth.c408
-rw-r--r--drivers/staging/panel/panel.c1
-rw-r--r--drivers/staging/phison/phison.c2
-rw-r--r--drivers/staging/pohmelfs/inode.c28
-rw-r--r--drivers/staging/pohmelfs/netfs.h3
-rw-r--r--drivers/staging/quatech_usb2/quatech_usb2.c2
-rw-r--r--drivers/staging/ramzswap/Kconfig2
-rw-r--r--drivers/staging/ramzswap/ramzswap.txt6
-rw-r--r--drivers/staging/ramzswap/ramzswap_drv.c144
-rw-r--r--drivers/staging/ramzswap/ramzswap_drv.h67
-rw-r--r--drivers/staging/ramzswap/ramzswap_ioctl.h7
-rw-r--r--drivers/staging/ramzswap/xvmalloc.c4
-rw-r--r--drivers/staging/ramzswap/xvmalloc.h2
-rw-r--r--drivers/staging/ramzswap/xvmalloc_int.h4
-rw-r--r--drivers/staging/rar/Kconfig17
-rw-r--r--drivers/staging/rar/Makefile2
-rw-r--r--drivers/staging/rar/rar_driver.c444
-rw-r--r--drivers/staging/rar/rar_driver.h99
-rw-r--r--drivers/staging/rar_register/Kconfig30
-rw-r--r--drivers/staging/rar_register/Makefile2
-rw-r--r--drivers/staging/rar_register/rar_register.c615
-rw-r--r--drivers/staging/rar_register/rar_register.h84
-rw-r--r--drivers/staging/rt2860/Kconfig2
-rw-r--r--drivers/staging/rt2860/common/firmware.h558
-rw-r--r--drivers/staging/rt2860/common/firmware_3070.h517
-rw-r--r--drivers/staging/rt2860/common/rtmp_mcu.c167
-rw-r--r--drivers/staging/rt2860/rt_linux.c13
-rw-r--r--drivers/staging/rt2860/rt_linux.h4
-rw-r--r--drivers/staging/rt2860/rt_main_dev.c2
-rw-r--r--drivers/staging/rt2860/rtmp.h7
-rw-r--r--drivers/staging/rt2860/sta/connect.c4
-rw-r--r--drivers/staging/rt2860/sta_ioctl.c5
-rw-r--r--drivers/staging/rt2860/usb_main_dev.c6
-rw-r--r--drivers/staging/rt2870/Kconfig2
-rw-r--r--drivers/staging/rt2870/common/rtusb_io.c10
-rw-r--r--drivers/staging/rt3070/firmware.h558
-rw-r--r--drivers/staging/rt3070/md4.h8
-rw-r--r--drivers/staging/rt3090/firmware.h517
-rw-r--r--drivers/staging/rtl8187se/Kconfig1
-rw-r--r--drivers/staging/rtl8187se/Makefile1
-rw-r--r--drivers/staging/rtl8187se/TODO1
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h5
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c21
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c20
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c48
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c2
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c3
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c6
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c6
-rw-r--r--drivers/staging/rtl8187se/r8180.h4
-rw-r--r--drivers/staging/rtl8187se/r8180_93cx6.c146
-rw-r--r--drivers/staging/rtl8187se/r8180_93cx6.h17
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c502
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.c67
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225z2.c232
-rw-r--r--drivers/staging/rtl8187se/r8185b_init.c986
-rw-r--r--drivers/staging/rtl8192e/Makefile9
-rw-r--r--drivers/staging/rtl8192e/dot11d.h138
-rw-r--r--drivers/staging/rtl8192e/ieee80211.h3
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211.h160
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c2
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c37
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c29
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c148
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c246
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c26
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c80
-rw-r--r--drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c6
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c6
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h4
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c65
-rw-r--r--drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c6
-rw-r--r--drivers/staging/rtl8192e/r8180_93cx6.c63
-rw-r--r--drivers/staging/rtl8192e/r8180_93cx6.h33
-rw-r--r--drivers/staging/rtl8192e/r8190_rtl8256.c360
-rw-r--r--drivers/staging/rtl8192e/r8190_rtl8256.h49
-rw-r--r--drivers/staging/rtl8192e/r8192E.h23
-rw-r--r--drivers/staging/rtl8192e/r8192E_core.c773
-rw-r--r--drivers/staging/rtl8192e/r8192E_dm.c40
-rw-r--r--drivers/staging/rtl8192e/r8192E_hw.h8
-rw-r--r--drivers/staging/rtl8192e/r8192E_wx.c212
-rw-r--r--drivers/staging/rtl8192e/r8192E_wx.h1
-rw-r--r--drivers/staging/rtl8192e/r819xE_cmdpkt.c2
-rw-r--r--drivers/staging/rtl8192e/r819xE_firmware.c85
-rw-r--r--drivers/staging/rtl8192e/r819xE_phy.c2
-rw-r--r--drivers/staging/rtl8192e/r819xE_phy.h194
-rw-r--r--drivers/staging/rtl8192e/r819xE_phyreg.h1117
-rw-r--r--drivers/staging/rtl8192su/Kconfig3
-rw-r--r--drivers/staging/rtl8192su/TODO1
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211.h5
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c19
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c21
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c20
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_module.c2
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c48
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c6
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c4
-rw-r--r--drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c6
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c21
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c2
-rw-r--r--drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c6
-rw-r--r--drivers/staging/rtl8192su/r8192SU_HWImg.c4276
-rw-r--r--drivers/staging/rtl8192su/r8192SU_HWImg.h2
-rw-r--r--drivers/staging/rtl8192su/r8192S_firmware.c126
-rw-r--r--drivers/staging/rtl8192su/r8192S_firmware.h7
-rw-r--r--drivers/staging/rtl8192su/r8192S_phy.c16
-rw-r--r--drivers/staging/rtl8192su/r8192U.h1
-rw-r--r--drivers/staging/rtl8192su/r8192U_core.c183
-rw-r--r--drivers/staging/rtl8192su/r8192U_dm.c2
-rw-r--r--drivers/staging/rtl8192u/Kconfig3
-rw-r--r--drivers/staging/rtl8192u/Makefile2
-rw-r--r--drivers/staging/rtl8192u/ieee80211.h3
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211.h4
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c21
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c20
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_module.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c48
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c2
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c4
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c6
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c6
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c4
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c6
-rw-r--r--drivers/staging/rtl8192u/r8192U_core.c8
-rw-r--r--drivers/staging/samsung-laptop/samsung-laptop.c9
-rw-r--r--drivers/staging/sep/sep_driver.c28
-rw-r--r--drivers/staging/serqt_usb2/serqt_usb2.c4
-rw-r--r--drivers/staging/slicoss/slic.h9
-rw-r--r--drivers/staging/slicoss/slicoss.c116
-rw-r--r--drivers/staging/sm7xx/Kconfig7
-rw-r--r--drivers/staging/sm7xx/TODO1
-rw-r--r--drivers/staging/sm7xx/smtc2d.c979
-rw-r--r--drivers/staging/sm7xx/smtc2d.h530
-rw-r--r--drivers/staging/sm7xx/smtcfb.c131
-rw-r--r--drivers/staging/udlfb/Kconfig14
-rw-r--r--drivers/staging/udlfb/udlfb.c1993
-rw-r--r--drivers/staging/udlfb/udlfb.h281
-rw-r--r--drivers/staging/usbip/Kconfig7
-rw-r--r--drivers/staging/usbip/Makefile2
-rw-r--r--drivers/staging/usbip/usbip_common.c90
-rw-r--r--drivers/staging/usbip/usbip_common.h8
-rw-r--r--drivers/staging/vme/Kconfig2
-rw-r--r--drivers/staging/vme/Makefile1
-rw-r--r--drivers/staging/vme/TODO28
-rw-r--r--drivers/staging/vme/boards/Kconfig9
-rw-r--r--drivers/staging/vme/boards/Makefile5
-rw-r--r--drivers/staging/vme/boards/vme_vmivme7805.c124
-rw-r--r--drivers/staging/vme/boards/vme_vmivme7805.h37
-rw-r--r--drivers/staging/vme/bridges/Kconfig2
-rw-r--r--drivers/staging/vme/bridges/vme_ca91cx42.c1592
-rw-r--r--drivers/staging/vme/bridges/vme_ca91cx42.h136
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.c1010
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.h16
-rw-r--r--drivers/staging/vme/devices/vme_user.c65
-rw-r--r--drivers/staging/vme/vme.c248
-rw-r--r--drivers/staging/vme/vme.h33
-rw-r--r--drivers/staging/vme/vme_api.txt27
-rw-r--r--drivers/staging/vme/vme_bridge.h107
-rw-r--r--drivers/staging/vt6655/card.c6
-rw-r--r--drivers/staging/vt6655/device_main.c5
-rw-r--r--drivers/staging/vt6655/iwctl.c2
-rw-r--r--drivers/staging/winbond/core.h2
-rw-r--r--drivers/staging/winbond/localpara.h34
-rw-r--r--drivers/staging/winbond/mds_f.h3
-rw-r--r--drivers/staging/winbond/mds_s.h28
-rw-r--r--drivers/staging/winbond/mlme_s.h8
-rw-r--r--drivers/staging/winbond/mto.h5
-rw-r--r--drivers/staging/winbond/reg.c10
-rw-r--r--drivers/staging/winbond/scan_s.h1
-rw-r--r--drivers/staging/winbond/sme_api.h4
-rw-r--r--drivers/staging/winbond/wb35reg_f.h2
-rw-r--r--drivers/staging/winbond/wbusb.c24
-rw-r--r--drivers/staging/wlags49_h2/wl_main.c2
-rw-r--r--drivers/staging/wlags49_h2/wl_netdev.c2
-rw-r--r--drivers/staging/wlags49_h2/wl_pci.c1
-rw-r--r--drivers/staging/wlags49_h2/wl_profile.c76
-rw-r--r--drivers/staging/wlags49_h2/wl_util.c49
-rw-r--r--drivers/staging/wlags49_h2/wl_util.h2
-rw-r--r--drivers/staging/wlan-ng/Kconfig4
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h180
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c42
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c16
-rw-r--r--drivers/staging/wlan-ng/p80211conv.h4
-rw-r--r--drivers/staging/wlan-ng/p80211metadef.h18
-rw-r--r--drivers/staging/wlan-ng/p80211mgmt.h42
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c7
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h44
-rw-r--r--drivers/staging/wlan-ng/p80211req.c2
-rw-r--r--drivers/staging/wlan-ng/p80211req.h2
-rw-r--r--drivers/staging/wlan-ng/p80211types.h18
-rw-r--r--drivers/staging/wlan-ng/p80211wext.c83
-rw-r--r--drivers/staging/wlan-ng/prism2fw.c69
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c30
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h48
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c10
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c20
-rw-r--r--drivers/staging/wlan-ng/prism2usb.c6
-rw-r--r--drivers/usb/core/devices.c69
-rw-r--r--drivers/video/backlight/88pm860x_bl.c304
-rw-r--r--drivers/video/backlight/Kconfig13
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/max8925_bl.c200
-rw-r--r--drivers/video/console/Kconfig1
-rw-r--r--drivers/video/console/vgacon.c2
-rw-r--r--drivers/virtio/virtio_pci.c1
-rw-r--r--drivers/xen/Kconfig12
-rw-r--r--fs/Kconfig1
-rw-r--r--fs/Makefile1
-rw-r--r--fs/attr.c2
-rw-r--r--fs/binfmt_aout.c38
-rw-r--r--fs/binfmt_elf.c151
-rw-r--r--fs/binfmt_elf_fdpic.c181
-rw-r--r--fs/binfmt_flat.c2
-rw-r--r--fs/compat_binfmt_elf.c2
-rw-r--r--fs/compat_ioctl.c4
-rw-r--r--fs/exec.c50
-rw-r--r--fs/fcntl.c2
-rw-r--r--fs/file.c2
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/fscache/Kconfig1
-rw-r--r--fs/lockd/host.c2
-rw-r--r--fs/lockd/mon.c12
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/logfs/Kconfig17
-rw-r--r--fs/logfs/Makefile13
-rw-r--r--fs/logfs/compr.c95
-rw-r--r--fs/logfs/dev_bdev.c327
-rw-r--r--fs/logfs/dev_mtd.c254
-rw-r--r--fs/logfs/dir.c827
-rw-r--r--fs/logfs/file.c263
-rw-r--r--fs/logfs/gc.c730
-rw-r--r--fs/logfs/inode.c417
-rw-r--r--fs/logfs/journal.c883
-rw-r--r--fs/logfs/logfs.h724
-rw-r--r--fs/logfs/logfs_abi.h629
-rw-r--r--fs/logfs/readwrite.c2246
-rw-r--r--fs/logfs/segment.c927
-rw-r--r--fs/logfs/super.c650
-rw-r--r--fs/namei.c2
-rw-r--r--fs/nfs/callback.c2
-rw-r--r--fs/nfsd/nfs4callback.c5
-rw-r--r--fs/nfsd/nfs4recover.c4
-rw-r--r--fs/nfsd/nfs4state.c6
-rw-r--r--fs/nfsd/nfs4xdr.c2
-rw-r--r--fs/nfsd/nfsctl.c24
-rw-r--r--fs/nfsd/vfs.c153
-rw-r--r--fs/ocfs2/quota_local.c2
-rw-r--r--fs/proc/array.c4
-rw-r--r--fs/proc/generic.c33
-rw-r--r--fs/proc/task_mmu.c13
-rw-r--r--fs/select.c2
-rw-r--r--fs/seq_file.c4
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c221
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c20
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c854
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c10
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c796
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h29
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c10
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.c16
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h22
-rw-r--r--fs/xfs/xfs_bmap.c220
-rw-r--r--fs/xfs/xfs_fs.h3
-rw-r--r--fs/xfs/xfs_iget.c19
-rw-r--r--fs/xfs/xfs_inode.c68
-rw-r--r--fs/xfs/xfs_inode.h3
-rw-r--r--fs/xfs/xfs_inode_item.c18
-rw-r--r--fs/xfs/xfs_itable.c2
-rw-r--r--fs/xfs/xfs_log.c106
-rw-r--r--fs/xfs/xfs_log.h16
-rw-r--r--fs/xfs/xfs_mount.c69
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_trans.c2
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_buf.c216
-rw-r--r--fs/xfs/xfs_vnodeops.c107
-rw-r--r--fs/xfs/xfs_vnodeops.h15
-rw-r--r--include/asm-generic/gpio.h26
-rw-r--r--include/linux/binfmts.h1
-rw-r--r--include/linux/bitops.h4
-rw-r--r--include/linux/btree-128.h109
-rw-r--r--include/linux/btree-type.h147
-rw-r--r--include/linux/btree.h243
-rw-r--r--include/linux/coredump.h41
-rw-r--r--include/linux/cpumask.h8
-rw-r--r--include/linux/device-mapper.h5
-rw-r--r--include/linux/dm-io.h4
-rw-r--r--include/linux/dm-ioctl.h9
-rw-r--r--include/linux/elf.h28
-rw-r--r--include/linux/elfcore.h17
-rw-r--r--include/linux/exportfs.h5
-rw-r--r--include/linux/firmware-map.h6
-rw-r--r--include/linux/fs.h23
-rw-r--r--include/linux/gfp.h12
-rw-r--r--include/linux/htcpld.h24
-rw-r--r--include/linux/i2c/pca953x.h11
-rw-r--r--include/linux/i2c/twl.h28
-rw-r--r--include/linux/list.h6
-rw-r--r--include/linux/mfd/88pm8607.h217
-rw-r--r--include/linux/mfd/88pm860x.h375
-rw-r--r--include/linux/mfd/ab3100.h3
-rw-r--r--include/linux/mfd/max8925.h253
-rw-r--r--include/linux/mfd/mc13783.h26
-rw-r--r--include/linux/mfd/tmio.h3
-rw-r--r--include/linux/mfd/ucb1x00.h1
-rw-r--r--include/linux/mfd/wm831x/core.h6
-rw-r--r--include/linux/mfd/wm831x/gpio.h4
-rw-r--r--include/linux/mfd/wm8350/core.h49
-rw-r--r--include/linux/mfd/wm8350/gpio.h1
-rw-r--r--include/linux/mfd/wm8350/rtc.h1
-rw-r--r--include/linux/mfd/wm8994/core.h54
-rw-r--r--include/linux/mfd/wm8994/gpio.h72
-rw-r--r--include/linux/mfd/wm8994/pdata.h97
-rw-r--r--include/linux/mfd/wm8994/registers.h4292
-rw-r--r--include/linux/mm.h104
-rw-r--r--include/linux/mm_types.h43
-rw-r--r--include/linux/mmc/card.h7
-rw-r--r--include/linux/mmc/host.h5
-rw-r--r--include/linux/mmc/pm.h30
-rw-r--r--include/linux/mmc/sdio.h2
-rw-r--r--include/linux/mmc/sdio_func.h5
-rw-r--r--include/linux/mmzone.h7
-rw-r--r--include/linux/nodemask.h11
-rw-r--r--include/linux/pci.h2
-rw-r--r--include/linux/pci_regs.h1
-rw-r--r--include/linux/pm.h51
-rw-r--r--include/linux/pm_runtime.h6
-rw-r--r--include/linux/rmap.h38
-rw-r--r--include/linux/sched.h58
-rw-r--r--include/linux/serial_sci.h6
-rw-r--r--include/linux/smp.h2
-rw-r--r--include/linux/spi/max7301.h18
-rw-r--r--include/linux/usb/audio.h2
-rw-r--r--include/sound/asound.h2
-rw-r--r--init/initramfs.c12
-rw-r--r--init/main.c7
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/cpu.c2
-rw-r--r--kernel/elfcore.c28
-rw-r--r--kernel/exit.c5
-rw-r--r--kernel/fork.c19
-rw-r--r--kernel/panic.c46
-rw-r--r--kernel/params.c1
-rw-r--r--kernel/perf_event.c2
-rw-r--r--kernel/pid.c2
-rw-r--r--kernel/posix-cpu-timers.c36
-rw-r--r--kernel/power/hibernate.c9
-rw-r--r--kernel/power/suspend.c3
-rw-r--r--kernel/printk.c3
-rw-r--r--kernel/relay.c5
-rw-r--r--kernel/sched.c4
-rw-r--r--kernel/sched_cpupri.c2
-rw-r--r--kernel/sched_rt.c5
-rw-r--r--kernel/signal.c2
-rw-r--r--kernel/sys.c3
-rw-r--r--kernel/tsacct.c1
-rw-r--r--lib/Kconfig3
-rw-r--r--lib/Kconfig.debug5
-rw-r--r--lib/Makefile1
-rw-r--r--lib/bitmap.c19
-rw-r--r--lib/btree.c797
-rw-r--r--lib/crc32.c30
-rw-r--r--lib/list_sort.c263
-rw-r--r--lib/show_mem.c14
-rw-r--r--lib/string.c40
-rw-r--r--lib/vsprintf.c71
-rw-r--r--mm/fadvise.c10
-rw-r--r--mm/filemap.c2
-rw-r--r--mm/filemap_xip.c2
-rw-r--r--mm/fremap.c2
-rw-r--r--mm/ksm.c12
-rw-r--r--mm/memcontrol.c2
-rw-r--r--mm/memory-failure.c5
-rw-r--r--mm/memory.c161
-rw-r--r--mm/memory_hotplug.c4
-rw-r--r--mm/mempolicy.c112
-rw-r--r--mm/migrate.c4
-rw-r--r--mm/mlock.c12
-rw-r--r--mm/mmap.c151
-rw-r--r--mm/mremap.c9
-rw-r--r--mm/nommu.c6
-rw-r--r--mm/oom_kill.c4
-rw-r--r--mm/page_alloc.c53
-rw-r--r--mm/readahead.c6
-rw-r--r--mm/rmap.c185
-rw-r--r--mm/swap.c2
-rw-r--r--mm/swapfile.c40
-rw-r--r--mm/vmscan.c177
-rw-r--r--mm/vmstat.c2
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--net/sunrpc/svc_xprt.c27
-rw-r--r--net/sunrpc/svcauth_unix.c49
-rw-r--r--net/sunrpc/svcsock.c3
-rwxr-xr-xscripts/checkpatch.pl78
-rwxr-xr-xscripts/get_maintainer.pl185
-rw-r--r--sound/core/timer.c2
-rw-r--r--sound/isa/opti9xx/miro.c2
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c120
-rw-r--r--sound/isa/sb/jazz16.c1
-rw-r--r--sound/oss/coproc.h2
-rw-r--r--sound/oss/v_midi.h5
-rw-r--r--sound/pci/hda/Kconfig2
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_codec.c69
-rw-r--r--sound/pci/hda/hda_eld.c6
-rw-r--r--sound/pci/hda/hda_intel.c9
-rw-r--r--sound/pci/hda/patch_hdmi.c849
-rw-r--r--sound/pci/hda/patch_intelhdmi.c821
-rw-r--r--sound/pci/hda/patch_nvhdmi.c275
-rw-r--r--sound/pci/hda/patch_realtek.c10
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c2
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/soc/codecs/ak4104.c6
-rw-r--r--sound/soc/codecs/uda1380.c2
-rw-r--r--sound/soc/codecs/wm8350.c8
-rw-r--r--sound/soc/sh/siu.h2
-rw-r--r--sound/soc/sh/siu_pcm.c2
-rw-r--r--sound/soc/soc-core.c14
-rw-r--r--sound/usb/Kconfig6
-rw-r--r--sound/usb/caiaq/midi.h2
-rw-r--r--sound/usb/ua101.c100
-rw-r--r--sound/usb/usbaudio.c57
-rw-r--r--sound/usb/usbaudio.h3
-rw-r--r--sound/usb/usbquirks.h30
1007 files changed, 70517 insertions, 33398 deletions
diff --git a/.gitignore b/.gitignore
index de6344e15706..efab0ebec859 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,7 @@ modules.builtin
36# 36#
37tags 37tags
38TAGS 38TAGS
39linux
39vmlinux 40vmlinux
40vmlinuz 41vmlinuz
41System.map 42System.map
diff --git a/Documentation/ABI/stable/sysfs-devices-node b/Documentation/ABI/stable/sysfs-devices-node
new file mode 100644
index 000000000000..49b82cad7003
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-devices-node
@@ -0,0 +1,7 @@
1What: /sys/devices/system/node/nodeX
2Date: October 2002
3Contact: Linux Memory Management list <linux-mm@kvack.org>
4Description:
5 When CONFIG_NUMA is enabled, this is a directory containing
6 information on node X such as what CPUs are local to the
7 node.
diff --git a/Documentation/cpu-freq/pcc-cpufreq.txt b/Documentation/cpu-freq/pcc-cpufreq.txt
new file mode 100644
index 000000000000..9e3c3b33514c
--- /dev/null
+++ b/Documentation/cpu-freq/pcc-cpufreq.txt
@@ -0,0 +1,207 @@
1/*
2 * pcc-cpufreq.txt - PCC interface documentation
3 *
4 * Copyright (C) 2009 Red Hat, Matthew Garrett <mjg@redhat.com>
5 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
6 * Nagananda Chumbalkar <nagananda.chumbalkar@hp.com>
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or NON
17 * INFRINGEMENT. See the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
25
26
27 Processor Clocking Control Driver
28 ---------------------------------
29
30Contents:
31---------
321. Introduction
331.1 PCC interface
341.1.1 Get Average Frequency
351.1.2 Set Desired Frequency
361.2 Platforms affected
372. Driver and /sys details
382.1 scaling_available_frequencies
392.2 cpuinfo_transition_latency
402.3 cpuinfo_cur_freq
412.4 related_cpus
423. Caveats
43
441. Introduction:
45----------------
46Processor Clocking Control (PCC) is an interface between the platform
47firmware and OSPM. It is a mechanism for coordinating processor
48performance (ie: frequency) between the platform firmware and the OS.
49
50The PCC driver (pcc-cpufreq) allows OSPM to take advantage of the PCC
51interface.
52
53OS utilizes the PCC interface to inform platform firmware what frequency the
54OS wants for a logical processor. The platform firmware attempts to achieve
55the requested frequency. If the request for the target frequency could not be
56satisfied by platform firmware, then it usually means that power budget
57conditions are in place, and "power capping" is taking place.
58
591.1 PCC interface:
60------------------
61The complete PCC specification is available here:
62http://www.acpica.org/download/Processor-Clocking-Control-v1p0.pdf
63
64PCC relies on a shared memory region that provides a channel for communication
65between the OS and platform firmware. PCC also implements a "doorbell" that
66is used by the OS to inform the platform firmware that a command has been
67sent.
68
69The ACPI PCCH() method is used to discover the location of the PCC shared
70memory region. The shared memory region header contains the "command" and
71"status" interface. PCCH() also contains details on how to access the platform
72doorbell.
73
74The following commands are supported by the PCC interface:
75* Get Average Frequency
76* Set Desired Frequency
77
78The ACPI PCCP() method is implemented for each logical processor and is
79used to discover the offsets for the input and output buffers in the shared
80memory region.
81
82When PCC mode is enabled, the platform will not expose processor performance
83or throttle states (_PSS, _TSS and related ACPI objects) to OSPM. Therefore,
84the native P-state driver (such as acpi-cpufreq for Intel, powernow-k8 for
85AMD) will not load.
86
87However, OSPM remains in control of policy. The governor (eg: "ondemand")
88computes the required performance for each processor based on server workload.
89The PCC driver fills in the command interface, and the input buffer and
90communicates the request to the platform firmware. The platform firmware is
91responsible for delivering the requested performance.
92
93Each PCC command is "global" in scope and can affect all the logical CPUs in
94the system. Therefore, PCC is capable of performing "group" updates. With PCC
95the OS is capable of getting/setting the frequency of all the logical CPUs in
96the system with a single call to the BIOS.
97
981.1.1 Get Average Frequency:
99----------------------------
100This command is used by the OSPM to query the running frequency of the
101processor since the last time this command was completed. The output buffer
102indicates the average unhalted frequency of the logical processor expressed as
103a percentage of the nominal (ie: maximum) CPU frequency. The output buffer
104also signifies if the CPU frequency is limited by a power budget condition.
105
1061.1.2 Set Desired Frequency:
107----------------------------
108This command is used by the OSPM to communicate to the platform firmware the
109desired frequency for a logical processor. The output buffer is currently
110ignored by OSPM. The next invocation of "Get Average Frequency" will inform
111OSPM if the desired frequency was achieved or not.
112
1131.2 Platforms affected:
114-----------------------
115The PCC driver will load on any system where the platform firmware:
116* supports the PCC interface, and the associated PCCH() and PCCP() methods
117* assumes responsibility for managing the hardware clocking controls in order
118to deliver the requested processor performance
119
120Currently, certain HP ProLiant platforms implement the PCC interface. On those
121platforms PCC is the "default" choice.
122
123However, it is possible to disable this interface via a BIOS setting. In
124such an instance, as is also the case on platforms where the PCC interface
125is not implemented, the PCC driver will fail to load silently.
126
1272. Driver and /sys details:
128---------------------------
129When the driver loads, it merely prints the lowest and the highest CPU
130frequencies supported by the platform firmware.
131
132The PCC driver loads with a message such as:
133pcc-cpufreq: (v1.00.00) driver loaded with frequency limits: 1600 MHz, 2933
134MHz
135
136This means that the OPSM can request the CPU to run at any frequency in
137between the limits (1600 MHz, and 2933 MHz) specified in the message.
138
139Internally, there is no need for the driver to convert the "target" frequency
140to a corresponding P-state.
141
142The VERSION number for the driver will be of the format v.xy.ab.
143eg: 1.00.02
144 ----- --
145 | |
146 | -- this will increase with bug fixes/enhancements to the driver
147 |-- this is the version of the PCC specification the driver adheres to
148
149
150The following is a brief discussion on some of the fields exported via the
151/sys filesystem and how their values are affected by the PCC driver:
152
1532.1 scaling_available_frequencies:
154----------------------------------
155scaling_available_frequencies is not created in /sys. No intermediate
156frequencies need to be listed because the BIOS will try to achieve any
157frequency, within limits, requested by the governor. A frequency does not have
158to be strictly associated with a P-state.
159
1602.2 cpuinfo_transition_latency:
161-------------------------------
162The cpuinfo_transition_latency field is 0. The PCC specification does
163not include a field to expose this value currently.
164
1652.3 cpuinfo_cur_freq:
166---------------------
167A) Often cpuinfo_cur_freq will show a value different than what is declared
168in the scaling_available_frequencies or scaling_cur_freq, or scaling_max_freq.
169This is due to "turbo boost" available on recent Intel processors. If certain
170conditions are met the BIOS can achieve a slightly higher speed than requested
171by OSPM. An example:
172
173scaling_cur_freq : 2933000
174cpuinfo_cur_freq : 3196000
175
176B) There is a round-off error associated with the cpuinfo_cur_freq value.
177Since the driver obtains the current frequency as a "percentage" (%) of the
178nominal frequency from the BIOS, sometimes, the values displayed by
179scaling_cur_freq and cpuinfo_cur_freq may not match. An example:
180
181scaling_cur_freq : 1600000
182cpuinfo_cur_freq : 1583000
183
184In this example, the nominal frequency is 2933 MHz. The driver obtains the
185current frequency, cpuinfo_cur_freq, as 54% of the nominal frequency:
186
187 54% of 2933 MHz = 1583 MHz
188
189Nominal frequency is the maximum frequency of the processor, and it usually
190corresponds to the frequency of the P0 P-state.
191
1922.4 related_cpus:
193-----------------
194The related_cpus field is identical to affected_cpus.
195
196affected_cpus : 4
197related_cpus : 4
198
199Currently, the PCC driver does not evaluate _PSD. The platforms that support
200PCC do not implement SW_ALL. So OSPM doesn't need to perform any coordination
201to ensure that the same frequency is requested of all dependent CPUs.
202
2033. Caveats:
204-----------
205The "cpufreq_stats" module in its present form cannot be loaded and
206expected to work with the PCC driver. Since the "cpufreq_stats" module
207provides information wrt each P-state, it is not applicable to the PCC driver.
diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt
index e3a77b215135..0d5bc46dc167 100644
--- a/Documentation/device-mapper/snapshot.txt
+++ b/Documentation/device-mapper/snapshot.txt
@@ -122,3 +122,47 @@ volumeGroup-base: 0 2097152 snapshot-merge 254:11 254:12 P 16
122brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real 122brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
123brw------- 1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow 123brw------- 1 root root 254, 12 29 ago 18:16 /dev/mapper/volumeGroup-base-cow
124brw------- 1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base 124brw------- 1 root root 254, 10 29 ago 18:16 /dev/mapper/volumeGroup-base
125
126
127How to determine when a merging is complete
128===========================================
129The snapshot-merge and snapshot status lines end with:
130 <sectors_allocated>/<total_sectors> <metadata_sectors>
131
132Both <sectors_allocated> and <total_sectors> include both data and metadata.
133During merging, the number of sectors allocated gets smaller and
134smaller. Merging has finished when the number of sectors holding data
135is zero, in other words <sectors_allocated> == <metadata_sectors>.
136
137Here is a practical example (using a hybrid of lvm and dmsetup commands):
138
139# lvs
140 LV VG Attr LSize Origin Snap% Move Log Copy% Convert
141 base volumeGroup owi-a- 4.00g
142 snap volumeGroup swi-a- 1.00g base 18.97
143
144# dmsetup status volumeGroup-snap
1450 8388608 snapshot 397896/2097152 1560
146 ^^^^ metadata sectors
147
148# lvconvert --merge -b volumeGroup/snap
149 Merging of volume snap started.
150
151# lvs volumeGroup/snap
152 LV VG Attr LSize Origin Snap% Move Log Copy% Convert
153 base volumeGroup Owi-a- 4.00g 17.23
154
155# dmsetup status volumeGroup-base
1560 8388608 snapshot-merge 281688/2097152 1104
157
158# dmsetup status volumeGroup-base
1590 8388608 snapshot-merge 180480/2097152 712
160
161# dmsetup status volumeGroup-base
1620 8388608 snapshot-merge 16/2097152 16
163
164Merging has finished.
165
166# lvs
167 LV VG Attr LSize Origin Snap% Move Log Copy% Convert
168 base volumeGroup owi-a- 4.00g
diff --git a/Documentation/fault-injection/provoke-crashes.txt b/Documentation/fault-injection/provoke-crashes.txt
new file mode 100644
index 000000000000..7a9d3d81525b
--- /dev/null
+++ b/Documentation/fault-injection/provoke-crashes.txt
@@ -0,0 +1,38 @@
1The lkdtm module provides an interface to crash or injure the kernel at
2predefined crashpoints to evaluate the reliability of crash dumps obtained
3using different dumping solutions. The module uses KPROBEs to instrument
4crashing points, but can also crash the kernel directly without KRPOBE
5support.
6
7
8You can provide the way either through module arguments when inserting
9the module, or through a debugfs interface.
10
11Usage: insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<>
12 [cpoint_count={>0}]
13
14 recur_count : Recursion level for the stack overflow test. Default is 10.
15
16 cpoint_name : Crash point where the kernel is to be crashed. It can be
17 one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
18 FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
19 IDE_CORE_CP, DIRECT
20
21 cpoint_type : Indicates the action to be taken on hitting the crash point.
22 It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW,
23 CORRUPT_STACK, UNALIGNED_LOAD_STORE_WRITE, OVERWRITE_ALLOCATION,
24 WRITE_AFTER_FREE,
25
26 cpoint_count : Indicates the number of times the crash point is to be hit
27 to trigger an action. The default is 10.
28
29You can also induce failures by mounting debugfs and writing the type to
30<mountpoint>/provoke-crash/<crashpoint>. E.g.,
31
32 mount -t debugfs debugfs /mnt
33 echo EXCEPTION > /mnt/provoke-crash/INT_HARDWARE_ENTRY
34
35
36A special file is `DIRECT' which will induce the crash directly without
37KPROBE instrumentation. This mode is the only one available when the module
38is built on a kernel without KPROBEs support.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 31575e220f3b..a5cc0db63d7a 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -449,12 +449,6 @@ Who: Alok N Kataria <akataria@vmware.com>
449 449
450---------------------------- 450----------------------------
451 451
452What: adt7473 hardware monitoring driver
453When: February 2010
454Why: Obsoleted by the adt7475 driver.
455Who: Jean Delvare <khali@linux-fr.org>
456
457---------------------------
458What: Support for lcd_switch and display_get in asus-laptop driver 452What: Support for lcd_switch and display_get in asus-laptop driver
459When: March 2010 453When: March 2010
460Why: These two features use non-standard interfaces. There are the 454Why: These two features use non-standard interfaces. There are the
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index 875d49696b6e..5139b8c9d5af 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -62,6 +62,8 @@ jfs.txt
62 - info and mount options for the JFS filesystem. 62 - info and mount options for the JFS filesystem.
63locks.txt 63locks.txt
64 - info on file locking implementations, flock() vs. fcntl(), etc. 64 - info on file locking implementations, flock() vs. fcntl(), etc.
65logfs.txt
66 - info on the LogFS flash filesystem.
65mandatory-locking.txt 67mandatory-locking.txt
66 - info on the Linux implementation of Sys V mandatory file locking. 68 - info on the Linux implementation of Sys V mandatory file locking.
67ncpfs.txt 69ncpfs.txt
diff --git a/Documentation/filesystems/logfs.txt b/Documentation/filesystems/logfs.txt
new file mode 100644
index 000000000000..e64c94ba401a
--- /dev/null
+++ b/Documentation/filesystems/logfs.txt
@@ -0,0 +1,241 @@
1
2The LogFS Flash Filesystem
3==========================
4
5Specification
6=============
7
8Superblocks
9-----------
10
11Two superblocks exist at the beginning and end of the filesystem.
12Each superblock is 256 Bytes large, with another 3840 Bytes reserved
13for future purposes, making a total of 4096 Bytes.
14
15Superblock locations may differ for MTD and block devices. On MTD the
16first non-bad block contains a superblock in the first 4096 Bytes and
17the last non-bad block contains a superblock in the last 4096 Bytes.
18On block devices, the first 4096 Bytes of the device contain the first
19superblock and the last aligned 4096 Byte-block contains the second
20superblock.
21
22For the most part, the superblocks can be considered read-only. They
23are written only to correct errors detected within the superblocks,
24move the journal and change the filesystem parameters through tunefs.
25As a result, the superblock does not contain any fields that require
26constant updates, like the amount of free space, etc.
27
28Segments
29--------
30
31The space in the device is split up into equal-sized segments.
32Segments are the primary write unit of LogFS. Within each segments,
33writes happen from front (low addresses) to back (high addresses. If
34only a partial segment has been written, the segment number, the
35current position within and optionally a write buffer are stored in
36the journal.
37
38Segments are erased as a whole. Therefore Garbage Collection may be
39required to completely free a segment before doing so.
40
41Journal
42--------
43
44The journal contains all global information about the filesystem that
45is subject to frequent change. At mount time, it has to be scanned
46for the most recent commit entry, which contains a list of pointers to
47all currently valid entries.
48
49Object Store
50------------
51
52All space except for the superblocks and journal is part of the object
53store. Each segment contains a segment header and a number of
54objects, each consisting of the object header and the payload.
55Objects are either inodes, directory entries (dentries), file data
56blocks or indirect blocks.
57
58Levels
59------
60
61Garbage collection (GC) may fail if all data is written
62indiscriminately. One requirement of GC is that data is seperated
63roughly according to the distance between the tree root and the data.
64Effectively that means all file data is on level 0, indirect blocks
65are on levels 1, 2, 3 4 or 5 for 1x, 2x, 3x, 4x or 5x indirect blocks,
66respectively. Inode file data is on level 6 for the inodes and 7-11
67for indirect blocks.
68
69Each segment contains objects of a single level only. As a result,
70each level requires its own seperate segment to be open for writing.
71
72Inode File
73----------
74
75All inodes are stored in a special file, the inode file. Single
76exception is the inode file's inode (master inode) which for obvious
77reasons is stored in the journal instead. Instead of data blocks, the
78leaf nodes of the inode files are inodes.
79
80Aliases
81-------
82
83Writes in LogFS are done by means of a wandering tree. A naïve
84implementation would require that for each write or a block, all
85parent blocks are written as well, since the block pointers have
86changed. Such an implementation would not be very efficient.
87
88In LogFS, the block pointer changes are cached in the journal by means
89of alias entries. Each alias consists of its logical address - inode
90number, block index, level and child number (index into block) - and
91the changed data. Any 8-byte word can be changes in this manner.
92
93Currently aliases are used for block pointers, file size, file used
94bytes and the height of an inodes indirect tree.
95
96Segment Aliases
97---------------
98
99Related to regular aliases, these are used to handle bad blocks.
100Initially, bad blocks are handled by moving the affected segment
101content to a spare segment and noting this move in the journal with a
102segment alias, a simple (to, from) tupel. GC will later empty this
103segment and the alias can be removed again. This is used on MTD only.
104
105Vim
106---
107
108By cleverly predicting the life time of data, it is possible to
109seperate long-living data from short-living data and thereby reduce
110the GC overhead later. Each type of distinc life expectency (vim) can
111have a seperate segment open for writing. Each (level, vim) tupel can
112be open just once. If an open segment with unknown vim is encountered
113at mount time, it is closed and ignored henceforth.
114
115Indirect Tree
116-------------
117
118Inodes in LogFS are similar to FFS-style filesystems with direct and
119indirect block pointers. One difference is that LogFS uses a single
120indirect pointer that can be either a 1x, 2x, etc. indirect pointer.
121A height field in the inode defines the height of the indirect tree
122and thereby the indirection of the pointer.
123
124Another difference is the addressing of indirect blocks. In LogFS,
125the first 16 pointers in the first indirect block are left empty,
126corresponding to the 16 direct pointers in the inode. In ext2 (maybe
127others as well) the first pointer in the first indirect block
128corresponds to logical block 12, skipping the 12 direct pointers.
129So where ext2 is using arithmetic to better utilize space, LogFS keeps
130arithmetic simple and uses compression to save space.
131
132Compression
133-----------
134
135Both file data and metadata can be compressed. Compression for file
136data can be enabled with chattr +c and disabled with chattr -c. Doing
137so has no effect on existing data, but new data will be stored
138accordingly. New inodes will inherit the compression flag of the
139parent directory.
140
141Metadata is always compressed. However, the space accounting ignores
142this and charges for the uncompressed size. Failing to do so could
143result in GC failures when, after moving some data, indirect blocks
144compress worse than previously. Even on a 100% full medium, GC may
145not consume any extra space, so the compression gains are lost space
146to the user.
147
148However, they are not lost space to the filesystem internals. By
149cheating the user for those bytes, the filesystem gained some slack
150space and GC will run less often and faster.
151
152Garbage Collection and Wear Leveling
153------------------------------------
154
155Garbage collection is invoked whenever the number of free segments
156falls below a threshold. The best (known) candidate is picked based
157on the least amount of valid data contained in the segment. All
158remaining valid data is copied elsewhere, thereby invalidating it.
159
160The GC code also checks for aliases and writes then back if their
161number gets too large.
162
163Wear leveling is done by occasionally picking a suboptimal segment for
164garbage collection. If a stale segments erase count is significantly
165lower than the active segments' erase counts, it will be picked. Wear
166leveling is rate limited, so it will never monopolize the device for
167more than one segment worth at a time.
168
169Values for "occasionally", "significantly lower" are compile time
170constants.
171
172Hashed directories
173------------------
174
175To satisfy efficient lookup(), directory entries are hashed and
176located based on the hash. In order to both support large directories
177and not be overly inefficient for small directories, several hash
178tables of increasing size are used. For each table, the hash value
179modulo the table size gives the table index.
180
181Tables sizes are chosen to limit the number of indirect blocks with a
182fully populated table to 0, 1, 2 or 3 respectively. So the first
183table contains 16 entries, the second 512-16, etc.
184
185The last table is special in several ways. First its size depends on
186the effective 32bit limit on telldir/seekdir cookies. Since logfs
187uses the upper half of the address space for indirect blocks, the size
188is limited to 2^31. Secondly the table contains hash buckets with 16
189entries each.
190
191Using single-entry buckets would result in birthday "attacks". At
192just 2^16 used entries, hash collisions would be likely (P >= 0.5).
193My math skills are insufficient to do the combinatorics for the 17x
194collisions necessary to overflow a bucket, but testing showed that in
19510,000 runs the lowest directory fill before a bucket overflow was
196188,057,130 entries with an average of 315,149,915 entries. So for
197directory sizes of up to a million, bucket overflows should be
198virtually impossible under normal circumstances.
199
200With carefully chosen filenames, it is obviously possible to cause an
201overflow with just 21 entries (4 higher tables + 16 entries + 1). So
202there may be a security concern if a malicious user has write access
203to a directory.
204
205Open For Discussion
206===================
207
208Device Address Space
209--------------------
210
211A device address space is used for caching. Both block devices and
212MTD provide functions to either read a single page or write a segment.
213Partial segments may be written for data integrity, but where possible
214complete segments are written for performance on simple block device
215flash media.
216
217Meta Inodes
218-----------
219
220Inodes are stored in the inode file, which is just a regular file for
221most purposes. At umount time, however, the inode file needs to
222remain open until all dirty inodes are written. So
223generic_shutdown_super() may not close this inode, but shouldn't
224complain about remaining inodes due to the inode file either. Same
225goes for mapping inode of the device address space.
226
227Currently logfs uses a hack that essentially copies part of fs/inode.c
228code over. A general solution would be preferred.
229
230Indirect block mapping
231----------------------
232
233With compression, the block device (or mapping inode) cannot be used
234to cache indirect blocks. Some other place is required. Currently
235logfs uses the top half of each inode's address space. The low 8TB
236(on 32bit) are filled with file data, the high 8TB are used for
237indirect blocks.
238
239One problem is that 16TB files created on 64bit systems actually have
240data in the top 8TB. But files >16TB would cause problems anyway, so
241only the limit has changed.
diff --git a/Documentation/filesystems/nfs/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt
index 1bd0d0c05171..6a53a84afc72 100644
--- a/Documentation/filesystems/nfs/nfs41-server.txt
+++ b/Documentation/filesystems/nfs/nfs41-server.txt
@@ -17,8 +17,7 @@ kernels must turn 4.1 on or off *before* turning support for version 4
17on or off; rpc.nfsd does this correctly.) 17on or off; rpc.nfsd does this correctly.)
18 18
19The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based 19The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
20on the latest NFSv4.1 Internet Draft: 20on RFC 5661.
21http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
22 21
23From the many new features in NFSv4.1 the current implementation 22From the many new features in NFSv4.1 the current implementation
24focuses on the mandatory-to-implement NFSv4.1 Sessions, providing 23focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
@@ -44,7 +43,7 @@ interoperability problems with future clients. Known issues:
44 trunking, but this is a mandatory feature, and its use is 43 trunking, but this is a mandatory feature, and its use is
45 recommended to clients in a number of places. (E.g. to ensure 44 recommended to clients in a number of places. (E.g. to ensure
46 timely renewal in case an existing connection's retry timeouts 45 timely renewal in case an existing connection's retry timeouts
47 have gotten too long; see section 8.3 of the draft.) 46 have gotten too long; see section 8.3 of the RFC.)
48 Therefore, lack of this feature may cause future clients to 47 Therefore, lack of this feature may cause future clients to
49 fail. 48 fail.
50 - Incomplete backchannel support: incomplete backchannel gss 49 - Incomplete backchannel support: incomplete backchannel gss
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 0d07513a67a6..96a44dd95e03 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -164,6 +164,7 @@ read the file /proc/PID/status:
164 VmExe: 68 kB 164 VmExe: 68 kB
165 VmLib: 1412 kB 165 VmLib: 1412 kB
166 VmPTE: 20 kb 166 VmPTE: 20 kb
167 VmSwap: 0 kB
167 Threads: 1 168 Threads: 1
168 SigQ: 0/28578 169 SigQ: 0/28578
169 SigPnd: 0000000000000000 170 SigPnd: 0000000000000000
@@ -188,6 +189,12 @@ memory usage. Its seven fields are explained in Table 1-3. The stat file
188contains details information about the process itself. Its fields are 189contains details information about the process itself. Its fields are
189explained in Table 1-4. 190explained in Table 1-4.
190 191
192(for SMP CONFIG users)
193For making accounting scalable, RSS related information are handled in
194asynchronous manner and the vaule may not be very precise. To see a precise
195snapshot of a moment, you can see /proc/<pid>/smaps file and scan page table.
196It's slow but very precise.
197
191Table 1-2: Contents of the statm files (as of 2.6.30-rc7) 198Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
192.............................................................................. 199..............................................................................
193 Field Content 200 Field Content
@@ -213,6 +220,7 @@ Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
213 VmExe size of text segment 220 VmExe size of text segment
214 VmLib size of shared library code 221 VmLib size of shared library code
215 VmPTE size of page table entries 222 VmPTE size of page table entries
223 VmSwap size of swap usage (the number of referred swapents)
216 Threads number of threads 224 Threads number of threads
217 SigQ number of signals queued/max. number for queue 225 SigQ number of signals queued/max. number for queue
218 SigPnd bitmap of pending signals for the thread 226 SigPnd bitmap of pending signals for the thread
@@ -430,6 +438,7 @@ Table 1-5: Kernel info in /proc
430 modules List of loaded modules 438 modules List of loaded modules
431 mounts Mounted filesystems 439 mounts Mounted filesystems
432 net Networking info (see text) 440 net Networking info (see text)
441 pagetypeinfo Additional page allocator information (see text) (2.5)
433 partitions Table of partitions known to the system 442 partitions Table of partitions known to the system
434 pci Deprecated info of PCI bus (new way -> /proc/bus/pci/, 443 pci Deprecated info of PCI bus (new way -> /proc/bus/pci/,
435 decoupled by lspci (2.4) 444 decoupled by lspci (2.4)
@@ -584,7 +593,7 @@ Node 0, zone DMA 0 4 5 4 4 3 ...
584Node 0, zone Normal 1 0 0 1 101 8 ... 593Node 0, zone Normal 1 0 0 1 101 8 ...
585Node 0, zone HighMem 2 0 0 1 1 0 ... 594Node 0, zone HighMem 2 0 0 1 1 0 ...
586 595
587Memory fragmentation is a problem under some workloads, and buddyinfo is a 596External fragmentation is a problem under some workloads, and buddyinfo is a
588useful tool for helping diagnose these problems. Buddyinfo will give you a 597useful tool for helping diagnose these problems. Buddyinfo will give you a
589clue as to how big an area you can safely allocate, or why a previous 598clue as to how big an area you can safely allocate, or why a previous
590allocation failed. 599allocation failed.
@@ -594,6 +603,48 @@ available. In this case, there are 0 chunks of 2^0*PAGE_SIZE available in
594ZONE_DMA, 4 chunks of 2^1*PAGE_SIZE in ZONE_DMA, 101 chunks of 2^4*PAGE_SIZE 603ZONE_DMA, 4 chunks of 2^1*PAGE_SIZE in ZONE_DMA, 101 chunks of 2^4*PAGE_SIZE
595available in ZONE_NORMAL, etc... 604available in ZONE_NORMAL, etc...
596 605
606More information relevant to external fragmentation can be found in
607pagetypeinfo.
608
609> cat /proc/pagetypeinfo
610Page block order: 9
611Pages per block: 512
612
613Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10
614Node 0, zone DMA, type Unmovable 0 0 0 1 1 1 1 1 1 1 0
615Node 0, zone DMA, type Reclaimable 0 0 0 0 0 0 0 0 0 0 0
616Node 0, zone DMA, type Movable 1 1 2 1 2 1 1 0 1 0 2
617Node 0, zone DMA, type Reserve 0 0 0 0 0 0 0 0 0 1 0
618Node 0, zone DMA, type Isolate 0 0 0 0 0 0 0 0 0 0 0
619Node 0, zone DMA32, type Unmovable 103 54 77 1 1 1 11 8 7 1 9
620Node 0, zone DMA32, type Reclaimable 0 0 2 1 0 0 0 0 1 0 0
621Node 0, zone DMA32, type Movable 169 152 113 91 77 54 39 13 6 1 452
622Node 0, zone DMA32, type Reserve 1 2 2 2 2 0 1 1 1 1 0
623Node 0, zone DMA32, type Isolate 0 0 0 0 0 0 0 0 0 0 0
624
625Number of blocks type Unmovable Reclaimable Movable Reserve Isolate
626Node 0, zone DMA 2 0 5 1 0
627Node 0, zone DMA32 41 6 967 2 0
628
629Fragmentation avoidance in the kernel works by grouping pages of different
630migrate types into the same contiguous regions of memory called page blocks.
631A page block is typically the size of the default hugepage size e.g. 2MB on
632X86-64. By keeping pages grouped based on their ability to move, the kernel
633can reclaim pages within a page block to satisfy a high-order allocation.
634
635The pagetypinfo begins with information on the size of a page block. It
636then gives the same type of information as buddyinfo except broken down
637by migrate-type and finishes with details on how many page blocks of each
638type exist.
639
640If min_free_kbytes has been tuned correctly (recommendations made by hugeadm
641from libhugetlbfs http://sourceforge.net/projects/libhugetlbfs/), one can
642make an estimate of the likely number of huge pages that can be allocated
643at a given point in time. All the "Movable" blocks should be allocatable
644unless memory has been mlock()'d. Some of the Reclaimable blocks should
645also be allocatable although a lot of filesystem metadata may have to be
646reclaimed to achieve this.
647
597.............................................................................. 648..............................................................................
598 649
599meminfo: 650meminfo:
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index 1866c27eec69..c2c6e9b39bbe 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -253,6 +253,70 @@ pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
253Also note that it's your responsibility to have stopped using a GPIO 253Also note that it's your responsibility to have stopped using a GPIO
254before you free it. 254before you free it.
255 255
256Considering in most cases GPIOs are actually configured right after they
257are claimed, three additional calls are defined:
258
259 /* request a single GPIO, with initial configuration specified by
260 * 'flags', identical to gpio_request() wrt other arguments and
261 * return value
262 */
263 int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
264
265 /* request multiple GPIOs in a single call
266 */
267 int gpio_request_array(struct gpio *array, size_t num);
268
269 /* release multiple GPIOs in a single call
270 */
271 void gpio_free_array(struct gpio *array, size_t num);
272
273where 'flags' is currently defined to specify the following properties:
274
275 * GPIOF_DIR_IN - to configure direction as input
276 * GPIOF_DIR_OUT - to configure direction as output
277
278 * GPIOF_INIT_LOW - as output, set initial level to LOW
279 * GPIOF_INIT_HIGH - as output, set initial level to HIGH
280
281since GPIOF_INIT_* are only valid when configured as output, so group valid
282combinations as:
283
284 * GPIOF_IN - configure as input
285 * GPIOF_OUT_INIT_LOW - configured as output, initial level LOW
286 * GPIOF_OUT_INIT_HIGH - configured as output, initial level HIGH
287
288In the future, these flags can be extended to support more properties such
289as open-drain status.
290
291Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is
292introduced to encapsulate all three fields as:
293
294 struct gpio {
295 unsigned gpio;
296 unsigned long flags;
297 const char *label;
298 };
299
300A typical example of usage:
301
302 static struct gpio leds_gpios[] = {
303 { 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* default to ON */
304 { 33, GPIOF_OUT_INIT_LOW, "Green LED" }, /* default to OFF */
305 { 34, GPIOF_OUT_INIT_LOW, "Red LED" }, /* default to OFF */
306 { 35, GPIOF_OUT_INIT_LOW, "Blue LED" }, /* default to OFF */
307 { ... },
308 };
309
310 err = gpio_request_one(31, GPIOF_IN, "Reset Button");
311 if (err)
312 ...
313
314 err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
315 if (err)
316 ...
317
318 gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
319
256 320
257GPIOs mapped to IRQs 321GPIOs mapped to IRQs
258-------------------- 322--------------------
diff --git a/Documentation/hwmon/adt7411 b/Documentation/hwmon/adt7411
new file mode 100644
index 000000000000..1632960f9745
--- /dev/null
+++ b/Documentation/hwmon/adt7411
@@ -0,0 +1,42 @@
1Kernel driver adt7411
2=====================
3
4Supported chips:
5 * Analog Devices ADT7411
6 Prefix: 'adt7411'
7 Addresses scanned: 0x48, 0x4a, 0x4b
8 Datasheet: Publicly available at the Analog Devices website
9
10Author: Wolfram Sang (based on adt7470 by Darrick J. Wong)
11
12Description
13-----------
14
15This driver implements support for the Analog Devices ADT7411 chip. There may
16be other chips that implement this interface.
17
18The ADT7411 can use an I2C/SMBus compatible 2-wire interface or an
19SPI-compatible 4-wire interface. It provides a 10-bit analog to digital
20converter which measures 1 temperature, vdd and 8 input voltages. It has an
21internal temperature sensor, but an external one can also be connected (one
22loses 2 inputs then). There are high- and low-limit registers for all inputs.
23
24Check the datasheet for details.
25
26sysfs-Interface
27---------------
28
29in0_input - vdd voltage input
30in[1-8]_input - analog 1-8 input
31temp1_input - temperature input
32
33Besides standard interfaces, this driver adds (0 = off, 1 = on):
34
35 adc_ref_vdd - Use vdd as reference instead of 2.25 V
36 fast_sampling - Sample at 22.5 kHz instead of 1.4 kHz, but drop filters
37 no_average - Turn off averaging over 16 samples
38
39Notes
40-----
41
42SPI, external temperature sensor and limit registers are not supported yet.
diff --git a/Documentation/hwmon/adt7473 b/Documentation/hwmon/adt7473
deleted file mode 100644
index 446612bd1fb9..000000000000
--- a/Documentation/hwmon/adt7473
+++ /dev/null
@@ -1,74 +0,0 @@
1Kernel driver adt7473
2======================
3
4Supported chips:
5 * Analog Devices ADT7473
6 Prefix: 'adt7473'
7 Addresses scanned: I2C 0x2C, 0x2D, 0x2E
8 Datasheet: Publicly available at the Analog Devices website
9
10Author: Darrick J. Wong
11
12This driver is depreacted, please use the adt7475 driver instead.
13
14Description
15-----------
16
17This driver implements support for the Analog Devices ADT7473 chip family.
18
19The ADT7473 uses the 2-wire interface compatible with the SMBUS 2.0
20specification. Using an analog to digital converter it measures three (3)
21temperatures and two (2) voltages. It has four (4) 16-bit counters for
22measuring fan speed. There are three (3) PWM outputs that can be used
23to control fan speed.
24
25A sophisticated control system for the PWM outputs is designed into the
26ADT7473 that allows fan speed to be adjusted automatically based on any of the
27three temperature sensors. Each PWM output is individually adjustable and
28programmable. Once configured, the ADT7473 will adjust the PWM outputs in
29response to the measured temperatures without further host intervention.
30This feature can also be disabled for manual control of the PWM's.
31
32Each of the measured inputs (voltage, temperature, fan speed) has
33corresponding high/low limit values. The ADT7473 will signal an ALARM if
34any measured value exceeds either limit.
35
36The ADT7473 samples all inputs continuously. The driver will not read
37the registers more often than once every other second. Further,
38configuration data is only read once per minute.
39
40Special Features
41----------------
42
43The ADT7473 have a 10-bit ADC and can therefore measure temperatures
44with 0.25 degC resolution. Temperature readings can be configured either
45for twos complement format or "Offset 64" format, wherein 63 is subtracted
46from the raw value to get the temperature value.
47
48The Analog Devices datasheet is very detailed and describes a procedure for
49determining an optimal configuration for the automatic PWM control.
50
51Configuration Notes
52-------------------
53
54Besides standard interfaces driver adds the following:
55
56* PWM Control
57
58* pwm#_auto_point1_pwm and temp#_auto_point1_temp and
59* pwm#_auto_point2_pwm and temp#_auto_point2_temp -
60
61point1: Set the pwm speed at a lower temperature bound.
62point2: Set the pwm speed at a higher temperature bound.
63
64The ADT7473 will scale the pwm between the lower and higher pwm speed when
65the temperature is between the two temperature boundaries. PWM values range
66from 0 (off) to 255 (full speed). Fan speed will be set to maximum when the
67temperature sensor associated with the PWM control exceeds temp#_max.
68
69Notes
70-----
71
72The NVIDIA binary driver presents an ADT7473 chip via an on-card i2c bus.
73Unfortunately, they fail to set the i2c adapter class, so this driver may
74fail to find the chip until the nvidia driver is patched.
diff --git a/Documentation/hwmon/asc7621 b/Documentation/hwmon/asc7621
new file mode 100644
index 000000000000..7287be7e1f21
--- /dev/null
+++ b/Documentation/hwmon/asc7621
@@ -0,0 +1,296 @@
1Kernel driver asc7621
2==================
3
4Supported chips:
5 Andigilog aSC7621 and aSC7621a
6 Prefix: 'asc7621'
7 Addresses scanned: I2C 0x2c, 0x2d, 0x2e
8 Datasheet: http://www.fairview5.com/linux/asc7621/asc7621.pdf
9
10Author:
11 George Joseph
12
13Description provided by Dave Pivin @ Andigilog:
14
15Andigilog has both the PECI and pre-PECI versions of the Heceta-6, as
16Intel calls them. Heceta-6e has high frequency PWM and Heceta-6p has
17added PECI and a 4th thermal zone. The Andigilog aSC7611 is the
18Heceta-6e part and aSC7621 is the Heceta-6p part. They are both in
19volume production, shipping to Intel and their subs.
20
21We have enhanced both parts relative to the governing Intel
22specification. First enhancement is temperature reading resolution. We
23have used registers below 20h for vendor-specific functions in addition
24to those in the Intel-specified vendor range.
25
26Our conversion process produces a result that is reported as two bytes.
27The fan speed control uses this finer value to produce a "step-less" fan
28PWM output. These two bytes are "read-locked" to guarantee that once a
29high or low byte is read, the other byte is locked-in until after the
30next read of any register. So to get an atomic reading, read high or low
31byte, then the very next read should be the opposite byte. Our data
32sheet says 10-bits of resolution, although you may find the lower bits
33are active, they are not necessarily reliable or useful externally. We
34chose not to mask them.
35
36We employ significant filtering that is user tunable as described in the
37data sheet. Our temperature reports and fan PWM outputs are very smooth
38when compared to the competition, in addition to the higher resolution
39temperature reports. The smoother PWM output does not require user
40intervention.
41
42We offer GPIO features on the former VID pins. These are open-drain
43outputs or inputs and may be used as general purpose I/O or as alarm
44outputs that are based on temperature limits. These are in 19h and 1Ah.
45
46We offer flexible mapping of temperature readings to thermal zones. Any
47temperature may be mapped to any zone, which has a default assignment
48that follows Intel's specs.
49
50Since there is a fan to zone assignment that allows for the "hotter" of
51a set of zones to control the PWM of an individual fan, but there is no
52indication to the user, we have added an indicator that shows which zone
53is currently controlling the PWM for a given fan. This is in register
5400h.
55
56Both remote diode temperature readings may be given an offset value such
57that the reported reading as well as the temperature used to determine
58PWM may be offset for system calibration purposes.
59
60PECI Extended configuration allows for having more than two domains per
61PECI address and also provides an enabling function for each PECI
62address. One could use our flexible zone assignment to have a zone
63assigned to up to 4 PECI addresses. This is not possible in the default
64Intel configuration. This would be useful in multi-CPU systems with
65individual fans on each that would benefit from individual fan control.
66This is in register 0Eh.
67
68The tachometer measurement system is flexible and able to adapt to many
69fan types. We can also support pulse-stretched PWM so that 3-wire fans
70may be used. These characteristics are in registers 04h to 07h.
71
72Finally, we have added a tach disable function that turns off the tach
73measurement system for individual tachs in order to save power. That is
74in register 75h.
75
76--
77aSC7621 Product Description
78
79The aSC7621 has a two wire digital interface compatible with SMBus 2.0.
80Using a 10-bit ADC, the aSC7621 measures the temperature of two remote diode
81connected transistors as well as its own die. Support for Platform
82Environmental Control Interface (PECI) is included.
83
84Using temperature information from these four zones, an automatic fan speed
85control algorithm is employed to minimize acoustic impact while achieving
86recommended CPU temperature under varying operational loads.
87
88To set fan speed, the aSC7621 has three independent pulse width modulation
89(PWM) outputs that are controlled by one, or a combination of three,
90temperature zones. Both high- and low-frequency PWM ranges are supported.
91
92The aSC7621 also includes a digital filter that can be invoked to smooth
93temperature readings for better control of fan speed and minimum acoustic
94impact.
95
96The aSC7621 has tachometer inputs to measure fan speed on up to four fans.
97Limit and status registers for all measured values are included to alert
98the system host that any measurements are outside of programmed limits
99via status registers.
100
101System voltages of VCCP, 2.5V, 3.3V, 5.0V, and 12V motherboard power are
102monitored efficiently with internal scaling resistors.
103
104Features
105- Supports PECI interface and monitors internal and remote thermal diodes
106- 2-wire, SMBus 2.0 compliant, serial interface
107- 10-bit ADC
108- Monitors VCCP, 2.5V, 3.3V, 5.0V, and 12V motherboard/processor supplies
109- Programmable autonomous fan control based on temperature readings
110- Noise filtering of temperature reading for fan speed control
111- 0.25C digital temperature sensor resolution
112- 3 PWM fan speed control outputs for 2-, 3- or 4-wire fans and up to 4 fan
113 tachometer inputs
114- Enhanced measured temperature to Temperature Zone assignment.
115- Provides high and low PWM frequency ranges
116- 3 GPIO pins for custom use
117- 24-Lead QSOP package
118
119Configuration Notes
120===================
121
122Except where noted below, the sysfs entries created by this driver follow
123the standards defined in "sysfs-interface".
124
125temp1_source
126 0 (default) peci_legacy = 0, Remote 1 Temperature
127 peci_legacy = 1, PECI Processor Temperature 0
128 1 Remote 1 Temperature
129 2 Remote 2 Temperature
130 3 Internal Temperature
131 4 PECI Processor Temperature 0
132 5 PECI Processor Temperature 1
133 6 PECI Processor Temperature 2
134 7 PECI Processor Temperature 3
135
136temp2_source
137 0 (default) Internal Temperature
138 1 Remote 1 Temperature
139 2 Remote 2 Temperature
140 3 Internal Temperature
141 4 PECI Processor Temperature 0
142 5 PECI Processor Temperature 1
143 6 PECI Processor Temperature 2
144 7 PECI Processor Temperature 3
145
146temp3_source
147 0 (default) Remote 2 Temperature
148 1 Remote 1 Temperature
149 2 Remote 2 Temperature
150 3 Internal Temperature
151 4 PECI Processor Temperature 0
152 5 PECI Processor Temperature 1
153 6 PECI Processor Temperature 2
154 7 PECI Processor Temperature 3
155
156temp4_source
157 0 (default) peci_legacy = 0, PECI Processor Temperature 0
158 peci_legacy = 1, Remote 1 Temperature
159 1 Remote 1 Temperature
160 2 Remote 2 Temperature
161 3 Internal Temperature
162 4 PECI Processor Temperature 0
163 5 PECI Processor Temperature 1
164 6 PECI Processor Temperature 2
165 7 PECI Processor Temperature 3
166
167temp[1-4]_smoothing_enable
168temp[1-4]_smoothing_time
169 Smooths spikes in temp readings caused by noise.
170 Valid values in milliseconds are:
171 35000
172 17600
173 11800
174 7000
175 4400
176 3000
177 1600
178 800
179
180temp[1-4]_crit
181 When the corresponding zone temperature reaches this value,
182 ALL pwm outputs will got to 100%.
183
184temp[5-8]_input
185temp[5-8]_enable
186 The aSC7621 can also read temperatures provided by the processor
187 via the PECI bus. Usually these are "core" temps and are relative
188 to the point where the automatic thermal control circuit starts
189 throttling. This means that these are usually negative numbers.
190
191pwm[1-3]_enable
192 0 Fan off.
193 1 Fan on manual control.
194 2 Fan on automatic control and will run at the minimum pwm
195 if the temperature for the zone is below the minimum.
196 3 Fan on automatic control but will be off if the temperature
197 for the zone is below the minimum.
198 4-254 Ignored.
199 255 Fan on full.
200
201pwm[1-3]_auto_channels
202 Bitmap as described in sysctl-interface with the following
203 exceptions...
204 Only the following combination of zones (and their corresponding masks)
205 are valid:
206 1
207 2
208 3
209 2,3
210 1,2,3
211 4
212 1,2,3,4
213
214 Special values:
215 0 Disabled.
216 16 Fan on manual control.
217 31 Fan on full.
218
219
220pwm[1-3]_invert
221 When set, inverts the meaning of pwm[1-3].
222 i.e. when pwm = 0, the fan will be on full and
223 when pwm = 255 the fan will be off.
224
225pwm[1-3]_freq
226 PWM frequency in Hz
227 Valid values in Hz are:
228
229 10
230 15
231 23
232 30 (default)
233 38
234 47
235 62
236 94
237 23000
238 24000
239 25000
240 26000
241 27000
242 28000
243 29000
244 30000
245
246 Setting any other value will be ignored.
247
248peci_enable
249 Enables or disables PECI
250
251peci_avg
252 Input filter average time.
253
254 0 0 Sec. (no Smoothing) (default)
255 1 0.25 Sec.
256 2 0.5 Sec.
257 3 1.0 Sec.
258 4 2.0 Sec.
259 5 4.0 Sec.
260 6 8.0 Sec.
261 7 0.0 Sec.
262
263peci_legacy
264
265 0 Standard Mode (default)
266 Remote Diode 1 reading is associated with
267 Temperature Zone 1, PECI is associated with
268 Zone 4
269
270 1 Legacy Mode
271 PECI is associated with Temperature Zone 1,
272 Remote Diode 1 is associated with Zone 4
273
274peci_diode
275 Diode filter
276
277 0 0.25 Sec.
278 1 1.1 Sec.
279 2 2.4 Sec. (default)
280 3 3.4 Sec.
281 4 5.0 Sec.
282 5 6.8 Sec.
283 6 10.2 Sec.
284 7 16.4 Sec.
285
286peci_4domain
287 Four domain enable
288
289 0 1 or 2 Domains for enabled processors (default)
290 1 3 or 4 Domains for enabled processors
291
292peci_domain
293 Domain
294
295 0 Processor contains a single domain (0) (default)
296 1 Processor contains two domains (0,1)
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index f9ba96c0ac4a..8d08bf0d38ed 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -5,31 +5,23 @@ Supported chips:
5 * IT8705F 5 * IT8705F
6 Prefix: 'it87' 6 Prefix: 'it87'
7 Addresses scanned: from Super I/O config space (8 I/O ports) 7 Addresses scanned: from Super I/O config space (8 I/O ports)
8 Datasheet: Publicly available at the ITE website 8 Datasheet: Once publicly available at the ITE website, but no longer
9 http://www.ite.com.tw/product_info/file/pc/IT8705F_V.0.4.1.pdf
10 * IT8712F 9 * IT8712F
11 Prefix: 'it8712' 10 Prefix: 'it8712'
12 Addresses scanned: from Super I/O config space (8 I/O ports) 11 Addresses scanned: from Super I/O config space (8 I/O ports)
13 Datasheet: Publicly available at the ITE website 12 Datasheet: Once publicly available at the ITE website, but no longer
14 http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf
15 http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf
16 http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf
17 * IT8716F/IT8726F 13 * IT8716F/IT8726F
18 Prefix: 'it8716' 14 Prefix: 'it8716'
19 Addresses scanned: from Super I/O config space (8 I/O ports) 15 Addresses scanned: from Super I/O config space (8 I/O ports)
20 Datasheet: Publicly available at the ITE website 16 Datasheet: Once publicly available at the ITE website, but no longer
21 http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP
22 http://www.ite.com.tw/product_info/file/pc/IT8726F_V0.3.pdf
23 * IT8718F 17 * IT8718F
24 Prefix: 'it8718' 18 Prefix: 'it8718'
25 Addresses scanned: from Super I/O config space (8 I/O ports) 19 Addresses scanned: from Super I/O config space (8 I/O ports)
26 Datasheet: Publicly available at the ITE website 20 Datasheet: Once publicly available at the ITE website, but no longer
27 http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip
28 http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip
29 * IT8720F 21 * IT8720F
30 Prefix: 'it8720' 22 Prefix: 'it8720'
31 Addresses scanned: from Super I/O config space (8 I/O ports) 23 Addresses scanned: from Super I/O config space (8 I/O ports)
32 Datasheet: Not yet publicly available. 24 Datasheet: Not publicly available
33 * SiS950 [clone of IT8705F] 25 * SiS950 [clone of IT8705F]
34 Prefix: 'it87' 26 Prefix: 'it87'
35 Addresses scanned: from Super I/O config space (8 I/O ports) 27 Addresses scanned: from Super I/O config space (8 I/O ports)
@@ -136,6 +128,10 @@ registers are read whenever any data is read (unless it is less than 1.5
136seconds since the last update). This means that you can easily miss 128seconds since the last update). This means that you can easily miss
137once-only alarms. 129once-only alarms.
138 130
131Out-of-limit readings can also result in beeping, if the chip is properly
132wired and configured. Beeping can be enabled or disabled per sensor type
133(temperatures, voltages and fans.)
134
139The IT87xx only updates its values each 1.5 seconds; reading it more often 135The IT87xx only updates its values each 1.5 seconds; reading it more often
140will do no harm, but will return 'old' values. 136will do no harm, but will return 'old' values.
141 137
@@ -150,11 +146,38 @@ Fan speed control
150----------------- 146-----------------
151 147
152The fan speed control features are limited to manual PWM mode. Automatic 148The fan speed control features are limited to manual PWM mode. Automatic
153"Smart Guardian" mode control handling is not implemented. However 149"Smart Guardian" mode control handling is only implemented for older chips
154if you want to go for "manual mode" just write 1 to pwmN_enable. 150(see below.) However if you want to go for "manual mode" just write 1 to
151pwmN_enable.
155 152
156If you are only able to control the fan speed with very small PWM values, 153If you are only able to control the fan speed with very small PWM values,
157try lowering the PWM base frequency (pwm1_freq). Depending on the fan, 154try lowering the PWM base frequency (pwm1_freq). Depending on the fan,
158it may give you a somewhat greater control range. The same frequency is 155it may give you a somewhat greater control range. The same frequency is
159used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are 156used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are
160read-only. 157read-only.
158
159
160Automatic fan speed control (old interface)
161-------------------------------------------
162
163The driver supports the old interface to automatic fan speed control
164which is implemented by IT8705F chips up to revision F and IT8712F
165chips up to revision G.
166
167This interface implements 4 temperature vs. PWM output trip points.
168The PWM output of trip point 4 is always the maximum value (fan running
169at full speed) while the PWM output of the other 3 trip points can be
170freely chosen. The temperature of all 4 trip points can be freely chosen.
171Additionally, trip point 1 has an hysteresis temperature attached, to
172prevent fast switching between fan on and off.
173
174The chip automatically computes the PWM output value based on the input
175temperature, based on this simple rule: if the temperature value is
176between trip point N and trip point N+1 then the PWM output value is
177the one of trip point N. The automatic control mode is less flexible
178than the manual control mode, but it reacts faster, is more robust and
179doesn't use CPU cycles.
180
181Trip points must be set properly before switching to automatic fan speed
182control mode. The driver will perform basic integrity checks before
183actually switching to automatic control mode.
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
index 93d8e3d55150..6a03dd4bcc94 100644
--- a/Documentation/hwmon/lm90
+++ b/Documentation/hwmon/lm90
@@ -84,6 +84,10 @@ Supported chips:
84 Addresses scanned: I2C 0x4c 84 Addresses scanned: I2C 0x4c
85 Datasheet: Publicly available at the Maxim website 85 Datasheet: Publicly available at the Maxim website
86 http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500 86 http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3500
87 * Winbond/Nuvoton W83L771AWG/ASG
88 Prefix: 'w83l771'
89 Addresses scanned: I2C 0x4c
90 Datasheet: Not publicly available, can be requested from Nuvoton
87 91
88 92
89Author: Jean Delvare <khali@linux-fr.org> 93Author: Jean Delvare <khali@linux-fr.org>
@@ -147,6 +151,12 @@ MAX6680 and MAX6681:
147 * Selectable address 151 * Selectable address
148 * Remote sensor type selection 152 * Remote sensor type selection
149 153
154W83L771AWG/ASG
155 * The AWG and ASG variants only differ in package format.
156 * Filter and alert configuration register at 0xBF
157 * Diode ideality factor configuration (remote sensor) at 0xE3
158 * Moving average (depending on conversion rate)
159
150All temperature values are given in degrees Celsius. Resolution 160All temperature values are given in degrees Celsius. Resolution
151is 1.0 degree for the local temperature, 0.125 degree for the remote 161is 1.0 degree for the local temperature, 0.125 degree for the remote
152temperature, except for the MAX6657, MAX6658 and MAX6659 which have a 162temperature, except for the MAX6657, MAX6658 and MAX6659 which have a
@@ -163,6 +173,18 @@ The lm90 driver will not update its values more frequently than every
163other second; reading them more often will do no harm, but will return 173other second; reading them more often will do no harm, but will return
164'old' values. 174'old' values.
165 175
176SMBus Alert Support
177-------------------
178
179This driver has basic support for SMBus alert. When an alert is received,
180the status register is read and the faulty temperature channel is logged.
181
182The Analog Devices chips (ADM1032 and ADT7461) do not implement the SMBus
183alert protocol properly so additional care is needed: the ALERT output is
184disabled when an alert is received, and is re-enabled only when the alarm
185is gone. Otherwise the chip would block alerts from other chips in the bus
186as long as the alarm is active.
187
166PEC Support 188PEC Support
167----------- 189-----------
168 190
diff --git a/Documentation/init.txt b/Documentation/init.txt
new file mode 100644
index 000000000000..535ad5e82b98
--- /dev/null
+++ b/Documentation/init.txt
@@ -0,0 +1,49 @@
1Explaining the dreaded "No init found." boot hang message
2=========================================================
3
4OK, so you've got this pretty unintuitive message (currently located
5in init/main.c) and are wondering what the H*** went wrong.
6Some high-level reasons for failure (listed roughly in order of execution)
7to load the init binary are:
8A) Unable to mount root FS
9B) init binary doesn't exist on rootfs
10C) broken console device
11D) binary exists but dependencies not available
12E) binary cannot be loaded
13
14Detailed explanations:
150) Set "debug" kernel parameter (in bootloader config file or CONFIG_CMDLINE)
16 to get more detailed kernel messages.
17A) make sure you have the correct root FS type
18 (and root= kernel parameter points to the correct partition),
19 required drivers such as storage hardware (such as SCSI or USB!)
20 and filesystem (ext3, jffs2 etc.) are builtin (alternatively as modules,
21 to be pre-loaded by an initrd)
22C) Possibly a conflict in console= setup --> initial console unavailable.
23 E.g. some serial consoles are unreliable due to serial IRQ issues (e.g.
24 missing interrupt-based configuration).
25 Try using a different console= device or e.g. netconsole= .
26D) e.g. required library dependencies of the init binary such as
27 /lib/ld-linux.so.2 missing or broken. Use readelf -d <INIT>|grep NEEDED
28 to find out which libraries are required.
29E) make sure the binary's architecture matches your hardware.
30 E.g. i386 vs. x86_64 mismatch, or trying to load x86 on ARM hardware.
31 In case you tried loading a non-binary file here (shell script?),
32 you should make sure that the script specifies an interpreter in its shebang
33 header line (#!/...) that is fully working (including its library
34 dependencies). And before tackling scripts, better first test a simple
35 non-script binary such as /bin/sh and confirm its successful execution.
36 To find out more, add code to init/main.c to display kernel_execve()s
37 return values.
38
39Please extend this explanation whenever you find new failure causes
40(after all loading the init binary is a CRITICAL and hard transition step
41which needs to be made as painless as possible), then submit patch to LKML.
42Further TODOs:
43- Implement the various run_init_process() invocations via a struct array
44 which can then store the kernel_execve() result value and on failure
45 log it all by iterating over _all_ results (very important usability fix).
46- try to make the implementation itself more helpful in general,
47 e.g. by providing additional error messages at affected places.
48
49Andreas Mohr <andi at lisas period de>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index d80930d58dae..3bc48b0bd3a9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2834,6 +2834,12 @@ and is between 256 and 4096 characters. It is defined in the file
2834 default x2apic cluster mode on platforms 2834 default x2apic cluster mode on platforms
2835 supporting x2apic. 2835 supporting x2apic.
2836 2836
2837 x86_mrst_timer= [X86-32,APBT]
2838 Choose timer option for x86 Moorestown MID platform.
2839 Two valid options are apbt timer only and lapic timer
2840 plus one apbt timer for broadcast timer.
2841 x86_mrst_timer=apbt_only | lapic_and_apbt
2842
2837 xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks. 2843 xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
2838 xd_geo= See header of drivers/block/xd.c. 2844 xd_geo= See header of drivers/block/xd.c.
2839 2845
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 356fd86f4ea8..ab00eeddecaf 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -224,6 +224,12 @@ defined in include/linux/pm.h:
224 RPM_SUSPENDED, which means that each device is initially regarded by the 224 RPM_SUSPENDED, which means that each device is initially regarded by the
225 PM core as 'suspended', regardless of its real hardware status 225 PM core as 'suspended', regardless of its real hardware status
226 226
227 unsigned int runtime_auto;
228 - if set, indicates that the user space has allowed the device driver to
229 power manage the device at run time via the /sys/devices/.../power/control
230 interface; it may only be modified with the help of the pm_runtime_allow()
231 and pm_runtime_forbid() helper functions
232
227All of the above fields are members of the 'power' member of 'struct device'. 233All of the above fields are members of the 'power' member of 'struct device'.
228 234
2294. Run-time PM Device Helper Functions 2354. Run-time PM Device Helper Functions
@@ -329,6 +335,20 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
329 'power.runtime_error' is set or 'power.disable_depth' is greater than 335 'power.runtime_error' is set or 'power.disable_depth' is greater than
330 zero) 336 zero)
331 337
338 bool pm_runtime_suspended(struct device *dev);
339 - return true if the device's runtime PM status is 'suspended', or false
340 otherwise
341
342 void pm_runtime_allow(struct device *dev);
343 - set the power.runtime_auto flag for the device and decrease its usage
344 counter (used by the /sys/devices/.../power/control interface to
345 effectively allow the device to be power managed at run time)
346
347 void pm_runtime_forbid(struct device *dev);
348 - unset the power.runtime_auto flag for the device and increase its usage
349 counter (used by the /sys/devices/.../power/control interface to
350 effectively prevent the device from being power managed at run time)
351
332It is safe to execute the following helper functions from interrupt context: 352It is safe to execute the following helper functions from interrupt context:
333 353
334pm_request_idle() 354pm_request_idle()
@@ -382,6 +402,18 @@ may be desirable to suspend the device as soon as ->probe() or ->remove() has
382finished, so the PM core uses pm_runtime_idle_sync() to invoke the 402finished, so the PM core uses pm_runtime_idle_sync() to invoke the
383subsystem-level idle callback for the device at that time. 403subsystem-level idle callback for the device at that time.
384 404
405The user space can effectively disallow the driver of the device to power manage
406it at run time by changing the value of its /sys/devices/.../power/control
407attribute to "on", which causes pm_runtime_forbid() to be called. In principle,
408this mechanism may also be used by the driver to effectively turn off the
409run-time power management of the device until the user space turns it on.
410Namely, during the initialization the driver can make sure that the run-time PM
411status of the device is 'active' and call pm_runtime_forbid(). It should be
412noted, however, that if the user space has already intentionally changed the
413value of /sys/devices/.../power/control to "auto" to allow the driver to power
414manage the device at run time, the driver may confuse it by using
415pm_runtime_forbid() this way.
416
3856. Run-time PM and System Sleep 4176. Run-time PM and System Sleep
386 418
387Run-time PM and system sleep (i.e., system suspend and hibernation, also known 419Run-time PM and system sleep (i.e., system suspend and hibernation, also known
@@ -431,3 +463,64 @@ The PM core always increments the run-time usage counter before calling the
431->prepare() callback and decrements it after calling the ->complete() callback. 463->prepare() callback and decrements it after calling the ->complete() callback.
432Hence disabling run-time PM temporarily like this will not cause any run-time 464Hence disabling run-time PM temporarily like this will not cause any run-time
433suspend callbacks to be lost. 465suspend callbacks to be lost.
466
4677. Generic subsystem callbacks
468
469Subsystems may wish to conserve code space by using the set of generic power
470management callbacks provided by the PM core, defined in
471driver/base/power/generic_ops.c:
472
473 int pm_generic_runtime_idle(struct device *dev);
474 - invoke the ->runtime_idle() callback provided by the driver of this
475 device, if defined, and call pm_runtime_suspend() for this device if the
476 return value is 0 or the callback is not defined
477
478 int pm_generic_runtime_suspend(struct device *dev);
479 - invoke the ->runtime_suspend() callback provided by the driver of this
480 device and return its result, or return -EINVAL if not defined
481
482 int pm_generic_runtime_resume(struct device *dev);
483 - invoke the ->runtime_resume() callback provided by the driver of this
484 device and return its result, or return -EINVAL if not defined
485
486 int pm_generic_suspend(struct device *dev);
487 - if the device has not been suspended at run time, invoke the ->suspend()
488 callback provided by its driver and return its result, or return 0 if not
489 defined
490
491 int pm_generic_resume(struct device *dev);
492 - invoke the ->resume() callback provided by the driver of this device and,
493 if successful, change the device's runtime PM status to 'active'
494
495 int pm_generic_freeze(struct device *dev);
496 - if the device has not been suspended at run time, invoke the ->freeze()
497 callback provided by its driver and return its result, or return 0 if not
498 defined
499
500 int pm_generic_thaw(struct device *dev);
501 - if the device has not been suspended at run time, invoke the ->thaw()
502 callback provided by its driver and return its result, or return 0 if not
503 defined
504
505 int pm_generic_poweroff(struct device *dev);
506 - if the device has not been suspended at run time, invoke the ->poweroff()
507 callback provided by its driver and return its result, or return 0 if not
508 defined
509
510 int pm_generic_restore(struct device *dev);
511 - invoke the ->restore() callback provided by the driver of this device and,
512 if successful, change the device's runtime PM status to 'active'
513
514These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(),
515->runtime_resume(), ->suspend(), ->resume(), ->freeze(), ->thaw(), ->poweroff(),
516or ->restore() callback pointers in the subsystem-level dev_pm_ops structures.
517
518If a subsystem wishes to use all of them at the same time, it can simply assign
519the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its
520dev_pm_ops structure pointer.
521
522Device drivers that wish to use the same function as a system suspend, freeze,
523poweroff and run-time suspend callback, and similarly for system resume, thaw,
524restore, and run-time resume, can achieve this with the help of the
525UNIVERSAL_DEV_PM_OPS macro defined in include/linux/pm.h (possibly setting its
526last argument to NULL).
diff --git a/Documentation/powerpc/dts-bindings/fsl/i2c.txt b/Documentation/powerpc/dts-bindings/fsl/i2c.txt
index b6d2e21474f9..50da20310585 100644
--- a/Documentation/powerpc/dts-bindings/fsl/i2c.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/i2c.txt
@@ -2,15 +2,14 @@
2 2
3Required properties : 3Required properties :
4 4
5 - device_type : Should be "i2c"
6 - reg : Offset and length of the register set for the device 5 - reg : Offset and length of the register set for the device
6 - compatible : should be "fsl,CHIP-i2c" where CHIP is the name of a
7 compatible processor, e.g. mpc8313, mpc8543, mpc8544, mpc5121,
8 mpc5200 or mpc5200b. For the mpc5121, an additional node
9 "fsl,mpc5121-i2c-ctrl" is required as shown in the example below.
7 10
8Recommended properties : 11Recommended properties :
9 12
10 - compatible : compatibility list with 2 entries, the first should
11 be "fsl,CHIP-i2c" where CHIP is the name of a compatible processor,
12 e.g. mpc8313, mpc8543, mpc8544, mpc5200 or mpc5200b. The second one
13 should be "fsl-i2c".
14 - interrupts : <a b> where a is the interrupt number and b is a 13 - interrupts : <a b> where a is the interrupt number and b is a
15 field that represents an encoding of the sense and level 14 field that represents an encoding of the sense and level
16 information for the interrupt. This should be encoded based on 15 information for the interrupt. This should be encoded based on
@@ -24,25 +23,40 @@ Recommended properties :
24 23
25Examples : 24Examples :
26 25
26 /* MPC5121 based board */
27 i2c@1740 {
28 #address-cells = <1>;
29 #size-cells = <0>;
30 compatible = "fsl,mpc5121-i2c", "fsl-i2c";
31 reg = <0x1740 0x20>;
32 interrupts = <11 0x8>;
33 interrupt-parent = <&ipic>;
34 clock-frequency = <100000>;
35 };
36
37 i2ccontrol@1760 {
38 compatible = "fsl,mpc5121-i2c-ctrl";
39 reg = <0x1760 0x8>;
40 };
41
42 /* MPC5200B based board */
27 i2c@3d00 { 43 i2c@3d00 {
28 #address-cells = <1>; 44 #address-cells = <1>;
29 #size-cells = <0>; 45 #size-cells = <0>;
30 compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; 46 compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
31 cell-index = <0>;
32 reg = <0x3d00 0x40>; 47 reg = <0x3d00 0x40>;
33 interrupts = <2 15 0>; 48 interrupts = <2 15 0>;
34 interrupt-parent = <&mpc5200_pic>; 49 interrupt-parent = <&mpc5200_pic>;
35 fsl,preserve-clocking; 50 fsl,preserve-clocking;
36 }; 51 };
37 52
53 /* MPC8544 base board */
38 i2c@3100 { 54 i2c@3100 {
39 #address-cells = <1>; 55 #address-cells = <1>;
40 #size-cells = <0>; 56 #size-cells = <0>;
41 cell-index = <1>;
42 compatible = "fsl,mpc8544-i2c", "fsl-i2c"; 57 compatible = "fsl,mpc8544-i2c", "fsl-i2c";
43 reg = <0x3100 0x100>; 58 reg = <0x3100 0x100>;
44 interrupts = <43 2>; 59 interrupts = <43 2>;
45 interrupt-parent = <&mpic>; 60 interrupt-parent = <&mpic>;
46 clock-frequency = <400000>; 61 clock-frequency = <400000>;
47 }; 62 };
48
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 33df82e3a398..bfcbbf88c44d 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1812,7 +1812,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1812 Module snd-ua101 1812 Module snd-ua101
1813 ---------------- 1813 ----------------
1814 1814
1815 Module for the Edirol UA-101 audio/MIDI interface. 1815 Module for the Edirol UA-101/UA-1000 audio/MIDI interfaces.
1816 1816
1817 This module supports multiple devices, autoprobe and hotplugging. 1817 This module supports multiple devices, autoprobe and hotplugging.
1818 1818
diff --git a/MAINTAINERS b/MAINTAINERS
index 51d8b5221dd8..c8a8b1fd58b3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -71,6 +71,7 @@ Descriptions of section entries:
71 M: Mail patches to: FullName <address@domain> 71 M: Mail patches to: FullName <address@domain>
72 L: Mailing list that is relevant to this area 72 L: Mailing list that is relevant to this area
73 W: Web-page with status/info 73 W: Web-page with status/info
74 Q: Patchwork web based patch tracking system site
74 T: SCM tree type and location. Type is one of: git, hg, quilt, stgit. 75 T: SCM tree type and location. Type is one of: git, hg, quilt, stgit.
75 S: Status, one of the following: 76 S: Status, one of the following:
76 Supported: Someone is actually paid to look after this. 77 Supported: Someone is actually paid to look after this.
@@ -182,6 +183,7 @@ M: Ron Minnich <rminnich@sandia.gov>
182M: Latchesar Ionkov <lucho@ionkov.net> 183M: Latchesar Ionkov <lucho@ionkov.net>
183L: v9fs-developer@lists.sourceforge.net 184L: v9fs-developer@lists.sourceforge.net
184W: http://swik.net/v9fs 185W: http://swik.net/v9fs
186Q: http://patchwork.kernel.org/project/v9fs-devel/list/
185T: git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git 187T: git git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git
186S: Maintained 188S: Maintained
187F: Documentation/filesystems/9p.txt 189F: Documentation/filesystems/9p.txt
@@ -238,6 +240,7 @@ ACPI
238M: Len Brown <lenb@kernel.org> 240M: Len Brown <lenb@kernel.org>
239L: linux-acpi@vger.kernel.org 241L: linux-acpi@vger.kernel.org
240W: http://www.lesswatts.org/projects/acpi/ 242W: http://www.lesswatts.org/projects/acpi/
243Q: http://patchwork.kernel.org/project/linux-acpi/list/
241T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git 244T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
242S: Supported 245S: Supported
243F: drivers/acpi/ 246F: drivers/acpi/
@@ -428,7 +431,6 @@ P: Jordan Crouse
428L: linux-geode@lists.infradead.org (moderated for non-subscribers) 431L: linux-geode@lists.infradead.org (moderated for non-subscribers)
429W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html 432W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
430S: Supported 433S: Supported
431F: arch/x86/kernel/geode_32.c
432F: drivers/char/hw_random/geode-rng.c 434F: drivers/char/hw_random/geode-rng.c
433F: drivers/crypto/geode* 435F: drivers/crypto/geode*
434F: drivers/video/geode/ 436F: drivers/video/geode/
@@ -966,6 +968,13 @@ W: http://www.arm.linux.org.uk/
966S: Maintained 968S: Maintained
967F: arch/arm/vfp/ 969F: arch/arm/vfp/
968 970
971ASC7621 HARDWARE MONITOR DRIVER
972M: George Joseph <george.joseph@fairview5.com>
973L: lm-sensors@lm-sensors.org
974S: Maintained
975F: Documentation/hwmon/asc7621
976F: drivers/hwmon/asc7621.c
977
969ASUS ACPI EXTRAS DRIVER 978ASUS ACPI EXTRAS DRIVER
970M: Corentin Chary <corentincj@iksaif.net> 979M: Corentin Chary <corentincj@iksaif.net>
971M: Karol Kozimor <sziwan@users.sourceforge.net> 980M: Karol Kozimor <sziwan@users.sourceforge.net>
@@ -1332,6 +1341,7 @@ BTRFS FILE SYSTEM
1332M: Chris Mason <chris.mason@oracle.com> 1341M: Chris Mason <chris.mason@oracle.com>
1333L: linux-btrfs@vger.kernel.org 1342L: linux-btrfs@vger.kernel.org
1334W: http://btrfs.wiki.kernel.org/ 1343W: http://btrfs.wiki.kernel.org/
1344Q: http://patchwork.kernel.org/project/linux-btrfs/list/
1335T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git 1345T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable.git
1336S: Maintained 1346S: Maintained
1337F: Documentation/filesystems/btrfs.txt 1347F: Documentation/filesystems/btrfs.txt
@@ -1496,6 +1506,7 @@ M: Steve French <sfrench@samba.org>
1496L: linux-cifs-client@lists.samba.org (moderated for non-subscribers) 1506L: linux-cifs-client@lists.samba.org (moderated for non-subscribers)
1497L: samba-technical@lists.samba.org (moderated for non-subscribers) 1507L: samba-technical@lists.samba.org (moderated for non-subscribers)
1498W: http://linux-cifs.samba.org/ 1508W: http://linux-cifs.samba.org/
1509Q: http://patchwork.ozlabs.org/project/linux-cifs-client/list/
1499T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git 1510T: git git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
1500S: Supported 1511S: Supported
1501F: Documentation/filesystems/cifs.txt 1512F: Documentation/filesystems/cifs.txt
@@ -1782,6 +1793,7 @@ DEVICE-MAPPER (LVM)
1782P: Alasdair Kergon 1793P: Alasdair Kergon
1783L: dm-devel@redhat.com 1794L: dm-devel@redhat.com
1784W: http://sources.redhat.com/dm 1795W: http://sources.redhat.com/dm
1796Q: http://patchwork.kernel.org/project/dm-devel/list/
1785S: Maintained 1797S: Maintained
1786F: Documentation/device-mapper/ 1798F: Documentation/device-mapper/
1787F: drivers/md/dm* 1799F: drivers/md/dm*
@@ -2126,6 +2138,7 @@ M: "Theodore Ts'o" <tytso@mit.edu>
2126M: Andreas Dilger <adilger@sun.com> 2138M: Andreas Dilger <adilger@sun.com>
2127L: linux-ext4@vger.kernel.org 2139L: linux-ext4@vger.kernel.org
2128W: http://ext4.wiki.kernel.org 2140W: http://ext4.wiki.kernel.org
2141Q: http://patchwork.ozlabs.org/project/linux-ext4/list/
2129S: Maintained 2142S: Maintained
2130F: Documentation/filesystems/ext4.txt 2143F: Documentation/filesystems/ext4.txt
2131F: fs/ext4/ 2144F: fs/ext4/
@@ -2502,13 +2515,6 @@ L: linux-parisc@vger.kernel.org
2502S: Maintained 2515S: Maintained
2503F: sound/parisc/harmony.* 2516F: sound/parisc/harmony.*
2504 2517
2505HAYES ESP SERIAL DRIVER
2506M: "Andrew J. Robinson" <arobinso@nyx.net>
2507W: http://www.nyx.net/~arobinso
2508S: Maintained
2509F: Documentation/serial/hayes-esp.txt
2510F: drivers/char/esp.c
2511
2512HEWLETT-PACKARD SMART2 RAID DRIVER 2518HEWLETT-PACKARD SMART2 RAID DRIVER
2513M: Chirag Kantharia <chirag.kantharia@hp.com> 2519M: Chirag Kantharia <chirag.kantharia@hp.com>
2514L: iss_storagedev@hp.com 2520L: iss_storagedev@hp.com
@@ -2717,6 +2723,7 @@ F: drivers/scsi/ips.*
2717IDE SUBSYSTEM 2723IDE SUBSYSTEM
2718M: "David S. Miller" <davem@davemloft.net> 2724M: "David S. Miller" <davem@davemloft.net>
2719L: linux-ide@vger.kernel.org 2725L: linux-ide@vger.kernel.org
2726Q: http://patchwork.ozlabs.org/project/linux-ide/list/
2720T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git 2727T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git
2721S: Maintained 2728S: Maintained
2722F: Documentation/ide/ 2729F: Documentation/ide/
@@ -2771,6 +2778,7 @@ M: Sean Hefty <sean.hefty@intel.com>
2771M: Hal Rosenstock <hal.rosenstock@gmail.com> 2778M: Hal Rosenstock <hal.rosenstock@gmail.com>
2772L: linux-rdma@vger.kernel.org 2779L: linux-rdma@vger.kernel.org
2773W: http://www.openib.org/ 2780W: http://www.openib.org/
2781Q: http://patchwork.kernel.org/project/linux-rdma/list/
2774T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git 2782T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git
2775S: Supported 2783S: Supported
2776F: Documentation/infiniband/ 2784F: Documentation/infiniband/
@@ -2790,6 +2798,7 @@ INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN) DRIVERS
2790M: Dmitry Torokhov <dmitry.torokhov@gmail.com> 2798M: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2791M: Dmitry Torokhov <dtor@mail.ru> 2799M: Dmitry Torokhov <dtor@mail.ru>
2792L: linux-input@vger.kernel.org 2800L: linux-input@vger.kernel.org
2801Q: http://patchwork.kernel.org/project/linux-input/list/
2793T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git 2802T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git
2794S: Maintained 2803S: Maintained
2795F: drivers/input/ 2804F: drivers/input/
@@ -3046,6 +3055,13 @@ W: http://www.melware.de
3046S: Maintained 3055S: Maintained
3047F: drivers/isdn/hardware/eicon/ 3056F: drivers/isdn/hardware/eicon/
3048 3057
3058IT87 HARDWARE MONITORING DRIVER
3059M: Jean Delvare <khali@linux-fr.org>
3060L: lm-sensors@lm-sensors.org
3061S: Maintained
3062F: Documentation/hwmon/it87
3063F: drivers/hwmon/it87.c
3064
3049IVTV VIDEO4LINUX DRIVER 3065IVTV VIDEO4LINUX DRIVER
3050M: Andy Walls <awalls@radix.net> 3066M: Andy Walls <awalls@radix.net>
3051L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) 3067L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
@@ -3099,6 +3115,7 @@ F: drivers/hwmon/k8temp.c
3099KCONFIG 3115KCONFIG
3100M: Roman Zippel <zippel@linux-m68k.org> 3116M: Roman Zippel <zippel@linux-m68k.org>
3101L: linux-kbuild@vger.kernel.org 3117L: linux-kbuild@vger.kernel.org
3118Q: http://patchwork.kernel.org/project/linux-kbuild/list/
3102S: Maintained 3119S: Maintained
3103F: Documentation/kbuild/kconfig-language.txt 3120F: Documentation/kbuild/kconfig-language.txt
3104F: scripts/kconfig/ 3121F: scripts/kconfig/
@@ -3312,6 +3329,7 @@ M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
3312M: Paul Mackerras <paulus@samba.org> 3329M: Paul Mackerras <paulus@samba.org>
3313W: http://www.penguinppc.org/ 3330W: http://www.penguinppc.org/
3314L: linuxppc-dev@ozlabs.org 3331L: linuxppc-dev@ozlabs.org
3332Q: http://patchwork.ozlabs.org/project/linuxppc-dev/list/
3315T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git 3333T: git git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
3316S: Supported 3334S: Supported
3317F: Documentation/powerpc/ 3335F: Documentation/powerpc/
@@ -3432,6 +3450,13 @@ S: Maintained
3432F: Documentation/ldm.txt 3450F: Documentation/ldm.txt
3433F: fs/partitions/ldm.* 3451F: fs/partitions/ldm.*
3434 3452
3453LogFS
3454M: Joern Engel <joern@logfs.org>
3455L: logfs@logfs.org
3456W: logfs.org
3457S: Maintained
3458F: fs/logfs/
3459
3435LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI) 3460LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
3436M: Eric Moore <Eric.Moore@lsi.com> 3461M: Eric Moore <Eric.Moore@lsi.com>
3437M: support@lsi.com 3462M: support@lsi.com
@@ -3568,6 +3593,7 @@ M: Mauro Carvalho Chehab <mchehab@infradead.org>
3568P: LinuxTV.org Project 3593P: LinuxTV.org Project
3569L: linux-media@vger.kernel.org 3594L: linux-media@vger.kernel.org
3570W: http://linuxtv.org 3595W: http://linuxtv.org
3596Q: http://patchwork.kernel.org/project/linux-media/list/
3571T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git 3597T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
3572S: Maintained 3598S: Maintained
3573F: Documentation/dvb/ 3599F: Documentation/dvb/
@@ -3603,8 +3629,9 @@ F: mm/memcontrol.c
3603 3629
3604MEMORY TECHNOLOGY DEVICES (MTD) 3630MEMORY TECHNOLOGY DEVICES (MTD)
3605M: David Woodhouse <dwmw2@infradead.org> 3631M: David Woodhouse <dwmw2@infradead.org>
3606W: http://www.linux-mtd.infradead.org/
3607L: linux-mtd@lists.infradead.org 3632L: linux-mtd@lists.infradead.org
3633W: http://www.linux-mtd.infradead.org/
3634Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
3608T: git git://git.infradead.org/mtd-2.6.git 3635T: git git://git.infradead.org/mtd-2.6.git
3609S: Maintained 3636S: Maintained
3610F: drivers/mtd/ 3637F: drivers/mtd/
@@ -3864,6 +3891,7 @@ S: Maintained
3864NETWORKING [WIRELESS] 3891NETWORKING [WIRELESS]
3865M: "John W. Linville" <linville@tuxdriver.com> 3892M: "John W. Linville" <linville@tuxdriver.com>
3866L: linux-wireless@vger.kernel.org 3893L: linux-wireless@vger.kernel.org
3894Q: http://patchwork.kernel.org/project/linux-wireless/list/
3867T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git 3895T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
3868S: Maintained 3896S: Maintained
3869F: net/mac80211/ 3897F: net/mac80211/
@@ -3956,6 +3984,7 @@ M: Tony Lindgren <tony@atomide.com>
3956L: linux-omap@vger.kernel.org 3984L: linux-omap@vger.kernel.org
3957W: http://www.muru.com/linux/omap/ 3985W: http://www.muru.com/linux/omap/
3958W: http://linux.omap.com/ 3986W: http://linux.omap.com/
3987Q: http://patchwork.kernel.org/project/linux-omap/list/
3959T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git 3988T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
3960S: Maintained 3989S: Maintained
3961F: arch/arm/*omap*/ 3990F: arch/arm/*omap*/
@@ -4182,6 +4211,7 @@ M: Helge Deller <deller@gmx.de>
4182M: "James E.J. Bottomley" <jejb@parisc-linux.org> 4211M: "James E.J. Bottomley" <jejb@parisc-linux.org>
4183L: linux-parisc@vger.kernel.org 4212L: linux-parisc@vger.kernel.org
4184W: http://www.parisc-linux.org/ 4213W: http://www.parisc-linux.org/
4214Q: http://patchwork.kernel.org/project/linux-parisc/list/
4185T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git 4215T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
4186S: Maintained 4216S: Maintained
4187F: arch/parisc/ 4217F: arch/parisc/
@@ -4224,6 +4254,7 @@ F: Documentation/powerpc/eeh-pci-error-recovery.txt
4224PCI SUBSYSTEM 4254PCI SUBSYSTEM
4225M: Jesse Barnes <jbarnes@virtuousgeek.org> 4255M: Jesse Barnes <jbarnes@virtuousgeek.org>
4226L: linux-pci@vger.kernel.org 4256L: linux-pci@vger.kernel.org
4257Q: http://patchwork.kernel.org/project/linux-pci/list/
4227T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git 4258T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
4228S: Supported 4259S: Supported
4229F: Documentation/PCI/ 4260F: Documentation/PCI/
@@ -4265,7 +4296,9 @@ M: Ingo Molnar <mingo@elte.hu>
4265S: Supported 4296S: Supported
4266F: kernel/perf_event.c 4297F: kernel/perf_event.c
4267F: include/linux/perf_event.h 4298F: include/linux/perf_event.h
4268F: arch/*/*/kernel/perf_event.c 4299F: arch/*/kernel/perf_event.c
4300F: arch/*/kernel/*/perf_event.c
4301F: arch/*/kernel/*/*/perf_event.c
4269F: arch/*/include/asm/perf_event.h 4302F: arch/*/include/asm/perf_event.h
4270F: arch/*/lib/perf_event.c 4303F: arch/*/lib/perf_event.c
4271F: arch/*/kernel/perf_callchain.c 4304F: arch/*/kernel/perf_callchain.c
@@ -4599,6 +4632,7 @@ F: include/linux/rtc.h
4599REAL TIME CLOCK (RTC) SUBSYSTEM 4632REAL TIME CLOCK (RTC) SUBSYSTEM
4600M: Alessandro Zummo <a.zummo@towertech.it> 4633M: Alessandro Zummo <a.zummo@towertech.it>
4601L: rtc-linux@googlegroups.com 4634L: rtc-linux@googlegroups.com
4635Q: http://patchwork.ozlabs.org/project/rtc-linux/list/
4602S: Maintained 4636S: Maintained
4603F: Documentation/rtc.txt 4637F: Documentation/rtc.txt
4604F: drivers/rtc/ 4638F: drivers/rtc/
@@ -4966,6 +5000,7 @@ F: drivers/*/*/*s3c2410*
4966TI DAVINCI MACHINE SUPPORT 5000TI DAVINCI MACHINE SUPPORT
4967P: Kevin Hilman 5001P: Kevin Hilman
4968M: davinci-linux-open-source@linux.davincidsp.com 5002M: davinci-linux-open-source@linux.davincidsp.com
5003Q: http://patchwork.kernel.org/project/linux-davinci/list/
4969S: Supported 5004S: Supported
4970F: arch/arm/mach-davinci 5005F: arch/arm/mach-davinci
4971 5006
@@ -5131,6 +5166,7 @@ F: include/sound/soc*
5131SPARC + UltraSPARC (sparc/sparc64) 5166SPARC + UltraSPARC (sparc/sparc64)
5132M: "David S. Miller" <davem@davemloft.net> 5167M: "David S. Miller" <davem@davemloft.net>
5133L: sparclinux@vger.kernel.org 5168L: sparclinux@vger.kernel.org
5169Q: http://patchwork.ozlabs.org/project/sparclinux/list/
5134T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git 5170T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
5135T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git 5171T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
5136S: Maintained 5172S: Maintained
@@ -5146,6 +5182,7 @@ SPI SUBSYSTEM
5146M: David Brownell <dbrownell@users.sourceforge.net> 5182M: David Brownell <dbrownell@users.sourceforge.net>
5147M: Grant Likely <grant.likely@secretlab.ca> 5183M: Grant Likely <grant.likely@secretlab.ca>
5148L: spi-devel-general@lists.sourceforge.net 5184L: spi-devel-general@lists.sourceforge.net
5185Q: http://patchwork.kernel.org/project/spi-devel-general/list/
5149S: Maintained 5186S: Maintained
5150F: Documentation/spi/ 5187F: Documentation/spi/
5151F: drivers/spi/ 5188F: drivers/spi/
@@ -5201,7 +5238,7 @@ F: drivers/net/starfire*
5201 5238
5202STARMODE RADIO IP (STRIP) PROTOCOL DRIVER 5239STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
5203S: Orphan 5240S: Orphan
5204F: drivers/net/wireless/strip.c 5241F: drivers/staging/strip/strip.c
5205F: include/linux/if_strip.h 5242F: include/linux/if_strip.h
5206 5243
5207STRADIS MPEG-2 DECODER DRIVER 5244STRADIS MPEG-2 DECODER DRIVER
@@ -5222,6 +5259,7 @@ SUPERH
5222M: Paul Mundt <lethal@linux-sh.org> 5259M: Paul Mundt <lethal@linux-sh.org>
5223L: linux-sh@vger.kernel.org 5260L: linux-sh@vger.kernel.org
5224W: http://www.linux-sh.org 5261W: http://www.linux-sh.org
5262Q: http://patchwork.kernel.org/project/linux-sh/list/
5225T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git 5263T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git
5226S: Supported 5264S: Supported
5227F: Documentation/sh/ 5265F: Documentation/sh/
@@ -5989,7 +6027,7 @@ L: linux-wireless@vger.kernel.org
5989W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ 6027W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
5990S: Maintained 6028S: Maintained
5991F: Documentation/networking/wavelan.txt 6029F: Documentation/networking/wavelan.txt
5992F: drivers/net/wireless/wavelan* 6030F: drivers/staging/wavelan/
5993 6031
5994WD7000 SCSI DRIVER 6032WD7000 SCSI DRIVER
5995M: Miroslav Zagorac <zaga@fly.cc.fer.hr> 6033M: Miroslav Zagorac <zaga@fly.cc.fer.hr>
@@ -6185,6 +6223,7 @@ F: drivers/serial/zs.*
6185THE REST 6223THE REST
6186M: Linus Torvalds <torvalds@linux-foundation.org> 6224M: Linus Torvalds <torvalds@linux-foundation.org>
6187L: linux-kernel@vger.kernel.org 6225L: linux-kernel@vger.kernel.org
6226Q: http://patchwork.kernel.org/project/LKML/list/
6188T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git 6227T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
6189S: Buried alive in reporters 6228S: Buried alive in reporters
6190F: * 6229F: *
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 62619f25132f..53c213f70fcb 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -361,7 +361,7 @@ osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
361SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path, 361SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
362 int, flag, void __user *, data) 362 int, flag, void __user *, data)
363{ 363{
364 int retval = -EINVAL; 364 int retval;
365 char *name; 365 char *name;
366 366
367 name = getname(path); 367 name = getname(path);
@@ -379,6 +379,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, char __user *, path,
379 retval = osf_procfs_mount(name, data, flag); 379 retval = osf_procfs_mount(name, data, flag);
380 break; 380 break;
381 default: 381 default:
382 retval = -EINVAL;
382 printk("osf_mount(%ld, %x)\n", typenr, flag); 383 printk("osf_mount(%ld, %x)\n", typenr, flag);
383 } 384 }
384 putname(name); 385 putname(name);
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 7adac388a771..059eac6abda1 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -20,6 +20,12 @@ config RWSEM_GENERIC_SPINLOCK
20config RWSEM_XCHGADD_ALGORITHM 20config RWSEM_XCHGADD_ALGORITHM
21 bool 21 bool
22 22
23config GENERIC_TIME
24 def_bool y
25
26config ARCH_USES_GETTIMEOFFSET
27 def_bool y
28
23config GENERIC_IOMAP 29config GENERIC_IOMAP
24 bool 30 bool
25 default y 31 default y
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index fd529a0ec758..b70fb34939d9 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -628,9 +628,9 @@ static int create_output_descriptors(struct cryptocop_operation *operation, int
628 cdesc->dma_descr->buf = (char*)virt_to_phys(operation->tfrm_op.indata[*iniov_ix].iov_base + *iniov_offset); 628 cdesc->dma_descr->buf = (char*)virt_to_phys(operation->tfrm_op.indata[*iniov_ix].iov_base + *iniov_offset);
629 cdesc->dma_descr->after = cdesc->dma_descr->buf + dlength; 629 cdesc->dma_descr->after = cdesc->dma_descr->buf + dlength;
630 630
631 assert(desc_len >= dlength);
631 desc_len -= dlength; 632 desc_len -= dlength;
632 *iniov_offset += dlength; 633 *iniov_offset += dlength;
633 assert(desc_len >= 0);
634 if (*iniov_offset >= operation->tfrm_op.indata[*iniov_ix].iov_len) { 634 if (*iniov_offset >= operation->tfrm_op.indata[*iniov_ix].iov_len) {
635 *iniov_offset = 0; 635 *iniov_offset = 0;
636 ++(*iniov_ix); 636 ++(*iniov_ix);
diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c
index 84d31bd7b692..82ef293c4c81 100644
--- a/arch/cris/arch-v32/mach-fs/arbiter.c
+++ b/arch/cris/arch-v32/mach-fs/arbiter.c
@@ -332,7 +332,7 @@ int crisv32_arbiter_unwatch(int id)
332 if (id == 0) 332 if (id == 0)
333 intr_mask.bp0 = regk_marb_no; 333 intr_mask.bp0 = regk_marb_no;
334 else if (id == 1) 334 else if (id == 1)
335 intr_mask.bp2 = regk_marb_no; 335 intr_mask.bp1 = regk_marb_no;
336 else if (id == 2) 336 else if (id == 2)
337 intr_mask.bp2 = regk_marb_no; 337 intr_mask.bp2 = regk_marb_no;
338 else if (id == 3) 338 else if (id == 3)
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index 074fe7dea96b..a05dd31f3efb 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -42,75 +42,11 @@ unsigned long loops_per_usec;
42extern unsigned long do_slow_gettimeoffset(void); 42extern unsigned long do_slow_gettimeoffset(void);
43static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; 43static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
44 44
45/* 45u32 arch_gettimeoffset(void)
46 * This version of gettimeofday has near microsecond resolution.
47 *
48 * Note: Division is quite slow on CRIS and do_gettimeofday is called
49 * rather often. Maybe we should do some kind of approximation here
50 * (a naive approximation would be to divide by 1024).
51 */
52void do_gettimeofday(struct timeval *tv)
53{
54 unsigned long flags;
55 signed long usec, sec;
56 local_irq_save(flags);
57 usec = do_gettimeoffset();
58
59 /*
60 * If time_adjust is negative then NTP is slowing the clock
61 * so make sure not to go into next possible interval.
62 * Better to lose some accuracy than have time go backwards..
63 */
64 if (unlikely(time_adjust < 0) && usec > tickadj)
65 usec = tickadj;
66
67 sec = xtime.tv_sec;
68 usec += xtime.tv_nsec / 1000;
69 local_irq_restore(flags);
70
71 while (usec >= 1000000) {
72 usec -= 1000000;
73 sec++;
74 }
75
76 tv->tv_sec = sec;
77 tv->tv_usec = usec;
78}
79
80EXPORT_SYMBOL(do_gettimeofday);
81
82int do_settimeofday(struct timespec *tv)
83{ 46{
84 time_t wtm_sec, sec = tv->tv_sec; 47 return do_gettimeoffset() * 1000;
85 long wtm_nsec, nsec = tv->tv_nsec;
86
87 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
88 return -EINVAL;
89
90 write_seqlock_irq(&xtime_lock);
91 /*
92 * This is revolting. We need to set "xtime" correctly. However, the
93 * value in this location is the value at the most recent update of
94 * wall time. Discover what correction gettimeofday() would have
95 * made, and then undo it!
96 */
97 nsec -= do_gettimeoffset() * NSEC_PER_USEC;
98
99 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
100 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
101
102 set_normalized_timespec(&xtime, sec, nsec);
103 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
104
105 ntp_clear();
106 write_sequnlock_irq(&xtime_lock);
107 clock_was_set();
108 return 0;
109} 48}
110 49
111EXPORT_SYMBOL(do_settimeofday);
112
113
114/* 50/*
115 * BUG: This routine does not handle hour overflow properly; it just 51 * BUG: This routine does not handle hour overflow properly; it just
116 * sets the minutes. Usually you'll only notice that after reboot! 52 * sets the minutes. Usually you'll only notice that after reboot!
diff --git a/arch/frv/include/asm/pci.h b/arch/frv/include/asm/pci.h
index 492b5c4dfed6..8c7260a3cd41 100644
--- a/arch/frv/include/asm/pci.h
+++ b/arch/frv/include/asm/pci.h
@@ -68,41 +68,4 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
68#define PCIBIOS_MIN_IO 0x100 68#define PCIBIOS_MIN_IO 0x100
69#define PCIBIOS_MIN_MEM 0x00010000 69#define PCIBIOS_MIN_MEM 0x00010000
70 70
71/* Make physical memory consistent for a single
72 * streaming mode DMA translation after a transfer.
73 *
74 * If you perform a pci_map_single() but wish to interrogate the
75 * buffer using the cpu, yet do not wish to teardown the PCI dma
76 * mapping, you must call this function before doing so. At the
77 * next point you give the PCI dma address back to the card, the
78 * device again owns the buffer.
79 */
80static inline void pci_dma_sync_single(struct pci_dev *hwdev,
81 dma_addr_t dma_handle,
82 size_t size, int direction)
83{
84 BUG_ON(direction == PCI_DMA_NONE);
85
86 frv_cache_wback_inv((unsigned long)bus_to_virt(dma_handle),
87 (unsigned long)bus_to_virt(dma_handle) + size);
88}
89
90/* Make physical memory consistent for a set of streaming
91 * mode DMA translations after a transfer.
92 *
93 * The same as pci_dma_sync_single but for a scatter-gather list,
94 * same rules and usage.
95 */
96static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
97 struct scatterlist *sg,
98 int nelems, int direction)
99{
100 int i;
101 BUG_ON(direction == PCI_DMA_NONE);
102
103 for (i = 0; i < nelems; i++)
104 frv_cache_wback_inv(sg_dma_address(&sg[i]),
105 sg_dma_address(&sg[i])+sg_dma_len(&sg[i]));
106}
107
108#endif /* _ASM_FRV_PCI_H */ 71#endif /* _ASM_FRV_PCI_H */
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 4c41656ede87..b5298eb09adb 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -219,54 +219,6 @@ do { \
219 NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \ 219 NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \
220} while (0) 220} while (0)
221 221
222
223/*
224 * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
225 * extra segments containing the gate DSO contents. Dumping its
226 * contents makes post-mortem fully interpretable later without matching up
227 * the same kernel and hardware config to see what PC values meant.
228 * Dumping its extra ELF program headers includes all the other information
229 * a debugger needs to easily find how the gate DSO was being used.
230 */
231#define ELF_CORE_EXTRA_PHDRS (GATE_EHDR->e_phnum)
232#define ELF_CORE_WRITE_EXTRA_PHDRS \
233do { \
234 const struct elf_phdr *const gate_phdrs = \
235 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
236 int i; \
237 Elf64_Off ofs = 0; \
238 for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
239 struct elf_phdr phdr = gate_phdrs[i]; \
240 if (phdr.p_type == PT_LOAD) { \
241 phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \
242 phdr.p_filesz = phdr.p_memsz; \
243 if (ofs == 0) { \
244 ofs = phdr.p_offset = offset; \
245 offset += phdr.p_filesz; \
246 } \
247 else \
248 phdr.p_offset = ofs; \
249 } \
250 else \
251 phdr.p_offset += ofs; \
252 phdr.p_paddr = 0; /* match other core phdrs */ \
253 DUMP_WRITE(&phdr, sizeof(phdr)); \
254 } \
255} while (0)
256#define ELF_CORE_WRITE_EXTRA_DATA \
257do { \
258 const struct elf_phdr *const gate_phdrs = \
259 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
260 int i; \
261 for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
262 if (gate_phdrs[i].p_type == PT_LOAD) { \
263 DUMP_WRITE((void *) gate_phdrs[i].p_vaddr, \
264 PAGE_ALIGN(gate_phdrs[i].p_memsz)); \
265 break; \
266 } \
267 } \
268} while (0)
269
270/* 222/*
271 * format for entries in the Global Offset Table 223 * format for entries in the Global Offset Table
272 */ 224 */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 4138282aefa8..db10b1e378b0 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -45,6 +45,8 @@ endif
45obj-$(CONFIG_DMAR) += pci-dma.o 45obj-$(CONFIG_DMAR) += pci-dma.o
46obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 46obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
47 47
48obj-$(CONFIG_BINFMT_ELF) += elfcore.o
49
48# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. 50# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
49CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 51CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
50 52
diff --git a/arch/ia64/kernel/elfcore.c b/arch/ia64/kernel/elfcore.c
new file mode 100644
index 000000000000..bac1639bc320
--- /dev/null
+++ b/arch/ia64/kernel/elfcore.c
@@ -0,0 +1,80 @@
1#include <linux/elf.h>
2#include <linux/coredump.h>
3#include <linux/fs.h>
4#include <linux/mm.h>
5
6#include <asm/elf.h>
7
8
9Elf64_Half elf_core_extra_phdrs(void)
10{
11 return GATE_EHDR->e_phnum;
12}
13
14int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
15 unsigned long limit)
16{
17 const struct elf_phdr *const gate_phdrs =
18 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
19 int i;
20 Elf64_Off ofs = 0;
21
22 for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
23 struct elf_phdr phdr = gate_phdrs[i];
24
25 if (phdr.p_type == PT_LOAD) {
26 phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
27 phdr.p_filesz = phdr.p_memsz;
28 if (ofs == 0) {
29 ofs = phdr.p_offset = offset;
30 offset += phdr.p_filesz;
31 } else {
32 phdr.p_offset = ofs;
33 }
34 } else {
35 phdr.p_offset += ofs;
36 }
37 phdr.p_paddr = 0; /* match other core phdrs */
38 *size += sizeof(phdr);
39 if (*size > limit || !dump_write(file, &phdr, sizeof(phdr)))
40 return 0;
41 }
42 return 1;
43}
44
45int elf_core_write_extra_data(struct file *file, size_t *size,
46 unsigned long limit)
47{
48 const struct elf_phdr *const gate_phdrs =
49 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
50 int i;
51
52 for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
53 if (gate_phdrs[i].p_type == PT_LOAD) {
54 void *addr = (void *)gate_phdrs[i].p_vaddr;
55 size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);
56
57 *size += memsz;
58 if (*size > limit || !dump_write(file, addr, memsz))
59 return 0;
60 break;
61 }
62 }
63 return 1;
64}
65
66size_t elf_core_extra_data_size(void)
67{
68 const struct elf_phdr *const gate_phdrs =
69 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
70 int i;
71 size_t size = 0;
72
73 for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
74 if (gate_phdrs[i].p_type == PT_LOAD) {
75 size += PAGE_ALIGN(gate_phdrs[i].p_memsz);
76 break;
77 }
78 }
79 return size;
80}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index b81e46b1629b..703062c44fb9 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2315,6 +2315,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
2315 DPRINT(("Cannot allocate vma\n")); 2315 DPRINT(("Cannot allocate vma\n"));
2316 goto error_kmem; 2316 goto error_kmem;
2317 } 2317 }
2318 INIT_LIST_HEAD(&vma->anon_vma_chain);
2318 2319
2319 /* 2320 /*
2320 * partially initialize the vma for the sampling buffer 2321 * partially initialize the vma for the sampling buffer
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index ca3335ea56cc..ed41759efcac 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -117,6 +117,7 @@ ia64_init_addr_space (void)
117 */ 117 */
118 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 118 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
119 if (vma) { 119 if (vma) {
120 INIT_LIST_HEAD(&vma->anon_vma_chain);
120 vma->vm_mm = current->mm; 121 vma->vm_mm = current->mm;
121 vma->vm_start = current->thread.rbs_bot & PAGE_MASK; 122 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
122 vma->vm_end = vma->vm_start + PAGE_SIZE; 123 vma->vm_end = vma->vm_start + PAGE_SIZE;
@@ -135,6 +136,7 @@ ia64_init_addr_space (void)
135 if (!(current->personality & MMAP_PAGE_ZERO)) { 136 if (!(current->personality & MMAP_PAGE_ZERO)) {
136 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); 137 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
137 if (vma) { 138 if (vma) {
139 INIT_LIST_HEAD(&vma->anon_vma_chain);
138 vma->vm_mm = current->mm; 140 vma->vm_mm = current->mm;
139 vma->vm_end = PAGE_SIZE; 141 vma->vm_end = PAGE_SIZE;
140 vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT); 142 vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug
index bc989e522a04..7305ac8f7f5b 100644
--- a/arch/parisc/Kconfig.debug
+++ b/arch/parisc/Kconfig.debug
@@ -12,4 +12,18 @@ config DEBUG_RODATA
12 portion of the kernel code won't be covered by a TLB anymore. 12 portion of the kernel code won't be covered by a TLB anymore.
13 If in doubt, say "N". 13 If in doubt, say "N".
14 14
15config DEBUG_STRICT_USER_COPY_CHECKS
16 bool "Strict copy size checks"
17 depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
18 ---help---
19 Enabling this option turns a certain set of sanity checks for user
20 copy operations into compile time failures.
21
22 The copy_from_user() etc checks are there to help test if there
23 are sufficient security checks on the length argument of
24 the copy operation, by having gcc prove that the argument is
25 within bounds.
26
27 If unsure, or if you run an older (pre 4.4) gcc, say N.
28
15endmenu 29endmenu
diff --git a/arch/parisc/include/asm/param.h b/arch/parisc/include/asm/param.h
index 32e03d877858..965d45427975 100644
--- a/arch/parisc/include/asm/param.h
+++ b/arch/parisc/include/asm/param.h
@@ -1,22 +1 @@
1#ifndef _ASMPARISC_PARAM_H #include <asm-generic/param.h>
2#define _ASMPARISC_PARAM_H
3
4#ifdef __KERNEL__
5#define HZ CONFIG_HZ
6#define USER_HZ 100 /* some user API use "ticks" */
7#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
8#endif
9
10#ifndef HZ
11#define HZ 100
12#endif
13
14#define EXEC_PAGESIZE 4096
15
16#ifndef NOGROUP
17#define NOGROUP (-1)
18#endif
19
20#define MAXHOSTNAMELEN 64 /* max length of hostname */
21
22#endif
diff --git a/arch/parisc/include/asm/system.h b/arch/parisc/include/asm/system.h
index d91357bca5b4..4653c77bf9d1 100644
--- a/arch/parisc/include/asm/system.h
+++ b/arch/parisc/include/asm/system.h
@@ -160,7 +160,7 @@ static inline void set_eiem(unsigned long val)
160 ldcd). */ 160 ldcd). */
161 161
162#define __PA_LDCW_ALIGNMENT 4 162#define __PA_LDCW_ALIGNMENT 4
163#define __ldcw_align(a) ((volatile unsigned int *)a) 163#define __ldcw_align(a) (&(a)->slock)
164#define __LDCW "ldcw,co" 164#define __LDCW "ldcw,co"
165 165
166#endif /*!CONFIG_PA20*/ 166#endif /*!CONFIG_PA20*/
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
index 7cf799d70b4c..ff4cf9dab8d2 100644
--- a/arch/parisc/include/asm/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
@@ -7,6 +7,7 @@
7#include <asm/page.h> 7#include <asm/page.h>
8#include <asm/system.h> 8#include <asm/system.h>
9#include <asm/cache.h> 9#include <asm/cache.h>
10#include <asm/errno.h>
10#include <asm-generic/uaccess-unaligned.h> 11#include <asm-generic/uaccess-unaligned.h>
11 12
12#define VERIFY_READ 0 13#define VERIFY_READ 0
@@ -234,13 +235,35 @@ extern long lstrnlen_user(const char __user *,long);
234 235
235unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len); 236unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len);
236#define __copy_to_user copy_to_user 237#define __copy_to_user copy_to_user
237unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len); 238unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len);
238#define __copy_from_user copy_from_user
239unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len); 239unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len);
240#define __copy_in_user copy_in_user 240#define __copy_in_user copy_in_user
241#define __copy_to_user_inatomic __copy_to_user 241#define __copy_to_user_inatomic __copy_to_user
242#define __copy_from_user_inatomic __copy_from_user 242#define __copy_from_user_inatomic __copy_from_user
243 243
244extern void copy_from_user_overflow(void)
245#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
246 __compiletime_error("copy_from_user() buffer size is not provably correct")
247#else
248 __compiletime_warning("copy_from_user() buffer size is not provably correct")
249#endif
250;
251
252static inline unsigned long __must_check copy_from_user(void *to,
253 const void __user *from,
254 unsigned long n)
255{
256 int sz = __compiletime_object_size(to);
257 int ret = -EFAULT;
258
259 if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n))
260 ret = __copy_from_user(to, from, n);
261 else
262 copy_from_user_overflow();
263
264 return ret;
265}
266
244struct pt_regs; 267struct pt_regs;
245int fixup_exception(struct pt_regs *regs); 268int fixup_exception(struct pt_regs *regs);
246 269
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cda158318c62..1ce7d2851d90 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -811,8 +811,10 @@
811#define __NR_pwritev (__NR_Linux + 316) 811#define __NR_pwritev (__NR_Linux + 316)
812#define __NR_rt_tgsigqueueinfo (__NR_Linux + 317) 812#define __NR_rt_tgsigqueueinfo (__NR_Linux + 317)
813#define __NR_perf_event_open (__NR_Linux + 318) 813#define __NR_perf_event_open (__NR_Linux + 318)
814#define __NR_recvmmsg (__NR_Linux + 319)
815#define __NR_accept4 (__NR_Linux + 320)
814 816
815#define __NR_Linux_syscalls (__NR_perf_event_open + 1) 817#define __NR_Linux_syscalls (__NR_accept4 + 1)
816 818
817 819
818#define __IGNORE_select /* newselect */ 820#define __IGNORE_select /* newselect */
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 1054baa2fc69..d054f3da3ff5 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -171,14 +171,14 @@ parisc_cache_init(void)
171 cache_info.ic_conf.cc_cst, 171 cache_info.ic_conf.cc_cst,
172 cache_info.ic_conf.cc_hv); 172 cache_info.ic_conf.cc_hv);
173 173
174 printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", 174 printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
175 cache_info.dt_conf.tc_sh, 175 cache_info.dt_conf.tc_sh,
176 cache_info.dt_conf.tc_page, 176 cache_info.dt_conf.tc_page,
177 cache_info.dt_conf.tc_cst, 177 cache_info.dt_conf.tc_cst,
178 cache_info.dt_conf.tc_aid, 178 cache_info.dt_conf.tc_aid,
179 cache_info.dt_conf.tc_pad1); 179 cache_info.dt_conf.tc_pad1);
180 180
181 printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", 181 printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d\n",
182 cache_info.it_conf.tc_sh, 182 cache_info.it_conf.tc_sh,
183 cache_info.it_conf.tc_page, 183 cache_info.it_conf.tc_page,
184 cache_info.it_conf.tc_cst, 184 cache_info.it_conf.tc_cst,
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 01c4fcf8f481..de5f6dab48b7 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -417,6 +417,8 @@
417 ENTRY_COMP(pwritev) 417 ENTRY_COMP(pwritev)
418 ENTRY_COMP(rt_tgsigqueueinfo) 418 ENTRY_COMP(rt_tgsigqueueinfo)
419 ENTRY_SAME(perf_event_open) 419 ENTRY_SAME(perf_event_open)
420 ENTRY_COMP(recvmmsg)
421 ENTRY_SAME(accept4) /* 320 */
420 422
421 /* Nothing yet */ 423 /* Nothing yet */
422 424
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index a79c6f9e7e2c..05511ccb61d2 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -250,9 +250,21 @@ static int __init rtc_init(void)
250} 250}
251module_init(rtc_init); 251module_init(rtc_init);
252 252
253void __init time_init(void) 253void read_persistent_clock(struct timespec *ts)
254{ 254{
255 static struct pdc_tod tod_data; 255 static struct pdc_tod tod_data;
256 if (pdc_tod_read(&tod_data) == 0) {
257 ts->tv_sec = tod_data.tod_sec;
258 ts->tv_nsec = tod_data.tod_usec * 1000;
259 } else {
260 printk(KERN_ERR "Error reading tod clock\n");
261 ts->tv_sec = 0;
262 ts->tv_nsec = 0;
263 }
264}
265
266void __init time_init(void)
267{
256 unsigned long current_cr16_khz; 268 unsigned long current_cr16_khz;
257 269
258 clocktick = (100 * PAGE0->mem_10msec) / HZ; 270 clocktick = (100 * PAGE0->mem_10msec) / HZ;
@@ -264,19 +276,4 @@ void __init time_init(void)
264 clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz, 276 clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz,
265 clocksource_cr16.shift); 277 clocksource_cr16.shift);
266 clocksource_register(&clocksource_cr16); 278 clocksource_register(&clocksource_cr16);
267
268 if (pdc_tod_read(&tod_data) == 0) {
269 unsigned long flags;
270
271 write_seqlock_irqsave(&xtime_lock, flags);
272 xtime.tv_sec = tod_data.tod_sec;
273 xtime.tv_nsec = tod_data.tod_usec * 1000;
274 set_normalized_timespec(&wall_to_monotonic,
275 -xtime.tv_sec, -xtime.tv_nsec);
276 write_sequnlock_irqrestore(&xtime_lock, flags);
277 } else {
278 printk(KERN_ERR "Error reading tod clock\n");
279 xtime.tv_sec = 0;
280 xtime.tv_nsec = 0;
281 }
282} 279}
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index e6f4b7a4b7e3..92d977bb5ea8 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -25,6 +25,7 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/signal.h> 27#include <linux/signal.h>
28#include <linux/ratelimit.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29 30
30/* #define DEBUG_UNALIGNED 1 */ 31/* #define DEBUG_UNALIGNED 1 */
@@ -446,8 +447,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
446 447
447void handle_unaligned(struct pt_regs *regs) 448void handle_unaligned(struct pt_regs *regs)
448{ 449{
449 static unsigned long unaligned_count = 0; 450 static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
450 static unsigned long last_time = 0;
451 unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0; 451 unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
452 int modify = 0; 452 int modify = 0;
453 int ret = ERR_NOTHANDLED; 453 int ret = ERR_NOTHANDLED;
@@ -460,14 +460,8 @@ void handle_unaligned(struct pt_regs *regs)
460 goto force_sigbus; 460 goto force_sigbus;
461 } 461 }
462 462
463 if (unaligned_count > 5 && 463 if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
464 time_after(jiffies, last_time + 5 * HZ)) { 464 __ratelimit(&ratelimit)) {
465 unaligned_count = 0;
466 last_time = jiffies;
467 }
468
469 if (!(current->thread.flags & PARISC_UAC_NOPRINT)
470 && ++unaligned_count < 5) {
471 char buf[256]; 465 char buf[256];
472 sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n", 466 sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
473 current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]); 467 current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index abf41f4632a9..1dbca5c31b3c 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -475,7 +475,8 @@ unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len)
475 return pa_memcpy((void __force *)dst, src, len); 475 return pa_memcpy((void __force *)dst, src, len);
476} 476}
477 477
478unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len) 478EXPORT_SYMBOL(__copy_from_user);
479unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len)
479{ 480{
480 mtsp(get_user_space(), 1); 481 mtsp(get_user_space(), 1);
481 mtsp(get_kernel_space(), 2); 482 mtsp(get_kernel_space(), 2);
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b037d95eeadc..64c00227b997 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -451,7 +451,7 @@ static int __cpuinit numa_setup_cpu(unsigned long lcpu)
451 nid = of_node_to_nid_single(cpu); 451 nid = of_node_to_nid_single(cpu);
452 452
453 if (nid < 0 || !node_online(nid)) 453 if (nid < 0 || !node_online(nid))
454 nid = any_online_node(NODE_MASK_ALL); 454 nid = first_online_node;
455out: 455out:
456 map_cpu_to_node(lcpu, nid); 456 map_cpu_to_node(lcpu, nid);
457 457
@@ -1114,7 +1114,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
1114 int nid, found = 0; 1114 int nid, found = 0;
1115 1115
1116 if (!numa_enabled || (min_common_depth < 0)) 1116 if (!numa_enabled || (min_common_depth < 0))
1117 return any_online_node(NODE_MASK_ALL); 1117 return first_online_node;
1118 1118
1119 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); 1119 memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
1120 if (memory) { 1120 if (memory) {
@@ -1125,7 +1125,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
1125 } 1125 }
1126 1126
1127 if (nid < 0 || !node_online(nid)) 1127 if (nid < 0 || !node_online(nid))
1128 nid = any_online_node(NODE_MASK_ALL); 1128 nid = first_online_node;
1129 1129
1130 if (NODE_DATA(nid)->node_spanned_pages) 1130 if (NODE_DATA(nid)->node_spanned_pages)
1131 return nid; 1131 return nid;
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index c666bfe5e984..9b04b1102bbc 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -321,11 +321,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
321#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40 321#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40
322#define QDIO_ERROR_SLSB_STATE 0x80 322#define QDIO_ERROR_SLSB_STATE 0x80
323 323
324/* for qdio_initialize */
325#define QDIO_INBOUND_0COPY_SBALS 0x01
326#define QDIO_OUTBOUND_0COPY_SBALS 0x02
327#define QDIO_USE_OUTBOUND_PCIS 0x04
328
329/* for qdio_cleanup */ 324/* for qdio_cleanup */
330#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 325#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
331#define QDIO_FLAG_CLEANUP_USING_HALT 0x02 326#define QDIO_FLAG_CLEANUP_USING_HALT 0x02
@@ -344,7 +339,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
344 * @input_handler: handler to be called for input queues 339 * @input_handler: handler to be called for input queues
345 * @output_handler: handler to be called for output queues 340 * @output_handler: handler to be called for output queues
346 * @int_parm: interruption parameter 341 * @int_parm: interruption parameter
347 * @flags: initialization flags
348 * @input_sbal_addr_array: address of no_input_qs * 128 pointers 342 * @input_sbal_addr_array: address of no_input_qs * 128 pointers
349 * @output_sbal_addr_array: address of no_output_qs * 128 pointers 343 * @output_sbal_addr_array: address of no_output_qs * 128 pointers
350 */ 344 */
@@ -361,7 +355,6 @@ struct qdio_initialize {
361 qdio_handler_t *input_handler; 355 qdio_handler_t *input_handler;
362 qdio_handler_t *output_handler; 356 qdio_handler_t *output_handler;
363 unsigned long int_parm; 357 unsigned long int_parm;
364 unsigned long flags;
365 void **input_sbal_addr_array; 358 void **input_sbal_addr_array;
366 void **output_sbal_addr_array; 359 void **output_sbal_addr_array;
367}; 360};
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index a8f93f1705ad..8b22e7f316bb 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -73,15 +73,15 @@ unsigned long long monotonic_clock(void)
73} 73}
74EXPORT_SYMBOL(monotonic_clock); 74EXPORT_SYMBOL(monotonic_clock);
75 75
76void tod_to_timeval(__u64 todval, struct timespec *xtime) 76void tod_to_timeval(__u64 todval, struct timespec *xt)
77{ 77{
78 unsigned long long sec; 78 unsigned long long sec;
79 79
80 sec = todval >> 12; 80 sec = todval >> 12;
81 do_div(sec, 1000000); 81 do_div(sec, 1000000);
82 xtime->tv_sec = sec; 82 xt->tv_sec = sec;
83 todval -= (sec * 1000000) << 12; 83 todval -= (sec * 1000000) << 12;
84 xtime->tv_nsec = ((todval * 1000) >> 12); 84 xt->tv_nsec = ((todval * 1000) >> 12);
85} 85}
86EXPORT_SYMBOL(tod_to_timeval); 86EXPORT_SYMBOL(tod_to_timeval);
87 87
@@ -216,8 +216,8 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
216 ++vdso_data->tb_update_count; 216 ++vdso_data->tb_update_count;
217 smp_wmb(); 217 smp_wmb();
218 vdso_data->xtime_tod_stamp = clock->cycle_last; 218 vdso_data->xtime_tod_stamp = clock->cycle_last;
219 vdso_data->xtime_clock_sec = xtime.tv_sec; 219 vdso_data->xtime_clock_sec = wall_time->tv_sec;
220 vdso_data->xtime_clock_nsec = xtime.tv_nsec; 220 vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
221 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; 221 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
222 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; 222 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
223 smp_wmb(); 223 smp_wmb();
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index cd54a1c352af..761ab8b56afc 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -2,7 +2,8 @@
2# Makefile for s390-specific library files.. 2# Makefile for s390-specific library files..
3# 3#
4 4
5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o usercopy.o 5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
6obj-y += usercopy.o
6obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o 7obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o
7lib-$(CONFIG_64BIT) += uaccess_mvcos.o 8lib-$(CONFIG_64BIT) += uaccess_mvcos.o
8lib-$(CONFIG_SMP) += spinlock.o 9lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index 76a3637b88e0..f16bd04e39e9 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -374,7 +374,7 @@ static struct ctl_table cmm_dir_table[] = {
374#ifdef CONFIG_CMM_IUCV 374#ifdef CONFIG_CMM_IUCV
375#define SMSG_PREFIX "CMM" 375#define SMSG_PREFIX "CMM"
376static void 376static void
377cmm_smsg_target(char *from, char *msg) 377cmm_smsg_target(const char *from, char *msg)
378{ 378{
379 long nr, seconds; 379 long nr, seconds;
380 380
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index be300aaca6fe..7da0fc94a01e 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -419,6 +419,9 @@ static struct i2c_board_info migor_i2c_devices[] = {
419 I2C_BOARD_INFO("migor_ts", 0x51), 419 I2C_BOARD_INFO("migor_ts", 0x51),
420 .irq = 38, /* IRQ6 */ 420 .irq = 38, /* IRQ6 */
421 }, 421 },
422 {
423 I2C_BOARD_INFO("wm8978", 0x1a),
424 },
422}; 425};
423 426
424static struct i2c_board_info migor_i2c_camera[] = { 427static struct i2c_board_info migor_i2c_camera[] = {
@@ -619,6 +622,19 @@ static int __init migor_devices_setup(void)
619 622
620 platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20); 623 platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
621 624
625 /* SIU: Port B */
626 gpio_request(GPIO_FN_SIUBOLR, NULL);
627 gpio_request(GPIO_FN_SIUBOBT, NULL);
628 gpio_request(GPIO_FN_SIUBISLD, NULL);
629 gpio_request(GPIO_FN_SIUBOSLD, NULL);
630 gpio_request(GPIO_FN_SIUMCKB, NULL);
631
632 /*
633 * The original driver sets SIUB OLR/OBT, ILR/IBT, and SIUA OLR/OBT to
634 * output. Need only SIUB, set to output for master mode (table 34.2)
635 */
636 __raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA);
637
622 i2c_register_board_info(0, migor_i2c_devices, 638 i2c_register_board_info(0, migor_i2c_devices,
623 ARRAY_SIZE(migor_i2c_devices)); 639 ARRAY_SIZE(migor_i2c_devices));
624 640
diff --git a/arch/sh/boot/compressed/cache.c b/arch/sh/boot/compressed/cache.c
index e27fc74f228c..d0b77b68a4d0 100644
--- a/arch/sh/boot/compressed/cache.c
+++ b/arch/sh/boot/compressed/cache.c
@@ -5,7 +5,7 @@ int cache_control(unsigned int command)
5 5
6 for (i = 0; i < (32 * 1024); i += 32) { 6 for (i = 0; i < (32 * 1024); i += 32) {
7 (void)*p; 7 (void)*p;
8 p += (32 / sizeof (int)); 8 p += (32 / sizeof(int));
9 } 9 }
10 10
11 return 0; 11 return 0;
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index da3ebec921a7..1f4e562c5e8c 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -86,8 +86,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma,
86 struct page *page, unsigned long vaddr, void *dst, const void *src, 86 struct page *page, unsigned long vaddr, void *dst, const void *src,
87 unsigned long len); 87 unsigned long len);
88 88
89#define flush_cache_vmap(start, end) flush_cache_all() 89#define flush_cache_vmap(start, end) local_flush_cache_all(NULL)
90#define flush_cache_vunmap(start, end) flush_cache_all() 90#define flush_cache_vunmap(start, end) local_flush_cache_all(NULL)
91 91
92#define flush_dcache_mmap_lock(mapping) do { } while (0) 92#define flush_dcache_mmap_lock(mapping) do { } while (0)
93#define flush_dcache_mmap_unlock(mapping) do { } while (0) 93#define flush_dcache_mmap_unlock(mapping) do { } while (0)
diff --git a/arch/sh/include/asm/dma-register.h b/arch/sh/include/asm/dma-register.h
new file mode 100644
index 000000000000..51cd78feacff
--- /dev/null
+++ b/arch/sh/include/asm/dma-register.h
@@ -0,0 +1,51 @@
1/*
2 * Common header for the legacy SH DMA driver and the new dmaengine driver
3 *
4 * extracted from arch/sh/include/asm/dma-sh.h:
5 *
6 * Copyright (C) 2000 Takashi YOSHII
7 * Copyright (C) 2003 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#ifndef DMA_REGISTER_H
14#define DMA_REGISTER_H
15
16/* DMA register */
17#define SAR 0x00
18#define DAR 0x04
19#define TCR 0x08
20#define CHCR 0x0C
21#define DMAOR 0x40
22
23/* DMAOR definitions */
24#define DMAOR_AE 0x00000004
25#define DMAOR_NMIF 0x00000002
26#define DMAOR_DME 0x00000001
27
28/* Definitions for the SuperH DMAC */
29#define REQ_L 0x00000000
30#define REQ_E 0x00080000
31#define RACK_H 0x00000000
32#define RACK_L 0x00040000
33#define ACK_R 0x00000000
34#define ACK_W 0x00020000
35#define ACK_H 0x00000000
36#define ACK_L 0x00010000
37#define DM_INC 0x00004000
38#define DM_DEC 0x00008000
39#define DM_FIX 0x0000c000
40#define SM_INC 0x00001000
41#define SM_DEC 0x00002000
42#define SM_FIX 0x00003000
43#define RS_IN 0x00000200
44#define RS_OUT 0x00000300
45#define TS_BLK 0x00000040
46#define TM_BUR 0x00000020
47#define CHCR_DE 0x00000001
48#define CHCR_TE 0x00000002
49#define CHCR_IE 0x00000004
50
51#endif
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
index e934a2e66651..f3acb8e34c6b 100644
--- a/arch/sh/include/asm/dma-sh.h
+++ b/arch/sh/include/asm/dma-sh.h
@@ -11,7 +11,8 @@
11#ifndef __DMA_SH_H 11#ifndef __DMA_SH_H
12#define __DMA_SH_H 12#define __DMA_SH_H
13 13
14#include <asm/dma.h> 14#include <asm/dma-register.h>
15#include <cpu/dma-register.h>
15#include <cpu/dma.h> 16#include <cpu/dma.h>
16 17
17/* DMAOR contorl: The DMAOR access size is different by CPU.*/ 18/* DMAOR contorl: The DMAOR access size is different by CPU.*/
@@ -53,34 +54,6 @@ static int dmte_irq_map[] __maybe_unused = {
53#endif 54#endif
54}; 55};
55 56
56/* Definitions for the SuperH DMAC */
57#define REQ_L 0x00000000
58#define REQ_E 0x00080000
59#define RACK_H 0x00000000
60#define RACK_L 0x00040000
61#define ACK_R 0x00000000
62#define ACK_W 0x00020000
63#define ACK_H 0x00000000
64#define ACK_L 0x00010000
65#define DM_INC 0x00004000
66#define DM_DEC 0x00008000
67#define DM_FIX 0x0000c000
68#define SM_INC 0x00001000
69#define SM_DEC 0x00002000
70#define SM_FIX 0x00003000
71#define RS_IN 0x00000200
72#define RS_OUT 0x00000300
73#define TS_BLK 0x00000040
74#define TM_BUR 0x00000020
75#define CHCR_DE 0x00000001
76#define CHCR_TE 0x00000002
77#define CHCR_IE 0x00000004
78
79/* DMAOR definitions */
80#define DMAOR_AE 0x00000004
81#define DMAOR_NMIF 0x00000002
82#define DMAOR_DME 0x00000001
83
84/* 57/*
85 * Define the default configuration for dual address memory-memory transfer. 58 * Define the default configuration for dual address memory-memory transfer.
86 * The 0x400 value represents auto-request, external->external. 59 * The 0x400 value represents auto-request, external->external.
@@ -111,61 +84,4 @@ static u32 dma_base_addr[] __maybe_unused = {
111#endif 84#endif
112}; 85};
113 86
114/* DMA register */
115#define SAR 0x00
116#define DAR 0x04
117#define TCR 0x08
118#define CHCR 0x0C
119#define DMAOR 0x40
120
121/*
122 * for dma engine
123 *
124 * SuperH DMA mode
125 */
126#define SHDMA_MIX_IRQ (1 << 1)
127#define SHDMA_DMAOR1 (1 << 2)
128#define SHDMA_DMAE1 (1 << 3)
129
130enum sh_dmae_slave_chan_id {
131 SHDMA_SLAVE_SCIF0_TX,
132 SHDMA_SLAVE_SCIF0_RX,
133 SHDMA_SLAVE_SCIF1_TX,
134 SHDMA_SLAVE_SCIF1_RX,
135 SHDMA_SLAVE_SCIF2_TX,
136 SHDMA_SLAVE_SCIF2_RX,
137 SHDMA_SLAVE_SCIF3_TX,
138 SHDMA_SLAVE_SCIF3_RX,
139 SHDMA_SLAVE_SCIF4_TX,
140 SHDMA_SLAVE_SCIF4_RX,
141 SHDMA_SLAVE_SCIF5_TX,
142 SHDMA_SLAVE_SCIF5_RX,
143 SHDMA_SLAVE_SIUA_TX,
144 SHDMA_SLAVE_SIUA_RX,
145 SHDMA_SLAVE_SIUB_TX,
146 SHDMA_SLAVE_SIUB_RX,
147 SHDMA_SLAVE_NUMBER, /* Must stay last */
148};
149
150struct sh_dmae_slave_config {
151 enum sh_dmae_slave_chan_id slave_id;
152 dma_addr_t addr;
153 u32 chcr;
154 char mid_rid;
155};
156
157struct sh_dmae_pdata {
158 unsigned int mode;
159 struct sh_dmae_slave_config *config;
160 int config_num;
161};
162
163struct device;
164
165struct sh_dmae_slave {
166 enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */
167 struct device *dma_dev; /* Set by the platform */
168 struct sh_dmae_slave_config *config; /* Set by the driver */
169};
170
171#endif /* __DMA_SH_H */ 87#endif /* __DMA_SH_H */
diff --git a/arch/sh/include/asm/dmaengine.h b/arch/sh/include/asm/dmaengine.h
new file mode 100644
index 000000000000..bf2f30cf0a27
--- /dev/null
+++ b/arch/sh/include/asm/dmaengine.h
@@ -0,0 +1,93 @@
1/*
2 * Header for the new SH dmaengine driver
3 *
4 * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef ASM_DMAENGINE_H
11#define ASM_DMAENGINE_H
12
13#include <linux/dmaengine.h>
14#include <linux/list.h>
15
16#include <asm/dma-register.h>
17
18#define SH_DMAC_MAX_CHANNELS 6
19
20enum sh_dmae_slave_chan_id {
21 SHDMA_SLAVE_SCIF0_TX,
22 SHDMA_SLAVE_SCIF0_RX,
23 SHDMA_SLAVE_SCIF1_TX,
24 SHDMA_SLAVE_SCIF1_RX,
25 SHDMA_SLAVE_SCIF2_TX,
26 SHDMA_SLAVE_SCIF2_RX,
27 SHDMA_SLAVE_SCIF3_TX,
28 SHDMA_SLAVE_SCIF3_RX,
29 SHDMA_SLAVE_SCIF4_TX,
30 SHDMA_SLAVE_SCIF4_RX,
31 SHDMA_SLAVE_SCIF5_TX,
32 SHDMA_SLAVE_SCIF5_RX,
33 SHDMA_SLAVE_SIUA_TX,
34 SHDMA_SLAVE_SIUA_RX,
35 SHDMA_SLAVE_SIUB_TX,
36 SHDMA_SLAVE_SIUB_RX,
37 SHDMA_SLAVE_NUMBER, /* Must stay last */
38};
39
40struct sh_dmae_slave_config {
41 enum sh_dmae_slave_chan_id slave_id;
42 dma_addr_t addr;
43 u32 chcr;
44 char mid_rid;
45};
46
47struct sh_dmae_channel {
48 unsigned int offset;
49 unsigned int dmars;
50 unsigned int dmars_bit;
51};
52
53struct sh_dmae_pdata {
54 struct sh_dmae_slave_config *slave;
55 int slave_num;
56 struct sh_dmae_channel *channel;
57 int channel_num;
58 unsigned int ts_low_shift;
59 unsigned int ts_low_mask;
60 unsigned int ts_high_shift;
61 unsigned int ts_high_mask;
62 unsigned int *ts_shift;
63 int ts_shift_num;
64 u16 dmaor_init;
65};
66
67struct device;
68
69/* Used by slave DMA clients to request DMA to/from a specific peripheral */
70struct sh_dmae_slave {
71 enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */
72 struct device *dma_dev; /* Set by the platform */
73 struct sh_dmae_slave_config *config; /* Set by the driver */
74};
75
76struct sh_dmae_regs {
77 u32 sar; /* SAR / source address */
78 u32 dar; /* DAR / destination address */
79 u32 tcr; /* TCR / transfer count */
80};
81
82struct sh_desc {
83 struct sh_dmae_regs hw;
84 struct list_head node;
85 struct dma_async_tx_descriptor async_tx;
86 enum dma_data_direction direction;
87 dma_cookie_t cookie;
88 size_t partial;
89 int chunks;
90 int mark;
91};
92
93#endif
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 7dab7b23a5ec..f689554e17c1 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -291,21 +291,21 @@ unsigned long long poke_real_address_q(unsigned long long addr,
291 * doesn't exist, so everything must go through page tables. 291 * doesn't exist, so everything must go through page tables.
292 */ 292 */
293#ifdef CONFIG_MMU 293#ifdef CONFIG_MMU
294void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, 294void __iomem *__ioremap_caller(phys_addr_t offset, unsigned long size,
295 pgprot_t prot, void *caller); 295 pgprot_t prot, void *caller);
296void __iounmap(void __iomem *addr); 296void __iounmap(void __iomem *addr);
297 297
298static inline void __iomem * 298static inline void __iomem *
299__ioremap(unsigned long offset, unsigned long size, pgprot_t prot) 299__ioremap(phys_addr_t offset, unsigned long size, pgprot_t prot)
300{ 300{
301 return __ioremap_caller(offset, size, prot, __builtin_return_address(0)); 301 return __ioremap_caller(offset, size, prot, __builtin_return_address(0));
302} 302}
303 303
304static inline void __iomem * 304static inline void __iomem *
305__ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot) 305__ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
306{ 306{
307#ifdef CONFIG_29BIT 307#ifdef CONFIG_29BIT
308 unsigned long last_addr = offset + size - 1; 308 phys_addr_t last_addr = offset + size - 1;
309 309
310 /* 310 /*
311 * For P1 and P2 space this is trivial, as everything is already 311 * For P1 and P2 space this is trivial, as everything is already
@@ -329,7 +329,7 @@ __ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot)
329} 329}
330 330
331static inline void __iomem * 331static inline void __iomem *
332__ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot) 332__ioremap_mode(phys_addr_t offset, unsigned long size, pgprot_t prot)
333{ 333{
334 void __iomem *ret; 334 void __iomem *ret;
335 335
@@ -349,35 +349,32 @@ __ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot)
349#define __iounmap(addr) do { } while (0) 349#define __iounmap(addr) do { } while (0)
350#endif /* CONFIG_MMU */ 350#endif /* CONFIG_MMU */
351 351
352static inline void __iomem * 352static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
353ioremap(unsigned long offset, unsigned long size)
354{ 353{
355 return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE); 354 return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
356} 355}
357 356
358static inline void __iomem * 357static inline void __iomem *
359ioremap_cache(unsigned long offset, unsigned long size) 358ioremap_cache(phys_addr_t offset, unsigned long size)
360{ 359{
361 return __ioremap_mode(offset, size, PAGE_KERNEL); 360 return __ioremap_mode(offset, size, PAGE_KERNEL);
362} 361}
363 362
364#ifdef CONFIG_HAVE_IOREMAP_PROT 363#ifdef CONFIG_HAVE_IOREMAP_PROT
365static inline void __iomem * 364static inline void __iomem *
366ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) 365ioremap_prot(phys_addr_t offset, unsigned long size, unsigned long flags)
367{ 366{
368 return __ioremap_mode(offset, size, __pgprot(flags)); 367 return __ioremap_mode(offset, size, __pgprot(flags));
369} 368}
370#endif 369#endif
371 370
372#ifdef CONFIG_IOREMAP_FIXED 371#ifdef CONFIG_IOREMAP_FIXED
373extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, 372extern void __iomem *ioremap_fixed(phys_addr_t, unsigned long, pgprot_t);
374 unsigned long, pgprot_t);
375extern int iounmap_fixed(void __iomem *); 373extern int iounmap_fixed(void __iomem *);
376extern void ioremap_fixed_init(void); 374extern void ioremap_fixed_init(void);
377#else 375#else
378static inline void __iomem * 376static inline void __iomem *
379ioremap_fixed(resource_size_t phys_addr, unsigned long offset, 377ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
380 unsigned long size, pgprot_t prot)
381{ 378{
382 BUG(); 379 BUG();
383 return NULL; 380 return NULL;
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index 15a05b615ba7..19fe84550b49 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -55,19 +55,29 @@ typedef struct {
55 55
56#ifdef CONFIG_PMB 56#ifdef CONFIG_PMB
57/* arch/sh/mm/pmb.c */ 57/* arch/sh/mm/pmb.c */
58long pmb_remap(unsigned long virt, unsigned long phys,
59 unsigned long size, pgprot_t prot);
60void pmb_unmap(unsigned long addr);
61void pmb_init(void);
62bool __in_29bit_mode(void); 58bool __in_29bit_mode(void);
59
60void pmb_init(void);
61int pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
62 unsigned long size, pgprot_t prot);
63void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
64 pgprot_t prot, void *caller);
65int pmb_unmap(void __iomem *addr);
66
63#else 67#else
64static inline long pmb_remap(unsigned long virt, unsigned long phys, 68
65 unsigned long size, pgprot_t prot) 69static inline void __iomem *
70pmb_remap_caller(phys_addr_t phys, unsigned long size,
71 pgprot_t prot, void *caller)
72{
73 return NULL;
74}
75
76static inline int pmb_unmap(void __iomem *addr)
66{ 77{
67 return -EINVAL; 78 return -EINVAL;
68} 79}
69 80
70#define pmb_unmap(addr) do { } while (0)
71#define pmb_init(addr) do { } while (0) 81#define pmb_init(addr) do { } while (0)
72 82
73#ifdef CONFIG_29BIT 83#ifdef CONFIG_29BIT
@@ -77,6 +87,13 @@ static inline long pmb_remap(unsigned long virt, unsigned long phys,
77#endif 87#endif
78 88
79#endif /* CONFIG_PMB */ 89#endif /* CONFIG_PMB */
90
91static inline void __iomem *
92pmb_remap(phys_addr_t phys, unsigned long size, pgprot_t prot)
93{
94 return pmb_remap_caller(phys, size, prot, __builtin_return_address(0));
95}
96
80#endif /* __ASSEMBLY__ */ 97#endif /* __ASSEMBLY__ */
81 98
82#endif /* __MMU_H */ 99#endif /* __MMU_H */
diff --git a/arch/sh/include/asm/siu.h b/arch/sh/include/asm/siu.h
index 57565a3b551f..f1b1e6944a5f 100644
--- a/arch/sh/include/asm/siu.h
+++ b/arch/sh/include/asm/siu.h
@@ -11,7 +11,7 @@
11#ifndef ASM_SIU_H 11#ifndef ASM_SIU_H
12#define ASM_SIU_H 12#define ASM_SIU_H
13 13
14#include <asm/dma-sh.h> 14#include <asm/dmaengine.h>
15 15
16struct device; 16struct device;
17 17
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index 37cdadd975ac..88e734069fa6 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -35,7 +35,7 @@
35 35
36#define pcibus_to_node(bus) ((void)(bus), -1) 36#define pcibus_to_node(bus) ((void)(bus), -1)
37#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ 37#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
38 CPU_MASK_ALL_PTR : \ 38 cpu_all_mask : \
39 cpumask_of_node(pcibus_to_node(bus))) 39 cpumask_of_node(pcibus_to_node(bus)))
40 40
41#endif 41#endif
diff --git a/arch/sh/include/cpu-sh3/cpu/dma-register.h b/arch/sh/include/cpu-sh3/cpu/dma-register.h
new file mode 100644
index 000000000000..2349e488c9a6
--- /dev/null
+++ b/arch/sh/include/cpu-sh3/cpu/dma-register.h
@@ -0,0 +1,41 @@
1/*
2 * SH3 CPU-specific DMA definitions, used by both DMA drivers
3 *
4 * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef CPU_DMA_REGISTER_H
11#define CPU_DMA_REGISTER_H
12
13#define CHCR_TS_LOW_MASK 0x18
14#define CHCR_TS_LOW_SHIFT 3
15#define CHCR_TS_HIGH_MASK 0
16#define CHCR_TS_HIGH_SHIFT 0
17
18#define DMAOR_INIT DMAOR_DME
19
20/*
21 * The SuperH DMAC supports a number of transmit sizes, we list them here,
22 * with their respective values as they appear in the CHCR registers.
23 */
24enum {
25 XMIT_SZ_8BIT,
26 XMIT_SZ_16BIT,
27 XMIT_SZ_32BIT,
28 XMIT_SZ_128BIT,
29};
30
31/* log2(size / 8) - used to calculate number of transfers */
32#define TS_SHIFT { \
33 [XMIT_SZ_8BIT] = 0, \
34 [XMIT_SZ_16BIT] = 1, \
35 [XMIT_SZ_32BIT] = 2, \
36 [XMIT_SZ_128BIT] = 4, \
37}
38
39#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT)
40
41#endif
diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h
index 207811a7a650..24e28b91c9d5 100644
--- a/arch/sh/include/cpu-sh3/cpu/dma.h
+++ b/arch/sh/include/cpu-sh3/cpu/dma.h
@@ -20,31 +20,4 @@
20#define TS_32 0x00000010 20#define TS_32 0x00000010
21#define TS_128 0x00000018 21#define TS_128 0x00000018
22 22
23#define CHCR_TS_LOW_MASK 0x18
24#define CHCR_TS_LOW_SHIFT 3
25#define CHCR_TS_HIGH_MASK 0
26#define CHCR_TS_HIGH_SHIFT 0
27
28#define DMAOR_INIT DMAOR_DME
29
30/*
31 * The SuperH DMAC supports a number of transmit sizes, we list them here,
32 * with their respective values as they appear in the CHCR registers.
33 */
34enum {
35 XMIT_SZ_8BIT,
36 XMIT_SZ_16BIT,
37 XMIT_SZ_32BIT,
38 XMIT_SZ_128BIT,
39};
40
41#define TS_SHIFT { \
42 [XMIT_SZ_8BIT] = 0, \
43 [XMIT_SZ_16BIT] = 1, \
44 [XMIT_SZ_32BIT] = 2, \
45 [XMIT_SZ_128BIT] = 4, \
46}
47
48#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT)
49
50#endif /* __ASM_CPU_SH3_DMA_H */ 23#endif /* __ASM_CPU_SH3_DMA_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-register.h b/arch/sh/include/cpu-sh4/cpu/dma-register.h
new file mode 100644
index 000000000000..55f9fec082d4
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/dma-register.h
@@ -0,0 +1,112 @@
1/*
2 * SH4 CPU-specific DMA definitions, used by both DMA drivers
3 *
4 * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef CPU_DMA_REGISTER_H
11#define CPU_DMA_REGISTER_H
12
13/* SH7751/7760/7780 DMA IRQ sources */
14
15#ifdef CONFIG_CPU_SH4A
16
17#define DMAOR_INIT DMAOR_DME
18
19#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
20 defined(CONFIG_CPU_SUBTYPE_SH7730)
21#define CHCR_TS_LOW_MASK 0x00000018
22#define CHCR_TS_LOW_SHIFT 3
23#define CHCR_TS_HIGH_MASK 0
24#define CHCR_TS_HIGH_SHIFT 0
25#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \
26 defined(CONFIG_CPU_SUBTYPE_SH7724)
27#define CHCR_TS_LOW_MASK 0x00000018
28#define CHCR_TS_LOW_SHIFT 3
29#define CHCR_TS_HIGH_MASK 0x00300000
30#define CHCR_TS_HIGH_SHIFT (20 - 2) /* 2 bits for shifted low TS */
31#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
32 defined(CONFIG_CPU_SUBTYPE_SH7764)
33#define CHCR_TS_LOW_MASK 0x00000018
34#define CHCR_TS_LOW_SHIFT 3
35#define CHCR_TS_HIGH_MASK 0
36#define CHCR_TS_HIGH_SHIFT 0
37#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
38#define CHCR_TS_LOW_MASK 0x00000018
39#define CHCR_TS_LOW_SHIFT 3
40#define CHCR_TS_HIGH_MASK 0
41#define CHCR_TS_HIGH_SHIFT 0
42#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
43#define CHCR_TS_LOW_MASK 0x00000018
44#define CHCR_TS_LOW_SHIFT 3
45#define CHCR_TS_HIGH_MASK 0
46#define CHCR_TS_HIGH_SHIFT 0
47#else /* SH7785 */
48#define CHCR_TS_LOW_MASK 0x00000018
49#define CHCR_TS_LOW_SHIFT 3
50#define CHCR_TS_HIGH_MASK 0
51#define CHCR_TS_HIGH_SHIFT 0
52#endif
53
54/* Transmit sizes and respective CHCR register values */
55enum {
56 XMIT_SZ_8BIT = 0,
57 XMIT_SZ_16BIT = 1,
58 XMIT_SZ_32BIT = 2,
59 XMIT_SZ_64BIT = 7,
60 XMIT_SZ_128BIT = 3,
61 XMIT_SZ_256BIT = 4,
62 XMIT_SZ_128BIT_BLK = 0xb,
63 XMIT_SZ_256BIT_BLK = 0xc,
64};
65
66/* log2(size / 8) - used to calculate number of transfers */
67#define TS_SHIFT { \
68 [XMIT_SZ_8BIT] = 0, \
69 [XMIT_SZ_16BIT] = 1, \
70 [XMIT_SZ_32BIT] = 2, \
71 [XMIT_SZ_64BIT] = 3, \
72 [XMIT_SZ_128BIT] = 4, \
73 [XMIT_SZ_256BIT] = 5, \
74 [XMIT_SZ_128BIT_BLK] = 4, \
75 [XMIT_SZ_256BIT_BLK] = 5, \
76}
77
78#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
79 ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
80
81#else /* CONFIG_CPU_SH4A */
82
83#define DMAOR_INIT (0x8000 | DMAOR_DME)
84
85#define CHCR_TS_LOW_MASK 0x70
86#define CHCR_TS_LOW_SHIFT 4
87#define CHCR_TS_HIGH_MASK 0
88#define CHCR_TS_HIGH_SHIFT 0
89
90/* Transmit sizes and respective CHCR register values */
91enum {
92 XMIT_SZ_8BIT = 1,
93 XMIT_SZ_16BIT = 2,
94 XMIT_SZ_32BIT = 3,
95 XMIT_SZ_64BIT = 0,
96 XMIT_SZ_256BIT = 4,
97};
98
99/* log2(size / 8) - used to calculate number of transfers */
100#define TS_SHIFT { \
101 [XMIT_SZ_8BIT] = 0, \
102 [XMIT_SZ_16BIT] = 1, \
103 [XMIT_SZ_32BIT] = 2, \
104 [XMIT_SZ_64BIT] = 3, \
105 [XMIT_SZ_256BIT] = 5, \
106}
107
108#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT)
109
110#endif /* CONFIG_CPU_SH4A */
111
112#endif
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
index e734ea47d8a0..9647e681fd27 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -8,20 +8,12 @@
8#define DMAE0_IRQ 78 /* DMA Error IRQ*/ 8#define DMAE0_IRQ 78 /* DMA Error IRQ*/
9#define SH_DMAC_BASE0 0xFE008020 9#define SH_DMAC_BASE0 0xFE008020
10#define SH_DMARS_BASE0 0xFE009000 10#define SH_DMARS_BASE0 0xFE009000
11#define CHCR_TS_LOW_MASK 0x00000018
12#define CHCR_TS_LOW_SHIFT 3
13#define CHCR_TS_HIGH_MASK 0
14#define CHCR_TS_HIGH_SHIFT 0
15#elif defined(CONFIG_CPU_SUBTYPE_SH7722) 11#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
16#define DMTE0_IRQ 48 12#define DMTE0_IRQ 48
17#define DMTE4_IRQ 76 13#define DMTE4_IRQ 76
18#define DMAE0_IRQ 78 /* DMA Error IRQ*/ 14#define DMAE0_IRQ 78 /* DMA Error IRQ*/
19#define SH_DMAC_BASE0 0xFE008020 15#define SH_DMAC_BASE0 0xFE008020
20#define SH_DMARS_BASE0 0xFE009000 16#define SH_DMARS_BASE0 0xFE009000
21#define CHCR_TS_LOW_MASK 0x00000018
22#define CHCR_TS_LOW_SHIFT 3
23#define CHCR_TS_HIGH_MASK 0x00300000
24#define CHCR_TS_HIGH_SHIFT 20
25#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ 17#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
26 defined(CONFIG_CPU_SUBTYPE_SH7764) 18 defined(CONFIG_CPU_SUBTYPE_SH7764)
27#define DMTE0_IRQ 34 19#define DMTE0_IRQ 34
@@ -29,10 +21,6 @@
29#define DMAE0_IRQ 38 21#define DMAE0_IRQ 38
30#define SH_DMAC_BASE0 0xFF608020 22#define SH_DMAC_BASE0 0xFF608020
31#define SH_DMARS_BASE0 0xFF609000 23#define SH_DMARS_BASE0 0xFF609000
32#define CHCR_TS_LOW_MASK 0x00000018
33#define CHCR_TS_LOW_SHIFT 3
34#define CHCR_TS_HIGH_MASK 0
35#define CHCR_TS_HIGH_SHIFT 0
36#elif defined(CONFIG_CPU_SUBTYPE_SH7723) 24#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
37#define DMTE0_IRQ 48 /* DMAC0A*/ 25#define DMTE0_IRQ 48 /* DMAC0A*/
38#define DMTE4_IRQ 76 /* DMAC0B */ 26#define DMTE4_IRQ 76 /* DMAC0B */
@@ -46,10 +34,6 @@
46#define SH_DMAC_BASE0 0xFE008020 34#define SH_DMAC_BASE0 0xFE008020
47#define SH_DMAC_BASE1 0xFDC08020 35#define SH_DMAC_BASE1 0xFDC08020
48#define SH_DMARS_BASE0 0xFDC09000 36#define SH_DMARS_BASE0 0xFDC09000
49#define CHCR_TS_LOW_MASK 0x00000018
50#define CHCR_TS_LOW_SHIFT 3
51#define CHCR_TS_HIGH_MASK 0
52#define CHCR_TS_HIGH_SHIFT 0
53#elif defined(CONFIG_CPU_SUBTYPE_SH7724) 37#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
54#define DMTE0_IRQ 48 /* DMAC0A*/ 38#define DMTE0_IRQ 48 /* DMAC0A*/
55#define DMTE4_IRQ 76 /* DMAC0B */ 39#define DMTE4_IRQ 76 /* DMAC0B */
@@ -64,10 +48,6 @@
64#define SH_DMAC_BASE1 0xFDC08020 48#define SH_DMAC_BASE1 0xFDC08020
65#define SH_DMARS_BASE0 0xFE009000 49#define SH_DMARS_BASE0 0xFE009000
66#define SH_DMARS_BASE1 0xFDC09000 50#define SH_DMARS_BASE1 0xFDC09000
67#define CHCR_TS_LOW_MASK 0x00000018
68#define CHCR_TS_LOW_SHIFT 3
69#define CHCR_TS_HIGH_MASK 0x00600000
70#define CHCR_TS_HIGH_SHIFT 21
71#elif defined(CONFIG_CPU_SUBTYPE_SH7780) 51#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
72#define DMTE0_IRQ 34 52#define DMTE0_IRQ 34
73#define DMTE4_IRQ 44 53#define DMTE4_IRQ 44
@@ -80,10 +60,6 @@
80#define SH_DMAC_BASE0 0xFC808020 60#define SH_DMAC_BASE0 0xFC808020
81#define SH_DMAC_BASE1 0xFC818020 61#define SH_DMAC_BASE1 0xFC818020
82#define SH_DMARS_BASE0 0xFC809000 62#define SH_DMARS_BASE0 0xFC809000
83#define CHCR_TS_LOW_MASK 0x00000018
84#define CHCR_TS_LOW_SHIFT 3
85#define CHCR_TS_HIGH_MASK 0
86#define CHCR_TS_HIGH_SHIFT 0
87#else /* SH7785 */ 63#else /* SH7785 */
88#define DMTE0_IRQ 33 64#define DMTE0_IRQ 33
89#define DMTE4_IRQ 37 65#define DMTE4_IRQ 37
@@ -97,10 +73,6 @@
97#define SH_DMAC_BASE0 0xFC808020 73#define SH_DMAC_BASE0 0xFC808020
98#define SH_DMAC_BASE1 0xFCC08020 74#define SH_DMAC_BASE1 0xFCC08020
99#define SH_DMARS_BASE0 0xFC809000 75#define SH_DMARS_BASE0 0xFC809000
100#define CHCR_TS_LOW_MASK 0x00000018
101#define CHCR_TS_LOW_SHIFT 3
102#define CHCR_TS_HIGH_MASK 0
103#define CHCR_TS_HIGH_SHIFT 0
104#endif 76#endif
105 77
106#define REQ_HE 0x000000C0 78#define REQ_HE 0x000000C0
@@ -108,38 +80,4 @@
108#define REQ_LE 0x00000040 80#define REQ_LE 0x00000040
109#define TM_BURST 0x00000020 81#define TM_BURST 0x00000020
110 82
111/*
112 * The SuperH DMAC supports a number of transmit sizes, we list them here,
113 * with their respective values as they appear in the CHCR registers.
114 *
115 * Defaults to a 64-bit transfer size.
116 */
117enum {
118 XMIT_SZ_8BIT = 0,
119 XMIT_SZ_16BIT = 1,
120 XMIT_SZ_32BIT = 2,
121 XMIT_SZ_64BIT = 7,
122 XMIT_SZ_128BIT = 3,
123 XMIT_SZ_256BIT = 4,
124 XMIT_SZ_128BIT_BLK = 0xb,
125 XMIT_SZ_256BIT_BLK = 0xc,
126};
127
128/*
129 * The DMA count is defined as the number of bytes to transfer.
130 */
131#define TS_SHIFT { \
132 [XMIT_SZ_8BIT] = 0, \
133 [XMIT_SZ_16BIT] = 1, \
134 [XMIT_SZ_32BIT] = 2, \
135 [XMIT_SZ_64BIT] = 3, \
136 [XMIT_SZ_128BIT] = 4, \
137 [XMIT_SZ_256BIT] = 5, \
138 [XMIT_SZ_128BIT_BLK] = 4, \
139 [XMIT_SZ_256BIT_BLK] = 5, \
140}
141
142#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
143 ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
144
145#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */ 83#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h
index 114a369705bc..ca747e93c2ed 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma.h
@@ -5,9 +5,8 @@
5 5
6#ifdef CONFIG_CPU_SH4A 6#ifdef CONFIG_CPU_SH4A
7 7
8#define DMAOR_INIT (DMAOR_DME)
9
10#include <cpu/dma-sh4a.h> 8#include <cpu/dma-sh4a.h>
9
11#else /* CONFIG_CPU_SH4A */ 10#else /* CONFIG_CPU_SH4A */
12/* 11/*
13 * SH7750/SH7751/SH7760 12 * SH7750/SH7751/SH7760
@@ -17,7 +16,6 @@
17#define DMTE6_IRQ 46 16#define DMTE6_IRQ 46
18#define DMAE0_IRQ 38 17#define DMAE0_IRQ 38
19 18
20#define DMAOR_INIT (0x8000|DMAOR_DME)
21#define SH_DMAC_BASE0 0xffa00000 19#define SH_DMAC_BASE0 0xffa00000
22#define SH_DMAC_BASE1 0xffa00070 20#define SH_DMAC_BASE1 0xffa00070
23/* Definitions for the SuperH DMAC */ 21/* Definitions for the SuperH DMAC */
@@ -27,40 +25,8 @@
27#define TS_32 0x00000030 25#define TS_32 0x00000030
28#define TS_64 0x00000000 26#define TS_64 0x00000000
29 27
30#define CHCR_TS_LOW_MASK 0x70
31#define CHCR_TS_LOW_SHIFT 4
32#define CHCR_TS_HIGH_MASK 0
33#define CHCR_TS_HIGH_SHIFT 0
34
35#define DMAOR_COD 0x00000008 28#define DMAOR_COD 0x00000008
36 29
37/*
38 * The SuperH DMAC supports a number of transmit sizes, we list them here,
39 * with their respective values as they appear in the CHCR registers.
40 *
41 * Defaults to a 64-bit transfer size.
42 */
43enum {
44 XMIT_SZ_8BIT = 1,
45 XMIT_SZ_16BIT = 2,
46 XMIT_SZ_32BIT = 3,
47 XMIT_SZ_64BIT = 0,
48 XMIT_SZ_256BIT = 4,
49};
50
51/*
52 * The DMA count is defined as the number of bytes to transfer.
53 */
54#define TS_SHIFT { \
55 [XMIT_SZ_8BIT] = 0, \
56 [XMIT_SZ_16BIT] = 1, \
57 [XMIT_SZ_32BIT] = 2, \
58 [XMIT_SZ_64BIT] = 3, \
59 [XMIT_SZ_256BIT] = 5, \
60}
61
62#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT)
63
64#endif 30#endif
65 31
66#endif /* __ASM_CPU_SH4_DMA_H */ 32#endif /* __ASM_CPU_SH4_DMA_H */
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
index cee6cb88e020..42fccf93412e 100644
--- a/arch/sh/include/mach-migor/mach/migor.h
+++ b/arch/sh/include/mach-migor/mach/migor.h
@@ -1,6 +1,7 @@
1#ifndef __ASM_SH_MIGOR_H 1#ifndef __ASM_SH_MIGOR_H
2#define __ASM_SH_MIGOR_H 2#define __ASM_SH_MIGOR_H
3 3
4#define PORT_MSELCRA 0xa4050180
4#define PORT_MSELCRB 0xa4050182 5#define PORT_MSELCRB 0xa4050182
5#define BSC_CS4BCR 0xfec10010 6#define BSC_CS4BCR 0xfec10010
6#define BSC_CS6ABCR 0xfec1001c 7#define BSC_CS6ABCR 0xfec1001c
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index ef3f97827808..fd7e3639e845 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -7,19 +7,167 @@
7 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10#include <linux/platform_device.h>
11#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/mm.h>
12#include <linux/platform_device.h>
12#include <linux/serial.h> 13#include <linux/serial.h>
13#include <linux/serial_sci.h> 14#include <linux/serial_sci.h>
14#include <linux/mm.h> 15#include <linux/sh_timer.h>
15#include <linux/uio_driver.h> 16#include <linux/uio_driver.h>
16#include <linux/usb/m66592.h> 17#include <linux/usb/m66592.h>
17#include <linux/sh_timer.h> 18
18#include <asm/clock.h> 19#include <asm/clock.h>
20#include <asm/dmaengine.h>
19#include <asm/mmzone.h> 21#include <asm/mmzone.h>
20#include <asm/dma-sh.h> 22#include <asm/siu.h>
23
24#include <cpu/dma-register.h>
21#include <cpu/sh7722.h> 25#include <cpu/sh7722.h>
22 26
27static struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
28 {
29 .slave_id = SHDMA_SLAVE_SCIF0_TX,
30 .addr = 0xffe0000c,
31 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
32 .mid_rid = 0x21,
33 }, {
34 .slave_id = SHDMA_SLAVE_SCIF0_RX,
35 .addr = 0xffe00014,
36 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
37 .mid_rid = 0x22,
38 }, {
39 .slave_id = SHDMA_SLAVE_SCIF1_TX,
40 .addr = 0xffe1000c,
41 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
42 .mid_rid = 0x25,
43 }, {
44 .slave_id = SHDMA_SLAVE_SCIF1_RX,
45 .addr = 0xffe10014,
46 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
47 .mid_rid = 0x26,
48 }, {
49 .slave_id = SHDMA_SLAVE_SCIF2_TX,
50 .addr = 0xffe2000c,
51 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
52 .mid_rid = 0x29,
53 }, {
54 .slave_id = SHDMA_SLAVE_SCIF2_RX,
55 .addr = 0xffe20014,
56 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
57 .mid_rid = 0x2a,
58 }, {
59 .slave_id = SHDMA_SLAVE_SIUA_TX,
60 .addr = 0xa454c098,
61 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
62 .mid_rid = 0xb1,
63 }, {
64 .slave_id = SHDMA_SLAVE_SIUA_RX,
65 .addr = 0xa454c090,
66 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
67 .mid_rid = 0xb2,
68 }, {
69 .slave_id = SHDMA_SLAVE_SIUB_TX,
70 .addr = 0xa454c09c,
71 .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
72 .mid_rid = 0xb5,
73 }, {
74 .slave_id = SHDMA_SLAVE_SIUB_RX,
75 .addr = 0xa454c094,
76 .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
77 .mid_rid = 0xb6,
78 },
79};
80
81static struct sh_dmae_channel sh7722_dmae_channels[] = {
82 {
83 .offset = 0,
84 .dmars = 0,
85 .dmars_bit = 0,
86 }, {
87 .offset = 0x10,
88 .dmars = 0,
89 .dmars_bit = 8,
90 }, {
91 .offset = 0x20,
92 .dmars = 4,
93 .dmars_bit = 0,
94 }, {
95 .offset = 0x30,
96 .dmars = 4,
97 .dmars_bit = 8,
98 }, {
99 .offset = 0x50,
100 .dmars = 8,
101 .dmars_bit = 0,
102 }, {
103 .offset = 0x60,
104 .dmars = 8,
105 .dmars_bit = 8,
106 }
107};
108
109static unsigned int ts_shift[] = TS_SHIFT;
110
111static struct sh_dmae_pdata dma_platform_data = {
112 .slave = sh7722_dmae_slaves,
113 .slave_num = ARRAY_SIZE(sh7722_dmae_slaves),
114 .channel = sh7722_dmae_channels,
115 .channel_num = ARRAY_SIZE(sh7722_dmae_channels),
116 .ts_low_shift = CHCR_TS_LOW_SHIFT,
117 .ts_low_mask = CHCR_TS_LOW_MASK,
118 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
119 .ts_high_mask = CHCR_TS_HIGH_MASK,
120 .ts_shift = ts_shift,
121 .ts_shift_num = ARRAY_SIZE(ts_shift),
122 .dmaor_init = DMAOR_INIT,
123};
124
125static struct resource sh7722_dmae_resources[] = {
126 [0] = {
127 /* Channel registers and DMAOR */
128 .start = 0xfe008020,
129 .end = 0xfe00808f,
130 .flags = IORESOURCE_MEM,
131 },
132 [1] = {
133 /* DMARSx */
134 .start = 0xfe009000,
135 .end = 0xfe00900b,
136 .flags = IORESOURCE_MEM,
137 },
138 {
139 /* DMA error IRQ */
140 .start = 78,
141 .end = 78,
142 .flags = IORESOURCE_IRQ,
143 },
144 {
145 /* IRQ for channels 0-3 */
146 .start = 48,
147 .end = 51,
148 .flags = IORESOURCE_IRQ,
149 },
150 {
151 /* IRQ for channels 4-5 */
152 .start = 76,
153 .end = 77,
154 .flags = IORESOURCE_IRQ,
155 },
156};
157
158struct platform_device dma_device = {
159 .name = "sh-dma-engine",
160 .id = -1,
161 .resource = sh7722_dmae_resources,
162 .num_resources = ARRAY_SIZE(sh7722_dmae_resources),
163 .dev = {
164 .platform_data = &dma_platform_data,
165 },
166 .archdata = {
167 .hwblk_id = HWBLK_DMAC,
168 },
169};
170
23/* Serial */ 171/* Serial */
24static struct plat_sci_port scif0_platform_data = { 172static struct plat_sci_port scif0_platform_data = {
25 .mapbase = 0xffe00000, 173 .mapbase = 0xffe00000,
@@ -388,15 +536,36 @@ static struct platform_device tmu2_device = {
388 }, 536 },
389}; 537};
390 538
391static struct sh_dmae_pdata dma_platform_data = { 539static struct siu_platform siu_platform_data = {
392 .mode = 0, 540 .dma_dev = &dma_device.dev,
541 .dma_slave_tx_a = SHDMA_SLAVE_SIUA_TX,
542 .dma_slave_rx_a = SHDMA_SLAVE_SIUA_RX,
543 .dma_slave_tx_b = SHDMA_SLAVE_SIUB_TX,
544 .dma_slave_rx_b = SHDMA_SLAVE_SIUB_RX,
393}; 545};
394 546
395static struct platform_device dma_device = { 547static struct resource siu_resources[] = {
396 .name = "sh-dma-engine", 548 [0] = {
549 .start = 0xa4540000,
550 .end = 0xa454c10f,
551 .flags = IORESOURCE_MEM,
552 },
553 [1] = {
554 .start = 108,
555 .flags = IORESOURCE_IRQ,
556 },
557};
558
559static struct platform_device siu_device = {
560 .name = "sh_siu",
397 .id = -1, 561 .id = -1,
398 .dev = { 562 .dev = {
399 .platform_data = &dma_platform_data, 563 .platform_data = &siu_platform_data,
564 },
565 .resource = siu_resources,
566 .num_resources = ARRAY_SIZE(siu_resources),
567 .archdata = {
568 .hwblk_id = HWBLK_SIU,
400 }, 569 },
401}; 570};
402 571
@@ -414,6 +583,7 @@ static struct platform_device *sh7722_devices[] __initdata = {
414 &vpu_device, 583 &vpu_device,
415 &veu_device, 584 &veu_device,
416 &jpu_device, 585 &jpu_device,
586 &siu_device,
417 &dma_device, 587 &dma_device,
418}; 588};
419 589
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index 31e3451f7e3d..e7fa2a92fc1f 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -21,22 +21,189 @@
21#include <linux/sh_timer.h> 21#include <linux/sh_timer.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/notifier.h> 23#include <linux/notifier.h>
24
24#include <asm/suspend.h> 25#include <asm/suspend.h>
25#include <asm/clock.h> 26#include <asm/clock.h>
26#include <asm/dma-sh.h> 27#include <asm/dmaengine.h>
27#include <asm/mmzone.h> 28#include <asm/mmzone.h>
29
30#include <cpu/dma-register.h>
28#include <cpu/sh7724.h> 31#include <cpu/sh7724.h>
29 32
30/* DMA */ 33/* DMA */
31static struct sh_dmae_pdata dma_platform_data = { 34static struct sh_dmae_channel sh7724_dmae0_channels[] = {
32 .mode = SHDMA_DMAOR1, 35 {
36 .offset = 0,
37 .dmars = 0,
38 .dmars_bit = 0,
39 }, {
40 .offset = 0x10,
41 .dmars = 0,
42 .dmars_bit = 8,
43 }, {
44 .offset = 0x20,
45 .dmars = 4,
46 .dmars_bit = 0,
47 }, {
48 .offset = 0x30,
49 .dmars = 4,
50 .dmars_bit = 8,
51 }, {
52 .offset = 0x50,
53 .dmars = 8,
54 .dmars_bit = 0,
55 }, {
56 .offset = 0x60,
57 .dmars = 8,
58 .dmars_bit = 8,
59 }
60};
61
62static struct sh_dmae_channel sh7724_dmae1_channels[] = {
63 {
64 .offset = 0,
65 .dmars = 0,
66 .dmars_bit = 0,
67 }, {
68 .offset = 0x10,
69 .dmars = 0,
70 .dmars_bit = 8,
71 }, {
72 .offset = 0x20,
73 .dmars = 4,
74 .dmars_bit = 0,
75 }, {
76 .offset = 0x30,
77 .dmars = 4,
78 .dmars_bit = 8,
79 }, {
80 .offset = 0x50,
81 .dmars = 8,
82 .dmars_bit = 0,
83 }, {
84 .offset = 0x60,
85 .dmars = 8,
86 .dmars_bit = 8,
87 }
88};
89
90static unsigned int ts_shift[] = TS_SHIFT;
91
92static struct sh_dmae_pdata dma0_platform_data = {
93 .channel = sh7724_dmae0_channels,
94 .channel_num = ARRAY_SIZE(sh7724_dmae0_channels),
95 .ts_low_shift = CHCR_TS_LOW_SHIFT,
96 .ts_low_mask = CHCR_TS_LOW_MASK,
97 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
98 .ts_high_mask = CHCR_TS_HIGH_MASK,
99 .ts_shift = ts_shift,
100 .ts_shift_num = ARRAY_SIZE(ts_shift),
101 .dmaor_init = DMAOR_INIT,
102};
103
104static struct sh_dmae_pdata dma1_platform_data = {
105 .channel = sh7724_dmae1_channels,
106 .channel_num = ARRAY_SIZE(sh7724_dmae1_channels),
107 .ts_low_shift = CHCR_TS_LOW_SHIFT,
108 .ts_low_mask = CHCR_TS_LOW_MASK,
109 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
110 .ts_high_mask = CHCR_TS_HIGH_MASK,
111 .ts_shift = ts_shift,
112 .ts_shift_num = ARRAY_SIZE(ts_shift),
113 .dmaor_init = DMAOR_INIT,
114};
115
116/* Resource order important! */
117static struct resource sh7724_dmae0_resources[] = {
118 {
119 /* Channel registers and DMAOR */
120 .start = 0xfe008020,
121 .end = 0xfe00808f,
122 .flags = IORESOURCE_MEM,
123 },
124 {
125 /* DMARSx */
126 .start = 0xfe009000,
127 .end = 0xfe00900b,
128 .flags = IORESOURCE_MEM,
129 },
130 {
131 /* DMA error IRQ */
132 .start = 78,
133 .end = 78,
134 .flags = IORESOURCE_IRQ,
135 },
136 {
137 /* IRQ for channels 0-3 */
138 .start = 48,
139 .end = 51,
140 .flags = IORESOURCE_IRQ,
141 },
142 {
143 /* IRQ for channels 4-5 */
144 .start = 76,
145 .end = 77,
146 .flags = IORESOURCE_IRQ,
147 },
33}; 148};
34 149
35static struct platform_device dma_device = { 150/* Resource order important! */
36 .name = "sh-dma-engine", 151static struct resource sh7724_dmae1_resources[] = {
37 .id = -1, 152 {
38 .dev = { 153 /* Channel registers and DMAOR */
39 .platform_data = &dma_platform_data, 154 .start = 0xfdc08020,
155 .end = 0xfdc0808f,
156 .flags = IORESOURCE_MEM,
157 },
158 {
159 /* DMARSx */
160 .start = 0xfdc09000,
161 .end = 0xfdc0900b,
162 .flags = IORESOURCE_MEM,
163 },
164 {
165 /* DMA error IRQ */
166 .start = 74,
167 .end = 74,
168 .flags = IORESOURCE_IRQ,
169 },
170 {
171 /* IRQ for channels 0-3 */
172 .start = 40,
173 .end = 43,
174 .flags = IORESOURCE_IRQ,
175 },
176 {
177 /* IRQ for channels 4-5 */
178 .start = 72,
179 .end = 73,
180 .flags = IORESOURCE_IRQ,
181 },
182};
183
184static struct platform_device dma0_device = {
185 .name = "sh-dma-engine",
186 .id = 0,
187 .resource = sh7724_dmae0_resources,
188 .num_resources = ARRAY_SIZE(sh7724_dmae0_resources),
189 .dev = {
190 .platform_data = &dma0_platform_data,
191 },
192 .archdata = {
193 .hwblk_id = HWBLK_DMAC0,
194 },
195};
196
197static struct platform_device dma1_device = {
198 .name = "sh-dma-engine",
199 .id = 1,
200 .resource = sh7724_dmae1_resources,
201 .num_resources = ARRAY_SIZE(sh7724_dmae1_resources),
202 .dev = {
203 .platform_data = &dma1_platform_data,
204 },
205 .archdata = {
206 .hwblk_id = HWBLK_DMAC1,
40 }, 207 },
41}; 208};
42 209
@@ -663,7 +830,8 @@ static struct platform_device *sh7724_devices[] __initdata = {
663 &tmu3_device, 830 &tmu3_device,
664 &tmu4_device, 831 &tmu4_device,
665 &tmu5_device, 832 &tmu5_device,
666 &dma_device, 833 &dma0_device,
834 &dma1_device,
667 &rtc_device, 835 &rtc_device,
668 &iic0_device, 836 &iic0_device,
669 &iic1_device, 837 &iic1_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index f8f21618d785..02e792c90de6 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -13,7 +13,10 @@
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/serial_sci.h> 14#include <linux/serial_sci.h>
15#include <linux/sh_timer.h> 15#include <linux/sh_timer.h>
16#include <asm/dma-sh.h> 16
17#include <asm/dmaengine.h>
18
19#include <cpu/dma-register.h>
17 20
18static struct plat_sci_port scif0_platform_data = { 21static struct plat_sci_port scif0_platform_data = {
19 .mapbase = 0xffe00000, 22 .mapbase = 0xffe00000,
@@ -247,15 +250,131 @@ static struct platform_device rtc_device = {
247 .resource = rtc_resources, 250 .resource = rtc_resources,
248}; 251};
249 252
250static struct sh_dmae_pdata dma_platform_data = { 253/* DMA */
251 .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), 254static struct sh_dmae_channel sh7780_dmae0_channels[] = {
255 {
256 .offset = 0,
257 .dmars = 0,
258 .dmars_bit = 0,
259 }, {
260 .offset = 0x10,
261 .dmars = 0,
262 .dmars_bit = 8,
263 }, {
264 .offset = 0x20,
265 .dmars = 4,
266 .dmars_bit = 0,
267 }, {
268 .offset = 0x30,
269 .dmars = 4,
270 .dmars_bit = 8,
271 }, {
272 .offset = 0x50,
273 .dmars = 8,
274 .dmars_bit = 0,
275 }, {
276 .offset = 0x60,
277 .dmars = 8,
278 .dmars_bit = 8,
279 }
280};
281
282static struct sh_dmae_channel sh7780_dmae1_channels[] = {
283 {
284 .offset = 0,
285 }, {
286 .offset = 0x10,
287 }, {
288 .offset = 0x20,
289 }, {
290 .offset = 0x30,
291 }, {
292 .offset = 0x50,
293 }, {
294 .offset = 0x60,
295 }
296};
297
298static unsigned int ts_shift[] = TS_SHIFT;
299
300static struct sh_dmae_pdata dma0_platform_data = {
301 .channel = sh7780_dmae0_channels,
302 .channel_num = ARRAY_SIZE(sh7780_dmae0_channels),
303 .ts_low_shift = CHCR_TS_LOW_SHIFT,
304 .ts_low_mask = CHCR_TS_LOW_MASK,
305 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
306 .ts_high_mask = CHCR_TS_HIGH_MASK,
307 .ts_shift = ts_shift,
308 .ts_shift_num = ARRAY_SIZE(ts_shift),
309 .dmaor_init = DMAOR_INIT,
310};
311
312static struct sh_dmae_pdata dma1_platform_data = {
313 .channel = sh7780_dmae1_channels,
314 .channel_num = ARRAY_SIZE(sh7780_dmae1_channels),
315 .ts_low_shift = CHCR_TS_LOW_SHIFT,
316 .ts_low_mask = CHCR_TS_LOW_MASK,
317 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
318 .ts_high_mask = CHCR_TS_HIGH_MASK,
319 .ts_shift = ts_shift,
320 .ts_shift_num = ARRAY_SIZE(ts_shift),
321 .dmaor_init = DMAOR_INIT,
252}; 322};
253 323
254static struct platform_device dma_device = { 324static struct resource sh7780_dmae0_resources[] = {
325 [0] = {
326 /* Channel registers and DMAOR */
327 .start = 0xfc808020,
328 .end = 0xfc80808f,
329 .flags = IORESOURCE_MEM,
330 },
331 [1] = {
332 /* DMARSx */
333 .start = 0xfc809000,
334 .end = 0xfc80900b,
335 .flags = IORESOURCE_MEM,
336 },
337 {
338 /* Real DMA error IRQ is 38, and channel IRQs are 34-37, 44-45 */
339 .start = 34,
340 .end = 34,
341 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
342 },
343};
344
345static struct resource sh7780_dmae1_resources[] = {
346 [0] = {
347 /* Channel registers and DMAOR */
348 .start = 0xfc818020,
349 .end = 0xfc81808f,
350 .flags = IORESOURCE_MEM,
351 },
352 /* DMAC1 has no DMARS */
353 {
354 /* Real DMA error IRQ is 38, and channel IRQs are 46-47, 92-95 */
355 .start = 46,
356 .end = 46,
357 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
358 },
359};
360
361static struct platform_device dma0_device = {
255 .name = "sh-dma-engine", 362 .name = "sh-dma-engine",
256 .id = -1, 363 .id = 0,
364 .resource = sh7780_dmae0_resources,
365 .num_resources = ARRAY_SIZE(sh7780_dmae0_resources),
257 .dev = { 366 .dev = {
258 .platform_data = &dma_platform_data, 367 .platform_data = &dma0_platform_data,
368 },
369};
370
371static struct platform_device dma1_device = {
372 .name = "sh-dma-engine",
373 .id = 1,
374 .resource = sh7780_dmae1_resources,
375 .num_resources = ARRAY_SIZE(sh7780_dmae1_resources),
376 .dev = {
377 .platform_data = &dma1_platform_data,
259 }, 378 },
260}; 379};
261 380
@@ -269,7 +388,8 @@ static struct platform_device *sh7780_devices[] __initdata = {
269 &tmu4_device, 388 &tmu4_device,
270 &tmu5_device, 389 &tmu5_device,
271 &rtc_device, 390 &rtc_device,
272 &dma_device, 391 &dma0_device,
392 &dma1_device,
273}; 393};
274 394
275static int __init sh7780_devices_setup(void) 395static int __init sh7780_devices_setup(void)
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 23448d8c6711..1fcd88b1671e 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -14,9 +14,12 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/sh_timer.h> 16#include <linux/sh_timer.h>
17#include <asm/dma-sh.h> 17
18#include <asm/dmaengine.h>
18#include <asm/mmzone.h> 19#include <asm/mmzone.h>
19 20
21#include <cpu/dma-register.h>
22
20static struct plat_sci_port scif0_platform_data = { 23static struct plat_sci_port scif0_platform_data = {
21 .mapbase = 0xffea0000, 24 .mapbase = 0xffea0000,
22 .flags = UPF_BOOT_AUTOCONF, 25 .flags = UPF_BOOT_AUTOCONF,
@@ -295,15 +298,131 @@ static struct platform_device tmu5_device = {
295 .num_resources = ARRAY_SIZE(tmu5_resources), 298 .num_resources = ARRAY_SIZE(tmu5_resources),
296}; 299};
297 300
298static struct sh_dmae_pdata dma_platform_data = { 301/* DMA */
299 .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), 302static struct sh_dmae_channel sh7785_dmae0_channels[] = {
303 {
304 .offset = 0,
305 .dmars = 0,
306 .dmars_bit = 0,
307 }, {
308 .offset = 0x10,
309 .dmars = 0,
310 .dmars_bit = 8,
311 }, {
312 .offset = 0x20,
313 .dmars = 4,
314 .dmars_bit = 0,
315 }, {
316 .offset = 0x30,
317 .dmars = 4,
318 .dmars_bit = 8,
319 }, {
320 .offset = 0x50,
321 .dmars = 8,
322 .dmars_bit = 0,
323 }, {
324 .offset = 0x60,
325 .dmars = 8,
326 .dmars_bit = 8,
327 }
328};
329
330static struct sh_dmae_channel sh7785_dmae1_channels[] = {
331 {
332 .offset = 0,
333 }, {
334 .offset = 0x10,
335 }, {
336 .offset = 0x20,
337 }, {
338 .offset = 0x30,
339 }, {
340 .offset = 0x50,
341 }, {
342 .offset = 0x60,
343 }
344};
345
346static unsigned int ts_shift[] = TS_SHIFT;
347
348static struct sh_dmae_pdata dma0_platform_data = {
349 .channel = sh7785_dmae0_channels,
350 .channel_num = ARRAY_SIZE(sh7785_dmae0_channels),
351 .ts_low_shift = CHCR_TS_LOW_SHIFT,
352 .ts_low_mask = CHCR_TS_LOW_MASK,
353 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
354 .ts_high_mask = CHCR_TS_HIGH_MASK,
355 .ts_shift = ts_shift,
356 .ts_shift_num = ARRAY_SIZE(ts_shift),
357 .dmaor_init = DMAOR_INIT,
358};
359
360static struct sh_dmae_pdata dma1_platform_data = {
361 .channel = sh7785_dmae1_channels,
362 .channel_num = ARRAY_SIZE(sh7785_dmae1_channels),
363 .ts_low_shift = CHCR_TS_LOW_SHIFT,
364 .ts_low_mask = CHCR_TS_LOW_MASK,
365 .ts_high_shift = CHCR_TS_HIGH_SHIFT,
366 .ts_high_mask = CHCR_TS_HIGH_MASK,
367 .ts_shift = ts_shift,
368 .ts_shift_num = ARRAY_SIZE(ts_shift),
369 .dmaor_init = DMAOR_INIT,
300}; 370};
301 371
302static struct platform_device dma_device = { 372static struct resource sh7785_dmae0_resources[] = {
373 [0] = {
374 /* Channel registers and DMAOR */
375 .start = 0xfc808020,
376 .end = 0xfc80808f,
377 .flags = IORESOURCE_MEM,
378 },
379 [1] = {
380 /* DMARSx */
381 .start = 0xfc809000,
382 .end = 0xfc80900b,
383 .flags = IORESOURCE_MEM,
384 },
385 {
386 /* Real DMA error IRQ is 39, and channel IRQs are 33-38 */
387 .start = 33,
388 .end = 33,
389 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
390 },
391};
392
393static struct resource sh7785_dmae1_resources[] = {
394 [0] = {
395 /* Channel registers and DMAOR */
396 .start = 0xfcc08020,
397 .end = 0xfcc0808f,
398 .flags = IORESOURCE_MEM,
399 },
400 /* DMAC1 has no DMARS */
401 {
402 /* Real DMA error IRQ is 58, and channel IRQs are 52-57 */
403 .start = 52,
404 .end = 52,
405 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,
406 },
407};
408
409static struct platform_device dma0_device = {
303 .name = "sh-dma-engine", 410 .name = "sh-dma-engine",
304 .id = -1, 411 .id = 0,
412 .resource = sh7785_dmae0_resources,
413 .num_resources = ARRAY_SIZE(sh7785_dmae0_resources),
305 .dev = { 414 .dev = {
306 .platform_data = &dma_platform_data, 415 .platform_data = &dma0_platform_data,
416 },
417};
418
419static struct platform_device dma1_device = {
420 .name = "sh-dma-engine",
421 .id = 1,
422 .resource = sh7785_dmae1_resources,
423 .num_resources = ARRAY_SIZE(sh7785_dmae1_resources),
424 .dev = {
425 .platform_data = &dma1_platform_data,
307 }, 426 },
308}; 427};
309 428
@@ -320,7 +439,8 @@ static struct platform_device *sh7785_devices[] __initdata = {
320 &tmu3_device, 439 &tmu3_device,
321 &tmu4_device, 440 &tmu4_device,
322 &tmu5_device, 441 &tmu5_device,
323 &dma_device, 442 &dma0_device,
443 &dma1_device,
324}; 444};
325 445
326static int __init sh7785_devices_setup(void) 446static int __init sh7785_devices_setup(void)
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c
index e2f1753d275c..675eea7785d9 100644
--- a/arch/sh/kernel/hw_breakpoint.c
+++ b/arch/sh/kernel/hw_breakpoint.c
@@ -143,26 +143,6 @@ static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
143 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); 143 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
144} 144}
145 145
146/*
147 * Store a breakpoint's encoded address, length, and type.
148 */
149static int arch_store_info(struct perf_event *bp)
150{
151 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
152
153 /*
154 * User-space requests will always have the address field populated
155 * For kernel-addresses, either the address or symbol name can be
156 * specified.
157 */
158 if (info->name)
159 info->address = (unsigned long)kallsyms_lookup_name(info->name);
160 if (info->address)
161 return 0;
162
163 return -EINVAL;
164}
165
166int arch_bp_generic_fields(int sh_len, int sh_type, 146int arch_bp_generic_fields(int sh_len, int sh_type,
167 int *gen_len, int *gen_type) 147 int *gen_len, int *gen_type)
168{ 148{
@@ -276,10 +256,12 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
276 return ret; 256 return ret;
277 } 257 }
278 258
279 ret = arch_store_info(bp); 259 /*
280 260 * For kernel-addresses, either the address or symbol name can be
281 if (ret < 0) 261 * specified.
282 return ret; 262 */
263 if (info->name)
264 info->address = (unsigned long)kallsyms_lookup_name(info->name);
283 265
284 /* 266 /*
285 * Check that the low-order bits of the address are appropriate 267 * Check that the low-order bits of the address are appropriate
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 3459e70eed72..8870d6ba64bf 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -443,7 +443,7 @@ void __init setup_arch(char **cmdline_p)
443 443
444 nodes_clear(node_online_map); 444 nodes_clear(node_online_map);
445 445
446 /* Setup bootmem with available RAM */ 446 pmb_init();
447 lmb_init(); 447 lmb_init();
448 setup_memory(); 448 setup_memory();
449 sparse_init(); 449 sparse_init();
@@ -452,7 +452,6 @@ void __init setup_arch(char **cmdline_p)
452 conswitchp = &dummy_con; 452 conswitchp = &dummy_con;
453#endif 453#endif
454 paging_init(); 454 paging_init();
455 pmb_init();
456 455
457 ioremap_fixed_init(); 456 ioremap_fixed_init();
458 457
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 953fa1613312..8a0072de2bcc 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -39,12 +39,12 @@ static int null_rtc_set_time(const time_t secs)
39void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; 39void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
40int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; 40int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
41 41
42#ifdef CONFIG_GENERIC_CMOS_UPDATE
43void read_persistent_clock(struct timespec *ts) 42void read_persistent_clock(struct timespec *ts)
44{ 43{
45 rtc_sh_get_time(ts); 44 rtc_sh_get_time(ts);
46} 45}
47 46
47#ifdef CONFIG_GENERIC_CMOS_UPDATE
48int update_persistent_clock(struct timespec now) 48int update_persistent_clock(struct timespec now)
49{ 49{
50 return rtc_sh_set_time(now.tv_sec); 50 return rtc_sh_set_time(now.tv_sec);
@@ -113,9 +113,5 @@ void __init time_init(void)
113 hwblk_init(); 113 hwblk_init();
114 clk_init(); 114 clk_init();
115 115
116 rtc_sh_get_time(&xtime);
117 set_normalized_timespec(&wall_to_monotonic,
118 -xtime.tv_sec, -xtime.tv_nsec);
119
120 late_time_init = sh_late_time_init; 116 late_time_init = sh_late_time_init;
121} 117}
diff --git a/arch/sh/lib/libgcc.h b/arch/sh/lib/libgcc.h
index 3f19d1c5d942..05909d58e2fe 100644
--- a/arch/sh/lib/libgcc.h
+++ b/arch/sh/lib/libgcc.h
@@ -17,8 +17,7 @@ struct DWstruct {
17#error I feel sick. 17#error I feel sick.
18#endif 18#endif
19 19
20typedef union 20typedef union {
21{
22 struct DWstruct s; 21 struct DWstruct s;
23 long long ll; 22 long long ll;
24} DWunion; 23} DWunion;
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index c68d2d7d00a9..1ab2385ecefe 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -34,11 +34,12 @@
34 * caller shouldn't need to know that small detail. 34 * caller shouldn't need to know that small detail.
35 */ 35 */
36void __iomem * __init_refok 36void __iomem * __init_refok
37__ioremap_caller(unsigned long phys_addr, unsigned long size, 37__ioremap_caller(phys_addr_t phys_addr, unsigned long size,
38 pgprot_t pgprot, void *caller) 38 pgprot_t pgprot, void *caller)
39{ 39{
40 struct vm_struct *area; 40 struct vm_struct *area;
41 unsigned long offset, last_addr, addr, orig_addr; 41 unsigned long offset, last_addr, addr, orig_addr;
42 void __iomem *mapped;
42 43
43 /* Don't allow wraparound or zero size */ 44 /* Don't allow wraparound or zero size */
44 last_addr = phys_addr + size - 1; 45 last_addr = phys_addr + size - 1;
@@ -46,6 +47,20 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size,
46 return NULL; 47 return NULL;
47 48
48 /* 49 /*
50 * If we can't yet use the regular approach, go the fixmap route.
51 */
52 if (!mem_init_done)
53 return ioremap_fixed(phys_addr, size, pgprot);
54
55 /*
56 * First try to remap through the PMB.
57 * PMB entries are all pre-faulted.
58 */
59 mapped = pmb_remap_caller(phys_addr, size, pgprot, caller);
60 if (mapped && !IS_ERR(mapped))
61 return mapped;
62
63 /*
49 * Mappings have to be page-aligned 64 * Mappings have to be page-aligned
50 */ 65 */
51 offset = phys_addr & ~PAGE_MASK; 66 offset = phys_addr & ~PAGE_MASK;
@@ -53,12 +68,6 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size,
53 size = PAGE_ALIGN(last_addr+1) - phys_addr; 68 size = PAGE_ALIGN(last_addr+1) - phys_addr;
54 69
55 /* 70 /*
56 * If we can't yet use the regular approach, go the fixmap route.
57 */
58 if (!mem_init_done)
59 return ioremap_fixed(phys_addr, offset, size, pgprot);
60
61 /*
62 * Ok, go for it.. 71 * Ok, go for it..
63 */ 72 */
64 area = get_vm_area_caller(size, VM_IOREMAP, caller); 73 area = get_vm_area_caller(size, VM_IOREMAP, caller);
@@ -67,33 +76,10 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size,
67 area->phys_addr = phys_addr; 76 area->phys_addr = phys_addr;
68 orig_addr = addr = (unsigned long)area->addr; 77 orig_addr = addr = (unsigned long)area->addr;
69 78
70#ifdef CONFIG_PMB 79 if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) {
71 /* 80 vunmap((void *)orig_addr);
72 * First try to remap through the PMB once a valid VMA has been 81 return NULL;
73 * established. Smaller allocations (or the rest of the size
74 * remaining after a PMB mapping due to the size not being
75 * perfectly aligned on a PMB size boundary) are then mapped
76 * through the UTLB using conventional page tables.
77 *
78 * PMB entries are all pre-faulted.
79 */
80 if (unlikely(phys_addr >= P1SEG)) {
81 unsigned long mapped;
82
83 mapped = pmb_remap(addr, phys_addr, size, pgprot);
84 if (likely(mapped)) {
85 addr += mapped;
86 phys_addr += mapped;
87 size -= mapped;
88 }
89 } 82 }
90#endif
91
92 if (likely(size))
93 if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) {
94 vunmap((void *)orig_addr);
95 return NULL;
96 }
97 83
98 return (void __iomem *)(offset + (char *)orig_addr); 84 return (void __iomem *)(offset + (char *)orig_addr);
99} 85}
@@ -133,23 +119,11 @@ void __iounmap(void __iomem *addr)
133 if (iounmap_fixed(addr) == 0) 119 if (iounmap_fixed(addr) == 0)
134 return; 120 return;
135 121
136#ifdef CONFIG_PMB
137 /* 122 /*
138 * Purge any PMB entries that may have been established for this 123 * If the PMB handled it, there's nothing else to do.
139 * mapping, then proceed with conventional VMA teardown.
140 *
141 * XXX: Note that due to the way that remove_vm_area() does
142 * matching of the resultant VMA, we aren't able to fast-forward
143 * the address past the PMB space until the end of the VMA where
144 * the page tables reside. As such, unmap_vm_area() will be
145 * forced to linearly scan over the area until it finds the page
146 * tables where PTEs that need to be unmapped actually reside,
147 * which is far from optimal. Perhaps we need to use a separate
148 * VMA for the PMB mappings?
149 * -- PFM.
150 */ 124 */
151 pmb_unmap(vaddr); 125 if (pmb_unmap(addr) == 0)
152#endif 126 return;
153 127
154 p = remove_vm_area((void *)(vaddr & PAGE_MASK)); 128 p = remove_vm_area((void *)(vaddr & PAGE_MASK));
155 if (!p) { 129 if (!p) {
diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c
index 0b78b1e20ef1..7f682e5dafcf 100644
--- a/arch/sh/mm/ioremap_fixed.c
+++ b/arch/sh/mm/ioremap_fixed.c
@@ -45,14 +45,21 @@ void __init ioremap_fixed_init(void)
45} 45}
46 46
47void __init __iomem * 47void __init __iomem *
48ioremap_fixed(resource_size_t phys_addr, unsigned long offset, 48ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
49 unsigned long size, pgprot_t prot)
50{ 49{
51 enum fixed_addresses idx0, idx; 50 enum fixed_addresses idx0, idx;
52 struct ioremap_map *map; 51 struct ioremap_map *map;
53 unsigned int nrpages; 52 unsigned int nrpages;
53 unsigned long offset;
54 int i, slot; 54 int i, slot;
55 55
56 /*
57 * Mappings have to be page-aligned
58 */
59 offset = phys_addr & ~PAGE_MASK;
60 phys_addr &= PAGE_MASK;
61 size = PAGE_ALIGN(phys_addr + size) - phys_addr;
62
56 slot = -1; 63 slot = -1;
57 for (i = 0; i < FIX_N_IOREMAPS; i++) { 64 for (i = 0; i < FIX_N_IOREMAPS; i++) {
58 map = &ioremap_maps[i]; 65 map = &ioremap_maps[i];
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
index 422e92721878..961b34085e3b 100644
--- a/arch/sh/mm/numa.c
+++ b/arch/sh/mm/numa.c
@@ -74,6 +74,9 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
74 start_pfn = start >> PAGE_SHIFT; 74 start_pfn = start >> PAGE_SHIFT;
75 end_pfn = end >> PAGE_SHIFT; 75 end_pfn = end >> PAGE_SHIFT;
76 76
77 pmb_bolt_mapping((unsigned long)__va(start), start, end - start,
78 PAGE_KERNEL);
79
77 lmb_add(start, end - start); 80 lmb_add(start, end - start);
78 81
79 __add_active_range(nid, start_pfn, end_pfn); 82 __add_active_range(nid, start_pfn, end_pfn);
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 198bcff5e96f..a4662e2782c3 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -23,7 +23,8 @@
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/rwlock.h> 26#include <linux/vmalloc.h>
27#include <asm/cacheflush.h>
27#include <asm/sizes.h> 28#include <asm/sizes.h>
28#include <asm/system.h> 29#include <asm/system.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
@@ -52,12 +53,24 @@ struct pmb_entry {
52 struct pmb_entry *link; 53 struct pmb_entry *link;
53}; 54};
54 55
56static struct {
57 unsigned long size;
58 int flag;
59} pmb_sizes[] = {
60 { .size = SZ_512M, .flag = PMB_SZ_512M, },
61 { .size = SZ_128M, .flag = PMB_SZ_128M, },
62 { .size = SZ_64M, .flag = PMB_SZ_64M, },
63 { .size = SZ_16M, .flag = PMB_SZ_16M, },
64};
65
55static void pmb_unmap_entry(struct pmb_entry *, int depth); 66static void pmb_unmap_entry(struct pmb_entry *, int depth);
56 67
57static DEFINE_RWLOCK(pmb_rwlock); 68static DEFINE_RWLOCK(pmb_rwlock);
58static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES]; 69static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES];
59static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES); 70static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES);
60 71
72static unsigned int pmb_iomapping_enabled;
73
61static __always_inline unsigned long mk_pmb_entry(unsigned int entry) 74static __always_inline unsigned long mk_pmb_entry(unsigned int entry)
62{ 75{
63 return (entry & PMB_E_MASK) << PMB_E_SHIFT; 76 return (entry & PMB_E_MASK) << PMB_E_SHIFT;
@@ -73,6 +86,142 @@ static __always_inline unsigned long mk_pmb_data(unsigned int entry)
73 return mk_pmb_entry(entry) | PMB_DATA; 86 return mk_pmb_entry(entry) | PMB_DATA;
74} 87}
75 88
89static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn)
90{
91 return ppn >= __pa(memory_start) && ppn < __pa(memory_end);
92}
93
94/*
95 * Ensure that the PMB entries match our cache configuration.
96 *
97 * When we are in 32-bit address extended mode, CCR.CB becomes
98 * invalid, so care must be taken to manually adjust cacheable
99 * translations.
100 */
101static __always_inline unsigned long pmb_cache_flags(void)
102{
103 unsigned long flags = 0;
104
105#if defined(CONFIG_CACHE_OFF)
106 flags |= PMB_WT | PMB_UB;
107#elif defined(CONFIG_CACHE_WRITETHROUGH)
108 flags |= PMB_C | PMB_WT | PMB_UB;
109#elif defined(CONFIG_CACHE_WRITEBACK)
110 flags |= PMB_C;
111#endif
112
113 return flags;
114}
115
116/*
117 * Convert typical pgprot value to the PMB equivalent
118 */
119static inline unsigned long pgprot_to_pmb_flags(pgprot_t prot)
120{
121 unsigned long pmb_flags = 0;
122 u64 flags = pgprot_val(prot);
123
124 if (flags & _PAGE_CACHABLE)
125 pmb_flags |= PMB_C;
126 if (flags & _PAGE_WT)
127 pmb_flags |= PMB_WT | PMB_UB;
128
129 return pmb_flags;
130}
131
132static inline bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b)
133{
134 return (b->vpn == (a->vpn + a->size)) &&
135 (b->ppn == (a->ppn + a->size)) &&
136 (b->flags == a->flags);
137}
138
139static bool pmb_mapping_exists(unsigned long vaddr, phys_addr_t phys,
140 unsigned long size)
141{
142 int i;
143
144 read_lock(&pmb_rwlock);
145
146 for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
147 struct pmb_entry *pmbe, *iter;
148 unsigned long span;
149
150 if (!test_bit(i, pmb_map))
151 continue;
152
153 pmbe = &pmb_entry_list[i];
154
155 /*
156 * See if VPN and PPN are bounded by an existing mapping.
157 */
158 if ((vaddr < pmbe->vpn) || (vaddr >= (pmbe->vpn + pmbe->size)))
159 continue;
160 if ((phys < pmbe->ppn) || (phys >= (pmbe->ppn + pmbe->size)))
161 continue;
162
163 /*
164 * Now see if we're in range of a simple mapping.
165 */
166 if (size <= pmbe->size) {
167 read_unlock(&pmb_rwlock);
168 return true;
169 }
170
171 span = pmbe->size;
172
173 /*
174 * Finally for sizes that involve compound mappings, walk
175 * the chain.
176 */
177 for (iter = pmbe->link; iter; iter = iter->link)
178 span += iter->size;
179
180 /*
181 * Nothing else to do if the range requirements are met.
182 */
183 if (size <= span) {
184 read_unlock(&pmb_rwlock);
185 return true;
186 }
187 }
188
189 read_unlock(&pmb_rwlock);
190 return false;
191}
192
193static bool pmb_size_valid(unsigned long size)
194{
195 int i;
196
197 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
198 if (pmb_sizes[i].size == size)
199 return true;
200
201 return false;
202}
203
204static inline bool pmb_addr_valid(unsigned long addr, unsigned long size)
205{
206 return (addr >= P1SEG && (addr + size - 1) < P3SEG);
207}
208
209static inline bool pmb_prot_valid(pgprot_t prot)
210{
211 return (pgprot_val(prot) & _PAGE_USER) == 0;
212}
213
214static int pmb_size_to_flags(unsigned long size)
215{
216 int i;
217
218 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
219 if (pmb_sizes[i].size == size)
220 return pmb_sizes[i].flag;
221
222 return 0;
223}
224
76static int pmb_alloc_entry(void) 225static int pmb_alloc_entry(void)
77{ 226{
78 int pos; 227 int pos;
@@ -140,33 +289,22 @@ static void pmb_free(struct pmb_entry *pmbe)
140} 289}
141 290
142/* 291/*
143 * Ensure that the PMB entries match our cache configuration. 292 * Must be run uncached.
144 *
145 * When we are in 32-bit address extended mode, CCR.CB becomes
146 * invalid, so care must be taken to manually adjust cacheable
147 * translations.
148 */ 293 */
149static __always_inline unsigned long pmb_cache_flags(void) 294static void __set_pmb_entry(struct pmb_entry *pmbe)
150{ 295{
151 unsigned long flags = 0; 296 unsigned long addr, data;
152 297
153#if defined(CONFIG_CACHE_WRITETHROUGH) 298 addr = mk_pmb_addr(pmbe->entry);
154 flags |= PMB_C | PMB_WT | PMB_UB; 299 data = mk_pmb_data(pmbe->entry);
155#elif defined(CONFIG_CACHE_WRITEBACK)
156 flags |= PMB_C;
157#endif
158 300
159 return flags; 301 jump_to_uncached();
160}
161 302
162/* 303 /* Set V-bit */
163 * Must be run uncached. 304 __raw_writel(pmbe->vpn | PMB_V, addr);
164 */ 305 __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, data);
165static void __set_pmb_entry(struct pmb_entry *pmbe) 306
166{ 307 back_to_cached();
167 writel_uncached(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry));
168 writel_uncached(pmbe->ppn | pmbe->flags | PMB_V,
169 mk_pmb_data(pmbe->entry));
170} 308}
171 309
172static void __clear_pmb_entry(struct pmb_entry *pmbe) 310static void __clear_pmb_entry(struct pmb_entry *pmbe)
@@ -194,144 +332,155 @@ static void set_pmb_entry(struct pmb_entry *pmbe)
194 spin_unlock_irqrestore(&pmbe->lock, flags); 332 spin_unlock_irqrestore(&pmbe->lock, flags);
195} 333}
196 334
197static struct { 335int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
198 unsigned long size; 336 unsigned long size, pgprot_t prot)
199 int flag;
200} pmb_sizes[] = {
201 { .size = SZ_512M, .flag = PMB_SZ_512M, },
202 { .size = SZ_128M, .flag = PMB_SZ_128M, },
203 { .size = SZ_64M, .flag = PMB_SZ_64M, },
204 { .size = SZ_16M, .flag = PMB_SZ_16M, },
205};
206
207long pmb_remap(unsigned long vaddr, unsigned long phys,
208 unsigned long size, pgprot_t prot)
209{ 337{
210 struct pmb_entry *pmbp, *pmbe; 338 struct pmb_entry *pmbp, *pmbe;
211 unsigned long wanted; 339 unsigned long orig_addr, orig_size;
212 int pmb_flags, i; 340 unsigned long flags, pmb_flags;
213 long err; 341 int i, mapped;
214 u64 flags;
215 342
216 flags = pgprot_val(prot); 343 if (!pmb_addr_valid(vaddr, size))
344 return -EFAULT;
345 if (pmb_mapping_exists(vaddr, phys, size))
346 return 0;
217 347
218 pmb_flags = PMB_WT | PMB_UB; 348 orig_addr = vaddr;
219 349 orig_size = size;
220 /* Convert typical pgprot value to the PMB equivalent */
221 if (flags & _PAGE_CACHABLE) {
222 pmb_flags |= PMB_C;
223 350
224 if ((flags & _PAGE_WT) == 0) 351 flush_tlb_kernel_range(vaddr, vaddr + size);
225 pmb_flags &= ~(PMB_WT | PMB_UB);
226 }
227 352
353 pmb_flags = pgprot_to_pmb_flags(prot);
228 pmbp = NULL; 354 pmbp = NULL;
229 wanted = size;
230 355
231again: 356 do {
232 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { 357 for (i = mapped = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
233 unsigned long flags; 358 if (size < pmb_sizes[i].size)
359 continue;
360
361 pmbe = pmb_alloc(vaddr, phys, pmb_flags |
362 pmb_sizes[i].flag, PMB_NO_ENTRY);
363 if (IS_ERR(pmbe)) {
364 pmb_unmap_entry(pmbp, mapped);
365 return PTR_ERR(pmbe);
366 }
234 367
235 if (size < pmb_sizes[i].size) 368 spin_lock_irqsave(&pmbe->lock, flags);
236 continue;
237 369
238 pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag, 370 pmbe->size = pmb_sizes[i].size;
239 PMB_NO_ENTRY);
240 if (IS_ERR(pmbe)) {
241 err = PTR_ERR(pmbe);
242 goto out;
243 }
244 371
245 spin_lock_irqsave(&pmbe->lock, flags); 372 __set_pmb_entry(pmbe);
246 373
247 __set_pmb_entry(pmbe); 374 phys += pmbe->size;
375 vaddr += pmbe->size;
376 size -= pmbe->size;
248 377
249 phys += pmb_sizes[i].size; 378 /*
250 vaddr += pmb_sizes[i].size; 379 * Link adjacent entries that span multiple PMB
251 size -= pmb_sizes[i].size; 380 * entries for easier tear-down.
381 */
382 if (likely(pmbp)) {
383 spin_lock(&pmbp->lock);
384 pmbp->link = pmbe;
385 spin_unlock(&pmbp->lock);
386 }
252 387
253 pmbe->size = pmb_sizes[i].size; 388 pmbp = pmbe;
254 389
255 /* 390 /*
256 * Link adjacent entries that span multiple PMB entries 391 * Instead of trying smaller sizes on every
257 * for easier tear-down. 392 * iteration (even if we succeed in allocating
258 */ 393 * space), try using pmb_sizes[i].size again.
259 if (likely(pmbp)) { 394 */
260 spin_lock(&pmbp->lock); 395 i--;
261 pmbp->link = pmbe; 396 mapped++;
262 spin_unlock(&pmbp->lock); 397
398 spin_unlock_irqrestore(&pmbe->lock, flags);
263 } 399 }
400 } while (size >= SZ_16M);
264 401
265 pmbp = pmbe; 402 flush_cache_vmap(orig_addr, orig_addr + orig_size);
266 403
267 /* 404 return 0;
268 * Instead of trying smaller sizes on every iteration 405}
269 * (even if we succeed in allocating space), try using
270 * pmb_sizes[i].size again.
271 */
272 i--;
273 406
274 spin_unlock_irqrestore(&pmbe->lock, flags); 407void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
275 } 408 pgprot_t prot, void *caller)
409{
410 unsigned long vaddr;
411 phys_addr_t offset, last_addr;
412 phys_addr_t align_mask;
413 unsigned long aligned;
414 struct vm_struct *area;
415 int i, ret;
276 416
277 if (size >= SZ_16M) 417 if (!pmb_iomapping_enabled)
278 goto again; 418 return NULL;
279 419
280 return wanted - size; 420 /*
421 * Small mappings need to go through the TLB.
422 */
423 if (size < SZ_16M)
424 return ERR_PTR(-EINVAL);
425 if (!pmb_prot_valid(prot))
426 return ERR_PTR(-EINVAL);
281 427
282out: 428 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
283 pmb_unmap_entry(pmbp, NR_PMB_ENTRIES); 429 if (size >= pmb_sizes[i].size)
430 break;
431
432 last_addr = phys + size;
433 align_mask = ~(pmb_sizes[i].size - 1);
434 offset = phys & ~align_mask;
435 phys &= align_mask;
436 aligned = ALIGN(last_addr, pmb_sizes[i].size) - phys;
437
438 /*
439 * XXX: This should really start from uncached_end, but this
440 * causes the MMU to reset, so for now we restrict it to the
441 * 0xb000...0xc000 range.
442 */
443 area = __get_vm_area_caller(aligned, VM_IOREMAP, 0xb0000000,
444 P3SEG, caller);
445 if (!area)
446 return NULL;
447
448 area->phys_addr = phys;
449 vaddr = (unsigned long)area->addr;
450
451 ret = pmb_bolt_mapping(vaddr, phys, size, prot);
452 if (unlikely(ret != 0))
453 return ERR_PTR(ret);
284 454
285 return err; 455 return (void __iomem *)(offset + (char *)vaddr);
286} 456}
287 457
288void pmb_unmap(unsigned long addr) 458int pmb_unmap(void __iomem *addr)
289{ 459{
290 struct pmb_entry *pmbe = NULL; 460 struct pmb_entry *pmbe = NULL;
291 int i; 461 unsigned long vaddr = (unsigned long __force)addr;
462 int i, found = 0;
292 463
293 read_lock(&pmb_rwlock); 464 read_lock(&pmb_rwlock);
294 465
295 for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { 466 for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) {
296 if (test_bit(i, pmb_map)) { 467 if (test_bit(i, pmb_map)) {
297 pmbe = &pmb_entry_list[i]; 468 pmbe = &pmb_entry_list[i];
298 if (pmbe->vpn == addr) 469 if (pmbe->vpn == vaddr) {
470 found = 1;
299 break; 471 break;
472 }
300 } 473 }
301 } 474 }
302 475
303 read_unlock(&pmb_rwlock); 476 read_unlock(&pmb_rwlock);
304 477
305 pmb_unmap_entry(pmbe, NR_PMB_ENTRIES); 478 if (found) {
306} 479 pmb_unmap_entry(pmbe, NR_PMB_ENTRIES);
307 480 return 0;
308static bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b) 481 }
309{
310 return (b->vpn == (a->vpn + a->size)) &&
311 (b->ppn == (a->ppn + a->size)) &&
312 (b->flags == a->flags);
313}
314
315static bool pmb_size_valid(unsigned long size)
316{
317 int i;
318
319 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
320 if (pmb_sizes[i].size == size)
321 return true;
322
323 return false;
324}
325
326static int pmb_size_to_flags(unsigned long size)
327{
328 int i;
329
330 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++)
331 if (pmb_sizes[i].size == size)
332 return pmb_sizes[i].flag;
333 482
334 return 0; 483 return -EINVAL;
335} 484}
336 485
337static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth) 486static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
@@ -351,6 +500,8 @@ static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
351 */ 500 */
352 __clear_pmb_entry(pmbe); 501 __clear_pmb_entry(pmbe);
353 502
503 flush_cache_vunmap(pmbe->vpn, pmbe->vpn + pmbe->size);
504
354 pmbe = pmblink->link; 505 pmbe = pmblink->link;
355 506
356 pmb_free(pmblink); 507 pmb_free(pmblink);
@@ -369,11 +520,6 @@ static void pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
369 write_unlock_irqrestore(&pmb_rwlock, flags); 520 write_unlock_irqrestore(&pmb_rwlock, flags);
370} 521}
371 522
372static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn)
373{
374 return ppn >= __pa(memory_start) && ppn < __pa(memory_end);
375}
376
377static void __init pmb_notify(void) 523static void __init pmb_notify(void)
378{ 524{
379 int i; 525 int i;
@@ -625,6 +771,18 @@ static void __init pmb_resize(void)
625} 771}
626#endif 772#endif
627 773
774static int __init early_pmb(char *p)
775{
776 if (!p)
777 return 0;
778
779 if (strstr(p, "iomap"))
780 pmb_iomapping_enabled = 1;
781
782 return 0;
783}
784early_param("pmb", early_pmb);
785
628void __init pmb_init(void) 786void __init pmb_init(void)
629{ 787{
630 /* Synchronize software state */ 788 /* Synchronize software state */
@@ -713,7 +871,7 @@ static int __init pmb_debugfs_init(void)
713 871
714 return 0; 872 return 0;
715} 873}
716postcore_initcall(pmb_debugfs_init); 874subsys_initcall(pmb_debugfs_init);
717 875
718#ifdef CONFIG_PM 876#ifdef CONFIG_PM
719static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state) 877static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
diff --git a/arch/um/.gitignore b/arch/um/.gitignore
new file mode 100644
index 000000000000..a73d3a1cc746
--- /dev/null
+++ b/arch/um/.gitignore
@@ -0,0 +1,3 @@
1kernel/config.c
2kernel/config.tmp
3kernel/vmlinux.lds
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index cf8a97f34518..64cda95f59ca 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -18,10 +18,10 @@ static irqreturn_t line_interrupt(int irq, void *data)
18{ 18{
19 struct chan *chan = data; 19 struct chan *chan = data;
20 struct line *line = chan->line; 20 struct line *line = chan->line;
21 struct tty_struct *tty = line->tty; 21 struct tty_struct *tty;
22 22
23 if (line) 23 if (line)
24 chan_interrupt(&line->chan_list, &line->task, tty, irq); 24 chan_interrupt(&line->chan_list, &line->task, line->tty, irq);
25 return IRQ_HANDLED; 25 return IRQ_HANDLED;
26} 26}
27 27
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 1b549bca4645..804b28dd0328 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -6,6 +6,8 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ 6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
7 sys_call_table.o tls.o 7 sys_call_table.o tls.o
8 8
9obj-$(CONFIG_BINFMT_ELF) += elfcore.o
10
9subarch-obj-y = lib/semaphore_32.o lib/string_32.o 11subarch-obj-y = lib/semaphore_32.o lib/string_32.o
10subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 12subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
11subarch-obj-$(CONFIG_MODULES) += kernel/module.o 13subarch-obj-$(CONFIG_MODULES) += kernel/module.o
diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h
index 770885472ed4..e64cd41d7bab 100644
--- a/arch/um/sys-i386/asm/elf.h
+++ b/arch/um/sys-i386/asm/elf.h
@@ -116,47 +116,4 @@ do { \
116 } \ 116 } \
117} while (0) 117} while (0)
118 118
119/*
120 * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
121 * extra segments containing the vsyscall DSO contents. Dumping its
122 * contents makes post-mortem fully interpretable later without matching up
123 * the same kernel and hardware config to see what PC values meant.
124 * Dumping its extra ELF program headers includes all the other information
125 * a debugger needs to easily find how the vsyscall DSO was being used.
126 */
127#define ELF_CORE_EXTRA_PHDRS \
128 (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
129
130#define ELF_CORE_WRITE_EXTRA_PHDRS \
131if ( vsyscall_ehdr ) { \
132 const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
133 const struct elf_phdr *const phdrp = \
134 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
135 int i; \
136 Elf32_Off ofs = 0; \
137 for (i = 0; i < ehdrp->e_phnum; ++i) { \
138 struct elf_phdr phdr = phdrp[i]; \
139 if (phdr.p_type == PT_LOAD) { \
140 ofs = phdr.p_offset = offset; \
141 offset += phdr.p_filesz; \
142 } \
143 else \
144 phdr.p_offset += ofs; \
145 phdr.p_paddr = 0; /* match other core phdrs */ \
146 DUMP_WRITE(&phdr, sizeof(phdr)); \
147 } \
148}
149#define ELF_CORE_WRITE_EXTRA_DATA \
150if ( vsyscall_ehdr ) { \
151 const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
152 const struct elf_phdr *const phdrp = \
153 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
154 int i; \
155 for (i = 0; i < ehdrp->e_phnum; ++i) { \
156 if (phdrp[i].p_type == PT_LOAD) \
157 DUMP_WRITE((void *) phdrp[i].p_vaddr, \
158 phdrp[i].p_filesz); \
159 } \
160}
161
162#endif 119#endif
diff --git a/arch/um/sys-i386/elfcore.c b/arch/um/sys-i386/elfcore.c
new file mode 100644
index 000000000000..6bb49b687c97
--- /dev/null
+++ b/arch/um/sys-i386/elfcore.c
@@ -0,0 +1,83 @@
1#include <linux/elf.h>
2#include <linux/coredump.h>
3#include <linux/fs.h>
4#include <linux/mm.h>
5
6#include <asm/elf.h>
7
8
9Elf32_Half elf_core_extra_phdrs(void)
10{
11 return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
12}
13
14int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
15 unsigned long limit)
16{
17 if ( vsyscall_ehdr ) {
18 const struct elfhdr *const ehdrp =
19 (struct elfhdr *) vsyscall_ehdr;
20 const struct elf_phdr *const phdrp =
21 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
22 int i;
23 Elf32_Off ofs = 0;
24
25 for (i = 0; i < ehdrp->e_phnum; ++i) {
26 struct elf_phdr phdr = phdrp[i];
27
28 if (phdr.p_type == PT_LOAD) {
29 ofs = phdr.p_offset = offset;
30 offset += phdr.p_filesz;
31 } else {
32 phdr.p_offset += ofs;
33 }
34 phdr.p_paddr = 0; /* match other core phdrs */
35 *size += sizeof(phdr);
36 if (*size > limit
37 || !dump_write(file, &phdr, sizeof(phdr)))
38 return 0;
39 }
40 }
41 return 1;
42}
43
44int elf_core_write_extra_data(struct file *file, size_t *size,
45 unsigned long limit)
46{
47 if ( vsyscall_ehdr ) {
48 const struct elfhdr *const ehdrp =
49 (struct elfhdr *) vsyscall_ehdr;
50 const struct elf_phdr *const phdrp =
51 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
52 int i;
53
54 for (i = 0; i < ehdrp->e_phnum; ++i) {
55 if (phdrp[i].p_type == PT_LOAD) {
56 void *addr = (void *) phdrp[i].p_vaddr;
57 size_t filesz = phdrp[i].p_filesz;
58
59 *size += filesz;
60 if (*size > limit
61 || !dump_write(file, addr, filesz))
62 return 0;
63 }
64 }
65 }
66 return 1;
67}
68
69size_t elf_core_extra_data_size(void)
70{
71 if ( vsyscall_ehdr ) {
72 const struct elfhdr *const ehdrp =
73 (struct elfhdr *)vsyscall_ehdr;
74 const struct elf_phdr *const phdrp =
75 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
76 int i;
77
78 for (i = 0; i < ehdrp->e_phnum; ++i)
79 if (phdrp[i].p_type == PT_LOAD)
80 return (size_t) phdrp[i].p_filesz;
81 }
82 return 0;
83}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f15f37bfbd62..e98440371525 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -393,8 +393,12 @@ config X86_ELAN
393 393
394config X86_MRST 394config X86_MRST
395 bool "Moorestown MID platform" 395 bool "Moorestown MID platform"
396 depends on PCI
397 depends on PCI_GOANY
396 depends on X86_32 398 depends on X86_32
397 depends on X86_EXTENDED_PLATFORM 399 depends on X86_EXTENDED_PLATFORM
400 depends on X86_IO_APIC
401 select APB_TIMER
398 ---help--- 402 ---help---
399 Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin 403 Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
400 Internet Device(MID) platform. Moorestown consists of two chips: 404 Internet Device(MID) platform. Moorestown consists of two chips:
@@ -429,6 +433,7 @@ config X86_32_NON_STANDARD
429config X86_NUMAQ 433config X86_NUMAQ
430 bool "NUMAQ (IBM/Sequent)" 434 bool "NUMAQ (IBM/Sequent)"
431 depends on X86_32_NON_STANDARD 435 depends on X86_32_NON_STANDARD
436 depends on PCI
432 select NUMA 437 select NUMA
433 select X86_MPPARSE 438 select X86_MPPARSE
434 ---help--- 439 ---help---
@@ -629,6 +634,16 @@ config HPET_EMULATE_RTC
629 def_bool y 634 def_bool y
630 depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y) 635 depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y)
631 636
637config APB_TIMER
638 def_bool y if MRST
639 prompt "Langwell APB Timer Support" if X86_MRST
640 help
641 APB timer is the replacement for 8254, HPET on X86 MID platforms.
642 The APBT provides a stable time base on SMP
643 systems, unlike the TSC, but it is more expensive to access,
644 as it is off-chip. APB timers are always running regardless of CPU
645 C states, they are used as per CPU clockevent device when possible.
646
632# Mark as embedded because too many people got it wrong. 647# Mark as embedded because too many people got it wrong.
633# The code disables itself when not needed. 648# The code disables itself when not needed.
634config DMI 649config DMI
diff --git a/arch/x86/include/asm/apb_timer.h b/arch/x86/include/asm/apb_timer.h
new file mode 100644
index 000000000000..c74a2eebe570
--- /dev/null
+++ b/arch/x86/include/asm/apb_timer.h
@@ -0,0 +1,70 @@
1/*
2 * apb_timer.h: Driver for Langwell APB timer based on Synopsis DesignWare
3 *
4 * (C) Copyright 2009 Intel Corporation
5 * Author: Jacob Pan (jacob.jun.pan@intel.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 *
12 * Note:
13 */
14
15#ifndef ASM_X86_APBT_H
16#define ASM_X86_APBT_H
17#include <linux/sfi.h>
18
19#ifdef CONFIG_APB_TIMER
20
21/* Langwell DW APB timer registers */
22#define APBTMR_N_LOAD_COUNT 0x00
23#define APBTMR_N_CURRENT_VALUE 0x04
24#define APBTMR_N_CONTROL 0x08
25#define APBTMR_N_EOI 0x0c
26#define APBTMR_N_INT_STATUS 0x10
27
28#define APBTMRS_INT_STATUS 0xa0
29#define APBTMRS_EOI 0xa4
30#define APBTMRS_RAW_INT_STATUS 0xa8
31#define APBTMRS_COMP_VERSION 0xac
32#define APBTMRS_REG_SIZE 0x14
33
34/* register bits */
35#define APBTMR_CONTROL_ENABLE (1<<0)
36#define APBTMR_CONTROL_MODE_PERIODIC (1<<1) /*1: periodic 0:free running */
37#define APBTMR_CONTROL_INT (1<<2)
38
39/* default memory mapped register base */
40#define LNW_SCU_ADDR 0xFF100000
41#define LNW_EXT_TIMER_OFFSET 0x1B800
42#define APBT_DEFAULT_BASE (LNW_SCU_ADDR+LNW_EXT_TIMER_OFFSET)
43#define LNW_EXT_TIMER_PGOFFSET 0x800
44
45/* APBT clock speed range from PCLK to fabric base, 25-100MHz */
46#define APBT_MAX_FREQ 50
47#define APBT_MIN_FREQ 1
48#define APBT_MMAP_SIZE 1024
49
50#define APBT_DEV_USED 1
51
52extern void apbt_time_init(void);
53extern struct clock_event_device *global_clock_event;
54extern unsigned long apbt_quick_calibrate(void);
55extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu);
56extern void apbt_setup_secondary_clock(void);
57extern unsigned int boot_cpu_id;
58extern int disable_apbt_percpu;
59
60extern struct sfi_timer_table_entry *sfi_get_mtmr(int hint);
61extern void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr);
62extern int sfi_mtimer_num;
63
64#else /* CONFIG_APB_TIMER */
65
66static inline unsigned long apbt_quick_calibrate(void) {return 0; }
67static inline void apbt_time_init(void) {return 0; }
68
69#endif
70#endif /* ASM_X86_APBT_H */
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index eeac829a0f44..a929c9ede33d 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -53,13 +53,6 @@ extern void threshold_interrupt(void);
53extern void call_function_interrupt(void); 53extern void call_function_interrupt(void);
54extern void call_function_single_interrupt(void); 54extern void call_function_single_interrupt(void);
55 55
56/* PIC specific functions */
57extern void disable_8259A_irq(unsigned int irq);
58extern void enable_8259A_irq(unsigned int irq);
59extern int i8259A_irq_pending(unsigned int irq);
60extern void make_8259A_irq(unsigned int irq);
61extern void init_8259A(int aeoi);
62
63/* IOAPIC */ 56/* IOAPIC */
64#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) 57#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
65extern unsigned long io_apic_irqs; 58extern unsigned long io_apic_irqs;
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index 7ec65b18085d..1655147646aa 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -26,11 +26,6 @@ extern unsigned int cached_irq_mask;
26 26
27extern raw_spinlock_t i8259A_lock; 27extern raw_spinlock_t i8259A_lock;
28 28
29extern void init_8259A(int auto_eoi);
30extern void enable_8259A_irq(unsigned int irq);
31extern void disable_8259A_irq(unsigned int irq);
32extern unsigned int startup_8259A_irq(unsigned int irq);
33
34/* the PIC may need a careful delay on some platforms, hence specific calls */ 29/* the PIC may need a careful delay on some platforms, hence specific calls */
35static inline unsigned char inb_pic(unsigned int port) 30static inline unsigned char inb_pic(unsigned int port)
36{ 31{
@@ -57,7 +52,17 @@ static inline void outb_pic(unsigned char value, unsigned int port)
57 52
58extern struct irq_chip i8259A_chip; 53extern struct irq_chip i8259A_chip;
59 54
60extern void mask_8259A(void); 55struct legacy_pic {
61extern void unmask_8259A(void); 56 int nr_legacy_irqs;
57 struct irq_chip *chip;
58 void (*mask_all)(void);
59 void (*restore_mask)(void);
60 void (*init)(int auto_eoi);
61 int (*irq_pending)(unsigned int irq);
62 void (*make_irq)(unsigned int irq);
63};
64
65extern struct legacy_pic *legacy_pic;
66extern struct legacy_pic null_legacy_pic;
62 67
63#endif /* _ASM_X86_I8259_H */ 68#endif /* _ASM_X86_I8259_H */
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 5f61f6e0ffdd..35832a03a515 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -143,8 +143,6 @@ extern int noioapicreroute;
143/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */ 143/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
144extern int timer_through_8259; 144extern int timer_through_8259;
145 145
146extern void io_apic_disable_legacy(void);
147
148/* 146/*
149 * If we use the IO-APIC for IRQ routing, disable automatic 147 * If we use the IO-APIC for IRQ routing, disable automatic
150 * assignment of PCI IRQ's. 148 * assignment of PCI IRQ's.
@@ -189,6 +187,7 @@ extern struct mp_ioapic_gsi mp_gsi_routing[];
189int mp_find_ioapic(int gsi); 187int mp_find_ioapic(int gsi);
190int mp_find_ioapic_pin(int ioapic, int gsi); 188int mp_find_ioapic_pin(int ioapic, int gsi);
191void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); 189void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
190extern void __init pre_init_apic_IRQ0(void);
192 191
193#else /* !CONFIG_X86_IO_APIC */ 192#else /* !CONFIG_X86_IO_APIC */
194 193
@@ -198,7 +197,11 @@ static const int timer_through_8259 = 0;
198static inline void ioapic_init_mappings(void) { } 197static inline void ioapic_init_mappings(void) { }
199static inline void ioapic_insert_resources(void) { } 198static inline void ioapic_insert_resources(void) { }
200static inline void probe_nr_irqs_gsi(void) { } 199static inline void probe_nr_irqs_gsi(void) { }
200static inline int mp_find_ioapic(int gsi) { return 0; }
201 201
202struct io_apic_irq_attr;
203static inline int io_apic_set_pci_routing(struct device *dev, int irq,
204 struct io_apic_irq_attr *irq_attr) { return 0; }
202#endif 205#endif
203 206
204#endif /* _ASM_X86_IO_APIC_H */ 207#endif /* _ASM_X86_IO_APIC_H */
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 262292729fc4..5458380b6ef8 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -48,6 +48,5 @@ extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
48extern int vector_used_by_percpu_irq(unsigned int vector); 48extern int vector_used_by_percpu_irq(unsigned int vector);
49 49
50extern void init_ISA_irqs(void); 50extern void init_ISA_irqs(void);
51extern int nr_legacy_irqs;
52 51
53#endif /* _ASM_X86_IRQ_H */ 52#endif /* _ASM_X86_IRQ_H */
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
new file mode 100644
index 000000000000..451d30e7f62d
--- /dev/null
+++ b/arch/x86/include/asm/mrst.h
@@ -0,0 +1,19 @@
1/*
2 * mrst.h: Intel Moorestown platform specific setup code
3 *
4 * (C) Copyright 2009 Intel Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; version 2
9 * of the License.
10 */
11#ifndef _ASM_X86_MRST_H
12#define _ASM_X86_MRST_H
13extern int pci_mrst_init(void);
14int __init sfi_parse_mrtc(struct sfi_table_header *table);
15
16#define SFI_MTMR_MAX_NUM 8
17#define SFI_MRTC_MAX 8
18
19#endif /* _ASM_X86_MRST_H */
diff --git a/arch/x86/include/asm/numaq.h b/arch/x86/include/asm/numaq.h
index 13370b95ea94..37c516545ec8 100644
--- a/arch/x86/include/asm/numaq.h
+++ b/arch/x86/include/asm/numaq.h
@@ -30,6 +30,7 @@
30 30
31extern int found_numaq; 31extern int found_numaq;
32extern int get_memcfg_numaq(void); 32extern int get_memcfg_numaq(void);
33extern int pci_numaq_init(void);
33 34
34extern void *xquad_portio; 35extern void *xquad_portio;
35 36
diff --git a/arch/x86/include/asm/olpc.h b/arch/x86/include/asm/olpc.h
index 3a57385d9fa7..101229b0d8ed 100644
--- a/arch/x86/include/asm/olpc.h
+++ b/arch/x86/include/asm/olpc.h
@@ -13,7 +13,6 @@ struct olpc_platform_t {
13 13
14#define OLPC_F_PRESENT 0x01 14#define OLPC_F_PRESENT 0x01
15#define OLPC_F_DCON 0x02 15#define OLPC_F_DCON 0x02
16#define OLPC_F_VSA 0x04
17 16
18#ifdef CONFIG_OLPC 17#ifdef CONFIG_OLPC
19 18
@@ -51,18 +50,6 @@ static inline int olpc_has_dcon(void)
51} 50}
52 51
53/* 52/*
54 * The VSA is software from AMD that typical Geode bioses will include.
55 * It is used to emulate the PCI bus, VGA, etc. OLPC's Open Firmware does
56 * not include the VSA; instead, PCI is emulated by the kernel.
57 *
58 * The VSA is described further in arch/x86/pci/olpc.c.
59 */
60static inline int olpc_has_vsa(void)
61{
62 return (olpc_platform_info.flags & OLPC_F_VSA) ? 1 : 0;
63}
64
65/*
66 * The "Mass Production" version of OLPC's XO is identified as being model 53 * The "Mass Production" version of OLPC's XO is identified as being model
67 * C2. During the prototype phase, the following models (in chronological 54 * C2. During the prototype phase, the following models (in chronological
68 * order) were created: A1, B1, B2, B3, B4, C1. The A1 through B2 models 55 * order) were created: A1, B1, B2, B3, B4, C1. The A1 through B2 models
@@ -87,13 +74,10 @@ static inline int olpc_has_dcon(void)
87 return 0; 74 return 0;
88} 75}
89 76
90static inline int olpc_has_vsa(void)
91{
92 return 0;
93}
94
95#endif 77#endif
96 78
79extern int pci_olpc_init(void);
80
97/* EC related functions */ 81/* EC related functions */
98 82
99extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, 83extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen,
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index b4a00dd4eed5..3e002ca5a287 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -45,8 +45,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
45 45
46#ifdef CONFIG_PCI 46#ifdef CONFIG_PCI
47extern unsigned int pcibios_assign_all_busses(void); 47extern unsigned int pcibios_assign_all_busses(void);
48extern int pci_legacy_init(void);
49# ifdef CONFIG_ACPI
50# define x86_default_pci_init pci_acpi_init
51# else
52# define x86_default_pci_init pci_legacy_init
53# endif
48#else 54#else
49#define pcibios_assign_all_busses() 0 55# define pcibios_assign_all_busses() 0
56# define x86_default_pci_init NULL
50#endif 57#endif
51 58
52extern unsigned long pci_mem_start; 59extern unsigned long pci_mem_start;
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 05b58ccb2e82..1a0422348d6d 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -83,7 +83,6 @@ struct irq_routing_table {
83 83
84extern unsigned int pcibios_irq_mask; 84extern unsigned int pcibios_irq_mask;
85 85
86extern int pcibios_scanned;
87extern spinlock_t pci_config_lock; 86extern spinlock_t pci_config_lock;
88 87
89extern int (*pcibios_enable_irq)(struct pci_dev *dev); 88extern int (*pcibios_enable_irq)(struct pci_dev *dev);
@@ -106,16 +105,15 @@ extern bool port_cf9_safe;
106extern int pci_direct_probe(void); 105extern int pci_direct_probe(void);
107extern void pci_direct_init(int type); 106extern void pci_direct_init(int type);
108extern void pci_pcbios_init(void); 107extern void pci_pcbios_init(void);
109extern int pci_olpc_init(void);
110extern void __init dmi_check_pciprobe(void); 108extern void __init dmi_check_pciprobe(void);
111extern void __init dmi_check_skip_isa_align(void); 109extern void __init dmi_check_skip_isa_align(void);
112 110
113/* some common used subsys_initcalls */ 111/* some common used subsys_initcalls */
114extern int __init pci_acpi_init(void); 112extern int __init pci_acpi_init(void);
115extern int __init pcibios_irq_init(void); 113extern void __init pcibios_irq_init(void);
116extern int __init pci_visws_init(void);
117extern int __init pci_numaq_init(void);
118extern int __init pcibios_init(void); 114extern int __init pcibios_init(void);
115extern int pci_legacy_init(void);
116extern void pcibios_fixup_irqs(void);
119 117
120/* pci-mmconfig.c */ 118/* pci-mmconfig.c */
121 119
@@ -183,3 +181,17 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val)
183{ 181{
184 asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory"); 182 asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory");
185} 183}
184
185#ifdef CONFIG_PCI
186# ifdef CONFIG_ACPI
187# define x86_default_pci_init pci_acpi_init
188# else
189# define x86_default_pci_init pci_legacy_init
190# endif
191# define x86_default_pci_init_irq pcibios_irq_init
192# define x86_default_pci_fixup_irqs pcibios_fixup_irqs
193#else
194# define x86_default_pci_init NULL
195# define x86_default_pci_init_irq NULL
196# define x86_default_pci_fixup_irqs NULL
197#endif
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 18e496c98ff0..86b1506f4179 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -37,10 +37,8 @@ void setup_bios_corruption_check(void);
37 37
38#ifdef CONFIG_X86_VISWS 38#ifdef CONFIG_X86_VISWS
39extern void visws_early_detect(void); 39extern void visws_early_detect(void);
40extern int is_visws_box(void);
41#else 40#else
42static inline void visws_early_detect(void) { } 41static inline void visws_early_detect(void) { }
43static inline int is_visws_box(void) { return 0; }
44#endif 42#endif
45 43
46extern unsigned long saved_video_mode; 44extern unsigned long saved_video_mode;
diff --git a/arch/x86/include/asm/visws/cobalt.h b/arch/x86/include/asm/visws/cobalt.h
index 166adf61e770..2edb37637ead 100644
--- a/arch/x86/include/asm/visws/cobalt.h
+++ b/arch/x86/include/asm/visws/cobalt.h
@@ -122,4 +122,6 @@ extern char visws_board_type;
122 122
123extern char visws_board_rev; 123extern char visws_board_rev;
124 124
125extern int pci_visws_init(void);
126
125#endif /* _ASM_X86_VISWS_COBALT_H */ 127#endif /* _ASM_X86_VISWS_COBALT_H */
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 60cc35269083..519b54327d75 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -99,6 +99,20 @@ struct x86_init_iommu {
99}; 99};
100 100
101/** 101/**
102 * struct x86_init_pci - platform specific pci init functions
103 * @arch_init: platform specific pci arch init call
104 * @init: platform specific pci subsystem init
105 * @init_irq: platform specific pci irq init
106 * @fixup_irqs: platform specific pci irq fixup
107 */
108struct x86_init_pci {
109 int (*arch_init)(void);
110 int (*init)(void);
111 void (*init_irq)(void);
112 void (*fixup_irqs)(void);
113};
114
115/**
102 * struct x86_init_ops - functions for platform specific setup 116 * struct x86_init_ops - functions for platform specific setup
103 * 117 *
104 */ 118 */
@@ -110,6 +124,7 @@ struct x86_init_ops {
110 struct x86_init_paging paging; 124 struct x86_init_paging paging;
111 struct x86_init_timers timers; 125 struct x86_init_timers timers;
112 struct x86_init_iommu iommu; 126 struct x86_init_iommu iommu;
127 struct x86_init_pci pci;
113}; 128};
114 129
115/** 130/**
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index d87f09bc5a52..4c58352209e0 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_VM86) += vm86_32.o
87obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 87obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
88 88
89obj-$(CONFIG_HPET_TIMER) += hpet.o 89obj-$(CONFIG_HPET_TIMER) += hpet.o
90obj-$(CONFIG_APB_TIMER) += apb_timer.o
90 91
91obj-$(CONFIG_K8_NB) += k8.o 92obj-$(CONFIG_K8_NB) += k8.o
92obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o 93obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 738fcb60e708..a54d714545ff 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -35,6 +35,7 @@
35#include <linux/ioport.h> 35#include <linux/ioport.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37 37
38#include <asm/pci_x86.h>
38#include <asm/pgtable.h> 39#include <asm/pgtable.h>
39#include <asm/io_apic.h> 40#include <asm/io_apic.h>
40#include <asm/apic.h> 41#include <asm/apic.h>
@@ -1624,6 +1625,9 @@ int __init acpi_boot_init(void)
1624 1625
1625 acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); 1626 acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
1626 1627
1628 if (!acpi_noirq)
1629 x86_init.pci.init = pci_acpi_init;
1630
1627 return 0; 1631 return 0;
1628} 1632}
1629 1633
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c
new file mode 100644
index 000000000000..4b7099526d2c
--- /dev/null
+++ b/arch/x86/kernel/apb_timer.c
@@ -0,0 +1,784 @@
1/*
2 * apb_timer.c: Driver for Langwell APB timers
3 *
4 * (C) Copyright 2009 Intel Corporation
5 * Author: Jacob Pan (jacob.jun.pan@intel.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 *
12 * Note:
13 * Langwell is the south complex of Intel Moorestown MID platform. There are
14 * eight external timers in total that can be used by the operating system.
15 * The timer information, such as frequency and addresses, is provided to the
16 * OS via SFI tables.
17 * Timer interrupts are routed via FW/HW emulated IOAPIC independently via
18 * individual redirection table entries (RTE).
19 * Unlike HPET, there is no master counter, therefore one of the timers are
20 * used as clocksource. The overall allocation looks like:
21 * - timer 0 - NR_CPUs for per cpu timer
22 * - one timer for clocksource
23 * - one timer for watchdog driver.
24 * It is also worth notice that APB timer does not support true one-shot mode,
25 * free-running mode will be used here to emulate one-shot mode.
26 * APB timer can also be used as broadcast timer along with per cpu local APIC
27 * timer, but by default APB timer has higher rating than local APIC timers.
28 */
29
30#include <linux/clocksource.h>
31#include <linux/clockchips.h>
32#include <linux/delay.h>
33#include <linux/errno.h>
34#include <linux/init.h>
35#include <linux/sysdev.h>
36#include <linux/pm.h>
37#include <linux/pci.h>
38#include <linux/sfi.h>
39#include <linux/interrupt.h>
40#include <linux/cpu.h>
41#include <linux/irq.h>
42
43#include <asm/fixmap.h>
44#include <asm/apb_timer.h>
45
46#define APBT_MASK CLOCKSOURCE_MASK(32)
47#define APBT_SHIFT 22
48#define APBT_CLOCKEVENT_RATING 150
49#define APBT_CLOCKSOURCE_RATING 250
50#define APBT_MIN_DELTA_USEC 200
51
52#define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt)
53#define APBT_CLOCKEVENT0_NUM (0)
54#define APBT_CLOCKEVENT1_NUM (1)
55#define APBT_CLOCKSOURCE_NUM (2)
56
57static unsigned long apbt_address;
58static int apb_timer_block_enabled;
59static void __iomem *apbt_virt_address;
60static int phy_cs_timer_id;
61
62/*
63 * Common DW APB timer info
64 */
65static uint64_t apbt_freq;
66
67static void apbt_set_mode(enum clock_event_mode mode,
68 struct clock_event_device *evt);
69static int apbt_next_event(unsigned long delta,
70 struct clock_event_device *evt);
71static cycle_t apbt_read_clocksource(struct clocksource *cs);
72static void apbt_restart_clocksource(struct clocksource *cs);
73
74struct apbt_dev {
75 struct clock_event_device evt;
76 unsigned int num;
77 int cpu;
78 unsigned int irq;
79 unsigned int tick;
80 unsigned int count;
81 unsigned int flags;
82 char name[10];
83};
84
85int disable_apbt_percpu __cpuinitdata;
86
87static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);
88
89#ifdef CONFIG_SMP
90static unsigned int apbt_num_timers_used;
91static struct apbt_dev *apbt_devs;
92#endif
93
94static inline unsigned long apbt_readl_reg(unsigned long a)
95{
96 return readl(apbt_virt_address + a);
97}
98
99static inline void apbt_writel_reg(unsigned long d, unsigned long a)
100{
101 writel(d, apbt_virt_address + a);
102}
103
104static inline unsigned long apbt_readl(int n, unsigned long a)
105{
106 return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE);
107}
108
109static inline void apbt_writel(int n, unsigned long d, unsigned long a)
110{
111 writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE);
112}
113
114static inline void apbt_set_mapping(void)
115{
116 struct sfi_timer_table_entry *mtmr;
117
118 if (apbt_virt_address) {
119 pr_debug("APBT base already mapped\n");
120 return;
121 }
122 mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
123 if (mtmr == NULL) {
124 printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
125 APBT_CLOCKEVENT0_NUM);
126 return;
127 }
128 apbt_address = (unsigned long)mtmr->phys_addr;
129 if (!apbt_address) {
130 printk(KERN_WARNING "No timer base from SFI, use default\n");
131 apbt_address = APBT_DEFAULT_BASE;
132 }
133 apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE);
134 if (apbt_virt_address) {
135 pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\
136 (void *)apbt_address, (void *)apbt_virt_address);
137 } else {
138 pr_debug("Failed mapping APBT phy address at %p\n",\
139 (void *)apbt_address);
140 goto panic_noapbt;
141 }
142 apbt_freq = mtmr->freq_hz / USEC_PER_SEC;
143 sfi_free_mtmr(mtmr);
144
145 /* Now figure out the physical timer id for clocksource device */
146 mtmr = sfi_get_mtmr(APBT_CLOCKSOURCE_NUM);
147 if (mtmr == NULL)
148 goto panic_noapbt;
149
150 /* Now figure out the physical timer id */
151 phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff)
152 / APBTMRS_REG_SIZE;
153 pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id);
154 return;
155
156panic_noapbt:
157 panic("Failed to setup APB system timer\n");
158
159}
160
161static inline void apbt_clear_mapping(void)
162{
163 iounmap(apbt_virt_address);
164 apbt_virt_address = NULL;
165}
166
167/*
168 * APBT timer interrupt enable / disable
169 */
170static inline int is_apbt_capable(void)
171{
172 return apbt_virt_address ? 1 : 0;
173}
174
175static struct clocksource clocksource_apbt = {
176 .name = "apbt",
177 .rating = APBT_CLOCKSOURCE_RATING,
178 .read = apbt_read_clocksource,
179 .mask = APBT_MASK,
180 .shift = APBT_SHIFT,
181 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
182 .resume = apbt_restart_clocksource,
183};
184
185/* boot APB clock event device */
186static struct clock_event_device apbt_clockevent = {
187 .name = "apbt0",
188 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
189 .set_mode = apbt_set_mode,
190 .set_next_event = apbt_next_event,
191 .shift = APBT_SHIFT,
192 .irq = 0,
193 .rating = APBT_CLOCKEVENT_RATING,
194};
195
196/*
197 * if user does not want to use per CPU apb timer, just give it a lower rating
198 * than local apic timer and skip the late per cpu timer init.
199 */
200static inline int __init setup_x86_mrst_timer(char *arg)
201{
202 if (!arg)
203 return -EINVAL;
204
205 if (strcmp("apbt_only", arg) == 0)
206 disable_apbt_percpu = 0;
207 else if (strcmp("lapic_and_apbt", arg) == 0)
208 disable_apbt_percpu = 1;
209 else {
210 pr_warning("X86 MRST timer option %s not recognised"
211 " use x86_mrst_timer=apbt_only or lapic_and_apbt\n",
212 arg);
213 return -EINVAL;
214 }
215 return 0;
216}
217__setup("x86_mrst_timer=", setup_x86_mrst_timer);
218
219/*
220 * start count down from 0xffff_ffff. this is done by toggling the enable bit
221 * then load initial load count to ~0.
222 */
223static void apbt_start_counter(int n)
224{
225 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
226
227 ctrl &= ~APBTMR_CONTROL_ENABLE;
228 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
229 apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT);
230 /* enable, mask interrupt */
231 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
232 ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
233 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
234 /* read it once to get cached counter value initialized */
235 apbt_read_clocksource(&clocksource_apbt);
236}
237
238static irqreturn_t apbt_interrupt_handler(int irq, void *data)
239{
240 struct apbt_dev *dev = (struct apbt_dev *)data;
241 struct clock_event_device *aevt = &dev->evt;
242
243 if (!aevt->event_handler) {
244 printk(KERN_INFO "Spurious APBT timer interrupt on %d\n",
245 dev->num);
246 return IRQ_NONE;
247 }
248 aevt->event_handler(aevt);
249 return IRQ_HANDLED;
250}
251
252static void apbt_restart_clocksource(struct clocksource *cs)
253{
254 apbt_start_counter(phy_cs_timer_id);
255}
256
257/* Setup IRQ routing via IOAPIC */
258#ifdef CONFIG_SMP
259static void apbt_setup_irq(struct apbt_dev *adev)
260{
261 struct irq_chip *chip;
262 struct irq_desc *desc;
263
264 /* timer0 irq has been setup early */
265 if (adev->irq == 0)
266 return;
267 desc = irq_to_desc(adev->irq);
268 chip = get_irq_chip(adev->irq);
269 disable_irq(adev->irq);
270 desc->status |= IRQ_MOVE_PCNTXT;
271 irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
272 /* APB timer irqs are set up as mp_irqs, timer is edge triggerred */
273 set_irq_chip_and_handler_name(adev->irq, chip, handle_edge_irq, "edge");
274 enable_irq(adev->irq);
275 if (system_state == SYSTEM_BOOTING)
276 if (request_irq(adev->irq, apbt_interrupt_handler,
277 IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
278 adev->name, adev)) {
279 printk(KERN_ERR "Failed request IRQ for APBT%d\n",
280 adev->num);
281 }
282}
283#endif
284
285static void apbt_enable_int(int n)
286{
287 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
288 /* clear pending intr */
289 apbt_readl(n, APBTMR_N_EOI);
290 ctrl &= ~APBTMR_CONTROL_INT;
291 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
292}
293
294static void apbt_disable_int(int n)
295{
296 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
297
298 ctrl |= APBTMR_CONTROL_INT;
299 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
300}
301
302
303static int __init apbt_clockevent_register(void)
304{
305 struct sfi_timer_table_entry *mtmr;
306 struct apbt_dev *adev = &__get_cpu_var(cpu_apbt_dev);
307
308 mtmr = sfi_get_mtmr(APBT_CLOCKEVENT0_NUM);
309 if (mtmr == NULL) {
310 printk(KERN_ERR "Failed to get MTMR %d from SFI\n",
311 APBT_CLOCKEVENT0_NUM);
312 return -ENODEV;
313 }
314
315 /*
316 * We need to calculate the scaled math multiplication factor for
317 * nanosecond to apbt tick conversion.
318 * mult = (nsec/cycle)*2^APBT_SHIFT
319 */
320 apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq_hz
321 , NSEC_PER_SEC, APBT_SHIFT);
322
323 /* Calculate the min / max delta */
324 apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
325 &apbt_clockevent);
326 apbt_clockevent.min_delta_ns = clockevent_delta2ns(
327 APBT_MIN_DELTA_USEC*apbt_freq,
328 &apbt_clockevent);
329 /*
330 * Start apbt with the boot cpu mask and make it
331 * global if not used for per cpu timer.
332 */
333 apbt_clockevent.cpumask = cpumask_of(smp_processor_id());
334 adev->num = smp_processor_id();
335 memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device));
336
337 if (disable_apbt_percpu) {
338 apbt_clockevent.rating = APBT_CLOCKEVENT_RATING - 100;
339 global_clock_event = &adev->evt;
340 printk(KERN_DEBUG "%s clockevent registered as global\n",
341 global_clock_event->name);
342 }
343
344 if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler,
345 IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
346 apbt_clockevent.name, adev)) {
347 printk(KERN_ERR "Failed request IRQ for APBT%d\n",
348 apbt_clockevent.irq);
349 }
350
351 clockevents_register_device(&adev->evt);
352 /* Start APBT 0 interrupts */
353 apbt_enable_int(APBT_CLOCKEVENT0_NUM);
354
355 sfi_free_mtmr(mtmr);
356 return 0;
357}
358
359#ifdef CONFIG_SMP
360/* Should be called with per cpu */
361void apbt_setup_secondary_clock(void)
362{
363 struct apbt_dev *adev;
364 struct clock_event_device *aevt;
365 int cpu;
366
367 /* Don't register boot CPU clockevent */
368 cpu = smp_processor_id();
369 if (cpu == boot_cpu_id)
370 return;
371 /*
372 * We need to calculate the scaled math multiplication factor for
373 * nanosecond to apbt tick conversion.
374 * mult = (nsec/cycle)*2^APBT_SHIFT
375 */
376 printk(KERN_INFO "Init per CPU clockevent %d\n", cpu);
377 adev = &per_cpu(cpu_apbt_dev, cpu);
378 aevt = &adev->evt;
379
380 memcpy(aevt, &apbt_clockevent, sizeof(*aevt));
381 aevt->cpumask = cpumask_of(cpu);
382 aevt->name = adev->name;
383 aevt->mode = CLOCK_EVT_MODE_UNUSED;
384
385 printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n",
386 cpu, aevt->name, *(u32 *)aevt->cpumask);
387
388 apbt_setup_irq(adev);
389
390 clockevents_register_device(aevt);
391
392 apbt_enable_int(cpu);
393
394 return;
395}
396
397/*
398 * this notify handler process CPU hotplug events. in case of S0i3, nonboot
399 * cpus are disabled/enabled frequently, for performance reasons, we keep the
400 * per cpu timer irq registered so that we do need to do free_irq/request_irq.
401 *
402 * TODO: it might be more reliable to directly disable percpu clockevent device
403 * without the notifier chain. currently, cpu 0 may get interrupts from other
404 * cpu timers during the offline process due to the ordering of notification.
405 * the extra interrupt is harmless.
406 */
407static int apbt_cpuhp_notify(struct notifier_block *n,
408 unsigned long action, void *hcpu)
409{
410 unsigned long cpu = (unsigned long)hcpu;
411 struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu);
412
413 switch (action & 0xf) {
414 case CPU_DEAD:
415 apbt_disable_int(cpu);
416 if (system_state == SYSTEM_RUNNING)
417 pr_debug("skipping APBT CPU %lu offline\n", cpu);
418 else if (adev) {
419 pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
420 free_irq(adev->irq, adev);
421 }
422 break;
423 default:
424 pr_debug(KERN_INFO "APBT notified %lu, no action\n", action);
425 }
426 return NOTIFY_OK;
427}
428
429static __init int apbt_late_init(void)
430{
431 if (disable_apbt_percpu)
432 return 0;
433 /* This notifier should be called after workqueue is ready */
434 hotcpu_notifier(apbt_cpuhp_notify, -20);
435 return 0;
436}
437fs_initcall(apbt_late_init);
438#else
439
440void apbt_setup_secondary_clock(void) {}
441
442#endif /* CONFIG_SMP */
443
444static void apbt_set_mode(enum clock_event_mode mode,
445 struct clock_event_device *evt)
446{
447 unsigned long ctrl;
448 uint64_t delta;
449 int timer_num;
450 struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
451
452 timer_num = adev->num;
453 pr_debug("%s CPU %d timer %d mode=%d\n",
454 __func__, first_cpu(*evt->cpumask), timer_num, mode);
455
456 switch (mode) {
457 case CLOCK_EVT_MODE_PERIODIC:
458 delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult;
459 delta >>= apbt_clockevent.shift;
460 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
461 ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
462 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
463 /*
464 * DW APB p. 46, have to disable timer before load counter,
465 * may cause sync problem.
466 */
467 ctrl &= ~APBTMR_CONTROL_ENABLE;
468 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
469 udelay(1);
470 pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ);
471 apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
472 ctrl |= APBTMR_CONTROL_ENABLE;
473 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
474 break;
475 /* APB timer does not have one-shot mode, use free running mode */
476 case CLOCK_EVT_MODE_ONESHOT:
477 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
478 /*
479 * set free running mode, this mode will let timer reload max
480 * timeout which will give time (3min on 25MHz clock) to rearm
481 * the next event, therefore emulate the one-shot mode.
482 */
483 ctrl &= ~APBTMR_CONTROL_ENABLE;
484 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
485
486 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
487 /* write again to set free running mode */
488 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
489
490 /*
491 * DW APB p. 46, load counter with all 1s before starting free
492 * running mode.
493 */
494 apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT);
495 ctrl &= ~APBTMR_CONTROL_INT;
496 ctrl |= APBTMR_CONTROL_ENABLE;
497 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
498 break;
499
500 case CLOCK_EVT_MODE_UNUSED:
501 case CLOCK_EVT_MODE_SHUTDOWN:
502 apbt_disable_int(timer_num);
503 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
504 ctrl &= ~APBTMR_CONTROL_ENABLE;
505 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
506 break;
507
508 case CLOCK_EVT_MODE_RESUME:
509 apbt_enable_int(timer_num);
510 break;
511 }
512}
513
514static int apbt_next_event(unsigned long delta,
515 struct clock_event_device *evt)
516{
517 unsigned long ctrl;
518 int timer_num;
519
520 struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
521
522 timer_num = adev->num;
523 /* Disable timer */
524 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
525 ctrl &= ~APBTMR_CONTROL_ENABLE;
526 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
527 /* write new count */
528 apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
529 ctrl |= APBTMR_CONTROL_ENABLE;
530 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
531 return 0;
532}
533
534/*
535 * APB timer clock is not in sync with pclk on Langwell, which translates to
536 * unreliable read value caused by sampling error. the error does not add up
537 * overtime and only happens when sampling a 0 as a 1 by mistake. so the time
538 * would go backwards. the following code is trying to prevent time traveling
539 * backwards. little bit paranoid.
540 */
541static cycle_t apbt_read_clocksource(struct clocksource *cs)
542{
543 unsigned long t0, t1, t2;
544 static unsigned long last_read;
545
546bad_count:
547 t1 = apbt_readl(phy_cs_timer_id,
548 APBTMR_N_CURRENT_VALUE);
549 t2 = apbt_readl(phy_cs_timer_id,
550 APBTMR_N_CURRENT_VALUE);
551 if (unlikely(t1 < t2)) {
552 pr_debug("APBT: read current count error %lx:%lx:%lx\n",
553 t1, t2, t2 - t1);
554 goto bad_count;
555 }
556 /*
557 * check against cached last read, makes sure time does not go back.
558 * it could be a normal rollover but we will do tripple check anyway
559 */
560 if (unlikely(t2 > last_read)) {
561 /* check if we have a normal rollover */
562 unsigned long raw_intr_status =
563 apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
564 /*
565 * cs timer interrupt is masked but raw intr bit is set if
566 * rollover occurs. then we read EOI reg to clear it.
567 */
568 if (raw_intr_status & (1 << phy_cs_timer_id)) {
569 apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
570 goto out;
571 }
572 pr_debug("APB CS going back %lx:%lx:%lx ",
573 t2, last_read, t2 - last_read);
574bad_count_x3:
575 pr_debug(KERN_INFO "tripple check enforced\n");
576 t0 = apbt_readl(phy_cs_timer_id,
577 APBTMR_N_CURRENT_VALUE);
578 udelay(1);
579 t1 = apbt_readl(phy_cs_timer_id,
580 APBTMR_N_CURRENT_VALUE);
581 udelay(1);
582 t2 = apbt_readl(phy_cs_timer_id,
583 APBTMR_N_CURRENT_VALUE);
584 if ((t2 > t1) || (t1 > t0)) {
585 printk(KERN_ERR "Error: APB CS tripple check failed\n");
586 goto bad_count_x3;
587 }
588 }
589out:
590 last_read = t2;
591 return (cycle_t)~t2;
592}
593
594static int apbt_clocksource_register(void)
595{
596 u64 start, now;
597 cycle_t t1;
598
599 /* Start the counter, use timer 2 as source, timer 0/1 for event */
600 apbt_start_counter(phy_cs_timer_id);
601
602 /* Verify whether apbt counter works */
603 t1 = apbt_read_clocksource(&clocksource_apbt);
604 rdtscll(start);
605
606 /*
607 * We don't know the TSC frequency yet, but waiting for
608 * 200000 TSC cycles is safe:
609 * 4 GHz == 50us
610 * 1 GHz == 200us
611 */
612 do {
613 rep_nop();
614 rdtscll(now);
615 } while ((now - start) < 200000UL);
616
617 /* APBT is the only always on clocksource, it has to work! */
618 if (t1 == apbt_read_clocksource(&clocksource_apbt))
619 panic("APBT counter not counting. APBT disabled\n");
620
621 /*
622 * initialize and register APBT clocksource
623 * convert that to ns/clock cycle
624 * mult = (ns/c) * 2^APBT_SHIFT
625 */
626 clocksource_apbt.mult = div_sc(MSEC_PER_SEC,
627 (unsigned long) apbt_freq, APBT_SHIFT);
628 clocksource_register(&clocksource_apbt);
629
630 return 0;
631}
632
633/*
634 * Early setup the APBT timer, only use timer 0 for booting then switch to
635 * per CPU timer if possible.
636 * returns 1 if per cpu apbt is setup
637 * returns 0 if no per cpu apbt is chosen
638 * panic if set up failed, this is the only platform timer on Moorestown.
639 */
640void __init apbt_time_init(void)
641{
642#ifdef CONFIG_SMP
643 int i;
644 struct sfi_timer_table_entry *p_mtmr;
645 unsigned int percpu_timer;
646 struct apbt_dev *adev;
647#endif
648
649 if (apb_timer_block_enabled)
650 return;
651 apbt_set_mapping();
652 if (apbt_virt_address) {
653 pr_debug("Found APBT version 0x%lx\n",\
654 apbt_readl_reg(APBTMRS_COMP_VERSION));
655 } else
656 goto out_noapbt;
657 /*
658 * Read the frequency and check for a sane value, for ESL model
659 * we extend the possible clock range to allow time scaling.
660 */
661
662 if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
663 pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq);
664 goto out_noapbt;
665 }
666 if (apbt_clocksource_register()) {
667 pr_debug("APBT has failed to register clocksource\n");
668 goto out_noapbt;
669 }
670 if (!apbt_clockevent_register())
671 apb_timer_block_enabled = 1;
672 else {
673 pr_debug("APBT has failed to register clockevent\n");
674 goto out_noapbt;
675 }
676#ifdef CONFIG_SMP
677 /* kernel cmdline disable apb timer, so we will use lapic timers */
678 if (disable_apbt_percpu) {
679 printk(KERN_INFO "apbt: disabled per cpu timer\n");
680 return;
681 }
682 pr_debug("%s: %d CPUs online\n", __func__, num_online_cpus());
683 if (num_possible_cpus() <= sfi_mtimer_num) {
684 percpu_timer = 1;
685 apbt_num_timers_used = num_possible_cpus();
686 } else {
687 percpu_timer = 0;
688 apbt_num_timers_used = 1;
689 adev = &per_cpu(cpu_apbt_dev, 0);
690 adev->flags &= ~APBT_DEV_USED;
691 }
692 pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used);
693
694 /* here we set up per CPU timer data structure */
695 apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used,
696 GFP_KERNEL);
697 if (!apbt_devs) {
698 printk(KERN_ERR "Failed to allocate APB timer devices\n");
699 return;
700 }
701 for (i = 0; i < apbt_num_timers_used; i++) {
702 adev = &per_cpu(cpu_apbt_dev, i);
703 adev->num = i;
704 adev->cpu = i;
705 p_mtmr = sfi_get_mtmr(i);
706 if (p_mtmr) {
707 adev->tick = p_mtmr->freq_hz;
708 adev->irq = p_mtmr->irq;
709 } else
710 printk(KERN_ERR "Failed to get timer for cpu %d\n", i);
711 adev->count = 0;
712 sprintf(adev->name, "apbt%d", i);
713 }
714#endif
715
716 return;
717
718out_noapbt:
719 apbt_clear_mapping();
720 apb_timer_block_enabled = 0;
721 panic("failed to enable APB timer\n");
722}
723
724static inline void apbt_disable(int n)
725{
726 if (is_apbt_capable()) {
727 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
728 ctrl &= ~APBTMR_CONTROL_ENABLE;
729 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
730 }
731}
732
733/* called before apb_timer_enable, use early map */
734unsigned long apbt_quick_calibrate()
735{
736 int i, scale;
737 u64 old, new;
738 cycle_t t1, t2;
739 unsigned long khz = 0;
740 u32 loop, shift;
741
742 apbt_set_mapping();
743 apbt_start_counter(phy_cs_timer_id);
744
745 /* check if the timer can count down, otherwise return */
746 old = apbt_read_clocksource(&clocksource_apbt);
747 i = 10000;
748 while (--i) {
749 if (old != apbt_read_clocksource(&clocksource_apbt))
750 break;
751 }
752 if (!i)
753 goto failed;
754
755 /* count 16 ms */
756 loop = (apbt_freq * 1000) << 4;
757
758 /* restart the timer to ensure it won't get to 0 in the calibration */
759 apbt_start_counter(phy_cs_timer_id);
760
761 old = apbt_read_clocksource(&clocksource_apbt);
762 old += loop;
763
764 t1 = __native_read_tsc();
765
766 do {
767 new = apbt_read_clocksource(&clocksource_apbt);
768 } while (new < old);
769
770 t2 = __native_read_tsc();
771
772 shift = 5;
773 if (unlikely(loop >> shift == 0)) {
774 printk(KERN_INFO
775 "APBT TSC calibration failed, not enough resolution\n");
776 return 0;
777 }
778 scale = (int)div_u64((t2 - t1), loop >> shift);
779 khz = (scale * apbt_freq * 1000) >> shift;
780 printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz);
781 return khz;
782failed:
783 return 0;
784}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 6e29b2a77aa8..00187f1fcfb7 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1390,7 +1390,7 @@ void __init enable_IR_x2apic(void)
1390 } 1390 }
1391 1391
1392 local_irq_save(flags); 1392 local_irq_save(flags);
1393 mask_8259A(); 1393 legacy_pic->mask_all();
1394 mask_IO_APIC_setup(ioapic_entries); 1394 mask_IO_APIC_setup(ioapic_entries);
1395 1395
1396 if (dmar_table_init_ret) 1396 if (dmar_table_init_ret)
@@ -1422,7 +1422,7 @@ void __init enable_IR_x2apic(void)
1422nox2apic: 1422nox2apic:
1423 if (!ret) /* IR enabling failed */ 1423 if (!ret) /* IR enabling failed */
1424 restore_IO_APIC_setup(ioapic_entries); 1424 restore_IO_APIC_setup(ioapic_entries);
1425 unmask_8259A(); 1425 legacy_pic->restore_mask();
1426 local_irq_restore(flags); 1426 local_irq_restore(flags);
1427 1427
1428out: 1428out:
@@ -2018,7 +2018,7 @@ static int lapic_resume(struct sys_device *dev)
2018 } 2018 }
2019 2019
2020 mask_IO_APIC_setup(ioapic_entries); 2020 mask_IO_APIC_setup(ioapic_entries);
2021 mask_8259A(); 2021 legacy_pic->mask_all();
2022 } 2022 }
2023 2023
2024 if (x2apic_mode) 2024 if (x2apic_mode)
@@ -2062,7 +2062,7 @@ static int lapic_resume(struct sys_device *dev)
2062 2062
2063 if (intr_remapping_enabled) { 2063 if (intr_remapping_enabled) {
2064 reenable_intr_remapping(x2apic_mode); 2064 reenable_intr_remapping(x2apic_mode);
2065 unmask_8259A(); 2065 legacy_pic->restore_mask();
2066 restore_IO_APIC_setup(ioapic_entries); 2066 restore_IO_APIC_setup(ioapic_entries);
2067 free_ioapic_entries(ioapic_entries); 2067 free_ioapic_entries(ioapic_entries);
2068 } 2068 }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 14862f11cc4a..e4e0ddcb1546 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -143,12 +143,6 @@ static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY];
143static struct irq_cfg irq_cfgx[NR_IRQS]; 143static struct irq_cfg irq_cfgx[NR_IRQS];
144#endif 144#endif
145 145
146void __init io_apic_disable_legacy(void)
147{
148 nr_legacy_irqs = 0;
149 nr_irqs_gsi = 0;
150}
151
152int __init arch_early_irq_init(void) 146int __init arch_early_irq_init(void)
153{ 147{
154 struct irq_cfg *cfg; 148 struct irq_cfg *cfg;
@@ -157,6 +151,11 @@ int __init arch_early_irq_init(void)
157 int node; 151 int node;
158 int i; 152 int i;
159 153
154 if (!legacy_pic->nr_legacy_irqs) {
155 nr_irqs_gsi = 0;
156 io_apic_irqs = ~0UL;
157 }
158
160 cfg = irq_cfgx; 159 cfg = irq_cfgx;
161 count = ARRAY_SIZE(irq_cfgx); 160 count = ARRAY_SIZE(irq_cfgx);
162 node= cpu_to_node(boot_cpu_id); 161 node= cpu_to_node(boot_cpu_id);
@@ -170,7 +169,7 @@ int __init arch_early_irq_init(void)
170 * For legacy IRQ's, start with assigning irq0 to irq15 to 169 * For legacy IRQ's, start with assigning irq0 to irq15 to
171 * IRQ0_VECTOR to IRQ15_VECTOR on cpu 0. 170 * IRQ0_VECTOR to IRQ15_VECTOR on cpu 0.
172 */ 171 */
173 if (i < nr_legacy_irqs) { 172 if (i < legacy_pic->nr_legacy_irqs) {
174 cfg[i].vector = IRQ0_VECTOR + i; 173 cfg[i].vector = IRQ0_VECTOR + i;
175 cpumask_set_cpu(0, cfg[i].domain); 174 cpumask_set_cpu(0, cfg[i].domain);
176 } 175 }
@@ -852,7 +851,7 @@ static int __init find_isa_irq_apic(int irq, int type)
852 */ 851 */
853static int EISA_ELCR(unsigned int irq) 852static int EISA_ELCR(unsigned int irq)
854{ 853{
855 if (irq < nr_legacy_irqs) { 854 if (irq < legacy_pic->nr_legacy_irqs) {
856 unsigned int port = 0x4d0 + (irq >> 3); 855 unsigned int port = 0x4d0 + (irq >> 3);
857 return (inb(port) >> (irq & 7)) & 1; 856 return (inb(port) >> (irq & 7)) & 1;
858 } 857 }
@@ -1439,7 +1438,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
1439 * controllers like 8259. Now that IO-APIC can handle this irq, update 1438 * controllers like 8259. Now that IO-APIC can handle this irq, update
1440 * the cfg->domain. 1439 * the cfg->domain.
1441 */ 1440 */
1442 if (irq < nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain)) 1441 if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain))
1443 apic->vector_allocation_domain(0, cfg->domain); 1442 apic->vector_allocation_domain(0, cfg->domain);
1444 1443
1445 if (assign_irq_vector(irq, cfg, apic->target_cpus())) 1444 if (assign_irq_vector(irq, cfg, apic->target_cpus()))
@@ -1463,8 +1462,8 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
1463 } 1462 }
1464 1463
1465 ioapic_register_intr(irq, desc, trigger); 1464 ioapic_register_intr(irq, desc, trigger);
1466 if (irq < nr_legacy_irqs) 1465 if (irq < legacy_pic->nr_legacy_irqs)
1467 disable_8259A_irq(irq); 1466 legacy_pic->chip->mask(irq);
1468 1467
1469 ioapic_write_entry(apic_id, pin, entry); 1468 ioapic_write_entry(apic_id, pin, entry);
1470} 1469}
@@ -1873,7 +1872,7 @@ __apicdebuginit(void) print_PIC(void)
1873 unsigned int v; 1872 unsigned int v;
1874 unsigned long flags; 1873 unsigned long flags;
1875 1874
1876 if (!nr_legacy_irqs) 1875 if (!legacy_pic->nr_legacy_irqs)
1877 return; 1876 return;
1878 1877
1879 printk(KERN_DEBUG "\nprinting PIC contents\n"); 1878 printk(KERN_DEBUG "\nprinting PIC contents\n");
@@ -1957,7 +1956,7 @@ void __init enable_IO_APIC(void)
1957 nr_ioapic_registers[apic] = reg_01.bits.entries+1; 1956 nr_ioapic_registers[apic] = reg_01.bits.entries+1;
1958 } 1957 }
1959 1958
1960 if (!nr_legacy_irqs) 1959 if (!legacy_pic->nr_legacy_irqs)
1961 return; 1960 return;
1962 1961
1963 for(apic = 0; apic < nr_ioapics; apic++) { 1962 for(apic = 0; apic < nr_ioapics; apic++) {
@@ -2014,7 +2013,7 @@ void disable_IO_APIC(void)
2014 */ 2013 */
2015 clear_IO_APIC(); 2014 clear_IO_APIC();
2016 2015
2017 if (!nr_legacy_irqs) 2016 if (!legacy_pic->nr_legacy_irqs)
2018 return; 2017 return;
2019 2018
2020 /* 2019 /*
@@ -2247,9 +2246,9 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
2247 struct irq_cfg *cfg; 2246 struct irq_cfg *cfg;
2248 2247
2249 raw_spin_lock_irqsave(&ioapic_lock, flags); 2248 raw_spin_lock_irqsave(&ioapic_lock, flags);
2250 if (irq < nr_legacy_irqs) { 2249 if (irq < legacy_pic->nr_legacy_irqs) {
2251 disable_8259A_irq(irq); 2250 legacy_pic->chip->mask(irq);
2252 if (i8259A_irq_pending(irq)) 2251 if (legacy_pic->irq_pending(irq))
2253 was_pending = 1; 2252 was_pending = 1;
2254 } 2253 }
2255 cfg = irq_cfg(irq); 2254 cfg = irq_cfg(irq);
@@ -2782,8 +2781,8 @@ static inline void init_IO_APIC_traps(void)
2782 * so default to an old-fashioned 8259 2781 * so default to an old-fashioned 8259
2783 * interrupt if we can.. 2782 * interrupt if we can..
2784 */ 2783 */
2785 if (irq < nr_legacy_irqs) 2784 if (irq < legacy_pic->nr_legacy_irqs)
2786 make_8259A_irq(irq); 2785 legacy_pic->make_irq(irq);
2787 else 2786 else
2788 /* Strange. Oh, well.. */ 2787 /* Strange. Oh, well.. */
2789 desc->chip = &no_irq_chip; 2788 desc->chip = &no_irq_chip;
@@ -2940,7 +2939,7 @@ static inline void __init check_timer(void)
2940 /* 2939 /*
2941 * get/set the timer IRQ vector: 2940 * get/set the timer IRQ vector:
2942 */ 2941 */
2943 disable_8259A_irq(0); 2942 legacy_pic->chip->mask(0);
2944 assign_irq_vector(0, cfg, apic->target_cpus()); 2943 assign_irq_vector(0, cfg, apic->target_cpus());
2945 2944
2946 /* 2945 /*
@@ -2953,7 +2952,7 @@ static inline void __init check_timer(void)
2953 * automatically. 2952 * automatically.
2954 */ 2953 */
2955 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); 2954 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
2956 init_8259A(1); 2955 legacy_pic->init(1);
2957#ifdef CONFIG_X86_32 2956#ifdef CONFIG_X86_32
2958 { 2957 {
2959 unsigned int ver; 2958 unsigned int ver;
@@ -3012,7 +3011,7 @@ static inline void __init check_timer(void)
3012 if (timer_irq_works()) { 3011 if (timer_irq_works()) {
3013 if (nmi_watchdog == NMI_IO_APIC) { 3012 if (nmi_watchdog == NMI_IO_APIC) {
3014 setup_nmi(); 3013 setup_nmi();
3015 enable_8259A_irq(0); 3014 legacy_pic->chip->unmask(0);
3016 } 3015 }
3017 if (disable_timer_pin_1 > 0) 3016 if (disable_timer_pin_1 > 0)
3018 clear_IO_APIC_pin(0, pin1); 3017 clear_IO_APIC_pin(0, pin1);
@@ -3035,14 +3034,14 @@ static inline void __init check_timer(void)
3035 */ 3034 */
3036 replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2); 3035 replace_pin_at_irq_node(cfg, node, apic1, pin1, apic2, pin2);
3037 setup_timer_IRQ0_pin(apic2, pin2, cfg->vector); 3036 setup_timer_IRQ0_pin(apic2, pin2, cfg->vector);
3038 enable_8259A_irq(0); 3037 legacy_pic->chip->unmask(0);
3039 if (timer_irq_works()) { 3038 if (timer_irq_works()) {
3040 apic_printk(APIC_QUIET, KERN_INFO "....... works.\n"); 3039 apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
3041 timer_through_8259 = 1; 3040 timer_through_8259 = 1;
3042 if (nmi_watchdog == NMI_IO_APIC) { 3041 if (nmi_watchdog == NMI_IO_APIC) {
3043 disable_8259A_irq(0); 3042 legacy_pic->chip->mask(0);
3044 setup_nmi(); 3043 setup_nmi();
3045 enable_8259A_irq(0); 3044 legacy_pic->chip->unmask(0);
3046 } 3045 }
3047 goto out; 3046 goto out;
3048 } 3047 }
@@ -3050,7 +3049,7 @@ static inline void __init check_timer(void)
3050 * Cleanup, just in case ... 3049 * Cleanup, just in case ...
3051 */ 3050 */
3052 local_irq_disable(); 3051 local_irq_disable();
3053 disable_8259A_irq(0); 3052 legacy_pic->chip->mask(0);
3054 clear_IO_APIC_pin(apic2, pin2); 3053 clear_IO_APIC_pin(apic2, pin2);
3055 apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); 3054 apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
3056 } 3055 }
@@ -3069,22 +3068,22 @@ static inline void __init check_timer(void)
3069 3068
3070 lapic_register_intr(0, desc); 3069 lapic_register_intr(0, desc);
3071 apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ 3070 apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
3072 enable_8259A_irq(0); 3071 legacy_pic->chip->unmask(0);
3073 3072
3074 if (timer_irq_works()) { 3073 if (timer_irq_works()) {
3075 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); 3074 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
3076 goto out; 3075 goto out;
3077 } 3076 }
3078 local_irq_disable(); 3077 local_irq_disable();
3079 disable_8259A_irq(0); 3078 legacy_pic->chip->mask(0);
3080 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); 3079 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
3081 apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); 3080 apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
3082 3081
3083 apic_printk(APIC_QUIET, KERN_INFO 3082 apic_printk(APIC_QUIET, KERN_INFO
3084 "...trying to set up timer as ExtINT IRQ...\n"); 3083 "...trying to set up timer as ExtINT IRQ...\n");
3085 3084
3086 init_8259A(0); 3085 legacy_pic->init(0);
3087 make_8259A_irq(0); 3086 legacy_pic->make_irq(0);
3088 apic_write(APIC_LVT0, APIC_DM_EXTINT); 3087 apic_write(APIC_LVT0, APIC_DM_EXTINT);
3089 3088
3090 unlock_ExtINT_logic(); 3089 unlock_ExtINT_logic();
@@ -3126,7 +3125,7 @@ void __init setup_IO_APIC(void)
3126 /* 3125 /*
3127 * calling enable_IO_APIC() is moved to setup_local_APIC for BP 3126 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
3128 */ 3127 */
3129 io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL; 3128 io_apic_irqs = legacy_pic->nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
3130 3129
3131 apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); 3130 apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
3132 /* 3131 /*
@@ -3137,7 +3136,7 @@ void __init setup_IO_APIC(void)
3137 sync_Arb_IDs(); 3136 sync_Arb_IDs();
3138 setup_IO_APIC_irqs(); 3137 setup_IO_APIC_irqs();
3139 init_IO_APIC_traps(); 3138 init_IO_APIC_traps();
3140 if (nr_legacy_irqs) 3139 if (legacy_pic->nr_legacy_irqs)
3141 check_timer(); 3140 check_timer();
3142} 3141}
3143 3142
@@ -3928,7 +3927,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
3928 /* 3927 /*
3929 * IRQs < 16 are already in the irq_2_pin[] map 3928 * IRQs < 16 are already in the irq_2_pin[] map
3930 */ 3929 */
3931 if (irq >= nr_legacy_irqs) { 3930 if (irq >= legacy_pic->nr_legacy_irqs) {
3932 cfg = desc->chip_data; 3931 cfg = desc->chip_data;
3933 if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) { 3932 if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
3934 printk(KERN_INFO "can not add pin %d for irq %d\n", 3933 printk(KERN_INFO "can not add pin %d for irq %d\n",
@@ -4302,3 +4301,24 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
4302 4301
4303 nr_ioapics++; 4302 nr_ioapics++;
4304} 4303}
4304
4305/* Enable IOAPIC early just for system timer */
4306void __init pre_init_apic_IRQ0(void)
4307{
4308 struct irq_cfg *cfg;
4309 struct irq_desc *desc;
4310
4311 printk(KERN_INFO "Early APIC setup for system timer0\n");
4312#ifndef CONFIG_SMP
4313 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
4314#endif
4315 desc = irq_to_desc_alloc_node(0, 0);
4316
4317 setup_local_APIC();
4318
4319 cfg = irq_cfg(0);
4320 add_pin_to_irq_node(cfg, 0, 0, 0);
4321 set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
4322
4323 setup_IO_APIC_irq(0, 0, 0, desc, 0, 0);
4324}
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index bd7c96b5e8d8..8aa65adbd25d 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -177,7 +177,7 @@ int __init check_nmi_watchdog(void)
177error: 177error:
178 if (nmi_watchdog == NMI_IO_APIC) { 178 if (nmi_watchdog == NMI_IO_APIC) {
179 if (!timer_through_8259) 179 if (!timer_through_8259)
180 disable_8259A_irq(0); 180 legacy_pic->chip->mask(0);
181 on_each_cpu(__acpi_nmi_disable, NULL, 1); 181 on_each_cpu(__acpi_nmi_disable, NULL, 1);
182 } 182 }
183 183
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index 47dd856708e5..3e28401f161c 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -277,6 +277,7 @@ static __init void early_check_numaq(void)
277 x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus; 277 x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
278 x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info; 278 x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
279 x86_init.timers.tsc_pre_init = numaq_tsc_init; 279 x86_init.timers.tsc_pre_init = numaq_tsc_init;
280 x86_init.pci.init = pci_numaq_init;
280 } 281 }
281} 282}
282 283
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig
index f138c6c389b9..870e6cc6ad28 100644
--- a/arch/x86/kernel/cpu/cpufreq/Kconfig
+++ b/arch/x86/kernel/cpu/cpufreq/Kconfig
@@ -10,6 +10,20 @@ if CPU_FREQ
10 10
11comment "CPUFreq processor drivers" 11comment "CPUFreq processor drivers"
12 12
13config X86_PCC_CPUFREQ
14 tristate "Processor Clocking Control interface driver"
15 depends on ACPI && ACPI_PROCESSOR
16 help
17 This driver adds support for the PCC interface.
18
19 For details, take a look at:
20 <file:Documentation/cpu-freq/pcc-cpufreq.txt>.
21
22 To compile this driver as a module, choose M here: the
23 module will be called pcc-cpufreq.
24
25 If in doubt, say N.
26
13config X86_ACPI_CPUFREQ 27config X86_ACPI_CPUFREQ
14 tristate "ACPI Processor P-States driver" 28 tristate "ACPI Processor P-States driver"
15 select CPU_FREQ_TABLE 29 select CPU_FREQ_TABLE
diff --git a/arch/x86/kernel/cpu/cpufreq/Makefile b/arch/x86/kernel/cpu/cpufreq/Makefile
index 509296df294d..1840c0a5170b 100644
--- a/arch/x86/kernel/cpu/cpufreq/Makefile
+++ b/arch/x86/kernel/cpu/cpufreq/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o 5obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
6obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o 6obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
7obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o
7obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o 8obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
8obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o 9obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
9obj-$(CONFIG_X86_LONGHAUL) += longhaul.o 10obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
new file mode 100644
index 000000000000..ff36d2979a90
--- /dev/null
+++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
@@ -0,0 +1,620 @@
1/*
2 * pcc-cpufreq.c - Processor Clocking Control firmware cpufreq interface
3 *
4 * Copyright (C) 2009 Red Hat, Matthew Garrett <mjg@redhat.com>
5 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
6 * Nagananda Chumbalkar <nagananda.chumbalkar@hp.com>
7 *
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or NON
17 * INFRINGEMENT. See the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/smp.h>
30#include <linux/sched.h>
31#include <linux/cpufreq.h>
32#include <linux/compiler.h>
33
34#include <linux/acpi.h>
35#include <linux/io.h>
36#include <linux/spinlock.h>
37#include <linux/uaccess.h>
38
39#include <acpi/processor.h>
40
41#define PCC_VERSION "1.00.00"
42#define POLL_LOOPS 300
43
44#define CMD_COMPLETE 0x1
45#define CMD_GET_FREQ 0x0
46#define CMD_SET_FREQ 0x1
47
48#define BUF_SZ 4
49
50#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
51 "pcc-cpufreq", msg)
52
53struct pcc_register_resource {
54 u8 descriptor;
55 u16 length;
56 u8 space_id;
57 u8 bit_width;
58 u8 bit_offset;
59 u8 access_size;
60 u64 address;
61} __attribute__ ((packed));
62
63struct pcc_memory_resource {
64 u8 descriptor;
65 u16 length;
66 u8 space_id;
67 u8 resource_usage;
68 u8 type_specific;
69 u64 granularity;
70 u64 minimum;
71 u64 maximum;
72 u64 translation_offset;
73 u64 address_length;
74} __attribute__ ((packed));
75
76static struct cpufreq_driver pcc_cpufreq_driver;
77
78struct pcc_header {
79 u32 signature;
80 u16 length;
81 u8 major;
82 u8 minor;
83 u32 features;
84 u16 command;
85 u16 status;
86 u32 latency;
87 u32 minimum_time;
88 u32 maximum_time;
89 u32 nominal;
90 u32 throttled_frequency;
91 u32 minimum_frequency;
92};
93
94static void __iomem *pcch_virt_addr;
95static struct pcc_header __iomem *pcch_hdr;
96
97static DEFINE_SPINLOCK(pcc_lock);
98
99static struct acpi_generic_address doorbell;
100
101static u64 doorbell_preserve;
102static u64 doorbell_write;
103
104static u8 OSC_UUID[16] = {0x63, 0x9B, 0x2C, 0x9F, 0x70, 0x91, 0x49, 0x1f,
105 0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46};
106
107struct pcc_cpu {
108 u32 input_offset;
109 u32 output_offset;
110};
111
112static struct pcc_cpu *pcc_cpu_info;
113
114static int pcc_cpufreq_verify(struct cpufreq_policy *policy)
115{
116 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
117 policy->cpuinfo.max_freq);
118 return 0;
119}
120
121static inline void pcc_cmd(void)
122{
123 u64 doorbell_value;
124 int i;
125
126 acpi_read(&doorbell_value, &doorbell);
127 acpi_write((doorbell_value & doorbell_preserve) | doorbell_write,
128 &doorbell);
129
130 for (i = 0; i < POLL_LOOPS; i++) {
131 if (ioread16(&pcch_hdr->status) & CMD_COMPLETE)
132 break;
133 }
134}
135
136static inline void pcc_clear_mapping(void)
137{
138 if (pcch_virt_addr)
139 iounmap(pcch_virt_addr);
140 pcch_virt_addr = NULL;
141}
142
143static unsigned int pcc_get_freq(unsigned int cpu)
144{
145 struct pcc_cpu *pcc_cpu_data;
146 unsigned int curr_freq;
147 unsigned int freq_limit;
148 u16 status;
149 u32 input_buffer;
150 u32 output_buffer;
151
152 spin_lock(&pcc_lock);
153
154 dprintk("get: get_freq for CPU %d\n", cpu);
155 pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
156
157 input_buffer = 0x1;
158 iowrite32(input_buffer,
159 (pcch_virt_addr + pcc_cpu_data->input_offset));
160 iowrite16(CMD_GET_FREQ, &pcch_hdr->command);
161
162 pcc_cmd();
163
164 output_buffer =
165 ioread32(pcch_virt_addr + pcc_cpu_data->output_offset);
166
167 /* Clear the input buffer - we are done with the current command */
168 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
169
170 status = ioread16(&pcch_hdr->status);
171 if (status != CMD_COMPLETE) {
172 dprintk("get: FAILED: for CPU %d, status is %d\n",
173 cpu, status);
174 goto cmd_incomplete;
175 }
176 iowrite16(0, &pcch_hdr->status);
177 curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff))
178 / 100) * 1000);
179
180 dprintk("get: SUCCESS: (virtual) output_offset for cpu %d is "
181 "0x%x, contains a value of: 0x%x. Speed is: %d MHz\n",
182 cpu, (pcch_virt_addr + pcc_cpu_data->output_offset),
183 output_buffer, curr_freq);
184
185 freq_limit = (output_buffer >> 8) & 0xff;
186 if (freq_limit != 0xff) {
187 dprintk("get: frequency for cpu %d is being temporarily"
188 " capped at %d\n", cpu, curr_freq);
189 }
190
191 spin_unlock(&pcc_lock);
192 return curr_freq;
193
194cmd_incomplete:
195 iowrite16(0, &pcch_hdr->status);
196 spin_unlock(&pcc_lock);
197 return -EINVAL;
198}
199
200static int pcc_cpufreq_target(struct cpufreq_policy *policy,
201 unsigned int target_freq,
202 unsigned int relation)
203{
204 struct pcc_cpu *pcc_cpu_data;
205 struct cpufreq_freqs freqs;
206 u16 status;
207 u32 input_buffer;
208 int cpu;
209
210 spin_lock(&pcc_lock);
211 cpu = policy->cpu;
212 pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
213
214 dprintk("target: CPU %d should go to target freq: %d "
215 "(virtual) input_offset is 0x%x\n",
216 cpu, target_freq,
217 (pcch_virt_addr + pcc_cpu_data->input_offset));
218
219 freqs.new = target_freq;
220 freqs.cpu = cpu;
221 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
222
223 input_buffer = 0x1 | (((target_freq * 100)
224 / (ioread32(&pcch_hdr->nominal) * 1000)) << 8);
225 iowrite32(input_buffer,
226 (pcch_virt_addr + pcc_cpu_data->input_offset));
227 iowrite16(CMD_SET_FREQ, &pcch_hdr->command);
228
229 pcc_cmd();
230
231 /* Clear the input buffer - we are done with the current command */
232 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
233
234 status = ioread16(&pcch_hdr->status);
235 if (status != CMD_COMPLETE) {
236 dprintk("target: FAILED for cpu %d, with status: 0x%x\n",
237 cpu, status);
238 goto cmd_incomplete;
239 }
240 iowrite16(0, &pcch_hdr->status);
241
242 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
243 dprintk("target: was SUCCESSFUL for cpu %d\n", cpu);
244 spin_unlock(&pcc_lock);
245
246 return 0;
247
248cmd_incomplete:
249 iowrite16(0, &pcch_hdr->status);
250 spin_unlock(&pcc_lock);
251 return -EINVAL;
252}
253
254static int pcc_get_offset(int cpu)
255{
256 acpi_status status;
257 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
258 union acpi_object *pccp, *offset;
259 struct pcc_cpu *pcc_cpu_data;
260 struct acpi_processor *pr;
261 int ret = 0;
262
263 pr = per_cpu(processors, cpu);
264 pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
265
266 status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer);
267 if (ACPI_FAILURE(status))
268 return -ENODEV;
269
270 pccp = buffer.pointer;
271 if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) {
272 ret = -ENODEV;
273 goto out_free;
274 };
275
276 offset = &(pccp->package.elements[0]);
277 if (!offset || offset->type != ACPI_TYPE_INTEGER) {
278 ret = -ENODEV;
279 goto out_free;
280 }
281
282 pcc_cpu_data->input_offset = offset->integer.value;
283
284 offset = &(pccp->package.elements[1]);
285 if (!offset || offset->type != ACPI_TYPE_INTEGER) {
286 ret = -ENODEV;
287 goto out_free;
288 }
289
290 pcc_cpu_data->output_offset = offset->integer.value;
291
292 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
293 memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ);
294
295 dprintk("pcc_get_offset: for CPU %d: pcc_cpu_data "
296 "input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n",
297 cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset);
298out_free:
299 kfree(buffer.pointer);
300 return ret;
301}
302
303static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
304{
305 acpi_status status;
306 struct acpi_object_list input;
307 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
308 union acpi_object in_params[4];
309 union acpi_object *out_obj;
310 u32 capabilities[2];
311 u32 errors;
312 u32 supported;
313 int ret = 0;
314
315 input.count = 4;
316 input.pointer = in_params;
317 input.count = 4;
318 input.pointer = in_params;
319 in_params[0].type = ACPI_TYPE_BUFFER;
320 in_params[0].buffer.length = 16;
321 in_params[0].buffer.pointer = OSC_UUID;
322 in_params[1].type = ACPI_TYPE_INTEGER;
323 in_params[1].integer.value = 1;
324 in_params[2].type = ACPI_TYPE_INTEGER;
325 in_params[2].integer.value = 2;
326 in_params[3].type = ACPI_TYPE_BUFFER;
327 in_params[3].buffer.length = 8;
328 in_params[3].buffer.pointer = (u8 *)&capabilities;
329
330 capabilities[0] = OSC_QUERY_ENABLE;
331 capabilities[1] = 0x1;
332
333 status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
334 if (ACPI_FAILURE(status))
335 return -ENODEV;
336
337 if (!output.length)
338 return -ENODEV;
339
340 out_obj = output.pointer;
341 if (out_obj->type != ACPI_TYPE_BUFFER) {
342 ret = -ENODEV;
343 goto out_free;
344 }
345
346 errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
347 if (errors) {
348 ret = -ENODEV;
349 goto out_free;
350 }
351
352 supported = *((u32 *)(out_obj->buffer.pointer + 4));
353 if (!(supported & 0x1)) {
354 ret = -ENODEV;
355 goto out_free;
356 }
357
358 kfree(output.pointer);
359 capabilities[0] = 0x0;
360 capabilities[1] = 0x1;
361
362 status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
363 if (ACPI_FAILURE(status))
364 return -ENODEV;
365
366 if (!output.length)
367 return -ENODEV;
368
369 out_obj = output.pointer;
370 if (out_obj->type != ACPI_TYPE_BUFFER) {
371 ret = -ENODEV;
372 goto out_free;
373 }
374
375 errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
376 if (errors) {
377 ret = -ENODEV;
378 goto out_free;
379 }
380
381 supported = *((u32 *)(out_obj->buffer.pointer + 4));
382 if (!(supported & 0x1)) {
383 ret = -ENODEV;
384 goto out_free;
385 }
386
387out_free:
388 kfree(output.pointer);
389 return ret;
390}
391
392static int __init pcc_cpufreq_probe(void)
393{
394 acpi_status status;
395 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
396 struct pcc_memory_resource *mem_resource;
397 struct pcc_register_resource *reg_resource;
398 union acpi_object *out_obj, *member;
399 acpi_handle handle, osc_handle;
400 int ret = 0;
401
402 status = acpi_get_handle(NULL, "\\_SB", &handle);
403 if (ACPI_FAILURE(status))
404 return -ENODEV;
405
406 status = acpi_get_handle(handle, "_OSC", &osc_handle);
407 if (ACPI_SUCCESS(status)) {
408 ret = pcc_cpufreq_do_osc(&osc_handle);
409 if (ret)
410 dprintk("probe: _OSC evaluation did not succeed\n");
411 /* Firmware's use of _OSC is optional */
412 ret = 0;
413 }
414
415 status = acpi_evaluate_object(handle, "PCCH", NULL, &output);
416 if (ACPI_FAILURE(status))
417 return -ENODEV;
418
419 out_obj = output.pointer;
420 if (out_obj->type != ACPI_TYPE_PACKAGE) {
421 ret = -ENODEV;
422 goto out_free;
423 }
424
425 member = &out_obj->package.elements[0];
426 if (member->type != ACPI_TYPE_BUFFER) {
427 ret = -ENODEV;
428 goto out_free;
429 }
430
431 mem_resource = (struct pcc_memory_resource *)member->buffer.pointer;
432
433 dprintk("probe: mem_resource descriptor: 0x%x,"
434 " length: %d, space_id: %d, resource_usage: %d,"
435 " type_specific: %d, granularity: 0x%llx,"
436 " minimum: 0x%llx, maximum: 0x%llx,"
437 " translation_offset: 0x%llx, address_length: 0x%llx\n",
438 mem_resource->descriptor, mem_resource->length,
439 mem_resource->space_id, mem_resource->resource_usage,
440 mem_resource->type_specific, mem_resource->granularity,
441 mem_resource->minimum, mem_resource->maximum,
442 mem_resource->translation_offset,
443 mem_resource->address_length);
444
445 if (mem_resource->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
446 ret = -ENODEV;
447 goto out_free;
448 }
449
450 pcch_virt_addr = ioremap_nocache(mem_resource->minimum,
451 mem_resource->address_length);
452 if (pcch_virt_addr == NULL) {
453 dprintk("probe: could not map shared mem region\n");
454 goto out_free;
455 }
456 pcch_hdr = pcch_virt_addr;
457
458 dprintk("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr);
459 dprintk("probe: PCCH header is at physical address: 0x%llx,"
460 " signature: 0x%x, length: %d bytes, major: %d, minor: %d,"
461 " supported features: 0x%x, command field: 0x%x,"
462 " status field: 0x%x, nominal latency: %d us\n",
463 mem_resource->minimum, ioread32(&pcch_hdr->signature),
464 ioread16(&pcch_hdr->length), ioread8(&pcch_hdr->major),
465 ioread8(&pcch_hdr->minor), ioread32(&pcch_hdr->features),
466 ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status),
467 ioread32(&pcch_hdr->latency));
468
469 dprintk("probe: min time between commands: %d us,"
470 " max time between commands: %d us,"
471 " nominal CPU frequency: %d MHz,"
472 " minimum CPU frequency: %d MHz,"
473 " minimum CPU frequency without throttling: %d MHz\n",
474 ioread32(&pcch_hdr->minimum_time),
475 ioread32(&pcch_hdr->maximum_time),
476 ioread32(&pcch_hdr->nominal),
477 ioread32(&pcch_hdr->throttled_frequency),
478 ioread32(&pcch_hdr->minimum_frequency));
479
480 member = &out_obj->package.elements[1];
481 if (member->type != ACPI_TYPE_BUFFER) {
482 ret = -ENODEV;
483 goto pcch_free;
484 }
485
486 reg_resource = (struct pcc_register_resource *)member->buffer.pointer;
487
488 doorbell.space_id = reg_resource->space_id;
489 doorbell.bit_width = reg_resource->bit_width;
490 doorbell.bit_offset = reg_resource->bit_offset;
491 doorbell.access_width = 64;
492 doorbell.address = reg_resource->address;
493
494 dprintk("probe: doorbell: space_id is %d, bit_width is %d, "
495 "bit_offset is %d, access_width is %d, address is 0x%llx\n",
496 doorbell.space_id, doorbell.bit_width, doorbell.bit_offset,
497 doorbell.access_width, reg_resource->address);
498
499 member = &out_obj->package.elements[2];
500 if (member->type != ACPI_TYPE_INTEGER) {
501 ret = -ENODEV;
502 goto pcch_free;
503 }
504
505 doorbell_preserve = member->integer.value;
506
507 member = &out_obj->package.elements[3];
508 if (member->type != ACPI_TYPE_INTEGER) {
509 ret = -ENODEV;
510 goto pcch_free;
511 }
512
513 doorbell_write = member->integer.value;
514
515 dprintk("probe: doorbell_preserve: 0x%llx,"
516 " doorbell_write: 0x%llx\n",
517 doorbell_preserve, doorbell_write);
518
519 pcc_cpu_info = alloc_percpu(struct pcc_cpu);
520 if (!pcc_cpu_info) {
521 ret = -ENOMEM;
522 goto pcch_free;
523 }
524
525 printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency"
526 " limits: %d MHz, %d MHz\n", PCC_VERSION,
527 ioread32(&pcch_hdr->minimum_frequency),
528 ioread32(&pcch_hdr->nominal));
529 kfree(output.pointer);
530 return ret;
531pcch_free:
532 pcc_clear_mapping();
533out_free:
534 kfree(output.pointer);
535 return ret;
536}
537
538static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
539{
540 unsigned int cpu = policy->cpu;
541 unsigned int result = 0;
542
543 if (!pcch_virt_addr) {
544 result = -1;
545 goto pcch_null;
546 }
547
548 result = pcc_get_offset(cpu);
549 if (result) {
550 dprintk("init: PCCP evaluation failed\n");
551 goto free;
552 }
553
554 policy->max = policy->cpuinfo.max_freq =
555 ioread32(&pcch_hdr->nominal) * 1000;
556 policy->min = policy->cpuinfo.min_freq =
557 ioread32(&pcch_hdr->minimum_frequency) * 1000;
558 policy->cur = pcc_get_freq(cpu);
559
560 dprintk("init: policy->max is %d, policy->min is %d\n",
561 policy->max, policy->min);
562
563 return 0;
564free:
565 pcc_clear_mapping();
566 free_percpu(pcc_cpu_info);
567pcch_null:
568 return result;
569}
570
571static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
572{
573 return 0;
574}
575
576static struct cpufreq_driver pcc_cpufreq_driver = {
577 .flags = CPUFREQ_CONST_LOOPS,
578 .get = pcc_get_freq,
579 .verify = pcc_cpufreq_verify,
580 .target = pcc_cpufreq_target,
581 .init = pcc_cpufreq_cpu_init,
582 .exit = pcc_cpufreq_cpu_exit,
583 .name = "pcc-cpufreq",
584 .owner = THIS_MODULE,
585};
586
587static int __init pcc_cpufreq_init(void)
588{
589 int ret;
590
591 if (acpi_disabled)
592 return 0;
593
594 ret = pcc_cpufreq_probe();
595 if (ret) {
596 dprintk("pcc_cpufreq_init: PCCH evaluation failed\n");
597 return ret;
598 }
599
600 ret = cpufreq_register_driver(&pcc_cpufreq_driver);
601
602 return ret;
603}
604
605static void __exit pcc_cpufreq_exit(void)
606{
607 cpufreq_unregister_driver(&pcc_cpufreq_driver);
608
609 pcc_clear_mapping();
610
611 free_percpu(pcc_cpu_info);
612}
613
614MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar");
615MODULE_VERSION(PCC_VERSION);
616MODULE_DESCRIPTION("Processor Clocking Control interface driver");
617MODULE_LICENSE("GPL");
618
619late_initcall(pcc_cpufreq_init);
620module_exit(pcc_cpufreq_exit);
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 641ccb9dddbc..b1fbdeecf6c9 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -676,7 +676,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
676 if (c->weight != w) 676 if (c->weight != w)
677 continue; 677 continue;
678 678
679 for_each_bit(j, c->idxmsk, X86_PMC_IDX_MAX) { 679 for_each_set_bit(j, c->idxmsk, X86_PMC_IDX_MAX) {
680 if (!test_bit(j, used_mask)) 680 if (!test_bit(j, used_mask))
681 break; 681 break;
682 } 682 }
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index cf6590cf4a5f..977e7544738c 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -757,7 +757,7 @@ again:
757 757
758 inc_irq_stat(apic_perf_irqs); 758 inc_irq_stat(apic_perf_irqs);
759 ack = status; 759 ack = status;
760 for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { 760 for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
761 struct perf_event *event = cpuc->events[bit]; 761 struct perf_event *event = cpuc->events[bit];
762 762
763 clear_bit(bit, (unsigned long *) &status); 763 clear_bit(bit, (unsigned long *) &status);
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
index 8c93a84bb627..fb725ee15f55 100644
--- a/arch/x86/kernel/i8259.c
+++ b/arch/x86/kernel/i8259.c
@@ -34,6 +34,12 @@
34static int i8259A_auto_eoi; 34static int i8259A_auto_eoi;
35DEFINE_RAW_SPINLOCK(i8259A_lock); 35DEFINE_RAW_SPINLOCK(i8259A_lock);
36static void mask_and_ack_8259A(unsigned int); 36static void mask_and_ack_8259A(unsigned int);
37static void mask_8259A(void);
38static void unmask_8259A(void);
39static void disable_8259A_irq(unsigned int irq);
40static void enable_8259A_irq(unsigned int irq);
41static void init_8259A(int auto_eoi);
42static int i8259A_irq_pending(unsigned int irq);
37 43
38struct irq_chip i8259A_chip = { 44struct irq_chip i8259A_chip = {
39 .name = "XT-PIC", 45 .name = "XT-PIC",
@@ -63,7 +69,7 @@ unsigned int cached_irq_mask = 0xffff;
63 */ 69 */
64unsigned long io_apic_irqs; 70unsigned long io_apic_irqs;
65 71
66void disable_8259A_irq(unsigned int irq) 72static void disable_8259A_irq(unsigned int irq)
67{ 73{
68 unsigned int mask = 1 << irq; 74 unsigned int mask = 1 << irq;
69 unsigned long flags; 75 unsigned long flags;
@@ -77,7 +83,7 @@ void disable_8259A_irq(unsigned int irq)
77 raw_spin_unlock_irqrestore(&i8259A_lock, flags); 83 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
78} 84}
79 85
80void enable_8259A_irq(unsigned int irq) 86static void enable_8259A_irq(unsigned int irq)
81{ 87{
82 unsigned int mask = ~(1 << irq); 88 unsigned int mask = ~(1 << irq);
83 unsigned long flags; 89 unsigned long flags;
@@ -91,7 +97,7 @@ void enable_8259A_irq(unsigned int irq)
91 raw_spin_unlock_irqrestore(&i8259A_lock, flags); 97 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
92} 98}
93 99
94int i8259A_irq_pending(unsigned int irq) 100static int i8259A_irq_pending(unsigned int irq)
95{ 101{
96 unsigned int mask = 1<<irq; 102 unsigned int mask = 1<<irq;
97 unsigned long flags; 103 unsigned long flags;
@@ -107,7 +113,7 @@ int i8259A_irq_pending(unsigned int irq)
107 return ret; 113 return ret;
108} 114}
109 115
110void make_8259A_irq(unsigned int irq) 116static void make_8259A_irq(unsigned int irq)
111{ 117{
112 disable_irq_nosync(irq); 118 disable_irq_nosync(irq);
113 io_apic_irqs &= ~(1<<irq); 119 io_apic_irqs &= ~(1<<irq);
@@ -281,7 +287,7 @@ static int __init i8259A_init_sysfs(void)
281 287
282device_initcall(i8259A_init_sysfs); 288device_initcall(i8259A_init_sysfs);
283 289
284void mask_8259A(void) 290static void mask_8259A(void)
285{ 291{
286 unsigned long flags; 292 unsigned long flags;
287 293
@@ -293,7 +299,7 @@ void mask_8259A(void)
293 raw_spin_unlock_irqrestore(&i8259A_lock, flags); 299 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
294} 300}
295 301
296void unmask_8259A(void) 302static void unmask_8259A(void)
297{ 303{
298 unsigned long flags; 304 unsigned long flags;
299 305
@@ -305,7 +311,7 @@ void unmask_8259A(void)
305 raw_spin_unlock_irqrestore(&i8259A_lock, flags); 311 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
306} 312}
307 313
308void init_8259A(int auto_eoi) 314static void init_8259A(int auto_eoi)
309{ 315{
310 unsigned long flags; 316 unsigned long flags;
311 317
@@ -358,3 +364,47 @@ void init_8259A(int auto_eoi)
358 364
359 raw_spin_unlock_irqrestore(&i8259A_lock, flags); 365 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
360} 366}
367
368/*
369 * make i8259 a driver so that we can select pic functions at run time. the goal
370 * is to make x86 binary compatible among pc compatible and non-pc compatible
371 * platforms, such as x86 MID.
372 */
373
374static void legacy_pic_noop(void) { };
375static void legacy_pic_uint_noop(unsigned int unused) { };
376static void legacy_pic_int_noop(int unused) { };
377
378static struct irq_chip dummy_pic_chip = {
379 .name = "dummy pic",
380 .mask = legacy_pic_uint_noop,
381 .unmask = legacy_pic_uint_noop,
382 .disable = legacy_pic_uint_noop,
383 .mask_ack = legacy_pic_uint_noop,
384};
385static int legacy_pic_irq_pending_noop(unsigned int irq)
386{
387 return 0;
388}
389
390struct legacy_pic null_legacy_pic = {
391 .nr_legacy_irqs = 0,
392 .chip = &dummy_pic_chip,
393 .mask_all = legacy_pic_noop,
394 .restore_mask = legacy_pic_noop,
395 .init = legacy_pic_int_noop,
396 .irq_pending = legacy_pic_irq_pending_noop,
397 .make_irq = legacy_pic_uint_noop,
398};
399
400struct legacy_pic default_legacy_pic = {
401 .nr_legacy_irqs = NR_IRQS_LEGACY,
402 .chip = &i8259A_chip,
403 .mask_all = mask_8259A,
404 .restore_mask = unmask_8259A,
405 .init = init_8259A,
406 .irq_pending = i8259A_irq_pending,
407 .make_irq = make_8259A_irq,
408};
409
410struct legacy_pic *legacy_pic = &default_legacy_pic;
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index fce55d532631..ef257fc2921b 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -99,9 +99,6 @@ int vector_used_by_percpu_irq(unsigned int vector)
99 return 0; 99 return 0;
100} 100}
101 101
102/* Number of legacy interrupts */
103int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY;
104
105void __init init_ISA_irqs(void) 102void __init init_ISA_irqs(void)
106{ 103{
107 int i; 104 int i;
@@ -109,12 +106,12 @@ void __init init_ISA_irqs(void)
109#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC) 106#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
110 init_bsp_APIC(); 107 init_bsp_APIC();
111#endif 108#endif
112 init_8259A(0); 109 legacy_pic->init(0);
113 110
114 /* 111 /*
115 * 16 old-style INTA-cycle interrupts: 112 * 16 old-style INTA-cycle interrupts:
116 */ 113 */
117 for (i = 0; i < NR_IRQS_LEGACY; i++) { 114 for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) {
118 struct irq_desc *desc = irq_to_desc(i); 115 struct irq_desc *desc = irq_to_desc(i);
119 116
120 desc->status = IRQ_DISABLED; 117 desc->status = IRQ_DISABLED;
@@ -138,7 +135,7 @@ void __init init_IRQ(void)
138 * then this vector space can be freed and re-used dynamically as the 135 * then this vector space can be freed and re-used dynamically as the
139 * irq's migrate etc. 136 * irq's migrate etc.
140 */ 137 */
141 for (i = 0; i < nr_legacy_irqs; i++) 138 for (i = 0; i < legacy_pic->nr_legacy_irqs; i++)
142 per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i; 139 per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i;
143 140
144 x86_init.irqs.intr_init(); 141 x86_init.irqs.intr_init();
diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c
index 3b7078abc871..0aad8670858e 100644
--- a/arch/x86/kernel/mrst.c
+++ b/arch/x86/kernel/mrst.c
@@ -10,8 +10,211 @@
10 * of the License. 10 * of the License.
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/sfi.h>
15#include <linux/irq.h>
16#include <linux/module.h>
13 17
14#include <asm/setup.h> 18#include <asm/setup.h>
19#include <asm/mpspec_def.h>
20#include <asm/hw_irq.h>
21#include <asm/apic.h>
22#include <asm/io_apic.h>
23#include <asm/mrst.h>
24#include <asm/io.h>
25#include <asm/i8259.h>
26#include <asm/apb_timer.h>
27
28static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
29static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
30int sfi_mtimer_num;
31
32struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
33EXPORT_SYMBOL_GPL(sfi_mrtc_array);
34int sfi_mrtc_num;
35
36static inline void assign_to_mp_irq(struct mpc_intsrc *m,
37 struct mpc_intsrc *mp_irq)
38{
39 memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
40}
41
42static inline int mp_irq_cmp(struct mpc_intsrc *mp_irq,
43 struct mpc_intsrc *m)
44{
45 return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
46}
47
48static void save_mp_irq(struct mpc_intsrc *m)
49{
50 int i;
51
52 for (i = 0; i < mp_irq_entries; i++) {
53 if (!mp_irq_cmp(&mp_irqs[i], m))
54 return;
55 }
56
57 assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
58 if (++mp_irq_entries == MAX_IRQ_SOURCES)
59 panic("Max # of irq sources exceeded!!\n");
60}
61
62/* parse all the mtimer info to a static mtimer array */
63static int __init sfi_parse_mtmr(struct sfi_table_header *table)
64{
65 struct sfi_table_simple *sb;
66 struct sfi_timer_table_entry *pentry;
67 struct mpc_intsrc mp_irq;
68 int totallen;
69
70 sb = (struct sfi_table_simple *)table;
71 if (!sfi_mtimer_num) {
72 sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb,
73 struct sfi_timer_table_entry);
74 pentry = (struct sfi_timer_table_entry *) sb->pentry;
75 totallen = sfi_mtimer_num * sizeof(*pentry);
76 memcpy(sfi_mtimer_array, pentry, totallen);
77 }
78
79 printk(KERN_INFO "SFI: MTIMER info (num = %d):\n", sfi_mtimer_num);
80 pentry = sfi_mtimer_array;
81 for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
82 printk(KERN_INFO "timer[%d]: paddr = 0x%08x, freq = %dHz,"
83 " irq = %d\n", totallen, (u32)pentry->phys_addr,
84 pentry->freq_hz, pentry->irq);
85 if (!pentry->irq)
86 continue;
87 mp_irq.type = MP_IOAPIC;
88 mp_irq.irqtype = mp_INT;
89/* triggering mode edge bit 2-3, active high polarity bit 0-1 */
90 mp_irq.irqflag = 5;
91 mp_irq.srcbus = 0;
92 mp_irq.srcbusirq = pentry->irq; /* IRQ */
93 mp_irq.dstapic = MP_APIC_ALL;
94 mp_irq.dstirq = pentry->irq;
95 save_mp_irq(&mp_irq);
96 }
97
98 return 0;
99}
100
101struct sfi_timer_table_entry *sfi_get_mtmr(int hint)
102{
103 int i;
104 if (hint < sfi_mtimer_num) {
105 if (!sfi_mtimer_usage[hint]) {
106 pr_debug("hint taken for timer %d irq %d\n",\
107 hint, sfi_mtimer_array[hint].irq);
108 sfi_mtimer_usage[hint] = 1;
109 return &sfi_mtimer_array[hint];
110 }
111 }
112 /* take the first timer available */
113 for (i = 0; i < sfi_mtimer_num;) {
114 if (!sfi_mtimer_usage[i]) {
115 sfi_mtimer_usage[i] = 1;
116 return &sfi_mtimer_array[i];
117 }
118 i++;
119 }
120 return NULL;
121}
122
123void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr)
124{
125 int i;
126 for (i = 0; i < sfi_mtimer_num;) {
127 if (mtmr->irq == sfi_mtimer_array[i].irq) {
128 sfi_mtimer_usage[i] = 0;
129 return;
130 }
131 i++;
132 }
133}
134
135/* parse all the mrtc info to a global mrtc array */
136int __init sfi_parse_mrtc(struct sfi_table_header *table)
137{
138 struct sfi_table_simple *sb;
139 struct sfi_rtc_table_entry *pentry;
140 struct mpc_intsrc mp_irq;
141
142 int totallen;
143
144 sb = (struct sfi_table_simple *)table;
145 if (!sfi_mrtc_num) {
146 sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb,
147 struct sfi_rtc_table_entry);
148 pentry = (struct sfi_rtc_table_entry *)sb->pentry;
149 totallen = sfi_mrtc_num * sizeof(*pentry);
150 memcpy(sfi_mrtc_array, pentry, totallen);
151 }
152
153 printk(KERN_INFO "SFI: RTC info (num = %d):\n", sfi_mrtc_num);
154 pentry = sfi_mrtc_array;
155 for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
156 printk(KERN_INFO "RTC[%d]: paddr = 0x%08x, irq = %d\n",
157 totallen, (u32)pentry->phys_addr, pentry->irq);
158 mp_irq.type = MP_IOAPIC;
159 mp_irq.irqtype = mp_INT;
160 mp_irq.irqflag = 0;
161 mp_irq.srcbus = 0;
162 mp_irq.srcbusirq = pentry->irq; /* IRQ */
163 mp_irq.dstapic = MP_APIC_ALL;
164 mp_irq.dstirq = pentry->irq;
165 save_mp_irq(&mp_irq);
166 }
167 return 0;
168}
169
170/*
171 * the secondary clock in Moorestown can be APBT or LAPIC clock, default to
172 * APBT but cmdline option can also override it.
173 */
174static void __cpuinit mrst_setup_secondary_clock(void)
175{
176 /* restore default lapic clock if disabled by cmdline */
177 if (disable_apbt_percpu)
178 return setup_secondary_APIC_clock();
179 apbt_setup_secondary_clock();
180}
181
182static unsigned long __init mrst_calibrate_tsc(void)
183{
184 unsigned long flags, fast_calibrate;
185
186 local_irq_save(flags);
187 fast_calibrate = apbt_quick_calibrate();
188 local_irq_restore(flags);
189
190 if (fast_calibrate)
191 return fast_calibrate;
192
193 return 0;
194}
195
196void __init mrst_time_init(void)
197{
198 sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr);
199 pre_init_apic_IRQ0();
200 apbt_time_init();
201}
202
203void __init mrst_rtc_init(void)
204{
205 sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
206}
207
208/*
209 * if we use per cpu apb timer, the bootclock already setup. if we use lapic
210 * timer and one apbt timer for broadcast, we need to set up lapic boot clock.
211 */
212static void __init mrst_setup_boot_clock(void)
213{
214 pr_info("%s: per cpu apbt flag %d \n", __func__, disable_apbt_percpu);
215 if (disable_apbt_percpu)
216 setup_boot_APIC_clock();
217};
15 218
16/* 219/*
17 * Moorestown specific x86_init function overrides and early setup 220 * Moorestown specific x86_init function overrides and early setup
@@ -21,4 +224,17 @@ void __init x86_mrst_early_setup(void)
21{ 224{
22 x86_init.resources.probe_roms = x86_init_noop; 225 x86_init.resources.probe_roms = x86_init_noop;
23 x86_init.resources.reserve_resources = x86_init_noop; 226 x86_init.resources.reserve_resources = x86_init_noop;
227
228 x86_init.timers.timer_init = mrst_time_init;
229 x86_init.timers.setup_percpu_clockev = mrst_setup_boot_clock;
230
231 x86_init.irqs.pre_vector_init = x86_init_noop;
232
233 x86_cpuinit.setup_percpu_clockev = mrst_setup_secondary_clock;
234
235 x86_platform.calibrate_tsc = mrst_calibrate_tsc;
236 x86_init.pci.init = pci_mrst_init;
237 x86_init.pci.fixup_irqs = x86_init_noop;
238
239 legacy_pic = &null_legacy_pic;
24} 240}
diff --git a/arch/x86/kernel/olpc.c b/arch/x86/kernel/olpc.c
index 9d1d263f786f..8297160c41b3 100644
--- a/arch/x86/kernel/olpc.c
+++ b/arch/x86/kernel/olpc.c
@@ -17,7 +17,9 @@
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/string.h> 19#include <linux/string.h>
20
20#include <asm/geode.h> 21#include <asm/geode.h>
22#include <asm/setup.h>
21#include <asm/olpc.h> 23#include <asm/olpc.h>
22 24
23#ifdef CONFIG_OPEN_FIRMWARE 25#ifdef CONFIG_OPEN_FIRMWARE
@@ -243,9 +245,11 @@ static int __init olpc_init(void)
243 olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, 245 olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0,
244 (unsigned char *) &olpc_platform_info.ecver, 1); 246 (unsigned char *) &olpc_platform_info.ecver, 1);
245 247
246 /* check to see if the VSA exists */ 248#ifdef CONFIG_PCI_OLPC
247 if (cs5535_has_vsa2()) 249 /* If the VSA exists let it emulate PCI, if not emulate in kernel */
248 olpc_platform_info.flags |= OLPC_F_VSA; 250 if (!cs5535_has_vsa2())
251 x86_init.pci.arch_init = pci_olpc_init;
252#endif
249 253
250 printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n", 254 printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n",
251 ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "", 255 ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "",
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a435c76d714e..a02e80c3c54b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -48,6 +48,7 @@
48#include <linux/err.h> 48#include <linux/err.h>
49#include <linux/nmi.h> 49#include <linux/nmi.h>
50#include <linux/tboot.h> 50#include <linux/tboot.h>
51#include <linux/stackprotector.h>
51 52
52#include <asm/acpi.h> 53#include <asm/acpi.h>
53#include <asm/desc.h> 54#include <asm/desc.h>
@@ -67,6 +68,7 @@
67#include <linux/mc146818rtc.h> 68#include <linux/mc146818rtc.h>
68 69
69#include <asm/smpboot_hooks.h> 70#include <asm/smpboot_hooks.h>
71#include <asm/i8259.h>
70 72
71#ifdef CONFIG_X86_32 73#ifdef CONFIG_X86_32
72u8 apicid_2_node[MAX_APICID]; 74u8 apicid_2_node[MAX_APICID];
@@ -291,9 +293,9 @@ notrace static void __cpuinit start_secondary(void *unused)
291 check_tsc_sync_target(); 293 check_tsc_sync_target();
292 294
293 if (nmi_watchdog == NMI_IO_APIC) { 295 if (nmi_watchdog == NMI_IO_APIC) {
294 disable_8259A_irq(0); 296 legacy_pic->chip->mask(0);
295 enable_NMI_through_LVT0(); 297 enable_NMI_through_LVT0();
296 enable_8259A_irq(0); 298 legacy_pic->chip->unmask(0);
297 } 299 }
298 300
299#ifdef CONFIG_X86_32 301#ifdef CONFIG_X86_32
@@ -329,6 +331,9 @@ notrace static void __cpuinit start_secondary(void *unused)
329 /* enable local interrupts */ 331 /* enable local interrupts */
330 local_irq_enable(); 332 local_irq_enable();
331 333
334 /* to prevent fake stack check failure in clock setup */
335 boot_init_stack_canary();
336
332 x86_cpuinit.setup_percpu_clockev(); 337 x86_cpuinit.setup_percpu_clockev();
333 338
334 wmb(); 339 wmb();
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index ab38ce0984fa..e680ea52db9b 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -49,11 +49,6 @@ extern int no_broadcast;
49char visws_board_type = -1; 49char visws_board_type = -1;
50char visws_board_rev = -1; 50char visws_board_rev = -1;
51 51
52int is_visws_box(void)
53{
54 return visws_board_type >= 0;
55}
56
57static void __init visws_time_init(void) 52static void __init visws_time_init(void)
58{ 53{
59 printk(KERN_INFO "Starting Cobalt Timer system clock\n"); 54 printk(KERN_INFO "Starting Cobalt Timer system clock\n");
@@ -242,6 +237,8 @@ void __init visws_early_detect(void)
242 x86_init.irqs.pre_vector_init = visws_pre_intr_init; 237 x86_init.irqs.pre_vector_init = visws_pre_intr_init;
243 x86_init.irqs.trap_init = visws_trap_init; 238 x86_init.irqs.trap_init = visws_trap_init;
244 x86_init.timers.timer_init = visws_time_init; 239 x86_init.timers.timer_init = visws_time_init;
240 x86_init.pci.init = pci_visws_init;
241 x86_init.pci.init_irq = x86_init_noop;
245 242
246 /* 243 /*
247 * Install reboot quirks: 244 * Install reboot quirks:
@@ -508,7 +505,7 @@ static struct irq_chip cobalt_irq_type = {
508 */ 505 */
509static unsigned int startup_piix4_master_irq(unsigned int irq) 506static unsigned int startup_piix4_master_irq(unsigned int irq)
510{ 507{
511 init_8259A(0); 508 legacy_pic->init(0);
512 509
513 return startup_cobalt_irq(irq); 510 return startup_cobalt_irq(irq);
514} 511}
@@ -532,9 +529,6 @@ static struct irq_chip piix4_master_irq_type = {
532 529
533static struct irq_chip piix4_virtual_irq_type = { 530static struct irq_chip piix4_virtual_irq_type = {
534 .name = "PIIX4-virtual", 531 .name = "PIIX4-virtual",
535 .shutdown = disable_8259A_irq,
536 .enable = enable_8259A_irq,
537 .disable = disable_8259A_irq,
538}; 532};
539 533
540 534
@@ -609,7 +603,7 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id)
609 handle_IRQ_event(realirq, desc->action); 603 handle_IRQ_event(realirq, desc->action);
610 604
611 if (!(desc->status & IRQ_DISABLED)) 605 if (!(desc->status & IRQ_DISABLED))
612 enable_8259A_irq(realirq); 606 legacy_pic->chip->unmask(realirq);
613 607
614 return IRQ_HANDLED; 608 return IRQ_HANDLED;
615 609
@@ -628,6 +622,12 @@ static struct irqaction cascade_action = {
628 .name = "cascade", 622 .name = "cascade",
629}; 623};
630 624
625static inline void set_piix4_virtual_irq_type(void)
626{
627 piix4_virtual_irq_type.shutdown = i8259A_chip.mask;
628 piix4_virtual_irq_type.enable = i8259A_chip.unmask;
629 piix4_virtual_irq_type.disable = i8259A_chip.mask;
630}
631 631
632void init_VISWS_APIC_irqs(void) 632void init_VISWS_APIC_irqs(void)
633{ 633{
@@ -653,6 +653,7 @@ void init_VISWS_APIC_irqs(void)
653 desc->chip = &piix4_master_irq_type; 653 desc->chip = &piix4_master_irq_type;
654 } 654 }
655 else if (i < CO_IRQ_APIC0) { 655 else if (i < CO_IRQ_APIC0) {
656 set_piix4_virtual_irq_type();
656 desc->chip = &piix4_virtual_irq_type; 657 desc->chip = &piix4_virtual_irq_type;
657 } 658 }
658 else if (IS_CO_APIC(i)) { 659 else if (IS_CO_APIC(i)) {
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index ee5746c94628..61a1e8c7e19f 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -4,9 +4,11 @@
4 * For licencing details see kernel-base/COPYING 4 * For licencing details see kernel-base/COPYING
5 */ 5 */
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/ioport.h>
7 8
8#include <asm/bios_ebda.h> 9#include <asm/bios_ebda.h>
9#include <asm/paravirt.h> 10#include <asm/paravirt.h>
11#include <asm/pci_x86.h>
10#include <asm/mpspec.h> 12#include <asm/mpspec.h>
11#include <asm/setup.h> 13#include <asm/setup.h>
12#include <asm/apic.h> 14#include <asm/apic.h>
@@ -70,6 +72,12 @@ struct x86_init_ops x86_init __initdata = {
70 .iommu = { 72 .iommu = {
71 .iommu_init = iommu_init_noop, 73 .iommu_init = iommu_init_noop,
72 }, 74 },
75
76 .pci = {
77 .init = x86_default_pci_init,
78 .init_irq = x86_default_pci_init_irq,
79 .fixup_irqs = x86_default_pci_fixup_irqs,
80 },
73}; 81};
74 82
75struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = { 83struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 0b7d3e9593e1..b110d97fb925 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_X86_VISWS) += visws.o
13 13
14obj-$(CONFIG_X86_NUMAQ) += numaq_32.o 14obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
15 15
16obj-$(CONFIG_X86_MRST) += mrst.o
17
16obj-y += common.o early.o 18obj-y += common.o early.o
17obj-y += amd_bus.o bus_numa.o 19obj-y += amd_bus.o bus_numa.o
18 20
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 5f11ff6f5389..6e22454bfaa6 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -298,17 +298,14 @@ int __init pci_acpi_init(void)
298{ 298{
299 struct pci_dev *dev = NULL; 299 struct pci_dev *dev = NULL;
300 300
301 if (pcibios_scanned)
302 return 0;
303
304 if (acpi_noirq) 301 if (acpi_noirq)
305 return 0; 302 return -ENODEV;
306 303
307 printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); 304 printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
308 acpi_irq_penalty_init(); 305 acpi_irq_penalty_init();
309 pcibios_scanned++;
310 pcibios_enable_irq = acpi_pci_irq_enable; 306 pcibios_enable_irq = acpi_pci_irq_enable;
311 pcibios_disable_irq = acpi_pci_irq_disable; 307 pcibios_disable_irq = acpi_pci_irq_disable;
308 x86_init.pci.init_irq = x86_init_noop;
312 309
313 if (pci_routeirq) { 310 if (pci_routeirq) {
314 /* 311 /*
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 3736176acaab..294e10cb11e1 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -72,12 +72,6 @@ struct pci_ops pci_root_ops = {
72}; 72};
73 73
74/* 74/*
75 * legacy, numa, and acpi all want to call pcibios_scan_root
76 * from their initcalls. This flag prevents that.
77 */
78int pcibios_scanned;
79
80/*
81 * This interrupt-safe spinlock protects all accesses to PCI 75 * This interrupt-safe spinlock protects all accesses to PCI
82 * configuration space. 76 * configuration space.
83 */ 77 */
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index 25a1f8efed4a..adb62aaa7ecd 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -1,6 +1,7 @@
1#include <linux/pci.h> 1#include <linux/pci.h>
2#include <linux/init.h> 2#include <linux/init.h>
3#include <asm/pci_x86.h> 3#include <asm/pci_x86.h>
4#include <asm/x86_init.h>
4 5
5/* arch_initcall has too random ordering, so call the initializers 6/* arch_initcall has too random ordering, so call the initializers
6 in the right sequence from here. */ 7 in the right sequence from here. */
@@ -15,10 +16,9 @@ static __init int pci_arch_init(void)
15 if (!(pci_probe & PCI_PROBE_NOEARLY)) 16 if (!(pci_probe & PCI_PROBE_NOEARLY))
16 pci_mmcfg_early_init(); 17 pci_mmcfg_early_init();
17 18
18#ifdef CONFIG_PCI_OLPC 19 if (x86_init.pci.arch_init && !x86_init.pci.arch_init())
19 if (!pci_olpc_init()) 20 return 0;
20 return 0; /* skip additional checks if it's an XO */ 21
21#endif
22#ifdef CONFIG_PCI_BIOS 22#ifdef CONFIG_PCI_BIOS
23 pci_pcbios_init(); 23 pci_pcbios_init();
24#endif 24#endif
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index b02f6d8ac922..8b107521d24e 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -53,7 +53,7 @@ struct irq_router_handler {
53 int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); 53 int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
54}; 54};
55 55
56int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; 56int (*pcibios_enable_irq)(struct pci_dev *dev) = pirq_enable_irq;
57void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL; 57void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
58 58
59/* 59/*
@@ -1018,7 +1018,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
1018 return 1; 1018 return 1;
1019} 1019}
1020 1020
1021static void __init pcibios_fixup_irqs(void) 1021void __init pcibios_fixup_irqs(void)
1022{ 1022{
1023 struct pci_dev *dev = NULL; 1023 struct pci_dev *dev = NULL;
1024 u8 pin; 1024 u8 pin;
@@ -1112,12 +1112,12 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = {
1112 { } 1112 { }
1113}; 1113};
1114 1114
1115int __init pcibios_irq_init(void) 1115void __init pcibios_irq_init(void)
1116{ 1116{
1117 DBG(KERN_DEBUG "PCI: IRQ init\n"); 1117 DBG(KERN_DEBUG "PCI: IRQ init\n");
1118 1118
1119 if (pcibios_enable_irq || raw_pci_ops == NULL) 1119 if (raw_pci_ops == NULL)
1120 return 0; 1120 return;
1121 1121
1122 dmi_check_system(pciirq_dmi_table); 1122 dmi_check_system(pciirq_dmi_table);
1123 1123
@@ -1144,9 +1144,7 @@ int __init pcibios_irq_init(void)
1144 pirq_table = NULL; 1144 pirq_table = NULL;
1145 } 1145 }
1146 1146
1147 pcibios_enable_irq = pirq_enable_irq; 1147 x86_init.pci.fixup_irqs();
1148
1149 pcibios_fixup_irqs();
1150 1148
1151 if (io_apic_assign_pci_irqs && pci_routeirq) { 1149 if (io_apic_assign_pci_irqs && pci_routeirq) {
1152 struct pci_dev *dev = NULL; 1150 struct pci_dev *dev = NULL;
@@ -1159,8 +1157,6 @@ int __init pcibios_irq_init(void)
1159 for_each_pci_dev(dev) 1157 for_each_pci_dev(dev)
1160 pirq_enable_irq(dev); 1158 pirq_enable_irq(dev);
1161 } 1159 }
1162
1163 return 0;
1164} 1160}
1165 1161
1166static void pirq_penalize_isa_irq(int irq, int active) 1162static void pirq_penalize_isa_irq(int irq, int active)
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 4061bb0f267d..0db5eaf54560 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -35,16 +35,13 @@ static void __devinit pcibios_fixup_peer_bridges(void)
35 } 35 }
36} 36}
37 37
38static int __init pci_legacy_init(void) 38int __init pci_legacy_init(void)
39{ 39{
40 if (!raw_pci_ops) { 40 if (!raw_pci_ops) {
41 printk("PCI: System does not support PCI\n"); 41 printk("PCI: System does not support PCI\n");
42 return 0; 42 return 0;
43 } 43 }
44 44
45 if (pcibios_scanned++)
46 return 0;
47
48 printk("PCI: Probing PCI hardware\n"); 45 printk("PCI: Probing PCI hardware\n");
49 pci_root_bus = pcibios_scan_root(0); 46 pci_root_bus = pcibios_scan_root(0);
50 if (pci_root_bus) 47 if (pci_root_bus)
@@ -55,18 +52,15 @@ static int __init pci_legacy_init(void)
55 52
56int __init pci_subsys_init(void) 53int __init pci_subsys_init(void)
57{ 54{
58#ifdef CONFIG_X86_NUMAQ 55 /*
59 pci_numaq_init(); 56 * The init function returns an non zero value when
60#endif 57 * pci_legacy_init should be invoked.
61#ifdef CONFIG_ACPI 58 */
62 pci_acpi_init(); 59 if (x86_init.pci.init())
63#endif 60 pci_legacy_init();
64#ifdef CONFIG_X86_VISWS 61
65 pci_visws_init();
66#endif
67 pci_legacy_init();
68 pcibios_fixup_peer_bridges(); 62 pcibios_fixup_peer_bridges();
69 pcibios_irq_init(); 63 x86_init.pci.init_irq();
70 pcibios_init(); 64 pcibios_init();
71 65
72 return 0; 66 return 0;
diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c
new file mode 100644
index 000000000000..8bf2fcb88d04
--- /dev/null
+++ b/arch/x86/pci/mrst.c
@@ -0,0 +1,262 @@
1/*
2 * Moorestown PCI support
3 * Copyright (c) 2008 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Moorestown has an interesting PCI implementation:
7 * - configuration space is memory mapped (as defined by MCFG)
8 * - Lincroft devices also have a real, type 1 configuration space
9 * - Early Lincroft silicon has a type 1 access bug that will cause
10 * a hang if non-existent devices are accessed
11 * - some devices have the "fixed BAR" capability, which means
12 * they can't be relocated or modified; check for that during
13 * BAR sizing
14 *
15 * So, we use the MCFG space for all reads and writes, but also send
16 * Lincroft writes to type 1 space. But only read/write if the device
17 * actually exists, otherwise return all 1s for reads and bit bucket
18 * the writes.
19 */
20
21#include <linux/sched.h>
22#include <linux/pci.h>
23#include <linux/ioport.h>
24#include <linux/init.h>
25#include <linux/dmi.h>
26
27#include <asm/acpi.h>
28#include <asm/segment.h>
29#include <asm/io.h>
30#include <asm/smp.h>
31#include <asm/pci_x86.h>
32#include <asm/hw_irq.h>
33#include <asm/io_apic.h>
34
35#define PCIE_CAP_OFFSET 0x100
36
37/* Fixed BAR fields */
38#define PCIE_VNDR_CAP_ID_FIXED_BAR 0x00 /* Fixed BAR (TBD) */
39#define PCI_FIXED_BAR_0_SIZE 0x04
40#define PCI_FIXED_BAR_1_SIZE 0x08
41#define PCI_FIXED_BAR_2_SIZE 0x0c
42#define PCI_FIXED_BAR_3_SIZE 0x10
43#define PCI_FIXED_BAR_4_SIZE 0x14
44#define PCI_FIXED_BAR_5_SIZE 0x1c
45
46/**
47 * fixed_bar_cap - return the offset of the fixed BAR cap if found
48 * @bus: PCI bus
49 * @devfn: device in question
50 *
51 * Look for the fixed BAR cap on @bus and @devfn, returning its offset
52 * if found or 0 otherwise.
53 */
54static int fixed_bar_cap(struct pci_bus *bus, unsigned int devfn)
55{
56 int pos;
57 u32 pcie_cap = 0, cap_data;
58
59 pos = PCIE_CAP_OFFSET;
60
61 if (!raw_pci_ext_ops)
62 return 0;
63
64 while (pos) {
65 if (raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
66 devfn, pos, 4, &pcie_cap))
67 return 0;
68
69 if (pcie_cap == 0xffffffff)
70 return 0;
71
72 if (PCI_EXT_CAP_ID(pcie_cap) == PCI_EXT_CAP_ID_VNDR) {
73 raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
74 devfn, pos + 4, 4, &cap_data);
75 if ((cap_data & 0xffff) == PCIE_VNDR_CAP_ID_FIXED_BAR)
76 return pos;
77 }
78
79 pos = pcie_cap >> 20;
80 }
81
82 return 0;
83}
84
85static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
86 int reg, int len, u32 val, int offset)
87{
88 u32 size;
89 unsigned int domain, busnum;
90 int bar = (reg - PCI_BASE_ADDRESS_0) >> 2;
91
92 domain = pci_domain_nr(bus);
93 busnum = bus->number;
94
95 if (val == ~0 && len == 4) {
96 unsigned long decode;
97
98 raw_pci_ext_ops->read(domain, busnum, devfn,
99 offset + 8 + (bar * 4), 4, &size);
100
101 /* Turn the size into a decode pattern for the sizing code */
102 if (size) {
103 decode = size - 1;
104 decode |= decode >> 1;
105 decode |= decode >> 2;
106 decode |= decode >> 4;
107 decode |= decode >> 8;
108 decode |= decode >> 16;
109 decode++;
110 decode = ~(decode - 1);
111 } else {
112 decode = ~0;
113 }
114
115 /*
116 * If val is all ones, the core code is trying to size the reg,
117 * so update the mmconfig space with the real size.
118 *
119 * Note: this assumes the fixed size we got is a power of two.
120 */
121 return raw_pci_ext_ops->write(domain, busnum, devfn, reg, 4,
122 decode);
123 }
124
125 /* This is some other kind of BAR write, so just do it. */
126 return raw_pci_ext_ops->write(domain, busnum, devfn, reg, len, val);
127}
128
129/**
130 * type1_access_ok - check whether to use type 1
131 * @bus: bus number
132 * @devfn: device & function in question
133 *
134 * If the bus is on a Lincroft chip and it exists, or is not on a Lincroft at
135 * all, the we can go ahead with any reads & writes. If it's on a Lincroft,
136 * but doesn't exist, avoid the access altogether to keep the chip from
137 * hanging.
138 */
139static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
140{
141 /* This is a workaround for A0 LNC bug where PCI status register does
142 * not have new CAP bit set. can not be written by SW either.
143 *
144 * PCI header type in real LNC indicates a single function device, this
145 * will prevent probing other devices under the same function in PCI
146 * shim. Therefore, use the header type in shim instead.
147 */
148 if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
149 return 0;
150 if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0)))
151 return 1;
152 return 0; /* langwell on others */
153}
154
155static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
156 int size, u32 *value)
157{
158 if (type1_access_ok(bus->number, devfn, where))
159 return pci_direct_conf1.read(pci_domain_nr(bus), bus->number,
160 devfn, where, size, value);
161 return raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
162 devfn, where, size, value);
163}
164
165static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
166 int size, u32 value)
167{
168 int offset;
169
170 /* On MRST, there is no PCI ROM BAR, this will cause a subsequent read
171 * to ROM BAR return 0 then being ignored.
172 */
173 if (where == PCI_ROM_ADDRESS)
174 return 0;
175
176 /*
177 * Devices with fixed BARs need special handling:
178 * - BAR sizing code will save, write ~0, read size, restore
179 * - so writes to fixed BARs need special handling
180 * - other writes to fixed BAR devices should go through mmconfig
181 */
182 offset = fixed_bar_cap(bus, devfn);
183 if (offset &&
184 (where >= PCI_BASE_ADDRESS_0 && where <= PCI_BASE_ADDRESS_5)) {
185 return pci_device_update_fixed(bus, devfn, where, size, value,
186 offset);
187 }
188
189 /*
190 * On Moorestown update both real & mmconfig space
191 * Note: early Lincroft silicon can't handle type 1 accesses to
192 * non-existent devices, so just eat the write in that case.
193 */
194 if (type1_access_ok(bus->number, devfn, where))
195 return pci_direct_conf1.write(pci_domain_nr(bus), bus->number,
196 devfn, where, size, value);
197 return raw_pci_ext_ops->write(pci_domain_nr(bus), bus->number, devfn,
198 where, size, value);
199}
200
201static int mrst_pci_irq_enable(struct pci_dev *dev)
202{
203 u8 pin;
204 struct io_apic_irq_attr irq_attr;
205
206 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
207
208 /* MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to
209 * IOAPIC RTE entries, so we just enable RTE for the device.
210 */
211 irq_attr.ioapic = mp_find_ioapic(dev->irq);
212 irq_attr.ioapic_pin = dev->irq;
213 irq_attr.trigger = 1; /* level */
214 irq_attr.polarity = 1; /* active low */
215 io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
216
217 return 0;
218}
219
220struct pci_ops pci_mrst_ops = {
221 .read = pci_read,
222 .write = pci_write,
223};
224
225/**
226 * pci_mrst_init - installs pci_mrst_ops
227 *
228 * Moorestown has an interesting PCI implementation (see above).
229 * Called when the early platform detection installs it.
230 */
231int __init pci_mrst_init(void)
232{
233 printk(KERN_INFO "Moorestown platform detected, using MRST PCI ops\n");
234 pci_mmcfg_late_init();
235 pcibios_enable_irq = mrst_pci_irq_enable;
236 pci_root_ops = pci_mrst_ops;
237 /* Continue with standard init */
238 return 1;
239}
240
241/*
242 * Langwell devices reside at fixed offsets, don't try to move them.
243 */
244static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
245{
246 unsigned long offset;
247 u32 size;
248 int i;
249
250 /* Fixup the BAR sizes for fixed BAR devices and make them unmoveable */
251 offset = fixed_bar_cap(dev->bus, dev->devfn);
252 if (!offset || PCI_DEVFN(2, 0) == dev->devfn ||
253 PCI_DEVFN(2, 2) == dev->devfn)
254 return;
255
256 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
257 pci_read_config_dword(dev, offset + 8 + (i * 4), &size);
258 dev->resource[i].end = dev->resource[i].start + size - 1;
259 dev->resource[i].flags |= IORESOURCE_PCI_FIXED;
260 }
261}
262DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixed_bar_fixup);
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c
index 8884a1c1ada6..8223738ad806 100644
--- a/arch/x86/pci/numaq_32.c
+++ b/arch/x86/pci/numaq_32.c
@@ -148,14 +148,8 @@ int __init pci_numaq_init(void)
148{ 148{
149 int quad; 149 int quad;
150 150
151 if (!found_numaq)
152 return 0;
153
154 raw_pci_ops = &pci_direct_conf1_mq; 151 raw_pci_ops = &pci_direct_conf1_mq;
155 152
156 if (pcibios_scanned++)
157 return 0;
158
159 pci_root_bus = pcibios_scan_root(0); 153 pci_root_bus = pcibios_scan_root(0);
160 if (pci_root_bus) 154 if (pci_root_bus)
161 pci_bus_add_devices(pci_root_bus); 155 pci_bus_add_devices(pci_root_bus);
diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c
index b889d824f7c6..b34815408f58 100644
--- a/arch/x86/pci/olpc.c
+++ b/arch/x86/pci/olpc.c
@@ -304,9 +304,6 @@ static struct pci_raw_ops pci_olpc_conf = {
304 304
305int __init pci_olpc_init(void) 305int __init pci_olpc_init(void)
306{ 306{
307 if (!machine_is_olpc() || olpc_has_vsa())
308 return -ENODEV;
309
310 printk(KERN_INFO "PCI: Using configuration type OLPC\n"); 307 printk(KERN_INFO "PCI: Using configuration type OLPC\n");
311 raw_pci_ops = &pci_olpc_conf; 308 raw_pci_ops = &pci_olpc_conf;
312 is_lx = is_geode_lx(); 309 is_lx = is_geode_lx();
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c
index bcead7a46871..03008f72eb04 100644
--- a/arch/x86/pci/visws.c
+++ b/arch/x86/pci/visws.c
@@ -69,9 +69,6 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
69 69
70int __init pci_visws_init(void) 70int __init pci_visws_init(void)
71{ 71{
72 if (!is_visws_box())
73 return -1;
74
75 pcibios_enable_irq = &pci_visws_enable_irq; 72 pcibios_enable_irq = &pci_visws_enable_irq;
76 pcibios_disable_irq = &pci_visws_disable_irq; 73 pcibios_disable_irq = &pci_visws_disable_irq;
77 74
@@ -90,5 +87,6 @@ int __init pci_visws_init(void)
90 pci_scan_bus_with_sysdata(pci_bus1); 87 pci_scan_bus_with_sysdata(pci_bus1);
91 pci_fixup_irqs(pci_common_swizzle, visws_map_irq); 88 pci_fixup_irqs(pci_common_swizzle, visws_map_irq);
92 pcibios_resource_survey(); 89 pcibios_resource_survey();
93 return 0; 90 /* Request bus scan */
91 return 1;
94} 92}
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 368ae6d3a096..a2b902f4d437 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -96,8 +96,6 @@ source "drivers/edac/Kconfig"
96 96
97source "drivers/rtc/Kconfig" 97source "drivers/rtc/Kconfig"
98 98
99source "drivers/clocksource/Kconfig"
100
101source "drivers/dma/Kconfig" 99source "drivers/dma/Kconfig"
102 100
103source "drivers/dca/Kconfig" 101source "drivers/dca/Kconfig"
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9863c98c81ba..e9b7b402dbfb 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -123,6 +123,8 @@ static const struct file_operations acpi_processor_info_fops = {
123#endif 123#endif
124 124
125DEFINE_PER_CPU(struct acpi_processor *, processors); 125DEFINE_PER_CPU(struct acpi_processor *, processors);
126EXPORT_PER_CPU_SYMBOL(processors);
127
126struct acpi_processor_errata errata __read_mostly; 128struct acpi_processor_errata errata __read_mostly;
127 129
128/* -------------------------------------------------------------------------- 130/* --------------------------------------------------------------------------
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 3ce3519e8f30..89de75325cea 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,6 +1,7 @@
1obj-$(CONFIG_PM) += sysfs.o 1obj-$(CONFIG_PM) += sysfs.o
2obj-$(CONFIG_PM_SLEEP) += main.o 2obj-$(CONFIG_PM_SLEEP) += main.o
3obj-$(CONFIG_PM_RUNTIME) += runtime.o 3obj-$(CONFIG_PM_RUNTIME) += runtime.o
4obj-$(CONFIG_PM_OPS) += generic_ops.o
4obj-$(CONFIG_PM_TRACE_RTC) += trace.o 5obj-$(CONFIG_PM_TRACE_RTC) += trace.o
5 6
6ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG 7ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
new file mode 100644
index 000000000000..4b29d4981253
--- /dev/null
+++ b/drivers/base/power/generic_ops.c
@@ -0,0 +1,233 @@
1/*
2 * drivers/base/power/generic_ops.c - Generic PM callbacks for subsystems
3 *
4 * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
5 *
6 * This file is released under the GPLv2.
7 */
8
9#include <linux/pm.h>
10#include <linux/pm_runtime.h>
11
12#ifdef CONFIG_PM_RUNTIME
13/**
14 * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
15 * @dev: Device to handle.
16 *
17 * If PM operations are defined for the @dev's driver and they include
18 * ->runtime_idle(), execute it and return its error code, if nonzero.
19 * Otherwise, execute pm_runtime_suspend() for the device and return 0.
20 */
21int pm_generic_runtime_idle(struct device *dev)
22{
23 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
24
25 if (pm && pm->runtime_idle) {
26 int ret = pm->runtime_idle(dev);
27 if (ret)
28 return ret;
29 }
30
31 pm_runtime_suspend(dev);
32 return 0;
33}
34EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
35
36/**
37 * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
38 * @dev: Device to suspend.
39 *
40 * If PM operations are defined for the @dev's driver and they include
41 * ->runtime_suspend(), execute it and return its error code. Otherwise,
42 * return -EINVAL.
43 */
44int pm_generic_runtime_suspend(struct device *dev)
45{
46 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
47 int ret;
48
49 ret = pm && pm->runtime_suspend ? pm->runtime_suspend(dev) : -EINVAL;
50
51 return ret;
52}
53EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend);
54
55/**
56 * pm_generic_runtime_resume - Generic runtime resume callback for subsystems.
57 * @dev: Device to resume.
58 *
59 * If PM operations are defined for the @dev's driver and they include
60 * ->runtime_resume(), execute it and return its error code. Otherwise,
61 * return -EINVAL.
62 */
63int pm_generic_runtime_resume(struct device *dev)
64{
65 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
66 int ret;
67
68 ret = pm && pm->runtime_resume ? pm->runtime_resume(dev) : -EINVAL;
69
70 return ret;
71}
72EXPORT_SYMBOL_GPL(pm_generic_runtime_resume);
73#endif /* CONFIG_PM_RUNTIME */
74
75#ifdef CONFIG_PM_SLEEP
76/**
77 * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback.
78 * @dev: Device to handle.
79 * @event: PM transition of the system under way.
80 *
81 * If the device has not been suspended at run time, execute the
82 * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and
83 * return its error code. Otherwise, return zero.
84 */
85static int __pm_generic_call(struct device *dev, int event)
86{
87 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
88 int (*callback)(struct device *);
89
90 if (!pm || pm_runtime_suspended(dev))
91 return 0;
92
93 switch (event) {
94 case PM_EVENT_SUSPEND:
95 callback = pm->suspend;
96 break;
97 case PM_EVENT_FREEZE:
98 callback = pm->freeze;
99 break;
100 case PM_EVENT_HIBERNATE:
101 callback = pm->poweroff;
102 break;
103 case PM_EVENT_THAW:
104 callback = pm->thaw;
105 break;
106 default:
107 callback = NULL;
108 break;
109 }
110
111 return callback ? callback(dev) : 0;
112}
113
114/**
115 * pm_generic_suspend - Generic suspend callback for subsystems.
116 * @dev: Device to suspend.
117 */
118int pm_generic_suspend(struct device *dev)
119{
120 return __pm_generic_call(dev, PM_EVENT_SUSPEND);
121}
122EXPORT_SYMBOL_GPL(pm_generic_suspend);
123
124/**
125 * pm_generic_freeze - Generic freeze callback for subsystems.
126 * @dev: Device to freeze.
127 */
128int pm_generic_freeze(struct device *dev)
129{
130 return __pm_generic_call(dev, PM_EVENT_FREEZE);
131}
132EXPORT_SYMBOL_GPL(pm_generic_freeze);
133
134/**
135 * pm_generic_poweroff - Generic poweroff callback for subsystems.
136 * @dev: Device to handle.
137 */
138int pm_generic_poweroff(struct device *dev)
139{
140 return __pm_generic_call(dev, PM_EVENT_HIBERNATE);
141}
142EXPORT_SYMBOL_GPL(pm_generic_poweroff);
143
144/**
145 * pm_generic_thaw - Generic thaw callback for subsystems.
146 * @dev: Device to thaw.
147 */
148int pm_generic_thaw(struct device *dev)
149{
150 return __pm_generic_call(dev, PM_EVENT_THAW);
151}
152EXPORT_SYMBOL_GPL(pm_generic_thaw);
153
154/**
155 * __pm_generic_resume - Generic resume/restore callback for subsystems.
156 * @dev: Device to handle.
157 * @event: PM transition of the system under way.
158 *
159 * Execute the resume/resotre callback provided by the @dev's driver, if
160 * defined. If it returns 0, change the device's runtime PM status to 'active'.
161 * Return the callback's error code.
162 */
163static int __pm_generic_resume(struct device *dev, int event)
164{
165 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
166 int (*callback)(struct device *);
167 int ret;
168
169 if (!pm)
170 return 0;
171
172 switch (event) {
173 case PM_EVENT_RESUME:
174 callback = pm->resume;
175 break;
176 case PM_EVENT_RESTORE:
177 callback = pm->restore;
178 break;
179 default:
180 callback = NULL;
181 break;
182 }
183
184 if (!callback)
185 return 0;
186
187 ret = callback(dev);
188 if (!ret) {
189 pm_runtime_disable(dev);
190 pm_runtime_set_active(dev);
191 pm_runtime_enable(dev);
192 }
193
194 return ret;
195}
196
197/**
198 * pm_generic_resume - Generic resume callback for subsystems.
199 * @dev: Device to resume.
200 */
201int pm_generic_resume(struct device *dev)
202{
203 return __pm_generic_resume(dev, PM_EVENT_RESUME);
204}
205EXPORT_SYMBOL_GPL(pm_generic_resume);
206
207/**
208 * pm_generic_restore - Generic restore callback for subsystems.
209 * @dev: Device to restore.
210 */
211int pm_generic_restore(struct device *dev)
212{
213 return __pm_generic_resume(dev, PM_EVENT_RESTORE);
214}
215EXPORT_SYMBOL_GPL(pm_generic_restore);
216#endif /* CONFIG_PM_SLEEP */
217
218struct dev_pm_ops generic_subsys_pm_ops = {
219#ifdef CONFIG_PM_SLEEP
220 .suspend = pm_generic_suspend,
221 .resume = pm_generic_resume,
222 .freeze = pm_generic_freeze,
223 .thaw = pm_generic_thaw,
224 .poweroff = pm_generic_poweroff,
225 .restore = pm_generic_restore,
226#endif
227#ifdef CONFIG_PM_RUNTIME
228 .runtime_suspend = pm_generic_runtime_suspend,
229 .runtime_resume = pm_generic_runtime_resume,
230 .runtime_idle = pm_generic_runtime_idle,
231#endif
232};
233EXPORT_SYMBOL_GPL(generic_subsys_pm_ops);
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index 21681a81cc35..37b0542a4eeb 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -139,6 +139,8 @@ struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
139 * 139 *
140 * This function allocates a new struct iucv_tty_buffer element and, optionally, 140 * This function allocates a new struct iucv_tty_buffer element and, optionally,
141 * allocates an internal data buffer with the specified size @size. 141 * allocates an internal data buffer with the specified size @size.
142 * The internal data buffer is always allocated with GFP_DMA which is
143 * required for receiving and sending data with IUCV.
142 * Note: The total message size arises from the internal buffer size and the 144 * Note: The total message size arises from the internal buffer size and the
143 * members of the iucv_tty_msg structure. 145 * members of the iucv_tty_msg structure.
144 * The function returns NULL if memory allocation has failed. 146 * The function returns NULL if memory allocation has failed.
@@ -154,7 +156,7 @@ static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
154 156
155 if (size > 0) { 157 if (size > 0) {
156 bufp->msg.length = MSG_SIZE(size); 158 bufp->msg.length = MSG_SIZE(size);
157 bufp->mbuf = kmalloc(bufp->msg.length, flags); 159 bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA);
158 if (!bufp->mbuf) { 160 if (!bufp->mbuf) {
159 mempool_free(bufp, hvc_iucv_mempool); 161 mempool_free(bufp, hvc_iucv_mempool);
160 return NULL; 162 return NULL;
@@ -237,7 +239,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv,
237 if (!rb->mbuf) { /* message not yet received ... */ 239 if (!rb->mbuf) { /* message not yet received ... */
238 /* allocate mem to store msg data; if no memory is available 240 /* allocate mem to store msg data; if no memory is available
239 * then leave the buffer on the list and re-try later */ 241 * then leave the buffer on the list and re-try later */
240 rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC); 242 rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA);
241 if (!rb->mbuf) 243 if (!rb->mbuf)
242 return -ENOMEM; 244 return -ENOMEM;
243 245
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 213373b5f17f..f404ccfc9c20 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -379,7 +379,7 @@ static ssize_t send_control_msg(struct port *port, unsigned int event,
379 struct scatterlist sg[1]; 379 struct scatterlist sg[1];
380 struct virtio_console_control cpkt; 380 struct virtio_console_control cpkt;
381 struct virtqueue *vq; 381 struct virtqueue *vq;
382 int len; 382 unsigned int len;
383 383
384 if (!use_multiport(port->portdev)) 384 if (!use_multiport(port->portdev))
385 return 0; 385 return 0;
@@ -1071,27 +1071,27 @@ static void config_intr(struct virtio_device *vdev)
1071static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock) 1071static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
1072{ 1072{
1073 struct port_buffer *buf; 1073 struct port_buffer *buf;
1074 unsigned int ret; 1074 unsigned int nr_added_bufs;
1075 int err; 1075 int ret;
1076 1076
1077 ret = 0; 1077 nr_added_bufs = 0;
1078 do { 1078 do {
1079 buf = alloc_buf(PAGE_SIZE); 1079 buf = alloc_buf(PAGE_SIZE);
1080 if (!buf) 1080 if (!buf)
1081 break; 1081 break;
1082 1082
1083 spin_lock_irq(lock); 1083 spin_lock_irq(lock);
1084 err = add_inbuf(vq, buf); 1084 ret = add_inbuf(vq, buf);
1085 if (err < 0) { 1085 if (ret < 0) {
1086 spin_unlock_irq(lock); 1086 spin_unlock_irq(lock);
1087 free_buf(buf); 1087 free_buf(buf);
1088 break; 1088 break;
1089 } 1089 }
1090 ret++; 1090 nr_added_bufs++;
1091 spin_unlock_irq(lock); 1091 spin_unlock_irq(lock);
1092 } while (err > 0); 1092 } while (ret > 0);
1093 1093
1094 return ret; 1094 return nr_added_bufs;
1095} 1095}
1096 1096
1097static int add_port(struct ports_device *portdev, u32 id) 1097static int add_port(struct ports_device *portdev, u32 id)
@@ -1100,6 +1100,7 @@ static int add_port(struct ports_device *portdev, u32 id)
1100 struct port *port; 1100 struct port *port;
1101 struct port_buffer *buf; 1101 struct port_buffer *buf;
1102 dev_t devt; 1102 dev_t devt;
1103 unsigned int nr_added_bufs;
1103 int err; 1104 int err;
1104 1105
1105 port = kmalloc(sizeof(*port), GFP_KERNEL); 1106 port = kmalloc(sizeof(*port), GFP_KERNEL);
@@ -1144,8 +1145,8 @@ static int add_port(struct ports_device *portdev, u32 id)
1144 init_waitqueue_head(&port->waitqueue); 1145 init_waitqueue_head(&port->waitqueue);
1145 1146
1146 /* Fill the in_vq with buffers so the host can send us data. */ 1147 /* Fill the in_vq with buffers so the host can send us data. */
1147 err = fill_queue(port->in_vq, &port->inbuf_lock); 1148 nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
1148 if (!err) { 1149 if (!nr_added_bufs) {
1149 dev_err(port->dev, "Error allocating inbufs\n"); 1150 dev_err(port->dev, "Error allocating inbufs\n");
1150 err = -ENOMEM; 1151 err = -ENOMEM;
1151 goto free_device; 1152 goto free_device;
@@ -1442,12 +1443,14 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
1442 INIT_LIST_HEAD(&portdev->ports); 1443 INIT_LIST_HEAD(&portdev->ports);
1443 1444
1444 if (multiport) { 1445 if (multiport) {
1446 unsigned int nr_added_bufs;
1447
1445 spin_lock_init(&portdev->cvq_lock); 1448 spin_lock_init(&portdev->cvq_lock);
1446 INIT_WORK(&portdev->control_work, &control_work_handler); 1449 INIT_WORK(&portdev->control_work, &control_work_handler);
1447 INIT_WORK(&portdev->config_work, &config_work_handler); 1450 INIT_WORK(&portdev->config_work, &config_work_handler);
1448 1451
1449 err = fill_queue(portdev->c_ivq, &portdev->cvq_lock); 1452 nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock);
1450 if (!err) { 1453 if (!nr_added_bufs) {
1451 dev_err(&vdev->dev, 1454 dev_err(&vdev->dev,
1452 "Error allocating buffers for control queue\n"); 1455 "Error allocating buffers for control queue\n");
1453 err = -ENOMEM; 1456 err = -ENOMEM;
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
deleted file mode 100644
index 08f726c5fee5..000000000000
--- a/drivers/clocksource/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
1config CS5535_CLOCK_EVENT_SRC
2 tristate "CS5535/CS5536 high-res timer (MFGPT) events"
3 depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
4 help
5 This driver provides a clock event source based on the MFGPT
6 timer(s) in the CS5535 and CS5536 companion chips.
7 MFGPTs have a better resolution and max interval than the
8 generic PIT, and are suitable for use as high-res timers.
9
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index 73655aeb3a60..1aea7157d8ff 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -100,8 +100,8 @@ struct menu_device {
100 int needs_update; 100 int needs_update;
101 101
102 unsigned int expected_us; 102 unsigned int expected_us;
103 u64 predicted_us;
104 unsigned int measured_us; 103 unsigned int measured_us;
104 u64 predicted_us;
105 unsigned int exit_us; 105 unsigned int exit_us;
106 unsigned int bucket; 106 unsigned int bucket;
107 u64 correction_factor[BUCKETS]; 107 u64 correction_factor[BUCKETS];
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 5d0e42b263df..af14c9a5b8d4 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -71,7 +71,7 @@ static irqreturn_t ioat_dma_do_interrupt(int irq, void *data)
71 } 71 }
72 72
73 attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET); 73 attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
74 for_each_bit(bit, &attnstatus, BITS_PER_LONG) { 74 for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) {
75 chan = ioat_chan_by_index(instance, bit); 75 chan = ioat_chan_by_index(instance, bit);
76 tasklet_schedule(&chan->cleanup_task); 76 tasklet_schedule(&chan->cleanup_task);
77 } 77 }
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index b75ce8b84c46..5d17e09cb625 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -24,8 +24,10 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <cpu/dma.h> 27#include <linux/pm_runtime.h>
28#include <asm/dma-sh.h> 28
29#include <asm/dmaengine.h>
30
29#include "shdma.h" 31#include "shdma.h"
30 32
31/* DMA descriptor control */ 33/* DMA descriptor control */
@@ -38,30 +40,32 @@ enum sh_dmae_desc_status {
38}; 40};
39 41
40#define NR_DESCS_PER_CHANNEL 32 42#define NR_DESCS_PER_CHANNEL 32
41/* 43/* Default MEMCPY transfer size = 2^2 = 4 bytes */
42 * Define the default configuration for dual address memory-memory transfer. 44#define LOG2_DEFAULT_XFER_SIZE 2
43 * The 0x400 value represents auto-request, external->external.
44 *
45 * And this driver set 4byte burst mode.
46 * If you want to change mode, you need to change RS_DEFAULT of value.
47 * (ex 1byte burst mode -> (RS_DUAL & ~TS_32)
48 */
49#define RS_DEFAULT (RS_DUAL)
50 45
51/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */ 46/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
52static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)]; 47static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)];
53 48
54static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all); 49static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
55 50
56#define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id])
57static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) 51static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
58{ 52{
59 ctrl_outl(data, SH_DMAC_CHAN_BASE(sh_dc->id) + reg); 53 __raw_writel(data, sh_dc->base + reg / sizeof(u32));
60} 54}
61 55
62static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg) 56static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg)
63{ 57{
64 return ctrl_inl(SH_DMAC_CHAN_BASE(sh_dc->id) + reg); 58 return __raw_readl(sh_dc->base + reg / sizeof(u32));
59}
60
61static u16 dmaor_read(struct sh_dmae_device *shdev)
62{
63 return __raw_readw(shdev->chan_reg + DMAOR / sizeof(u32));
64}
65
66static void dmaor_write(struct sh_dmae_device *shdev, u16 data)
67{
68 __raw_writew(data, shdev->chan_reg + DMAOR / sizeof(u32));
65} 69}
66 70
67/* 71/*
@@ -69,24 +73,23 @@ static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg)
69 * 73 *
70 * SH7780 has two DMAOR register 74 * SH7780 has two DMAOR register
71 */ 75 */
72static void sh_dmae_ctl_stop(int id) 76static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev)
73{ 77{
74 unsigned short dmaor = dmaor_read_reg(id); 78 unsigned short dmaor = dmaor_read(shdev);
75 79
76 dmaor &= ~(DMAOR_NMIF | DMAOR_AE); 80 dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME));
77 dmaor_write_reg(id, dmaor);
78} 81}
79 82
80static int sh_dmae_rst(int id) 83static int sh_dmae_rst(struct sh_dmae_device *shdev)
81{ 84{
82 unsigned short dmaor; 85 unsigned short dmaor;
83 86
84 sh_dmae_ctl_stop(id); 87 sh_dmae_ctl_stop(shdev);
85 dmaor = dmaor_read_reg(id) | DMAOR_INIT; 88 dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init;
86 89
87 dmaor_write_reg(id, dmaor); 90 dmaor_write(shdev, dmaor);
88 if (dmaor_read_reg(id) & (DMAOR_AE | DMAOR_NMIF)) { 91 if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) {
89 pr_warning(KERN_ERR "dma-sh: Can't initialize DMAOR.\n"); 92 pr_warning("dma-sh: Can't initialize DMAOR.\n");
90 return -EINVAL; 93 return -EINVAL;
91 } 94 }
92 return 0; 95 return 0;
@@ -102,13 +105,36 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
102 return false; /* waiting */ 105 return false; /* waiting */
103} 106}
104 107
105static unsigned int ts_shift[] = TS_SHIFT; 108static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr)
106static inline unsigned int calc_xmit_shift(u32 chcr)
107{ 109{
108 int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) | 110 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
109 ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); 111 struct sh_dmae_device, common);
112 struct sh_dmae_pdata *pdata = shdev->pdata;
113 int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) |
114 ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift);
115
116 if (cnt >= pdata->ts_shift_num)
117 cnt = 0;
110 118
111 return ts_shift[cnt]; 119 return pdata->ts_shift[cnt];
120}
121
122static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size)
123{
124 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
125 struct sh_dmae_device, common);
126 struct sh_dmae_pdata *pdata = shdev->pdata;
127 int i;
128
129 for (i = 0; i < pdata->ts_shift_num; i++)
130 if (pdata->ts_shift[i] == l2size)
131 break;
132
133 if (i == pdata->ts_shift_num)
134 i = 0;
135
136 return ((i << pdata->ts_low_shift) & pdata->ts_low_mask) |
137 ((i << pdata->ts_high_shift) & pdata->ts_high_mask);
112} 138}
113 139
114static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) 140static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
@@ -136,8 +162,13 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan)
136 162
137static void dmae_init(struct sh_dmae_chan *sh_chan) 163static void dmae_init(struct sh_dmae_chan *sh_chan)
138{ 164{
139 u32 chcr = RS_DEFAULT; /* default is DUAL mode */ 165 /*
140 sh_chan->xmit_shift = calc_xmit_shift(chcr); 166 * Default configuration for dual address memory-memory transfer.
167 * 0x400 represents auto-request.
168 */
169 u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan,
170 LOG2_DEFAULT_XFER_SIZE);
171 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr);
141 sh_dmae_writel(sh_chan, chcr, CHCR); 172 sh_dmae_writel(sh_chan, chcr, CHCR);
142} 173}
143 174
@@ -147,37 +178,26 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
147 if (dmae_is_busy(sh_chan)) 178 if (dmae_is_busy(sh_chan))
148 return -EBUSY; 179 return -EBUSY;
149 180
150 sh_chan->xmit_shift = calc_xmit_shift(val); 181 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val);
151 sh_dmae_writel(sh_chan, val, CHCR); 182 sh_dmae_writel(sh_chan, val, CHCR);
152 183
153 return 0; 184 return 0;
154} 185}
155 186
156#define DMARS_SHIFT 8
157#define DMARS_CHAN_MSK 0x01
158static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) 187static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
159{ 188{
160 u32 addr; 189 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
161 int shift = 0; 190 struct sh_dmae_device, common);
191 struct sh_dmae_pdata *pdata = shdev->pdata;
192 struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
193 u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
194 int shift = chan_pdata->dmars_bit;
162 195
163 if (dmae_is_busy(sh_chan)) 196 if (dmae_is_busy(sh_chan))
164 return -EBUSY; 197 return -EBUSY;
165 198
166 if (sh_chan->id & DMARS_CHAN_MSK) 199 __raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift),
167 shift = DMARS_SHIFT; 200 addr);
168
169 if (sh_chan->id < 6)
170 /* DMA0RS0 - DMA0RS2 */
171 addr = SH_DMARS_BASE0 + (sh_chan->id / 2) * 4;
172#ifdef SH_DMARS_BASE1
173 else if (sh_chan->id < 12)
174 /* DMA1RS0 - DMA1RS2 */
175 addr = SH_DMARS_BASE1 + ((sh_chan->id - 6) / 2) * 4;
176#endif
177 else
178 return -EINVAL;
179
180 ctrl_outw((val << shift) | (ctrl_inw(addr) & (0xFF00 >> shift)), addr);
181 201
182 return 0; 202 return 0;
183} 203}
@@ -251,15 +271,15 @@ static struct sh_dmae_slave_config *sh_dmae_find_slave(
251 struct dma_device *dma_dev = sh_chan->common.device; 271 struct dma_device *dma_dev = sh_chan->common.device;
252 struct sh_dmae_device *shdev = container_of(dma_dev, 272 struct sh_dmae_device *shdev = container_of(dma_dev,
253 struct sh_dmae_device, common); 273 struct sh_dmae_device, common);
254 struct sh_dmae_pdata *pdata = &shdev->pdata; 274 struct sh_dmae_pdata *pdata = shdev->pdata;
255 int i; 275 int i;
256 276
257 if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER) 277 if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER)
258 return NULL; 278 return NULL;
259 279
260 for (i = 0; i < pdata->config_num; i++) 280 for (i = 0; i < pdata->slave_num; i++)
261 if (pdata->config[i].slave_id == slave_id) 281 if (pdata->slave[i].slave_id == slave_id)
262 return pdata->config + i; 282 return pdata->slave + i;
263 283
264 return NULL; 284 return NULL;
265} 285}
@@ -270,6 +290,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
270 struct sh_desc *desc; 290 struct sh_desc *desc;
271 struct sh_dmae_slave *param = chan->private; 291 struct sh_dmae_slave *param = chan->private;
272 292
293 pm_runtime_get_sync(sh_chan->dev);
294
273 /* 295 /*
274 * This relies on the guarantee from dmaengine that alloc_chan_resources 296 * This relies on the guarantee from dmaengine that alloc_chan_resources
275 * never runs concurrently with itself or free_chan_resources. 297 * never runs concurrently with itself or free_chan_resources.
@@ -288,9 +310,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
288 310
289 dmae_set_dmars(sh_chan, cfg->mid_rid); 311 dmae_set_dmars(sh_chan, cfg->mid_rid);
290 dmae_set_chcr(sh_chan, cfg->chcr); 312 dmae_set_chcr(sh_chan, cfg->chcr);
291 } else { 313 } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) {
292 if ((sh_dmae_readl(sh_chan, CHCR) & 0x700) != 0x400) 314 dmae_init(sh_chan);
293 dmae_set_chcr(sh_chan, RS_DEFAULT);
294 } 315 }
295 316
296 spin_lock_bh(&sh_chan->desc_lock); 317 spin_lock_bh(&sh_chan->desc_lock);
@@ -312,6 +333,9 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
312 } 333 }
313 spin_unlock_bh(&sh_chan->desc_lock); 334 spin_unlock_bh(&sh_chan->desc_lock);
314 335
336 if (!sh_chan->descs_allocated)
337 pm_runtime_put(sh_chan->dev);
338
315 return sh_chan->descs_allocated; 339 return sh_chan->descs_allocated;
316} 340}
317 341
@@ -323,6 +347,7 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
323 struct sh_dmae_chan *sh_chan = to_sh_chan(chan); 347 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
324 struct sh_desc *desc, *_desc; 348 struct sh_desc *desc, *_desc;
325 LIST_HEAD(list); 349 LIST_HEAD(list);
350 int descs = sh_chan->descs_allocated;
326 351
327 dmae_halt(sh_chan); 352 dmae_halt(sh_chan);
328 353
@@ -343,6 +368,9 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan)
343 368
344 spin_unlock_bh(&sh_chan->desc_lock); 369 spin_unlock_bh(&sh_chan->desc_lock);
345 370
371 if (descs > 0)
372 pm_runtime_put(sh_chan->dev);
373
346 list_for_each_entry_safe(desc, _desc, &list, node) 374 list_for_each_entry_safe(desc, _desc, &list, node)
347 kfree(desc); 375 kfree(desc);
348} 376}
@@ -559,6 +587,19 @@ static void sh_dmae_terminate_all(struct dma_chan *chan)
559 if (!chan) 587 if (!chan)
560 return; 588 return;
561 589
590 dmae_halt(sh_chan);
591
592 spin_lock_bh(&sh_chan->desc_lock);
593 if (!list_empty(&sh_chan->ld_queue)) {
594 /* Record partial transfer */
595 struct sh_desc *desc = list_entry(sh_chan->ld_queue.next,
596 struct sh_desc, node);
597 desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
598 sh_chan->xmit_shift;
599
600 }
601 spin_unlock_bh(&sh_chan->desc_lock);
602
562 sh_dmae_chan_ld_cleanup(sh_chan, true); 603 sh_dmae_chan_ld_cleanup(sh_chan, true);
563} 604}
564 605
@@ -661,7 +702,7 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
661 702
662static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) 703static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
663{ 704{
664 struct sh_desc *sd; 705 struct sh_desc *desc;
665 706
666 spin_lock_bh(&sh_chan->desc_lock); 707 spin_lock_bh(&sh_chan->desc_lock);
667 /* DMA work check */ 708 /* DMA work check */
@@ -671,10 +712,13 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
671 } 712 }
672 713
673 /* Find the first not transferred desciptor */ 714 /* Find the first not transferred desciptor */
674 list_for_each_entry(sd, &sh_chan->ld_queue, node) 715 list_for_each_entry(desc, &sh_chan->ld_queue, node)
675 if (sd->mark == DESC_SUBMITTED) { 716 if (desc->mark == DESC_SUBMITTED) {
717 dev_dbg(sh_chan->dev, "Queue #%d to %d: %u@%x -> %x\n",
718 desc->async_tx.cookie, sh_chan->id,
719 desc->hw.tcr, desc->hw.sar, desc->hw.dar);
676 /* Get the ld start address from ld_queue */ 720 /* Get the ld start address from ld_queue */
677 dmae_set_reg(sh_chan, &sd->hw); 721 dmae_set_reg(sh_chan, &desc->hw);
678 dmae_start(sh_chan); 722 dmae_start(sh_chan);
679 break; 723 break;
680 } 724 }
@@ -696,6 +740,7 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan,
696 struct sh_dmae_chan *sh_chan = to_sh_chan(chan); 740 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
697 dma_cookie_t last_used; 741 dma_cookie_t last_used;
698 dma_cookie_t last_complete; 742 dma_cookie_t last_complete;
743 enum dma_status status;
699 744
700 sh_dmae_chan_ld_cleanup(sh_chan, false); 745 sh_dmae_chan_ld_cleanup(sh_chan, false);
701 746
@@ -709,7 +754,27 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan,
709 if (used) 754 if (used)
710 *used = last_used; 755 *used = last_used;
711 756
712 return dma_async_is_complete(cookie, last_complete, last_used); 757 spin_lock_bh(&sh_chan->desc_lock);
758
759 status = dma_async_is_complete(cookie, last_complete, last_used);
760
761 /*
762 * If we don't find cookie on the queue, it has been aborted and we have
763 * to report error
764 */
765 if (status != DMA_SUCCESS) {
766 struct sh_desc *desc;
767 status = DMA_ERROR;
768 list_for_each_entry(desc, &sh_chan->ld_queue, node)
769 if (desc->cookie == cookie) {
770 status = DMA_IN_PROGRESS;
771 break;
772 }
773 }
774
775 spin_unlock_bh(&sh_chan->desc_lock);
776
777 return status;
713} 778}
714 779
715static irqreturn_t sh_dmae_interrupt(int irq, void *data) 780static irqreturn_t sh_dmae_interrupt(int irq, void *data)
@@ -732,40 +797,32 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data)
732#if defined(CONFIG_CPU_SH4) 797#if defined(CONFIG_CPU_SH4)
733static irqreturn_t sh_dmae_err(int irq, void *data) 798static irqreturn_t sh_dmae_err(int irq, void *data)
734{ 799{
735 int err = 0;
736 struct sh_dmae_device *shdev = (struct sh_dmae_device *)data; 800 struct sh_dmae_device *shdev = (struct sh_dmae_device *)data;
801 int i;
737 802
738 /* IRQ Multi */ 803 /* halt the dma controller */
739 if (shdev->pdata.mode & SHDMA_MIX_IRQ) { 804 sh_dmae_ctl_stop(shdev);
740 int __maybe_unused cnt = 0; 805
741 switch (irq) { 806 /* We cannot detect, which channel caused the error, have to reset all */
742#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ) 807 for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) {
743 case DMTE6_IRQ: 808 struct sh_dmae_chan *sh_chan = shdev->chan[i];
744 cnt++; 809 if (sh_chan) {
745#endif 810 struct sh_desc *desc;
746 case DMTE0_IRQ: 811 /* Stop the channel */
747 if (dmaor_read_reg(cnt) & (DMAOR_NMIF | DMAOR_AE)) { 812 dmae_halt(sh_chan);
748 disable_irq(irq); 813 /* Complete all */
749 return IRQ_HANDLED; 814 list_for_each_entry(desc, &sh_chan->ld_queue, node) {
815 struct dma_async_tx_descriptor *tx = &desc->async_tx;
816 desc->mark = DESC_IDLE;
817 if (tx->callback)
818 tx->callback(tx->callback_param);
750 } 819 }
751 default: 820 list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free);
752 return IRQ_NONE;
753 } 821 }
754 } else {
755 /* reset dma controller */
756 err = sh_dmae_rst(0);
757 if (err)
758 return err;
759#ifdef SH_DMAC_BASE1
760 if (shdev->pdata.mode & SHDMA_DMAOR1) {
761 err = sh_dmae_rst(1);
762 if (err)
763 return err;
764 }
765#endif
766 disable_irq(irq);
767 return IRQ_HANDLED;
768 } 822 }
823 sh_dmae_rst(shdev);
824
825 return IRQ_HANDLED;
769} 826}
770#endif 827#endif
771 828
@@ -796,19 +853,12 @@ static void dmae_do_tasklet(unsigned long data)
796 sh_dmae_chan_ld_cleanup(sh_chan, false); 853 sh_dmae_chan_ld_cleanup(sh_chan, false);
797} 854}
798 855
799static unsigned int get_dmae_irq(unsigned int id) 856static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
800{ 857 int irq, unsigned long flags)
801 unsigned int irq = 0;
802 if (id < ARRAY_SIZE(dmte_irq_map))
803 irq = dmte_irq_map[id];
804 return irq;
805}
806
807static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
808{ 858{
809 int err; 859 int err;
810 unsigned int irq = get_dmae_irq(id); 860 struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
811 unsigned long irqflags = IRQF_DISABLED; 861 struct platform_device *pdev = to_platform_device(shdev->common.dev);
812 struct sh_dmae_chan *new_sh_chan; 862 struct sh_dmae_chan *new_sh_chan;
813 863
814 /* alloc channel */ 864 /* alloc channel */
@@ -819,8 +869,13 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
819 return -ENOMEM; 869 return -ENOMEM;
820 } 870 }
821 871
872 /* copy struct dma_device */
873 new_sh_chan->common.device = &shdev->common;
874
822 new_sh_chan->dev = shdev->common.dev; 875 new_sh_chan->dev = shdev->common.dev;
823 new_sh_chan->id = id; 876 new_sh_chan->id = id;
877 new_sh_chan->irq = irq;
878 new_sh_chan->base = shdev->chan_reg + chan_pdata->offset / sizeof(u32);
824 879
825 /* Init DMA tasklet */ 880 /* Init DMA tasklet */
826 tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet, 881 tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet,
@@ -835,29 +890,20 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id)
835 INIT_LIST_HEAD(&new_sh_chan->ld_queue); 890 INIT_LIST_HEAD(&new_sh_chan->ld_queue);
836 INIT_LIST_HEAD(&new_sh_chan->ld_free); 891 INIT_LIST_HEAD(&new_sh_chan->ld_free);
837 892
838 /* copy struct dma_device */
839 new_sh_chan->common.device = &shdev->common;
840
841 /* Add the channel to DMA device channel list */ 893 /* Add the channel to DMA device channel list */
842 list_add_tail(&new_sh_chan->common.device_node, 894 list_add_tail(&new_sh_chan->common.device_node,
843 &shdev->common.channels); 895 &shdev->common.channels);
844 shdev->common.chancnt++; 896 shdev->common.chancnt++;
845 897
846 if (shdev->pdata.mode & SHDMA_MIX_IRQ) { 898 if (pdev->id >= 0)
847 irqflags = IRQF_SHARED; 899 snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
848#if defined(DMTE6_IRQ) 900 "sh-dmae%d.%d", pdev->id, new_sh_chan->id);
849 if (irq >= DMTE6_IRQ) 901 else
850 irq = DMTE6_IRQ; 902 snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
851 else 903 "sh-dma%d", new_sh_chan->id);
852#endif
853 irq = DMTE0_IRQ;
854 }
855
856 snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
857 "sh-dmae%d", new_sh_chan->id);
858 904
859 /* set up channel irq */ 905 /* set up channel irq */
860 err = request_irq(irq, &sh_dmae_interrupt, irqflags, 906 err = request_irq(irq, &sh_dmae_interrupt, flags,
861 new_sh_chan->dev_id, new_sh_chan); 907 new_sh_chan->dev_id, new_sh_chan);
862 if (err) { 908 if (err) {
863 dev_err(shdev->common.dev, "DMA channel %d request_irq error " 909 dev_err(shdev->common.dev, "DMA channel %d request_irq error "
@@ -881,12 +927,12 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev)
881 927
882 for (i = shdev->common.chancnt - 1 ; i >= 0 ; i--) { 928 for (i = shdev->common.chancnt - 1 ; i >= 0 ; i--) {
883 if (shdev->chan[i]) { 929 if (shdev->chan[i]) {
884 struct sh_dmae_chan *shchan = shdev->chan[i]; 930 struct sh_dmae_chan *sh_chan = shdev->chan[i];
885 if (!(shdev->pdata.mode & SHDMA_MIX_IRQ))
886 free_irq(dmte_irq_map[i], shchan);
887 931
888 list_del(&shchan->common.device_node); 932 free_irq(sh_chan->irq, sh_chan);
889 kfree(shchan); 933
934 list_del(&sh_chan->common.device_node);
935 kfree(sh_chan);
890 shdev->chan[i] = NULL; 936 shdev->chan[i] = NULL;
891 } 937 }
892 } 938 }
@@ -895,47 +941,84 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev)
895 941
896static int __init sh_dmae_probe(struct platform_device *pdev) 942static int __init sh_dmae_probe(struct platform_device *pdev)
897{ 943{
898 int err = 0, cnt, ecnt; 944 struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
899 unsigned long irqflags = IRQF_DISABLED; 945 unsigned long irqflags = IRQF_DISABLED,
900#if defined(CONFIG_CPU_SH4) 946 chan_flag[SH_DMAC_MAX_CHANNELS] = {};
901 int eirq[] = { DMAE0_IRQ, 947 int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
902#if defined(DMAE1_IRQ) 948 int err, i, irq_cnt = 0, irqres = 0;
903 DMAE1_IRQ
904#endif
905 };
906#endif
907 struct sh_dmae_device *shdev; 949 struct sh_dmae_device *shdev;
950 struct resource *chan, *dmars, *errirq_res, *chanirq_res;
908 951
909 /* get platform data */ 952 /* get platform data */
910 if (!pdev->dev.platform_data) 953 if (!pdata || !pdata->channel_num)
911 return -ENODEV; 954 return -ENODEV;
912 955
956 chan = platform_get_resource(pdev, IORESOURCE_MEM, 0);
957 /* DMARS area is optional, if absent, this controller cannot do slave DMA */
958 dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1);
959 /*
960 * IRQ resources:
961 * 1. there always must be at least one IRQ IO-resource. On SH4 it is
962 * the error IRQ, in which case it is the only IRQ in this resource:
963 * start == end. If it is the only IRQ resource, all channels also
964 * use the same IRQ.
965 * 2. DMA channel IRQ resources can be specified one per resource or in
966 * ranges (start != end)
967 * 3. iff all events (channels and, optionally, error) on this
968 * controller use the same IRQ, only one IRQ resource can be
969 * specified, otherwise there must be one IRQ per channel, even if
970 * some of them are equal
971 * 4. if all IRQs on this controller are equal or if some specific IRQs
972 * specify IORESOURCE_IRQ_SHAREABLE in their resources, they will be
973 * requested with the IRQF_SHARED flag
974 */
975 errirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
976 if (!chan || !errirq_res)
977 return -ENODEV;
978
979 if (!request_mem_region(chan->start, resource_size(chan), pdev->name)) {
980 dev_err(&pdev->dev, "DMAC register region already claimed\n");
981 return -EBUSY;
982 }
983
984 if (dmars && !request_mem_region(dmars->start, resource_size(dmars), pdev->name)) {
985 dev_err(&pdev->dev, "DMAC DMARS region already claimed\n");
986 err = -EBUSY;
987 goto ermrdmars;
988 }
989
990 err = -ENOMEM;
913 shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL); 991 shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL);
914 if (!shdev) { 992 if (!shdev) {
915 dev_err(&pdev->dev, "No enough memory\n"); 993 dev_err(&pdev->dev, "Not enough memory\n");
916 return -ENOMEM; 994 goto ealloc;
995 }
996
997 shdev->chan_reg = ioremap(chan->start, resource_size(chan));
998 if (!shdev->chan_reg)
999 goto emapchan;
1000 if (dmars) {
1001 shdev->dmars = ioremap(dmars->start, resource_size(dmars));
1002 if (!shdev->dmars)
1003 goto emapdmars;
917 } 1004 }
918 1005
919 /* platform data */ 1006 /* platform data */
920 memcpy(&shdev->pdata, pdev->dev.platform_data, 1007 shdev->pdata = pdata;
921 sizeof(struct sh_dmae_pdata)); 1008
1009 pm_runtime_enable(&pdev->dev);
1010 pm_runtime_get_sync(&pdev->dev);
922 1011
923 /* reset dma controller */ 1012 /* reset dma controller */
924 err = sh_dmae_rst(0); 1013 err = sh_dmae_rst(shdev);
925 if (err) 1014 if (err)
926 goto rst_err; 1015 goto rst_err;
927 1016
928 /* SH7780/85/23 has DMAOR1 */
929 if (shdev->pdata.mode & SHDMA_DMAOR1) {
930 err = sh_dmae_rst(1);
931 if (err)
932 goto rst_err;
933 }
934
935 INIT_LIST_HEAD(&shdev->common.channels); 1017 INIT_LIST_HEAD(&shdev->common.channels);
936 1018
937 dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask); 1019 dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
938 dma_cap_set(DMA_SLAVE, shdev->common.cap_mask); 1020 if (dmars)
1021 dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
939 1022
940 shdev->common.device_alloc_chan_resources 1023 shdev->common.device_alloc_chan_resources
941 = sh_dmae_alloc_chan_resources; 1024 = sh_dmae_alloc_chan_resources;
@@ -950,37 +1033,72 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
950 1033
951 shdev->common.dev = &pdev->dev; 1034 shdev->common.dev = &pdev->dev;
952 /* Default transfer size of 32 bytes requires 32-byte alignment */ 1035 /* Default transfer size of 32 bytes requires 32-byte alignment */
953 shdev->common.copy_align = 5; 1036 shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
954 1037
955#if defined(CONFIG_CPU_SH4) 1038#if defined(CONFIG_CPU_SH4)
956 /* Non Mix IRQ mode SH7722/SH7730 etc... */ 1039 chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
957 if (shdev->pdata.mode & SHDMA_MIX_IRQ) { 1040
1041 if (!chanirq_res)
1042 chanirq_res = errirq_res;
1043 else
1044 irqres++;
1045
1046 if (chanirq_res == errirq_res ||
1047 (errirq_res->flags & IORESOURCE_BITS) == IORESOURCE_IRQ_SHAREABLE)
958 irqflags = IRQF_SHARED; 1048 irqflags = IRQF_SHARED;
959 eirq[0] = DMTE0_IRQ; 1049
960#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ) 1050 errirq = errirq_res->start;
961 eirq[1] = DMTE6_IRQ; 1051
962#endif 1052 err = request_irq(errirq, sh_dmae_err, irqflags,
1053 "DMAC Address Error", shdev);
1054 if (err) {
1055 dev_err(&pdev->dev,
1056 "DMA failed requesting irq #%d, error %d\n",
1057 errirq, err);
1058 goto eirq_err;
963 } 1059 }
964 1060
965 for (ecnt = 0 ; ecnt < ARRAY_SIZE(eirq); ecnt++) { 1061#else
966 err = request_irq(eirq[ecnt], sh_dmae_err, irqflags, 1062 chanirq_res = errirq_res;
967 "DMAC Address Error", shdev); 1063#endif /* CONFIG_CPU_SH4 */
968 if (err) { 1064
969 dev_err(&pdev->dev, "DMA device request_irq" 1065 if (chanirq_res->start == chanirq_res->end &&
970 "error (irq %d) with return %d\n", 1066 !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
971 eirq[ecnt], err); 1067 /* Special case - all multiplexed */
972 goto eirq_err; 1068 for (; irq_cnt < pdata->channel_num; irq_cnt++) {
1069 chan_irq[irq_cnt] = chanirq_res->start;
1070 chan_flag[irq_cnt] = IRQF_SHARED;
973 } 1071 }
1072 } else {
1073 do {
1074 for (i = chanirq_res->start; i <= chanirq_res->end; i++) {
1075 if ((errirq_res->flags & IORESOURCE_BITS) ==
1076 IORESOURCE_IRQ_SHAREABLE)
1077 chan_flag[irq_cnt] = IRQF_SHARED;
1078 else
1079 chan_flag[irq_cnt] = IRQF_DISABLED;
1080 dev_dbg(&pdev->dev,
1081 "Found IRQ %d for channel %d\n",
1082 i, irq_cnt);
1083 chan_irq[irq_cnt++] = i;
1084 }
1085 chanirq_res = platform_get_resource(pdev,
1086 IORESOURCE_IRQ, ++irqres);
1087 } while (irq_cnt < pdata->channel_num && chanirq_res);
974 } 1088 }
975#endif /* CONFIG_CPU_SH4 */ 1089
1090 if (irq_cnt < pdata->channel_num)
1091 goto eirqres;
976 1092
977 /* Create DMA Channel */ 1093 /* Create DMA Channel */
978 for (cnt = 0 ; cnt < MAX_DMA_CHANNELS ; cnt++) { 1094 for (i = 0; i < pdata->channel_num; i++) {
979 err = sh_dmae_chan_probe(shdev, cnt); 1095 err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
980 if (err) 1096 if (err)
981 goto chan_probe_err; 1097 goto chan_probe_err;
982 } 1098 }
983 1099
1100 pm_runtime_put(&pdev->dev);
1101
984 platform_set_drvdata(pdev, shdev); 1102 platform_set_drvdata(pdev, shdev);
985 dma_async_device_register(&shdev->common); 1103 dma_async_device_register(&shdev->common);
986 1104
@@ -988,13 +1106,24 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
988 1106
989chan_probe_err: 1107chan_probe_err:
990 sh_dmae_chan_remove(shdev); 1108 sh_dmae_chan_remove(shdev);
991 1109eirqres:
1110#if defined(CONFIG_CPU_SH4)
1111 free_irq(errirq, shdev);
992eirq_err: 1112eirq_err:
993 for (ecnt-- ; ecnt >= 0; ecnt--) 1113#endif
994 free_irq(eirq[ecnt], shdev);
995
996rst_err: 1114rst_err:
1115 pm_runtime_put(&pdev->dev);
1116 if (dmars)
1117 iounmap(shdev->dmars);
1118emapdmars:
1119 iounmap(shdev->chan_reg);
1120emapchan:
997 kfree(shdev); 1121 kfree(shdev);
1122ealloc:
1123 if (dmars)
1124 release_mem_region(dmars->start, resource_size(dmars));
1125ermrdmars:
1126 release_mem_region(chan->start, resource_size(chan));
998 1127
999 return err; 1128 return err;
1000} 1129}
@@ -1002,36 +1131,39 @@ rst_err:
1002static int __exit sh_dmae_remove(struct platform_device *pdev) 1131static int __exit sh_dmae_remove(struct platform_device *pdev)
1003{ 1132{
1004 struct sh_dmae_device *shdev = platform_get_drvdata(pdev); 1133 struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
1134 struct resource *res;
1135 int errirq = platform_get_irq(pdev, 0);
1005 1136
1006 dma_async_device_unregister(&shdev->common); 1137 dma_async_device_unregister(&shdev->common);
1007 1138
1008 if (shdev->pdata.mode & SHDMA_MIX_IRQ) { 1139 if (errirq > 0)
1009 free_irq(DMTE0_IRQ, shdev); 1140 free_irq(errirq, shdev);
1010#if defined(DMTE6_IRQ)
1011 free_irq(DMTE6_IRQ, shdev);
1012#endif
1013 }
1014 1141
1015 /* channel data remove */ 1142 /* channel data remove */
1016 sh_dmae_chan_remove(shdev); 1143 sh_dmae_chan_remove(shdev);
1017 1144
1018 if (!(shdev->pdata.mode & SHDMA_MIX_IRQ)) { 1145 pm_runtime_disable(&pdev->dev);
1019 free_irq(DMAE0_IRQ, shdev); 1146
1020#if defined(DMAE1_IRQ) 1147 if (shdev->dmars)
1021 free_irq(DMAE1_IRQ, shdev); 1148 iounmap(shdev->dmars);
1022#endif 1149 iounmap(shdev->chan_reg);
1023 } 1150
1024 kfree(shdev); 1151 kfree(shdev);
1025 1152
1153 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1154 if (res)
1155 release_mem_region(res->start, resource_size(res));
1156 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1157 if (res)
1158 release_mem_region(res->start, resource_size(res));
1159
1026 return 0; 1160 return 0;
1027} 1161}
1028 1162
1029static void sh_dmae_shutdown(struct platform_device *pdev) 1163static void sh_dmae_shutdown(struct platform_device *pdev)
1030{ 1164{
1031 struct sh_dmae_device *shdev = platform_get_drvdata(pdev); 1165 struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
1032 sh_dmae_ctl_stop(0); 1166 sh_dmae_ctl_stop(shdev);
1033 if (shdev->pdata.mode & SHDMA_DMAOR1)
1034 sh_dmae_ctl_stop(1);
1035} 1167}
1036 1168
1037static struct platform_driver sh_dmae_driver = { 1169static struct platform_driver sh_dmae_driver = {
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 7e227f3c87c4..153609a1e96c 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -17,23 +17,9 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/list.h> 18#include <linux/list.h>
19 19
20#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ 20#include <asm/dmaengine.h>
21
22struct sh_dmae_regs {
23 u32 sar; /* SAR / source address */
24 u32 dar; /* DAR / destination address */
25 u32 tcr; /* TCR / transfer count */
26};
27 21
28struct sh_desc { 22#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */
29 struct sh_dmae_regs hw;
30 struct list_head node;
31 struct dma_async_tx_descriptor async_tx;
32 enum dma_data_direction direction;
33 dma_cookie_t cookie;
34 int chunks;
35 int mark;
36};
37 23
38struct device; 24struct device;
39 25
@@ -47,14 +33,18 @@ struct sh_dmae_chan {
47 struct tasklet_struct tasklet; /* Tasklet */ 33 struct tasklet_struct tasklet; /* Tasklet */
48 int descs_allocated; /* desc count */ 34 int descs_allocated; /* desc count */
49 int xmit_shift; /* log_2(bytes_per_xfer) */ 35 int xmit_shift; /* log_2(bytes_per_xfer) */
36 int irq;
50 int id; /* Raw id of this channel */ 37 int id; /* Raw id of this channel */
38 u32 __iomem *base;
51 char dev_id[16]; /* unique name per DMAC of channel */ 39 char dev_id[16]; /* unique name per DMAC of channel */
52}; 40};
53 41
54struct sh_dmae_device { 42struct sh_dmae_device {
55 struct dma_device common; 43 struct dma_device common;
56 struct sh_dmae_chan *chan[MAX_DMA_CHANNELS]; 44 struct sh_dmae_chan *chan[SH_DMAC_MAX_CHANNELS];
57 struct sh_dmae_pdata pdata; 45 struct sh_dmae_pdata *pdata;
46 u32 __iomem *chan_reg;
47 u16 __iomem *dmars;
58}; 48};
59 49
60#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common) 50#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common)
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 66958b3f10b4..806c77bfd434 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -39,10 +39,10 @@ static unsigned int enable_dev_count;
39static int disable_dev[EISA_MAX_FORCED_DEV]; 39static int disable_dev[EISA_MAX_FORCED_DEV];
40static unsigned int disable_dev_count; 40static unsigned int disable_dev_count;
41 41
42static int is_forced_dev (int *forced_tab, 42static int is_forced_dev(int *forced_tab,
43 int forced_count, 43 int forced_count,
44 struct eisa_root_device *root, 44 struct eisa_root_device *root,
45 struct eisa_device *edev) 45 struct eisa_device *edev)
46{ 46{
47 int i, x; 47 int i, x;
48 48
@@ -55,21 +55,21 @@ static int is_forced_dev (int *forced_tab,
55 return 0; 55 return 0;
56} 56}
57 57
58static void __init eisa_name_device (struct eisa_device *edev) 58static void __init eisa_name_device(struct eisa_device *edev)
59{ 59{
60#ifdef CONFIG_EISA_NAMES 60#ifdef CONFIG_EISA_NAMES
61 int i; 61 int i;
62 for (i = 0; i < EISA_INFOS; i++) { 62 for (i = 0; i < EISA_INFOS; i++) {
63 if (!strcmp (edev->id.sig, eisa_table[i].id.sig)) { 63 if (!strcmp(edev->id.sig, eisa_table[i].id.sig)) {
64 strlcpy (edev->pretty_name, 64 strlcpy(edev->pretty_name,
65 eisa_table[i].name, 65 eisa_table[i].name,
66 sizeof(edev->pretty_name)); 66 sizeof(edev->pretty_name));
67 return; 67 return;
68 } 68 }
69 } 69 }
70 70
71 /* No name was found */ 71 /* No name was found */
72 sprintf (edev->pretty_name, "EISA device %.7s", edev->id.sig); 72 sprintf(edev->pretty_name, "EISA device %.7s", edev->id.sig);
73#endif 73#endif
74} 74}
75 75
@@ -91,7 +91,7 @@ static char __init *decode_eisa_sig(unsigned long addr)
91 */ 91 */
92 outb(0x80 + i, addr); 92 outb(0x80 + i, addr);
93#endif 93#endif
94 sig[i] = inb (addr + i); 94 sig[i] = inb(addr + i);
95 95
96 if (!i && (sig[0] & 0x80)) 96 if (!i && (sig[0] & 0x80))
97 return NULL; 97 return NULL;
@@ -106,17 +106,17 @@ static char __init *decode_eisa_sig(unsigned long addr)
106 return sig_str; 106 return sig_str;
107} 107}
108 108
109static int eisa_bus_match (struct device *dev, struct device_driver *drv) 109static int eisa_bus_match(struct device *dev, struct device_driver *drv)
110{ 110{
111 struct eisa_device *edev = to_eisa_device (dev); 111 struct eisa_device *edev = to_eisa_device(dev);
112 struct eisa_driver *edrv = to_eisa_driver (drv); 112 struct eisa_driver *edrv = to_eisa_driver(drv);
113 const struct eisa_device_id *eids = edrv->id_table; 113 const struct eisa_device_id *eids = edrv->id_table;
114 114
115 if (!eids) 115 if (!eids)
116 return 0; 116 return 0;
117 117
118 while (strlen (eids->sig)) { 118 while (strlen(eids->sig)) {
119 if (!strcmp (eids->sig, edev->id.sig) && 119 if (!strcmp(eids->sig, edev->id.sig) &&
120 edev->state & EISA_CONFIG_ENABLED) { 120 edev->state & EISA_CONFIG_ENABLED) {
121 edev->id.driver_data = eids->driver_data; 121 edev->id.driver_data = eids->driver_data;
122 return 1; 122 return 1;
@@ -141,61 +141,71 @@ struct bus_type eisa_bus_type = {
141 .match = eisa_bus_match, 141 .match = eisa_bus_match,
142 .uevent = eisa_bus_uevent, 142 .uevent = eisa_bus_uevent,
143}; 143};
144EXPORT_SYMBOL(eisa_bus_type);
144 145
145int eisa_driver_register (struct eisa_driver *edrv) 146int eisa_driver_register(struct eisa_driver *edrv)
146{ 147{
147 edrv->driver.bus = &eisa_bus_type; 148 edrv->driver.bus = &eisa_bus_type;
148 return driver_register (&edrv->driver); 149 return driver_register(&edrv->driver);
149} 150}
151EXPORT_SYMBOL(eisa_driver_register);
150 152
151void eisa_driver_unregister (struct eisa_driver *edrv) 153void eisa_driver_unregister(struct eisa_driver *edrv)
152{ 154{
153 driver_unregister (&edrv->driver); 155 driver_unregister(&edrv->driver);
154} 156}
157EXPORT_SYMBOL(eisa_driver_unregister);
155 158
156static ssize_t eisa_show_sig (struct device *dev, struct device_attribute *attr, char *buf) 159static ssize_t eisa_show_sig(struct device *dev, struct device_attribute *attr,
160 char *buf)
157{ 161{
158 struct eisa_device *edev = to_eisa_device (dev); 162 struct eisa_device *edev = to_eisa_device(dev);
159 return sprintf (buf,"%s\n", edev->id.sig); 163 return sprintf(buf, "%s\n", edev->id.sig);
160} 164}
161 165
162static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL); 166static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
163 167
164static ssize_t eisa_show_state (struct device *dev, struct device_attribute *attr, char *buf) 168static ssize_t eisa_show_state(struct device *dev,
169 struct device_attribute *attr,
170 char *buf)
165{ 171{
166 struct eisa_device *edev = to_eisa_device (dev); 172 struct eisa_device *edev = to_eisa_device(dev);
167 return sprintf (buf,"%d\n", edev->state & EISA_CONFIG_ENABLED); 173 return sprintf(buf, "%d\n", edev->state & EISA_CONFIG_ENABLED);
168} 174}
169 175
170static DEVICE_ATTR(enabled, S_IRUGO, eisa_show_state, NULL); 176static DEVICE_ATTR(enabled, S_IRUGO, eisa_show_state, NULL);
171 177
172static ssize_t eisa_show_modalias (struct device *dev, struct device_attribute *attr, char *buf) 178static ssize_t eisa_show_modalias(struct device *dev,
179 struct device_attribute *attr,
180 char *buf)
173{ 181{
174 struct eisa_device *edev = to_eisa_device (dev); 182 struct eisa_device *edev = to_eisa_device(dev);
175 return sprintf (buf, EISA_DEVICE_MODALIAS_FMT "\n", edev->id.sig); 183 return sprintf(buf, EISA_DEVICE_MODALIAS_FMT "\n", edev->id.sig);
176} 184}
177 185
178static DEVICE_ATTR(modalias, S_IRUGO, eisa_show_modalias, NULL); 186static DEVICE_ATTR(modalias, S_IRUGO, eisa_show_modalias, NULL);
179 187
180static int __init eisa_init_device (struct eisa_root_device *root, 188static int __init eisa_init_device(struct eisa_root_device *root,
181 struct eisa_device *edev, 189 struct eisa_device *edev,
182 int slot) 190 int slot)
183{ 191{
184 char *sig; 192 char *sig;
185 unsigned long sig_addr; 193 unsigned long sig_addr;
186 int i; 194 int i;
187 195
188 sig_addr = SLOT_ADDRESS (root, slot) + EISA_VENDOR_ID_OFFSET; 196 sig_addr = SLOT_ADDRESS(root, slot) + EISA_VENDOR_ID_OFFSET;
189 197
190 if (!(sig = decode_eisa_sig (sig_addr))) 198 sig = decode_eisa_sig(sig_addr);
199 if (!sig)
191 return -1; /* No EISA device here */ 200 return -1; /* No EISA device here */
192 201
193 memcpy (edev->id.sig, sig, EISA_SIG_LEN); 202 memcpy(edev->id.sig, sig, EISA_SIG_LEN);
194 edev->slot = slot; 203 edev->slot = slot;
195 edev->state = inb (SLOT_ADDRESS (root, slot) + EISA_CONFIG_OFFSET) & EISA_CONFIG_ENABLED; 204 edev->state = inb(SLOT_ADDRESS(root, slot) + EISA_CONFIG_OFFSET)
196 edev->base_addr = SLOT_ADDRESS (root, slot); 205 & EISA_CONFIG_ENABLED;
206 edev->base_addr = SLOT_ADDRESS(root, slot);
197 edev->dma_mask = root->dma_mask; /* Default DMA mask */ 207 edev->dma_mask = root->dma_mask; /* Default DMA mask */
198 eisa_name_device (edev); 208 eisa_name_device(edev);
199 edev->dev.parent = root->dev; 209 edev->dev.parent = root->dev;
200 edev->dev.bus = &eisa_bus_type; 210 edev->dev.bus = &eisa_bus_type;
201 edev->dev.dma_mask = &edev->dma_mask; 211 edev->dev.dma_mask = &edev->dma_mask;
@@ -210,42 +220,45 @@ static int __init eisa_init_device (struct eisa_root_device *root,
210#endif 220#endif
211 } 221 }
212 222
213 if (is_forced_dev (enable_dev, enable_dev_count, root, edev)) 223 if (is_forced_dev(enable_dev, enable_dev_count, root, edev))
214 edev->state = EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED; 224 edev->state = EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED;
215 225
216 if (is_forced_dev (disable_dev, disable_dev_count, root, edev)) 226 if (is_forced_dev(disable_dev, disable_dev_count, root, edev))
217 edev->state = EISA_CONFIG_FORCED; 227 edev->state = EISA_CONFIG_FORCED;
218 228
219 return 0; 229 return 0;
220} 230}
221 231
222static int __init eisa_register_device (struct eisa_device *edev) 232static int __init eisa_register_device(struct eisa_device *edev)
223{ 233{
224 int rc = device_register (&edev->dev); 234 int rc = device_register(&edev->dev);
225 if (rc) 235 if (rc)
226 return rc; 236 return rc;
227 237
228 rc = device_create_file (&edev->dev, &dev_attr_signature); 238 rc = device_create_file(&edev->dev, &dev_attr_signature);
229 if (rc) goto err_devreg; 239 if (rc)
230 rc = device_create_file (&edev->dev, &dev_attr_enabled); 240 goto err_devreg;
231 if (rc) goto err_sig; 241 rc = device_create_file(&edev->dev, &dev_attr_enabled);
232 rc = device_create_file (&edev->dev, &dev_attr_modalias); 242 if (rc)
233 if (rc) goto err_enab; 243 goto err_sig;
244 rc = device_create_file(&edev->dev, &dev_attr_modalias);
245 if (rc)
246 goto err_enab;
234 247
235 return 0; 248 return 0;
236 249
237err_enab: 250err_enab:
238 device_remove_file (&edev->dev, &dev_attr_enabled); 251 device_remove_file(&edev->dev, &dev_attr_enabled);
239err_sig: 252err_sig:
240 device_remove_file (&edev->dev, &dev_attr_signature); 253 device_remove_file(&edev->dev, &dev_attr_signature);
241err_devreg: 254err_devreg:
242 device_unregister(&edev->dev); 255 device_unregister(&edev->dev);
243 return rc; 256 return rc;
244} 257}
245 258
246static int __init eisa_request_resources (struct eisa_root_device *root, 259static int __init eisa_request_resources(struct eisa_root_device *root,
247 struct eisa_device *edev, 260 struct eisa_device *edev,
248 int slot) 261 int slot)
249{ 262{
250 int i; 263 int i;
251 264
@@ -263,17 +276,19 @@ static int __init eisa_request_resources (struct eisa_root_device *root,
263 276
264 if (slot) { 277 if (slot) {
265 edev->res[i].name = NULL; 278 edev->res[i].name = NULL;
266 edev->res[i].start = SLOT_ADDRESS (root, slot) + (i * 0x400); 279 edev->res[i].start = SLOT_ADDRESS(root, slot)
280 + (i * 0x400);
267 edev->res[i].end = edev->res[i].start + 0xff; 281 edev->res[i].end = edev->res[i].start + 0xff;
268 edev->res[i].flags = IORESOURCE_IO; 282 edev->res[i].flags = IORESOURCE_IO;
269 } else { 283 } else {
270 edev->res[i].name = NULL; 284 edev->res[i].name = NULL;
271 edev->res[i].start = SLOT_ADDRESS (root, slot) + EISA_VENDOR_ID_OFFSET; 285 edev->res[i].start = SLOT_ADDRESS(root, slot)
286 + EISA_VENDOR_ID_OFFSET;
272 edev->res[i].end = edev->res[i].start + 3; 287 edev->res[i].end = edev->res[i].start + 3;
273 edev->res[i].flags = IORESOURCE_BUSY; 288 edev->res[i].flags = IORESOURCE_BUSY;
274 } 289 }
275 290
276 if (request_resource (root->res, &edev->res[i])) 291 if (request_resource(root->res, &edev->res[i]))
277 goto failed; 292 goto failed;
278 } 293 }
279 294
@@ -281,99 +296,100 @@ static int __init eisa_request_resources (struct eisa_root_device *root,
281 296
282 failed: 297 failed:
283 while (--i >= 0) 298 while (--i >= 0)
284 release_resource (&edev->res[i]); 299 release_resource(&edev->res[i]);
285 300
286 return -1; 301 return -1;
287} 302}
288 303
289static void __init eisa_release_resources (struct eisa_device *edev) 304static void __init eisa_release_resources(struct eisa_device *edev)
290{ 305{
291 int i; 306 int i;
292 307
293 for (i = 0; i < EISA_MAX_RESOURCES; i++) 308 for (i = 0; i < EISA_MAX_RESOURCES; i++)
294 if (edev->res[i].start || edev->res[i].end) 309 if (edev->res[i].start || edev->res[i].end)
295 release_resource (&edev->res[i]); 310 release_resource(&edev->res[i]);
296} 311}
297 312
298static int __init eisa_probe (struct eisa_root_device *root) 313static int __init eisa_probe(struct eisa_root_device *root)
299{ 314{
300 int i, c; 315 int i, c;
301 struct eisa_device *edev; 316 struct eisa_device *edev;
302 317
303 printk (KERN_INFO "EISA: Probing bus %d at %s\n", 318 printk(KERN_INFO "EISA: Probing bus %d at %s\n",
304 root->bus_nr, dev_name(root->dev)); 319 root->bus_nr, dev_name(root->dev));
305 320
306 /* First try to get hold of slot 0. If there is no device 321 /* First try to get hold of slot 0. If there is no device
307 * here, simply fail, unless root->force_probe is set. */ 322 * here, simply fail, unless root->force_probe is set. */
308 323
309 if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) { 324 edev = kzalloc(sizeof(*edev), GFP_KERNEL);
310 printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n"); 325 if (!edev) {
326 printk(KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
311 return -ENOMEM; 327 return -ENOMEM;
312 } 328 }
313 329
314 if (eisa_request_resources (root, edev, 0)) { 330 if (eisa_request_resources(root, edev, 0)) {
315 printk (KERN_WARNING \ 331 printk(KERN_WARNING \
316 "EISA: Cannot allocate resource for mainboard\n"); 332 "EISA: Cannot allocate resource for mainboard\n");
317 kfree (edev); 333 kfree(edev);
318 if (!root->force_probe) 334 if (!root->force_probe)
319 return -EBUSY; 335 return -EBUSY;
320 goto force_probe; 336 goto force_probe;
321 } 337 }
322 338
323 if (eisa_init_device (root, edev, 0)) { 339 if (eisa_init_device(root, edev, 0)) {
324 eisa_release_resources (edev); 340 eisa_release_resources(edev);
325 kfree (edev); 341 kfree(edev);
326 if (!root->force_probe) 342 if (!root->force_probe)
327 return -ENODEV; 343 return -ENODEV;
328 goto force_probe; 344 goto force_probe;
329 } 345 }
330 346
331 printk (KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig); 347 printk(KERN_INFO "EISA: Mainboard %s detected.\n", edev->id.sig);
332 348
333 if (eisa_register_device (edev)) { 349 if (eisa_register_device(edev)) {
334 printk (KERN_ERR "EISA: Failed to register %s\n", 350 printk(KERN_ERR "EISA: Failed to register %s\n",
335 edev->id.sig); 351 edev->id.sig);
336 eisa_release_resources (edev); 352 eisa_release_resources(edev);
337 kfree (edev); 353 kfree(edev);
338 } 354 }
339 355
340 force_probe: 356 force_probe:
341 357
342 for (c = 0, i = 1; i <= root->slots; i++) { 358 for (c = 0, i = 1; i <= root->slots; i++) {
343 if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) { 359 edev = kzalloc(sizeof(*edev), GFP_KERNEL);
344 printk (KERN_ERR "EISA: Out of memory for slot %d\n", 360 if (!edev) {
345 i); 361 printk(KERN_ERR "EISA: Out of memory for slot %d\n", i);
346 continue; 362 continue;
347 } 363 }
348 364
349 if (eisa_request_resources (root, edev, i)) { 365 if (eisa_request_resources(root, edev, i)) {
350 printk (KERN_WARNING \ 366 printk(KERN_WARNING \
351 "Cannot allocate resource for EISA slot %d\n", 367 "Cannot allocate resource for EISA slot %d\n",
352 i); 368 i);
353 kfree (edev); 369 kfree(edev);
354 continue; 370 continue;
355 } 371 }
356 372
357 if (eisa_init_device (root, edev, i)) { 373 if (eisa_init_device(root, edev, i)) {
358 eisa_release_resources (edev); 374 eisa_release_resources(edev);
359 kfree (edev); 375 kfree(edev);
360 continue; 376 continue;
361 } 377 }
362 378
363 printk (KERN_INFO "EISA: slot %d : %s detected", 379 printk(KERN_INFO "EISA: slot %d : %s detected",
364 i, edev->id.sig); 380 i, edev->id.sig);
365 381
366 switch (edev->state) { 382 switch (edev->state) {
367 case EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED: 383 case EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED:
368 printk (" (forced enabled)"); 384 printk(" (forced enabled)");
369 break; 385 break;
370 386
371 case EISA_CONFIG_FORCED: 387 case EISA_CONFIG_FORCED:
372 printk (" (forced disabled)"); 388 printk(" (forced disabled)");
373 break; 389 break;
374 390
375 case 0: 391 case 0:
376 printk (" (disabled)"); 392 printk(" (disabled)");
377 break; 393 break;
378 } 394 }
379 395
@@ -381,15 +397,15 @@ static int __init eisa_probe (struct eisa_root_device *root)
381 397
382 c++; 398 c++;
383 399
384 if (eisa_register_device (edev)) { 400 if (eisa_register_device(edev)) {
385 printk (KERN_ERR "EISA: Failed to register %s\n", 401 printk(KERN_ERR "EISA: Failed to register %s\n",
386 edev->id.sig); 402 edev->id.sig);
387 eisa_release_resources (edev); 403 eisa_release_resources(edev);
388 kfree (edev); 404 kfree(edev);
389 } 405 }
390 } 406 }
391 407
392 printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s"); 408 printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c == 1 ? "" : "s");
393 409
394 return 0; 410 return 0;
395} 411}
@@ -403,7 +419,7 @@ static struct resource eisa_root_res = {
403 419
404static int eisa_bus_count; 420static int eisa_bus_count;
405 421
406int __init eisa_root_register (struct eisa_root_device *root) 422int __init eisa_root_register(struct eisa_root_device *root)
407{ 423{
408 int err; 424 int err;
409 425
@@ -417,35 +433,35 @@ int __init eisa_root_register (struct eisa_root_device *root)
417 root->eisa_root_res.end = root->res->end; 433 root->eisa_root_res.end = root->res->end;
418 root->eisa_root_res.flags = IORESOURCE_BUSY; 434 root->eisa_root_res.flags = IORESOURCE_BUSY;
419 435
420 if ((err = request_resource (&eisa_root_res, &root->eisa_root_res))) 436 err = request_resource(&eisa_root_res, &root->eisa_root_res);
437 if (err)
421 return err; 438 return err;
422 439
423 root->bus_nr = eisa_bus_count++; 440 root->bus_nr = eisa_bus_count++;
424 441
425 if ((err = eisa_probe (root))) 442 err = eisa_probe(root);
426 release_resource (&root->eisa_root_res); 443 if (err)
444 release_resource(&root->eisa_root_res);
427 445
428 return err; 446 return err;
429} 447}
430 448
431static int __init eisa_init (void) 449static int __init eisa_init(void)
432{ 450{
433 int r; 451 int r;
434 452
435 if ((r = bus_register (&eisa_bus_type))) 453 r = bus_register(&eisa_bus_type);
454 if (r)
436 return r; 455 return r;
437 456
438 printk (KERN_INFO "EISA bus registered\n"); 457 printk(KERN_INFO "EISA bus registered\n");
439 return 0; 458 return 0;
440} 459}
441 460
442module_param_array(enable_dev, int, &enable_dev_count, 0444); 461module_param_array(enable_dev, int, &enable_dev_count, 0444);
443module_param_array(disable_dev, int, &disable_dev_count, 0444); 462module_param_array(disable_dev, int, &disable_dev_count, 0444);
444 463
445postcore_initcall (eisa_init); 464postcore_initcall(eisa_init);
446 465
447int EISA_bus; /* for legacy drivers */ 466int EISA_bus; /* for legacy drivers */
448EXPORT_SYMBOL (EISA_bus); 467EXPORT_SYMBOL(EISA_bus);
449EXPORT_SYMBOL (eisa_bus_type);
450EXPORT_SYMBOL (eisa_driver_register);
451EXPORT_SYMBOL (eisa_driver_unregister);
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c
index 56f9234781fa..20f645743ead 100644
--- a/drivers/firmware/memmap.c
+++ b/drivers/firmware/memmap.c
@@ -122,29 +122,53 @@ static int firmware_map_add_entry(u64 start, u64 end,
122 return 0; 122 return 0;
123} 123}
124 124
125/*
126 * Add memmap entry on sysfs
127 */
128static int add_sysfs_fw_map_entry(struct firmware_map_entry *entry)
129{
130 static int map_entries_nr;
131 static struct kset *mmap_kset;
132
133 if (!mmap_kset) {
134 mmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
135 if (!mmap_kset)
136 return -ENOMEM;
137 }
138
139 entry->kobj.kset = mmap_kset;
140 if (kobject_add(&entry->kobj, NULL, "%d", map_entries_nr++))
141 kobject_put(&entry->kobj);
142
143 return 0;
144}
145
125/** 146/**
126 * firmware_map_add() - Adds a firmware mapping entry. 147 * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
148 * memory hotplug.
127 * @start: Start of the memory range. 149 * @start: Start of the memory range.
128 * @end: End of the memory range (inclusive). 150 * @end: End of the memory range (inclusive).
129 * @type: Type of the memory range. 151 * @type: Type of the memory range.
130 * 152 *
131 * This function uses kmalloc() for memory 153 * Adds a firmware mapping entry. This function is for memory hotplug, it is
132 * allocation. Use firmware_map_add_early() if you want to use the bootmem 154 * similar to function firmware_map_add_early(). The only difference is that
133 * allocator. 155 * it will create the syfs entry dynamically.
134 *
135 * That function must be called before late_initcall.
136 * 156 *
137 * Returns 0 on success, or -ENOMEM if no memory could be allocated. 157 * Returns 0 on success, or -ENOMEM if no memory could be allocated.
138 **/ 158 **/
139int firmware_map_add(u64 start, u64 end, const char *type) 159int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
140{ 160{
141 struct firmware_map_entry *entry; 161 struct firmware_map_entry *entry;
142 162
143 entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC); 163 entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
144 if (!entry) 164 if (!entry)
145 return -ENOMEM; 165 return -ENOMEM;
146 166
147 return firmware_map_add_entry(start, end, type, entry); 167 firmware_map_add_entry(start, end, type, entry);
168 /* create the memmap entry */
169 add_sysfs_fw_map_entry(entry);
170
171 return 0;
148} 172}
149 173
150/** 174/**
@@ -154,7 +178,7 @@ int firmware_map_add(u64 start, u64 end, const char *type)
154 * @type: Type of the memory range. 178 * @type: Type of the memory range.
155 * 179 *
156 * Adds a firmware mapping entry. This function uses the bootmem allocator 180 * Adds a firmware mapping entry. This function uses the bootmem allocator
157 * for memory allocation. Use firmware_map_add() if you want to use kmalloc(). 181 * for memory allocation.
158 * 182 *
159 * That function must be called before late_initcall. 183 * That function must be called before late_initcall.
160 * 184 *
@@ -214,19 +238,10 @@ static ssize_t memmap_attr_show(struct kobject *kobj,
214 */ 238 */
215static int __init memmap_init(void) 239static int __init memmap_init(void)
216{ 240{
217 int i = 0;
218 struct firmware_map_entry *entry; 241 struct firmware_map_entry *entry;
219 struct kset *memmap_kset;
220
221 memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
222 if (WARN_ON(!memmap_kset))
223 return -ENOMEM;
224 242
225 list_for_each_entry(entry, &map_entries, list) { 243 list_for_each_entry(entry, &map_entries, list)
226 entry->kobj.kset = memmap_kset; 244 add_sysfs_fw_map_entry(entry);
227 if (kobject_add(&entry->kobj, NULL, "%d", i++))
228 kobject_put(&entry->kobj);
229 }
230 245
231 return 0; 246 return 0;
232} 247}
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 1f1d88ae68d6..fee678f74a19 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -65,8 +65,17 @@ config GPIO_SYSFS
65 65
66# put expanders in the right section, in alphabetical order 66# put expanders in the right section, in alphabetical order
67 67
68config GPIO_MAX730X
69 tristate
70
68comment "Memory mapped GPIO expanders:" 71comment "Memory mapped GPIO expanders:"
69 72
73config GPIO_IT8761E
74 tristate "IT8761E GPIO support"
75 depends on GPIOLIB
76 help
77 Say yes here to support GPIO functionality of IT8761E super I/O chip.
78
70config GPIO_PL061 79config GPIO_PL061
71 bool "PrimeCell PL061 GPIO support" 80 bool "PrimeCell PL061 GPIO support"
72 depends on ARM_AMBA 81 depends on ARM_AMBA
@@ -85,8 +94,32 @@ config GPIO_VR41XX
85 help 94 help
86 Say yes here to support the NEC VR4100 series General-purpose I/O Uint 95 Say yes here to support the NEC VR4100 series General-purpose I/O Uint
87 96
97config GPIO_SCH
98 tristate "Intel SCH GPIO"
99 depends on GPIOLIB && PCI
100 select MFD_CORE
101 select LPC_SCH
102 help
103 Say yes here to support GPIO interface on Intel Poulsbo SCH.
104 The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are
105 powered by the core power rail and are turned off during sleep
106 modes (S3 and higher). The remaining four GPIOs are powered by
107 the Intel SCH suspend power supply. These GPIOs remain
108 active during S3. The suspend powered GPIOs can be used to wake the
109 system from the Suspend-to-RAM state.
110
111 This driver can also be built as a module. If so, the module
112 will be called sch-gpio.
113
88comment "I2C GPIO expanders:" 114comment "I2C GPIO expanders:"
89 115
116config GPIO_MAX7300
117 tristate "Maxim MAX7300 GPIO expander"
118 depends on I2C
119 select GPIO_MAX730X
120 help
121 GPIO driver for Maxim MAX7301 I2C-based GPIO expander.
122
90config GPIO_MAX732X 123config GPIO_MAX732X
91 tristate "MAX7319, MAX7320-7327 I2C Port Expanders" 124 tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
92 depends on I2C 125 depends on I2C
@@ -124,6 +157,13 @@ config GPIO_PCA953X
124 This driver can also be built as a module. If so, the module 157 This driver can also be built as a module. If so, the module
125 will be called pca953x. 158 will be called pca953x.
126 159
160config GPIO_PCA953X_IRQ
161 bool "Interrupt controller support for PCA953x"
162 depends on GPIO_PCA953X=y
163 help
164 Say yes here to enable the pca953x to be used as an interrupt
165 controller. It requires the driver to be built in the kernel.
166
127config GPIO_PCF857X 167config GPIO_PCF857X
128 tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders" 168 tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders"
129 depends on I2C 169 depends on I2C
@@ -162,6 +202,20 @@ config GPIO_WM831X
162 Say yes here to access the GPIO signals of WM831x power management 202 Say yes here to access the GPIO signals of WM831x power management
163 chips from Wolfson Microelectronics. 203 chips from Wolfson Microelectronics.
164 204
205config GPIO_WM8350
206 tristate "WM8350 GPIOs"
207 depends on MFD_WM8350
208 help
209 Say yes here to access the GPIO signals of WM8350 power management
210 chips from Wolfson Microelectronics.
211
212config GPIO_WM8994
213 tristate "WM8994 GPIOs"
214 depends on MFD_WM8994
215 help
216 Say yes here to access the GPIO signals of WM8994 audio hub
217 CODECs from Wolfson Microelectronics.
218
165config GPIO_ADP5520 219config GPIO_ADP5520
166 tristate "GPIO Support for ADP5520 PMIC" 220 tristate "GPIO Support for ADP5520 PMIC"
167 depends on PMIC_ADP5520 221 depends on PMIC_ADP5520
@@ -226,8 +280,9 @@ comment "SPI GPIO expanders:"
226config GPIO_MAX7301 280config GPIO_MAX7301
227 tristate "Maxim MAX7301 GPIO expander" 281 tristate "Maxim MAX7301 GPIO expander"
228 depends on SPI_MASTER 282 depends on SPI_MASTER
283 select GPIO_MAX730X
229 help 284 help
230 gpio driver for Maxim MAX7301 SPI GPIO expander. 285 GPIO driver for Maxim MAX7301 SPI-based GPIO expander.
231 286
232config GPIO_MCP23S08 287config GPIO_MCP23S08
233 tristate "Microchip MCP23S08 I/O expander" 288 tristate "Microchip MCP23S08 I/O expander"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 48687238edb1..10f3f8d958b1 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_GPIOLIB) += gpiolib.o
7obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o 7obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o
8obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o 8obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
9obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o 9obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
10obj-$(CONFIG_GPIO_MAX730X) += max730x.o
11obj-$(CONFIG_GPIO_MAX7300) += max7300.o
10obj-$(CONFIG_GPIO_MAX7301) += max7301.o 12obj-$(CONFIG_GPIO_MAX7301) += max7301.o
11obj-$(CONFIG_GPIO_MAX732X) += max732x.o 13obj-$(CONFIG_GPIO_MAX732X) += max732x.o
12obj-$(CONFIG_GPIO_MC33880) += mc33880.o 14obj-$(CONFIG_GPIO_MC33880) += mc33880.o
@@ -20,5 +22,9 @@ obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o
20obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o 22obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o
21obj-$(CONFIG_GPIO_CS5535) += cs5535-gpio.o 23obj-$(CONFIG_GPIO_CS5535) += cs5535-gpio.o
22obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o 24obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o
25obj-$(CONFIG_GPIO_IT8761E) += it8761e_gpio.o
23obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o 26obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
24obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o 27obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.o
28obj-$(CONFIG_GPIO_WM8350) += wm8350-gpiolib.o
29obj-$(CONFIG_GPIO_WM8994) += wm8994-gpio.o
30obj-$(CONFIG_GPIO_SCH) += sch_gpio.o \ No newline at end of file
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
index 0fdbe94f24a3..0c3c498f2260 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/cs5535-gpio.c
@@ -154,7 +154,7 @@ static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
154 154
155static int chip_gpio_get(struct gpio_chip *chip, unsigned offset) 155static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
156{ 156{
157 return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL); 157 return cs5535_gpio_isset(offset, GPIO_READ_BACK);
158} 158}
159 159
160static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val) 160static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
@@ -172,6 +172,7 @@ static int chip_direction_input(struct gpio_chip *c, unsigned offset)
172 172
173 spin_lock_irqsave(&chip->lock, flags); 173 spin_lock_irqsave(&chip->lock, flags);
174 __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE); 174 __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
175 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
175 spin_unlock_irqrestore(&chip->lock, flags); 176 spin_unlock_irqrestore(&chip->lock, flags);
176 177
177 return 0; 178 return 0;
@@ -184,6 +185,7 @@ static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
184 185
185 spin_lock_irqsave(&chip->lock, flags); 186 spin_lock_irqsave(&chip->lock, flags);
186 187
188 __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
187 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE); 189 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
188 if (val) 190 if (val)
189 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL); 191 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 350842ad3632..9006fdb26fea 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1237,6 +1237,64 @@ void gpio_free(unsigned gpio)
1237} 1237}
1238EXPORT_SYMBOL_GPL(gpio_free); 1238EXPORT_SYMBOL_GPL(gpio_free);
1239 1239
1240/**
1241 * gpio_request_one - request a single GPIO with initial configuration
1242 * @gpio: the GPIO number
1243 * @flags: GPIO configuration as specified by GPIOF_*
1244 * @label: a literal description string of this GPIO
1245 */
1246int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
1247{
1248 int err;
1249
1250 err = gpio_request(gpio, label);
1251 if (err)
1252 return err;
1253
1254 if (flags & GPIOF_DIR_IN)
1255 err = gpio_direction_input(gpio);
1256 else
1257 err = gpio_direction_output(gpio,
1258 (flags & GPIOF_INIT_HIGH) ? 1 : 0);
1259
1260 return err;
1261}
1262EXPORT_SYMBOL_GPL(gpio_request_one);
1263
1264/**
1265 * gpio_request_array - request multiple GPIOs in a single call
1266 * @array: array of the 'struct gpio'
1267 * @num: how many GPIOs in the array
1268 */
1269int gpio_request_array(struct gpio *array, size_t num)
1270{
1271 int i, err;
1272
1273 for (i = 0; i < num; i++, array++) {
1274 err = gpio_request_one(array->gpio, array->flags, array->label);
1275 if (err)
1276 goto err_free;
1277 }
1278 return 0;
1279
1280err_free:
1281 while (i--)
1282 gpio_free((--array)->gpio);
1283 return err;
1284}
1285EXPORT_SYMBOL_GPL(gpio_request_array);
1286
1287/**
1288 * gpio_free_array - release multiple GPIOs in a single call
1289 * @array: array of the 'struct gpio'
1290 * @num: how many GPIOs in the array
1291 */
1292void gpio_free_array(struct gpio *array, size_t num)
1293{
1294 while (num--)
1295 gpio_free((array++)->gpio);
1296}
1297EXPORT_SYMBOL_GPL(gpio_free_array);
1240 1298
1241/** 1299/**
1242 * gpiochip_is_requested - return string iff signal was requested 1300 * gpiochip_is_requested - return string iff signal was requested
diff --git a/drivers/gpio/it8761e_gpio.c b/drivers/gpio/it8761e_gpio.c
new file mode 100644
index 000000000000..753219cf993a
--- /dev/null
+++ b/drivers/gpio/it8761e_gpio.c
@@ -0,0 +1,231 @@
1/*
2 * it8761_gpio.c - GPIO interface for IT8761E Super I/O chip
3 *
4 * Author: Denis Turischev <denis@compulab.co.il>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License 2 as published
8 * by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/io.h>
24#include <linux/errno.h>
25#include <linux/ioport.h>
26
27#include <linux/gpio.h>
28
29#define SIO_CHIP_ID 0x8761
30#define CHIP_ID_HIGH_BYTE 0x20
31#define CHIP_ID_LOW_BYTE 0x21
32
33static u8 ports[2] = { 0x2e, 0x4e };
34static u8 port;
35
36static DEFINE_SPINLOCK(sio_lock);
37
38#define GPIO_NAME "it8761-gpio"
39#define GPIO_BA_HIGH_BYTE 0x60
40#define GPIO_BA_LOW_BYTE 0x61
41#define GPIO_IOSIZE 4
42#define GPIO1X_IO 0xf0
43#define GPIO2X_IO 0xf1
44
45static u16 gpio_ba;
46
47static u8 read_reg(u8 addr, u8 port)
48{
49 outb(addr, port);
50 return inb(port + 1);
51}
52
53static void write_reg(u8 data, u8 addr, u8 port)
54{
55 outb(addr, port);
56 outb(data, port + 1);
57}
58
59static void enter_conf_mode(u8 port)
60{
61 outb(0x87, port);
62 outb(0x61, port);
63 outb(0x55, port);
64 outb((port == 0x2e) ? 0x55 : 0xaa, port);
65}
66
67static void exit_conf_mode(u8 port)
68{
69 outb(0x2, port);
70 outb(0x2, port + 1);
71}
72
73static void enter_gpio_mode(u8 port)
74{
75 write_reg(0x2, 0x7, port);
76}
77
78static int it8761e_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
79{
80 u16 reg;
81 u8 bit;
82
83 bit = gpio_num % 7;
84 reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
85
86 return !!(inb(reg) & (1 << bit));
87}
88
89static int it8761e_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
90{
91 u8 curr_dirs;
92 u8 io_reg, bit;
93
94 bit = gpio_num % 7;
95 io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
96
97 spin_lock(&sio_lock);
98
99 enter_conf_mode(port);
100 enter_gpio_mode(port);
101
102 curr_dirs = read_reg(io_reg, port);
103
104 if (curr_dirs & (1 << bit))
105 write_reg(curr_dirs & ~(1 << bit), io_reg, port);
106
107 exit_conf_mode(port);
108
109 spin_unlock(&sio_lock);
110 return 0;
111}
112
113static void it8761e_gpio_set(struct gpio_chip *gc,
114 unsigned gpio_num, int val)
115{
116 u8 curr_vals, bit;
117 u16 reg;
118
119 bit = gpio_num % 7;
120 reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
121
122 spin_lock(&sio_lock);
123
124 curr_vals = inb(reg);
125 if (val)
126 outb(curr_vals | (1 << bit) , reg);
127 else
128 outb(curr_vals & ~(1 << bit), reg);
129
130 spin_unlock(&sio_lock);
131}
132
133static int it8761e_gpio_direction_out(struct gpio_chip *gc,
134 unsigned gpio_num, int val)
135{
136 u8 curr_dirs, io_reg, bit;
137
138 bit = gpio_num % 7;
139 io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
140
141 it8761e_gpio_set(gc, gpio_num, val);
142
143 spin_lock(&sio_lock);
144
145 enter_conf_mode(port);
146 enter_gpio_mode(port);
147
148 curr_dirs = read_reg(io_reg, port);
149
150 if (!(curr_dirs & (1 << bit)))
151 write_reg(curr_dirs | (1 << bit), io_reg, port);
152
153 exit_conf_mode(port);
154
155 spin_unlock(&sio_lock);
156 return 0;
157}
158
159static struct gpio_chip it8761e_gpio_chip = {
160 .label = GPIO_NAME,
161 .owner = THIS_MODULE,
162 .get = it8761e_gpio_get,
163 .direction_input = it8761e_gpio_direction_in,
164 .set = it8761e_gpio_set,
165 .direction_output = it8761e_gpio_direction_out,
166};
167
168static int __init it8761e_gpio_init(void)
169{
170 int i, id, err;
171
172 /* chip and port detection */
173 for (i = 0; i < ARRAY_SIZE(ports); i++) {
174 spin_lock(&sio_lock);
175 enter_conf_mode(ports[i]);
176
177 id = (read_reg(CHIP_ID_HIGH_BYTE, ports[i]) << 8) +
178 read_reg(CHIP_ID_LOW_BYTE, ports[i]);
179
180 exit_conf_mode(ports[i]);
181 spin_unlock(&sio_lock);
182
183 if (id == SIO_CHIP_ID) {
184 port = ports[i];
185 break;
186 }
187 }
188
189 if (!port)
190 return -ENODEV;
191
192 /* fetch GPIO base address */
193 enter_conf_mode(port);
194 enter_gpio_mode(port);
195 gpio_ba = (read_reg(GPIO_BA_HIGH_BYTE, port) << 8) +
196 read_reg(GPIO_BA_LOW_BYTE, port);
197 exit_conf_mode(port);
198
199 if (!request_region(gpio_ba, GPIO_IOSIZE, GPIO_NAME))
200 return -EBUSY;
201
202 it8761e_gpio_chip.base = -1;
203 it8761e_gpio_chip.ngpio = 14;
204
205 err = gpiochip_add(&it8761e_gpio_chip);
206 if (err < 0)
207 goto gpiochip_add_err;
208
209 return 0;
210
211gpiochip_add_err:
212 release_region(gpio_ba, GPIO_IOSIZE);
213 gpio_ba = 0;
214 return err;
215}
216
217static void __exit it8761e_gpio_exit(void)
218{
219 if (gpio_ba) {
220 gpiochip_remove(&it8761e_gpio_chip);
221
222 release_region(gpio_ba, GPIO_IOSIZE);
223 gpio_ba = 0;
224 }
225}
226module_init(it8761e_gpio_init);
227module_exit(it8761e_gpio_exit);
228
229MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
230MODULE_DESCRIPTION("GPIO interface for IT8761E Super I/O chip");
231MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/max7300.c b/drivers/gpio/max7300.c
new file mode 100644
index 000000000000..9d74eef1157a
--- /dev/null
+++ b/drivers/gpio/max7300.c
@@ -0,0 +1,94 @@
1/*
2 * drivers/gpio/max7300.c
3 *
4 * Copyright (C) 2009 Wolfram Sang, Pengutronix
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Check max730x.c for further details.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/mutex.h>
17#include <linux/i2c.h>
18#include <linux/spi/max7301.h>
19
20static int max7300_i2c_write(struct device *dev, unsigned int reg,
21 unsigned int val)
22{
23 struct i2c_client *client = to_i2c_client(dev);
24
25 return i2c_smbus_write_byte_data(client, reg, val);
26}
27
28static int max7300_i2c_read(struct device *dev, unsigned int reg)
29{
30 struct i2c_client *client = to_i2c_client(dev);
31
32 return i2c_smbus_read_byte_data(client, reg);
33}
34
35static int __devinit max7300_probe(struct i2c_client *client,
36 const struct i2c_device_id *id)
37{
38 struct max7301 *ts;
39 int ret;
40
41 if (!i2c_check_functionality(client->adapter,
42 I2C_FUNC_SMBUS_BYTE_DATA))
43 return -EIO;
44
45 ts = kzalloc(sizeof(struct max7301), GFP_KERNEL);
46 if (!ts)
47 return -ENOMEM;
48
49 ts->read = max7300_i2c_read;
50 ts->write = max7300_i2c_write;
51 ts->dev = &client->dev;
52
53 ret = __max730x_probe(ts);
54 if (ret)
55 kfree(ts);
56 return ret;
57}
58
59static int __devexit max7300_remove(struct i2c_client *client)
60{
61 return __max730x_remove(&client->dev);
62}
63
64static const struct i2c_device_id max7300_id[] = {
65 { "max7300", 0 },
66 { }
67};
68MODULE_DEVICE_TABLE(i2c, max7300_id);
69
70static struct i2c_driver max7300_driver = {
71 .driver = {
72 .name = "max7300",
73 .owner = THIS_MODULE,
74 },
75 .probe = max7300_probe,
76 .remove = __devexit_p(max7300_remove),
77 .id_table = max7300_id,
78};
79
80static int __init max7300_init(void)
81{
82 return i2c_add_driver(&max7300_driver);
83}
84subsys_initcall(max7300_init);
85
86static void __exit max7300_exit(void)
87{
88 i2c_del_driver(&max7300_driver);
89}
90module_exit(max7300_exit);
91
92MODULE_AUTHOR("Wolfram Sang");
93MODULE_LICENSE("GPL v2");
94MODULE_DESCRIPTION("MAX7300 GPIO-Expander");
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c
index 480956f1ca50..965d9b1ea13e 100644
--- a/drivers/gpio/max7301.c
+++ b/drivers/gpio/max7301.c
@@ -1,98 +1,41 @@
1/** 1/*
2 * drivers/gpio/max7301.c 2 * drivers/gpio/max7301.c
3 * 3 *
4 * Copyright (C) 2006 Juergen Beisert, Pengutronix 4 * Copyright (C) 2006 Juergen Beisert, Pengutronix
5 * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix 5 * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
6 * Copyright (C) 2009 Wolfram Sang, Pengutronix
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
10 * 11 *
11 * The Maxim's MAX7301 device is an SPI driven GPIO expander. There are 12 * Check max730x.c for further details.
12 * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
13 * details
14 * Note:
15 * - DIN must be stable at the rising edge of clock.
16 * - when writing:
17 * - always clock in 16 clocks at once
18 * - at DIN: D15 first, D0 last
19 * - D0..D7 = databyte, D8..D14 = commandbyte
20 * - D15 = low -> write command
21 * - when reading
22 * - always clock in 16 clocks at once
23 * - at DIN: D15 first, D0 last
24 * - D0..D7 = dummy, D8..D14 = register address
25 * - D15 = high -> read command
26 * - raise CS and assert it again
27 * - always clock in 16 clocks at once
28 * - at DOUT: D15 first, D0 last
29 * - D0..D7 contains the data from the first cycle
30 *
31 * The driver exports a standard gpiochip interface
32 */ 13 */
33 14
15#include <linux/module.h>
34#include <linux/init.h> 16#include <linux/init.h>
35#include <linux/platform_device.h> 17#include <linux/platform_device.h>
36#include <linux/mutex.h> 18#include <linux/mutex.h>
37#include <linux/spi/spi.h> 19#include <linux/spi/spi.h>
38#include <linux/spi/max7301.h> 20#include <linux/spi/max7301.h>
39#include <linux/gpio.h>
40
41#define DRIVER_NAME "max7301"
42
43/*
44 * Pin configurations, see MAX7301 datasheet page 6
45 */
46#define PIN_CONFIG_MASK 0x03
47#define PIN_CONFIG_IN_PULLUP 0x03
48#define PIN_CONFIG_IN_WO_PULLUP 0x02
49#define PIN_CONFIG_OUT 0x01
50
51#define PIN_NUMBER 28
52
53
54/*
55 * Some registers must be read back to modify.
56 * To save time we cache them here in memory
57 */
58struct max7301 {
59 struct mutex lock;
60 u8 port_config[8]; /* field 0 is unused */
61 u32 out_level; /* cached output levels */
62 struct gpio_chip chip;
63 struct spi_device *spi;
64};
65 21
66/** 22/* A write to the MAX7301 means one message with one transfer */
67 * max7301_write - Write a new register content 23static int max7301_spi_write(struct device *dev, unsigned int reg,
68 * @spi: The SPI device 24 unsigned int val)
69 * @reg: Register offset
70 * @val: Value to write
71 *
72 * A write to the MAX7301 means one message with one transfer
73 *
74 * Returns 0 if successful or a negative value on error
75 */
76static int max7301_write(struct spi_device *spi, unsigned int reg, unsigned int val)
77{ 25{
26 struct spi_device *spi = to_spi_device(dev);
78 u16 word = ((reg & 0x7F) << 8) | (val & 0xFF); 27 u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
28
79 return spi_write(spi, (const u8 *)&word, sizeof(word)); 29 return spi_write(spi, (const u8 *)&word, sizeof(word));
80} 30}
81 31
82/** 32/* A read from the MAX7301 means two transfers; here, one message each */
83 * max7301_read - Read back register content 33
84 * @spi: The SPI device 34static int max7301_spi_read(struct device *dev, unsigned int reg)
85 * @reg: Register offset
86 *
87 * A read from the MAX7301 means two transfers; here, one message each
88 *
89 * Returns positive 8 bit value from device if successful or a
90 * negative value on error
91 */
92static int max7301_read(struct spi_device *spi, unsigned int reg)
93{ 35{
94 int ret; 36 int ret;
95 u16 word; 37 u16 word;
38 struct spi_device *spi = to_spi_device(dev);
96 39
97 word = 0x8000 | (reg << 8); 40 word = 0x8000 | (reg << 8);
98 ret = spi_write(spi, (const u8 *)&word, sizeof(word)); 41 ret = spi_write(spi, (const u8 *)&word, sizeof(word));
@@ -108,125 +51,13 @@ static int max7301_read(struct spi_device *spi, unsigned int reg)
108 return word & 0xff; 51 return word & 0xff;
109} 52}
110 53
111static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
112{
113 struct max7301 *ts = container_of(chip, struct max7301, chip);
114 u8 *config;
115 int ret;
116
117 /* First 4 pins are unused in the controller */
118 offset += 4;
119
120 config = &ts->port_config[offset >> 2];
121
122 mutex_lock(&ts->lock);
123
124 /* Standard GPIO API doesn't support pull-ups, has to be extended.
125 * Hard-coding no pollup for now. */
126 *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
127
128 ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
129
130 mutex_unlock(&ts->lock);
131
132 return ret;
133}
134
135static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
136{
137 if (value) {
138 ts->out_level |= 1 << offset;
139 return max7301_write(ts->spi, 0x20 + offset, 0x01);
140 } else {
141 ts->out_level &= ~(1 << offset);
142 return max7301_write(ts->spi, 0x20 + offset, 0x00);
143 }
144}
145
146static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
147 int value)
148{
149 struct max7301 *ts = container_of(chip, struct max7301, chip);
150 u8 *config;
151 int ret;
152
153 /* First 4 pins are unused in the controller */
154 offset += 4;
155
156 config = &ts->port_config[offset >> 2];
157
158 mutex_lock(&ts->lock);
159
160 *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
161
162 ret = __max7301_set(ts, offset, value);
163
164 if (!ret)
165 ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
166
167 mutex_unlock(&ts->lock);
168
169 return ret;
170}
171
172static int max7301_get(struct gpio_chip *chip, unsigned offset)
173{
174 struct max7301 *ts = container_of(chip, struct max7301, chip);
175 int config, level = -EINVAL;
176
177 /* First 4 pins are unused in the controller */
178 offset += 4;
179
180 mutex_lock(&ts->lock);
181
182 config = (ts->port_config[offset >> 2] >> ((offset & 3) * 2)) & 3;
183
184 switch (config) {
185 case 1:
186 /* Output: return cached level */
187 level = !!(ts->out_level & (1 << offset));
188 break;
189 case 2:
190 case 3:
191 /* Input: read out */
192 level = max7301_read(ts->spi, 0x20 + offset) & 0x01;
193 }
194 mutex_unlock(&ts->lock);
195
196 return level;
197}
198
199static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
200{
201 struct max7301 *ts = container_of(chip, struct max7301, chip);
202
203 /* First 4 pins are unused in the controller */
204 offset += 4;
205
206 mutex_lock(&ts->lock);
207
208 __max7301_set(ts, offset, value);
209
210 mutex_unlock(&ts->lock);
211}
212
213static int __devinit max7301_probe(struct spi_device *spi) 54static int __devinit max7301_probe(struct spi_device *spi)
214{ 55{
215 struct max7301 *ts; 56 struct max7301 *ts;
216 struct max7301_platform_data *pdata; 57 int ret;
217 int i, ret;
218
219 pdata = spi->dev.platform_data;
220 if (!pdata || !pdata->base) {
221 dev_dbg(&spi->dev, "incorrect or missing platform data\n");
222 return -EINVAL;
223 }
224 58
225 /* 59 /* bits_per_word cannot be configured in platform data */
226 * bits_per_word cannot be configured in platform data
227 */
228 spi->bits_per_word = 16; 60 spi->bits_per_word = 16;
229
230 ret = spi_setup(spi); 61 ret = spi_setup(spi);
231 if (ret < 0) 62 if (ret < 0)
232 return ret; 63 return ret;
@@ -235,90 +66,35 @@ static int __devinit max7301_probe(struct spi_device *spi)
235 if (!ts) 66 if (!ts)
236 return -ENOMEM; 67 return -ENOMEM;
237 68
238 mutex_init(&ts->lock); 69 ts->read = max7301_spi_read;
239 70 ts->write = max7301_spi_write;
240 dev_set_drvdata(&spi->dev, ts); 71 ts->dev = &spi->dev;
241 72
242 /* Power up the chip and disable IRQ output */ 73 ret = __max730x_probe(ts);
243 max7301_write(spi, 0x04, 0x01);
244
245 ts->spi = spi;
246
247 ts->chip.label = DRIVER_NAME,
248
249 ts->chip.direction_input = max7301_direction_input;
250 ts->chip.get = max7301_get;
251 ts->chip.direction_output = max7301_direction_output;
252 ts->chip.set = max7301_set;
253
254 ts->chip.base = pdata->base;
255 ts->chip.ngpio = PIN_NUMBER;
256 ts->chip.can_sleep = 1;
257 ts->chip.dev = &spi->dev;
258 ts->chip.owner = THIS_MODULE;
259
260 /*
261 * tristate all pins in hardware and cache the
262 * register values for later use.
263 */
264 for (i = 1; i < 8; i++) {
265 int j;
266 /* 0xAA means input with internal pullup disabled */
267 max7301_write(spi, 0x08 + i, 0xAA);
268 ts->port_config[i] = 0xAA;
269 for (j = 0; j < 4; j++) {
270 int offset = (i - 1) * 4 + j;
271 ret = max7301_direction_input(&ts->chip, offset);
272 if (ret)
273 goto exit_destroy;
274 }
275 }
276
277 ret = gpiochip_add(&ts->chip);
278 if (ret) 74 if (ret)
279 goto exit_destroy; 75 kfree(ts);
280
281 return ret;
282
283exit_destroy:
284 dev_set_drvdata(&spi->dev, NULL);
285 mutex_destroy(&ts->lock);
286 kfree(ts);
287 return ret; 76 return ret;
288} 77}
289 78
290static int __devexit max7301_remove(struct spi_device *spi) 79static int __devexit max7301_remove(struct spi_device *spi)
291{ 80{
292 struct max7301 *ts; 81 return __max730x_remove(&spi->dev);
293 int ret;
294
295 ts = dev_get_drvdata(&spi->dev);
296 if (ts == NULL)
297 return -ENODEV;
298
299 dev_set_drvdata(&spi->dev, NULL);
300
301 /* Power down the chip and disable IRQ output */
302 max7301_write(spi, 0x04, 0x00);
303
304 ret = gpiochip_remove(&ts->chip);
305 if (!ret) {
306 mutex_destroy(&ts->lock);
307 kfree(ts);
308 } else
309 dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
310 ret);
311
312 return ret;
313} 82}
314 83
84static const struct spi_device_id max7301_id[] = {
85 { "max7301", 0 },
86 { }
87};
88MODULE_DEVICE_TABLE(spi, max7301_id);
89
315static struct spi_driver max7301_driver = { 90static struct spi_driver max7301_driver = {
316 .driver = { 91 .driver = {
317 .name = DRIVER_NAME, 92 .name = "max7301",
318 .owner = THIS_MODULE, 93 .owner = THIS_MODULE,
319 }, 94 },
320 .probe = max7301_probe, 95 .probe = max7301_probe,
321 .remove = __devexit_p(max7301_remove), 96 .remove = __devexit_p(max7301_remove),
97 .id_table = max7301_id,
322}; 98};
323 99
324static int __init max7301_init(void) 100static int __init max7301_init(void)
@@ -336,7 +112,6 @@ static void __exit max7301_exit(void)
336} 112}
337module_exit(max7301_exit); 113module_exit(max7301_exit);
338 114
339MODULE_AUTHOR("Juergen Beisert"); 115MODULE_AUTHOR("Juergen Beisert, Wolfram Sang");
340MODULE_LICENSE("GPL v2"); 116MODULE_LICENSE("GPL v2");
341MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander"); 117MODULE_DESCRIPTION("MAX7301 GPIO-Expander");
342MODULE_ALIAS("spi:" DRIVER_NAME);
diff --git a/drivers/gpio/max730x.c b/drivers/gpio/max730x.c
new file mode 100644
index 000000000000..c9bced55f82b
--- /dev/null
+++ b/drivers/gpio/max730x.c
@@ -0,0 +1,244 @@
1/**
2 * drivers/gpio/max7301.c
3 *
4 * Copyright (C) 2006 Juergen Beisert, Pengutronix
5 * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
6 * Copyright (C) 2009 Wolfram Sang, Pengutronix
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * The Maxim MAX7300/1 device is an I2C/SPI driven GPIO expander. There are
13 * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
14 * details
15 * Note:
16 * - DIN must be stable at the rising edge of clock.
17 * - when writing:
18 * - always clock in 16 clocks at once
19 * - at DIN: D15 first, D0 last
20 * - D0..D7 = databyte, D8..D14 = commandbyte
21 * - D15 = low -> write command
22 * - when reading
23 * - always clock in 16 clocks at once
24 * - at DIN: D15 first, D0 last
25 * - D0..D7 = dummy, D8..D14 = register address
26 * - D15 = high -> read command
27 * - raise CS and assert it again
28 * - always clock in 16 clocks at once
29 * - at DOUT: D15 first, D0 last
30 * - D0..D7 contains the data from the first cycle
31 *
32 * The driver exports a standard gpiochip interface
33 */
34
35#include <linux/module.h>
36#include <linux/init.h>
37#include <linux/platform_device.h>
38#include <linux/mutex.h>
39#include <linux/spi/max7301.h>
40#include <linux/gpio.h>
41
42/*
43 * Pin configurations, see MAX7301 datasheet page 6
44 */
45#define PIN_CONFIG_MASK 0x03
46#define PIN_CONFIG_IN_PULLUP 0x03
47#define PIN_CONFIG_IN_WO_PULLUP 0x02
48#define PIN_CONFIG_OUT 0x01
49
50#define PIN_NUMBER 28
51
52static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
53{
54 struct max7301 *ts = container_of(chip, struct max7301, chip);
55 u8 *config;
56 u8 offset_bits;
57 int ret;
58
59 /* First 4 pins are unused in the controller */
60 offset += 4;
61 offset_bits = (offset & 3) << 1;
62
63 config = &ts->port_config[offset >> 2];
64
65 mutex_lock(&ts->lock);
66
67 /* Standard GPIO API doesn't support pull-ups, has to be extended.
68 * Hard-coding no pollup for now. */
69 *config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
70 | (PIN_CONFIG_IN_WO_PULLUP << offset_bits);
71
72 ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
73
74 mutex_unlock(&ts->lock);
75
76 return ret;
77}
78
79static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
80{
81 if (value) {
82 ts->out_level |= 1 << offset;
83 return ts->write(ts->dev, 0x20 + offset, 0x01);
84 } else {
85 ts->out_level &= ~(1 << offset);
86 return ts->write(ts->dev, 0x20 + offset, 0x00);
87 }
88}
89
90static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
91 int value)
92{
93 struct max7301 *ts = container_of(chip, struct max7301, chip);
94 u8 *config;
95 u8 offset_bits;
96 int ret;
97
98 /* First 4 pins are unused in the controller */
99 offset += 4;
100 offset_bits = (offset & 3) << 1;
101
102 config = &ts->port_config[offset >> 2];
103
104 mutex_lock(&ts->lock);
105
106 *config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
107 | (PIN_CONFIG_OUT << offset_bits);
108
109 ret = __max7301_set(ts, offset, value);
110
111 if (!ret)
112 ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
113
114 mutex_unlock(&ts->lock);
115
116 return ret;
117}
118
119static int max7301_get(struct gpio_chip *chip, unsigned offset)
120{
121 struct max7301 *ts = container_of(chip, struct max7301, chip);
122 int config, level = -EINVAL;
123
124 /* First 4 pins are unused in the controller */
125 offset += 4;
126
127 mutex_lock(&ts->lock);
128
129 config = (ts->port_config[offset >> 2] >> ((offset & 3) << 1))
130 & PIN_CONFIG_MASK;
131
132 switch (config) {
133 case PIN_CONFIG_OUT:
134 /* Output: return cached level */
135 level = !!(ts->out_level & (1 << offset));
136 break;
137 case PIN_CONFIG_IN_WO_PULLUP:
138 case PIN_CONFIG_IN_PULLUP:
139 /* Input: read out */
140 level = ts->read(ts->dev, 0x20 + offset) & 0x01;
141 }
142 mutex_unlock(&ts->lock);
143
144 return level;
145}
146
147static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
148{
149 struct max7301 *ts = container_of(chip, struct max7301, chip);
150
151 /* First 4 pins are unused in the controller */
152 offset += 4;
153
154 mutex_lock(&ts->lock);
155
156 __max7301_set(ts, offset, value);
157
158 mutex_unlock(&ts->lock);
159}
160
161int __devinit __max730x_probe(struct max7301 *ts)
162{
163 struct device *dev = ts->dev;
164 struct max7301_platform_data *pdata;
165 int i, ret;
166
167 pdata = dev->platform_data;
168 if (!pdata || !pdata->base) {
169 dev_err(dev, "incorrect or missing platform data\n");
170 return -EINVAL;
171 }
172
173 mutex_init(&ts->lock);
174 dev_set_drvdata(dev, ts);
175
176 /* Power up the chip and disable IRQ output */
177 ts->write(dev, 0x04, 0x01);
178
179 ts->chip.label = dev->driver->name;
180
181 ts->chip.direction_input = max7301_direction_input;
182 ts->chip.get = max7301_get;
183 ts->chip.direction_output = max7301_direction_output;
184 ts->chip.set = max7301_set;
185
186 ts->chip.base = pdata->base;
187 ts->chip.ngpio = PIN_NUMBER;
188 ts->chip.can_sleep = 1;
189 ts->chip.dev = dev;
190 ts->chip.owner = THIS_MODULE;
191
192 /*
193 * tristate all pins in hardware and cache the
194 * register values for later use.
195 */
196 for (i = 1; i < 8; i++) {
197 int j;
198 /* 0xAA means input with internal pullup disabled */
199 ts->write(dev, 0x08 + i, 0xAA);
200 ts->port_config[i] = 0xAA;
201 for (j = 0; j < 4; j++) {
202 int offset = (i - 1) * 4 + j;
203 ret = max7301_direction_input(&ts->chip, offset);
204 if (ret)
205 goto exit_destroy;
206 }
207 }
208
209 ret = gpiochip_add(&ts->chip);
210 if (ret)
211 goto exit_destroy;
212
213 return ret;
214
215exit_destroy:
216 dev_set_drvdata(dev, NULL);
217 mutex_destroy(&ts->lock);
218 return ret;
219}
220EXPORT_SYMBOL_GPL(__max730x_probe);
221
222int __devexit __max730x_remove(struct device *dev)
223{
224 struct max7301 *ts = dev_get_drvdata(dev);
225 int ret;
226
227 if (ts == NULL)
228 return -ENODEV;
229
230 dev_set_drvdata(dev, NULL);
231
232 /* Power down the chip and disable IRQ output */
233 ts->write(dev, 0x04, 0x00);
234
235 ret = gpiochip_remove(&ts->chip);
236 if (!ret) {
237 mutex_destroy(&ts->lock);
238 kfree(ts);
239 } else
240 dev_err(dev, "Failed to remove GPIO controller: %d\n", ret);
241
242 return ret;
243}
244EXPORT_SYMBOL_GPL(__max730x_remove);
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 6a2fb3fbb3d9..ab5daab14bc2 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -14,6 +14,8 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17#include <linux/interrupt.h>
18#include <linux/irq.h>
17#include <linux/i2c.h> 19#include <linux/i2c.h>
18#include <linux/i2c/pca953x.h> 20#include <linux/i2c/pca953x.h>
19#ifdef CONFIG_OF_GPIO 21#ifdef CONFIG_OF_GPIO
@@ -26,23 +28,28 @@
26#define PCA953X_INVERT 2 28#define PCA953X_INVERT 2
27#define PCA953X_DIRECTION 3 29#define PCA953X_DIRECTION 3
28 30
31#define PCA953X_GPIOS 0x00FF
32#define PCA953X_INT 0x0100
33
29static const struct i2c_device_id pca953x_id[] = { 34static const struct i2c_device_id pca953x_id[] = {
30 { "pca9534", 8, }, 35 { "pca9534", 8 | PCA953X_INT, },
31 { "pca9535", 16, }, 36 { "pca9535", 16 | PCA953X_INT, },
32 { "pca9536", 4, }, 37 { "pca9536", 4, },
33 { "pca9537", 4, }, 38 { "pca9537", 4 | PCA953X_INT, },
34 { "pca9538", 8, }, 39 { "pca9538", 8 | PCA953X_INT, },
35 { "pca9539", 16, }, 40 { "pca9539", 16 | PCA953X_INT, },
36 { "pca9554", 8, }, 41 { "pca9554", 8 | PCA953X_INT, },
37 { "pca9555", 16, }, 42 { "pca9555", 16 | PCA953X_INT, },
38 { "pca9556", 8, }, 43 { "pca9556", 8, },
39 { "pca9557", 8, }, 44 { "pca9557", 8, },
40 45
41 { "max7310", 8, }, 46 { "max7310", 8, },
42 { "max7315", 8, }, 47 { "max7312", 16 | PCA953X_INT, },
43 { "pca6107", 8, }, 48 { "max7313", 16 | PCA953X_INT, },
44 { "tca6408", 8, }, 49 { "max7315", 8 | PCA953X_INT, },
45 { "tca6416", 16, }, 50 { "pca6107", 8 | PCA953X_INT, },
51 { "tca6408", 8 | PCA953X_INT, },
52 { "tca6416", 16 | PCA953X_INT, },
46 /* NYET: { "tca6424", 24, }, */ 53 /* NYET: { "tca6424", 24, }, */
47 { } 54 { }
48}; 55};
@@ -53,6 +60,15 @@ struct pca953x_chip {
53 uint16_t reg_output; 60 uint16_t reg_output;
54 uint16_t reg_direction; 61 uint16_t reg_direction;
55 62
63#ifdef CONFIG_GPIO_PCA953X_IRQ
64 struct mutex irq_lock;
65 uint16_t irq_mask;
66 uint16_t irq_stat;
67 uint16_t irq_trig_raise;
68 uint16_t irq_trig_fall;
69 int irq_base;
70#endif
71
56 struct i2c_client *client; 72 struct i2c_client *client;
57 struct pca953x_platform_data *dyn_pdata; 73 struct pca953x_platform_data *dyn_pdata;
58 struct gpio_chip gpio_chip; 74 struct gpio_chip gpio_chip;
@@ -202,6 +218,210 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
202 gc->names = chip->names; 218 gc->names = chip->names;
203} 219}
204 220
221#ifdef CONFIG_GPIO_PCA953X_IRQ
222static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
223{
224 struct pca953x_chip *chip;
225
226 chip = container_of(gc, struct pca953x_chip, gpio_chip);
227 return chip->irq_base + off;
228}
229
230static void pca953x_irq_mask(unsigned int irq)
231{
232 struct pca953x_chip *chip = get_irq_chip_data(irq);
233
234 chip->irq_mask &= ~(1 << (irq - chip->irq_base));
235}
236
237static void pca953x_irq_unmask(unsigned int irq)
238{
239 struct pca953x_chip *chip = get_irq_chip_data(irq);
240
241 chip->irq_mask |= 1 << (irq - chip->irq_base);
242}
243
244static void pca953x_irq_bus_lock(unsigned int irq)
245{
246 struct pca953x_chip *chip = get_irq_chip_data(irq);
247
248 mutex_lock(&chip->irq_lock);
249}
250
251static void pca953x_irq_bus_sync_unlock(unsigned int irq)
252{
253 struct pca953x_chip *chip = get_irq_chip_data(irq);
254
255 mutex_unlock(&chip->irq_lock);
256}
257
258static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
259{
260 struct pca953x_chip *chip = get_irq_chip_data(irq);
261 uint16_t level = irq - chip->irq_base;
262 uint16_t mask = 1 << level;
263
264 if (!(type & IRQ_TYPE_EDGE_BOTH)) {
265 dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
266 irq, type);
267 return -EINVAL;
268 }
269
270 if (type & IRQ_TYPE_EDGE_FALLING)
271 chip->irq_trig_fall |= mask;
272 else
273 chip->irq_trig_fall &= ~mask;
274
275 if (type & IRQ_TYPE_EDGE_RISING)
276 chip->irq_trig_raise |= mask;
277 else
278 chip->irq_trig_raise &= ~mask;
279
280 return pca953x_gpio_direction_input(&chip->gpio_chip, level);
281}
282
283static struct irq_chip pca953x_irq_chip = {
284 .name = "pca953x",
285 .mask = pca953x_irq_mask,
286 .unmask = pca953x_irq_unmask,
287 .bus_lock = pca953x_irq_bus_lock,
288 .bus_sync_unlock = pca953x_irq_bus_sync_unlock,
289 .set_type = pca953x_irq_set_type,
290};
291
292static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
293{
294 uint16_t cur_stat;
295 uint16_t old_stat;
296 uint16_t pending;
297 uint16_t trigger;
298 int ret;
299
300 ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat);
301 if (ret)
302 return 0;
303
304 /* Remove output pins from the equation */
305 cur_stat &= chip->reg_direction;
306
307 old_stat = chip->irq_stat;
308 trigger = (cur_stat ^ old_stat) & chip->irq_mask;
309
310 if (!trigger)
311 return 0;
312
313 chip->irq_stat = cur_stat;
314
315 pending = (old_stat & chip->irq_trig_fall) |
316 (cur_stat & chip->irq_trig_raise);
317 pending &= trigger;
318
319 return pending;
320}
321
322static irqreturn_t pca953x_irq_handler(int irq, void *devid)
323{
324 struct pca953x_chip *chip = devid;
325 uint16_t pending;
326 uint16_t level;
327
328 pending = pca953x_irq_pending(chip);
329
330 if (!pending)
331 return IRQ_HANDLED;
332
333 do {
334 level = __ffs(pending);
335 handle_nested_irq(level + chip->irq_base);
336
337 pending &= ~(1 << level);
338 } while (pending);
339
340 return IRQ_HANDLED;
341}
342
343static int pca953x_irq_setup(struct pca953x_chip *chip,
344 const struct i2c_device_id *id)
345{
346 struct i2c_client *client = chip->client;
347 struct pca953x_platform_data *pdata = client->dev.platform_data;
348 int ret;
349
350 if (pdata->irq_base && (id->driver_data & PCA953X_INT)) {
351 int lvl;
352
353 ret = pca953x_read_reg(chip, PCA953X_INPUT,
354 &chip->irq_stat);
355 if (ret)
356 goto out_failed;
357
358 /*
359 * There is no way to know which GPIO line generated the
360 * interrupt. We have to rely on the previous read for
361 * this purpose.
362 */
363 chip->irq_stat &= chip->reg_direction;
364 chip->irq_base = pdata->irq_base;
365 mutex_init(&chip->irq_lock);
366
367 for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
368 int irq = lvl + chip->irq_base;
369
370 set_irq_chip_data(irq, chip);
371 set_irq_chip_and_handler(irq, &pca953x_irq_chip,
372 handle_edge_irq);
373 set_irq_nested_thread(irq, 1);
374#ifdef CONFIG_ARM
375 set_irq_flags(irq, IRQF_VALID);
376#else
377 set_irq_noprobe(irq);
378#endif
379 }
380
381 ret = request_threaded_irq(client->irq,
382 NULL,
383 pca953x_irq_handler,
384 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
385 dev_name(&client->dev), chip);
386 if (ret) {
387 dev_err(&client->dev, "failed to request irq %d\n",
388 client->irq);
389 goto out_failed;
390 }
391
392 chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
393 }
394
395 return 0;
396
397out_failed:
398 chip->irq_base = 0;
399 return ret;
400}
401
402static void pca953x_irq_teardown(struct pca953x_chip *chip)
403{
404 if (chip->irq_base)
405 free_irq(chip->client->irq, chip);
406}
407#else /* CONFIG_GPIO_PCA953X_IRQ */
408static int pca953x_irq_setup(struct pca953x_chip *chip,
409 const struct i2c_device_id *id)
410{
411 struct i2c_client *client = chip->client;
412 struct pca953x_platform_data *pdata = client->dev.platform_data;
413
414 if (pdata->irq_base && (id->driver_data & PCA953X_INT))
415 dev_warn(&client->dev, "interrupt support not compiled in\n");
416
417 return 0;
418}
419
420static void pca953x_irq_teardown(struct pca953x_chip *chip)
421{
422}
423#endif
424
205/* 425/*
206 * Handlers for alternative sources of platform_data 426 * Handlers for alternative sources of platform_data
207 */ 427 */
@@ -286,7 +506,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
286 /* initialize cached registers from their original values. 506 /* initialize cached registers from their original values.
287 * we can't share this chip with another i2c master. 507 * we can't share this chip with another i2c master.
288 */ 508 */
289 pca953x_setup_gpio(chip, id->driver_data); 509 pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS);
290 510
291 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); 511 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
292 if (ret) 512 if (ret)
@@ -301,6 +521,9 @@ static int __devinit pca953x_probe(struct i2c_client *client,
301 if (ret) 521 if (ret)
302 goto out_failed; 522 goto out_failed;
303 523
524 ret = pca953x_irq_setup(chip, id);
525 if (ret)
526 goto out_failed;
304 527
305 ret = gpiochip_add(&chip->gpio_chip); 528 ret = gpiochip_add(&chip->gpio_chip);
306 if (ret) 529 if (ret)
@@ -317,6 +540,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
317 return 0; 540 return 0;
318 541
319out_failed: 542out_failed:
543 pca953x_irq_teardown(chip);
320 kfree(chip->dyn_pdata); 544 kfree(chip->dyn_pdata);
321 kfree(chip); 545 kfree(chip);
322 return ret; 546 return ret;
@@ -345,6 +569,7 @@ static int pca953x_remove(struct i2c_client *client)
345 return ret; 569 return ret;
346 } 570 }
347 571
572 pca953x_irq_teardown(chip);
348 kfree(chip->dyn_pdata); 573 kfree(chip->dyn_pdata);
349 kfree(chip); 574 kfree(chip);
350 return 0; 575 return 0;
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c
index 4ee4c8367a3f..3ad1eeb49609 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -219,7 +219,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
219 if (pending == 0) 219 if (pending == 0)
220 continue; 220 continue;
221 221
222 for_each_bit(offset, &pending, PL061_GPIO_NR) 222 for_each_set_bit(offset, &pending, PL061_GPIO_NR)
223 generic_handle_irq(pl061_to_irq(&chip->gc, offset)); 223 generic_handle_irq(pl061_to_irq(&chip->gc, offset));
224 } 224 }
225 desc->chip->unmask(irq); 225 desc->chip->unmask(irq);
diff --git a/drivers/gpio/sch_gpio.c b/drivers/gpio/sch_gpio.c
new file mode 100644
index 000000000000..583521352c16
--- /dev/null
+++ b/drivers/gpio/sch_gpio.c
@@ -0,0 +1,295 @@
1/*
2 * sch_gpio.c - GPIO interface for Intel Poulsbo SCH
3 *
4 * Copyright (c) 2010 CompuLab Ltd
5 * Author: Denis Turischev <denis@compulab.co.il>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License 2 as published
9 * by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/io.h>
25#include <linux/errno.h>
26#include <linux/acpi.h>
27#include <linux/platform_device.h>
28
29#include <linux/gpio.h>
30
31static DEFINE_SPINLOCK(gpio_lock);
32
33#define CGEN (0x00)
34#define CGIO (0x04)
35#define CGLV (0x08)
36
37#define RGEN (0x20)
38#define RGIO (0x24)
39#define RGLV (0x28)
40
41static unsigned short gpio_ba;
42
43static int sch_gpio_core_direction_in(struct gpio_chip *gc, unsigned gpio_num)
44{
45 u8 curr_dirs;
46 unsigned short offset, bit;
47
48 spin_lock(&gpio_lock);
49
50 offset = CGIO + gpio_num / 8;
51 bit = gpio_num % 8;
52
53 curr_dirs = inb(gpio_ba + offset);
54
55 if (!(curr_dirs & (1 << bit)))
56 outb(curr_dirs | (1 << bit), gpio_ba + offset);
57
58 spin_unlock(&gpio_lock);
59 return 0;
60}
61
62static int sch_gpio_core_get(struct gpio_chip *gc, unsigned gpio_num)
63{
64 int res;
65 unsigned short offset, bit;
66
67 offset = CGLV + gpio_num / 8;
68 bit = gpio_num % 8;
69
70 res = !!(inb(gpio_ba + offset) & (1 << bit));
71 return res;
72}
73
74static void sch_gpio_core_set(struct gpio_chip *gc, unsigned gpio_num, int val)
75{
76 u8 curr_vals;
77 unsigned short offset, bit;
78
79 spin_lock(&gpio_lock);
80
81 offset = CGLV + gpio_num / 8;
82 bit = gpio_num % 8;
83
84 curr_vals = inb(gpio_ba + offset);
85
86 if (val)
87 outb(curr_vals | (1 << bit), gpio_ba + offset);
88 else
89 outb((curr_vals & ~(1 << bit)), gpio_ba + offset);
90 spin_unlock(&gpio_lock);
91}
92
93static int sch_gpio_core_direction_out(struct gpio_chip *gc,
94 unsigned gpio_num, int val)
95{
96 u8 curr_dirs;
97 unsigned short offset, bit;
98
99 sch_gpio_core_set(gc, gpio_num, val);
100
101 spin_lock(&gpio_lock);
102
103 offset = CGIO + gpio_num / 8;
104 bit = gpio_num % 8;
105
106 curr_dirs = inb(gpio_ba + offset);
107 if (curr_dirs & (1 << bit))
108 outb(curr_dirs & ~(1 << bit), gpio_ba + offset);
109
110 spin_unlock(&gpio_lock);
111 return 0;
112}
113
114static struct gpio_chip sch_gpio_core = {
115 .label = "sch_gpio_core",
116 .owner = THIS_MODULE,
117 .direction_input = sch_gpio_core_direction_in,
118 .get = sch_gpio_core_get,
119 .direction_output = sch_gpio_core_direction_out,
120 .set = sch_gpio_core_set,
121};
122
123static int sch_gpio_resume_direction_in(struct gpio_chip *gc,
124 unsigned gpio_num)
125{
126 u8 curr_dirs;
127
128 spin_lock(&gpio_lock);
129
130 curr_dirs = inb(gpio_ba + RGIO);
131
132 if (!(curr_dirs & (1 << gpio_num)))
133 outb(curr_dirs | (1 << gpio_num) , gpio_ba + RGIO);
134
135 spin_unlock(&gpio_lock);
136 return 0;
137}
138
139static int sch_gpio_resume_get(struct gpio_chip *gc, unsigned gpio_num)
140{
141 return !!(inb(gpio_ba + RGLV) & (1 << gpio_num));
142}
143
144static void sch_gpio_resume_set(struct gpio_chip *gc,
145 unsigned gpio_num, int val)
146{
147 u8 curr_vals;
148
149 spin_lock(&gpio_lock);
150
151 curr_vals = inb(gpio_ba + RGLV);
152
153 if (val)
154 outb(curr_vals | (1 << gpio_num), gpio_ba + RGLV);
155 else
156 outb((curr_vals & ~(1 << gpio_num)), gpio_ba + RGLV);
157
158 spin_unlock(&gpio_lock);
159}
160
161static int sch_gpio_resume_direction_out(struct gpio_chip *gc,
162 unsigned gpio_num, int val)
163{
164 u8 curr_dirs;
165
166 sch_gpio_resume_set(gc, gpio_num, val);
167
168 spin_lock(&gpio_lock);
169
170 curr_dirs = inb(gpio_ba + RGIO);
171 if (curr_dirs & (1 << gpio_num))
172 outb(curr_dirs & ~(1 << gpio_num), gpio_ba + RGIO);
173
174 spin_unlock(&gpio_lock);
175 return 0;
176}
177
178static struct gpio_chip sch_gpio_resume = {
179 .label = "sch_gpio_resume",
180 .owner = THIS_MODULE,
181 .direction_input = sch_gpio_resume_direction_in,
182 .get = sch_gpio_resume_get,
183 .direction_output = sch_gpio_resume_direction_out,
184 .set = sch_gpio_resume_set,
185};
186
187static int __devinit sch_gpio_probe(struct platform_device *pdev)
188{
189 struct resource *res;
190 int err;
191
192 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
193 if (!res)
194 return -EBUSY;
195
196 if (!request_region(res->start, resource_size(res), pdev->name))
197 return -EBUSY;
198
199 gpio_ba = res->start;
200
201 sch_gpio_core.base = 0;
202 sch_gpio_core.ngpio = 10;
203 sch_gpio_core.dev = &pdev->dev;
204
205 sch_gpio_resume.base = 10;
206 sch_gpio_resume.ngpio = 4;
207 sch_gpio_resume.dev = &pdev->dev;
208
209 err = gpiochip_add(&sch_gpio_core);
210 if (err < 0)
211 goto err_sch_gpio_core;
212
213 err = gpiochip_add(&sch_gpio_resume);
214 if (err < 0)
215 goto err_sch_gpio_resume;
216
217 /*
218 * GPIO[6:0] enabled by default
219 * GPIO7 is configured by the CMC as SLPIOVR
220 * Enable GPIO[9:8] core powered gpios explicitly
221 */
222 outb(0x3, gpio_ba + CGEN + 1);
223 /*
224 * SUS_GPIO[2:0] enabled by default
225 * Enable SUS_GPIO3 resume powered gpio explicitly
226 */
227 outb(0x8, gpio_ba + RGEN);
228
229 return 0;
230
231err_sch_gpio_resume:
232 err = gpiochip_remove(&sch_gpio_core);
233 if (err)
234 dev_err(&pdev->dev, "%s failed, %d\n",
235 "gpiochip_remove()", err);
236
237err_sch_gpio_core:
238 release_region(res->start, resource_size(res));
239 gpio_ba = 0;
240
241 return err;
242}
243
244static int __devexit sch_gpio_remove(struct platform_device *pdev)
245{
246 struct resource *res;
247 if (gpio_ba) {
248 int err;
249
250 err = gpiochip_remove(&sch_gpio_core);
251 if (err)
252 dev_err(&pdev->dev, "%s failed, %d\n",
253 "gpiochip_remove()", err);
254 err = gpiochip_remove(&sch_gpio_resume);
255 if (err)
256 dev_err(&pdev->dev, "%s failed, %d\n",
257 "gpiochip_remove()", err);
258
259 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
260
261 release_region(res->start, resource_size(res));
262 gpio_ba = 0;
263
264 return err;
265 }
266
267 return 0;
268}
269
270static struct platform_driver sch_gpio_driver = {
271 .driver = {
272 .name = "sch_gpio",
273 .owner = THIS_MODULE,
274 },
275 .probe = sch_gpio_probe,
276 .remove = __devexit_p(sch_gpio_remove),
277};
278
279static int __init sch_gpio_init(void)
280{
281 return platform_driver_register(&sch_gpio_driver);
282}
283
284static void __exit sch_gpio_exit(void)
285{
286 platform_driver_unregister(&sch_gpio_driver);
287}
288
289module_init(sch_gpio_init);
290module_exit(sch_gpio_exit);
291
292MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
293MODULE_DESCRIPTION("GPIO interface for Intel Poulsbo SCH");
294MODULE_LICENSE("GPL");
295MODULE_ALIAS("platform:sch_gpio");
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index a4d344ba8e5c..d4295fa5369e 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/irq.h>
26#include <linux/io.h> 27#include <linux/io.h>
27#include <linux/timb_gpio.h> 28#include <linux/timb_gpio.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
@@ -37,6 +38,8 @@
37#define TGPIO_ICR 0x14 38#define TGPIO_ICR 0x14
38#define TGPIO_FLR 0x18 39#define TGPIO_FLR 0x18
39#define TGPIO_LVR 0x1c 40#define TGPIO_LVR 0x1c
41#define TGPIO_VER 0x20
42#define TGPIO_BFLR 0x24
40 43
41struct timbgpio { 44struct timbgpio {
42 void __iomem *membase; 45 void __iomem *membase;
@@ -125,17 +128,23 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
125 struct timbgpio *tgpio = get_irq_chip_data(irq); 128 struct timbgpio *tgpio = get_irq_chip_data(irq);
126 int offset = irq - tgpio->irq_base; 129 int offset = irq - tgpio->irq_base;
127 unsigned long flags; 130 unsigned long flags;
128 u32 lvr, flr; 131 u32 lvr, flr, bflr = 0;
132 u32 ver;
129 133
130 if (offset < 0 || offset > tgpio->gpio.ngpio) 134 if (offset < 0 || offset > tgpio->gpio.ngpio)
131 return -EINVAL; 135 return -EINVAL;
132 136
137 ver = ioread32(tgpio->membase + TGPIO_VER);
138
133 spin_lock_irqsave(&tgpio->lock, flags); 139 spin_lock_irqsave(&tgpio->lock, flags);
134 140
135 lvr = ioread32(tgpio->membase + TGPIO_LVR); 141 lvr = ioread32(tgpio->membase + TGPIO_LVR);
136 flr = ioread32(tgpio->membase + TGPIO_FLR); 142 flr = ioread32(tgpio->membase + TGPIO_FLR);
143 if (ver > 2)
144 bflr = ioread32(tgpio->membase + TGPIO_BFLR);
137 145
138 if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { 146 if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
147 bflr &= ~(1 << offset);
139 flr &= ~(1 << offset); 148 flr &= ~(1 << offset);
140 if (trigger & IRQ_TYPE_LEVEL_HIGH) 149 if (trigger & IRQ_TYPE_LEVEL_HIGH)
141 lvr |= 1 << offset; 150 lvr |= 1 << offset;
@@ -143,21 +152,27 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
143 lvr &= ~(1 << offset); 152 lvr &= ~(1 << offset);
144 } 153 }
145 154
146 if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) 155 if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
147 return -EINVAL; 156 if (ver < 3)
148 else { 157 return -EINVAL;
158 else {
159 flr |= 1 << offset;
160 bflr |= 1 << offset;
161 }
162 } else {
163 bflr &= ~(1 << offset);
149 flr |= 1 << offset; 164 flr |= 1 << offset;
150 /* opposite compared to the datasheet, but it mirrors the
151 * reality
152 */
153 if (trigger & IRQ_TYPE_EDGE_FALLING) 165 if (trigger & IRQ_TYPE_EDGE_FALLING)
154 lvr |= 1 << offset;
155 else
156 lvr &= ~(1 << offset); 166 lvr &= ~(1 << offset);
167 else
168 lvr |= 1 << offset;
157 } 169 }
158 170
159 iowrite32(lvr, tgpio->membase + TGPIO_LVR); 171 iowrite32(lvr, tgpio->membase + TGPIO_LVR);
160 iowrite32(flr, tgpio->membase + TGPIO_FLR); 172 iowrite32(flr, tgpio->membase + TGPIO_FLR);
173 if (ver > 2)
174 iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
175
161 iowrite32(1 << offset, tgpio->membase + TGPIO_ICR); 176 iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
162 spin_unlock_irqrestore(&tgpio->lock, flags); 177 spin_unlock_irqrestore(&tgpio->lock, flags);
163 178
@@ -174,7 +189,7 @@ static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
174 ipr = ioread32(tgpio->membase + TGPIO_IPR); 189 ipr = ioread32(tgpio->membase + TGPIO_IPR);
175 iowrite32(ipr, tgpio->membase + TGPIO_ICR); 190 iowrite32(ipr, tgpio->membase + TGPIO_ICR);
176 191
177 for_each_bit(offset, &ipr, tgpio->gpio.ngpio) 192 for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio)
178 generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset)); 193 generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset));
179} 194}
180 195
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c
index b4468b616890..d09021f4a7d3 100644
--- a/drivers/gpio/wm831x-gpio.c
+++ b/drivers/gpio/wm831x-gpio.c
@@ -38,10 +38,14 @@ static int wm831x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
38{ 38{
39 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 39 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
40 struct wm831x *wm831x = wm831x_gpio->wm831x; 40 struct wm831x *wm831x = wm831x_gpio->wm831x;
41 int val = WM831X_GPN_DIR;
42
43 if (wm831x->has_gpio_ena)
44 val |= WM831X_GPN_TRI;
41 45
42 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, 46 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
43 WM831X_GPN_DIR | WM831X_GPN_TRI, 47 WM831X_GPN_DIR | WM831X_GPN_TRI |
44 WM831X_GPN_DIR); 48 WM831X_GPN_FN_MASK, val);
45} 49}
46 50
47static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) 51static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -60,23 +64,36 @@ static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
60 return 0; 64 return 0;
61} 65}
62 66
63static int wm831x_gpio_direction_out(struct gpio_chip *chip, 67static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
64 unsigned offset, int value)
65{ 68{
66 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 69 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
67 struct wm831x *wm831x = wm831x_gpio->wm831x; 70 struct wm831x *wm831x = wm831x_gpio->wm831x;
68 71
69 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, 72 wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
70 WM831X_GPN_DIR | WM831X_GPN_TRI, 0); 73 value << offset);
71} 74}
72 75
73static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 76static int wm831x_gpio_direction_out(struct gpio_chip *chip,
77 unsigned offset, int value)
74{ 78{
75 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 79 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
76 struct wm831x *wm831x = wm831x_gpio->wm831x; 80 struct wm831x *wm831x = wm831x_gpio->wm831x;
81 int val = 0;
82 int ret;
77 83
78 wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset, 84 if (wm831x->has_gpio_ena)
79 value << offset); 85 val |= WM831X_GPN_TRI;
86
87 ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
88 WM831X_GPN_DIR | WM831X_GPN_TRI |
89 WM831X_GPN_FN_MASK, val);
90 if (ret < 0)
91 return ret;
92
93 /* Can only set GPIO state once it's in output mode */
94 wm831x_gpio_set(chip, offset, value);
95
96 return 0;
80} 97}
81 98
82static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 99static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -95,7 +112,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
95{ 112{
96 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 113 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
97 struct wm831x *wm831x = wm831x_gpio->wm831x; 114 struct wm831x *wm831x = wm831x_gpio->wm831x;
98 int i; 115 int i, tristated;
99 116
100 for (i = 0; i < chip->ngpio; i++) { 117 for (i = 0; i < chip->ngpio; i++) {
101 int gpio = i + chip->base; 118 int gpio = i + chip->base;
@@ -162,15 +179,19 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
162 break; 179 break;
163 } 180 }
164 181
182 tristated = reg & WM831X_GPN_TRI;
183 if (wm831x->has_gpio_ena)
184 tristated = !tristated;
185
165 seq_printf(s, " %s %s %s %s%s\n" 186 seq_printf(s, " %s %s %s %s%s\n"
166 " %s%s (0x%4x)\n", 187 " %s%s (0x%4x)\n",
167 reg & WM831X_GPN_DIR ? "in" : "out", 188 reg & WM831X_GPN_DIR ? "in" : "out",
168 wm831x_gpio_get(chip, i) ? "high" : "low", 189 wm831x_gpio_get(chip, i) ? "high" : "low",
169 pull, 190 pull,
170 powerdomain, 191 powerdomain,
171 reg & WM831X_GPN_POL ? " inverted" : "", 192 reg & WM831X_GPN_POL ? "" : " inverted",
172 reg & WM831X_GPN_OD ? "open-drain" : "CMOS", 193 reg & WM831X_GPN_OD ? "open-drain" : "CMOS",
173 reg & WM831X_GPN_TRI ? " tristated" : "", 194 tristated ? " tristated" : "",
174 reg); 195 reg);
175 } 196 }
176} 197}
diff --git a/drivers/gpio/wm8350-gpiolib.c b/drivers/gpio/wm8350-gpiolib.c
new file mode 100644
index 000000000000..511840d1c7ba
--- /dev/null
+++ b/drivers/gpio/wm8350-gpiolib.c
@@ -0,0 +1,181 @@
1/*
2 * wm835x-gpiolib.c -- gpiolib support for Wolfson WM835x PMICs
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/gpio.h>
18#include <linux/mfd/core.h>
19#include <linux/platform_device.h>
20#include <linux/seq_file.h>
21
22#include <linux/mfd/wm8350/core.h>
23#include <linux/mfd/wm8350/gpio.h>
24
25struct wm8350_gpio_data {
26 struct wm8350 *wm8350;
27 struct gpio_chip gpio_chip;
28};
29
30static inline struct wm8350_gpio_data *to_wm8350_gpio(struct gpio_chip *chip)
31{
32 return container_of(chip, struct wm8350_gpio_data, gpio_chip);
33}
34
35static int wm8350_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
36{
37 struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
38 struct wm8350 *wm8350 = wm8350_gpio->wm8350;
39
40 return wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
41 1 << offset);
42}
43
44static int wm8350_gpio_get(struct gpio_chip *chip, unsigned offset)
45{
46 struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
47 struct wm8350 *wm8350 = wm8350_gpio->wm8350;
48 int ret;
49
50 ret = wm8350_reg_read(wm8350, WM8350_GPIO_LEVEL);
51 if (ret < 0)
52 return ret;
53
54 if (ret & (1 << offset))
55 return 1;
56 else
57 return 0;
58}
59
60static void wm8350_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
61{
62 struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
63 struct wm8350 *wm8350 = wm8350_gpio->wm8350;
64
65 if (value)
66 wm8350_set_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
67 else
68 wm8350_clear_bits(wm8350, WM8350_GPIO_LEVEL, 1 << offset);
69}
70
71static int wm8350_gpio_direction_out(struct gpio_chip *chip,
72 unsigned offset, int value)
73{
74 struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
75 struct wm8350 *wm8350 = wm8350_gpio->wm8350;
76 int ret;
77
78 ret = wm8350_clear_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O,
79 1 << offset);
80 if (ret < 0)
81 return ret;
82
83 /* Don't have an atomic direction/value setup */
84 wm8350_gpio_set(chip, offset, value);
85
86 return 0;
87}
88
89static int wm8350_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
90{
91 struct wm8350_gpio_data *wm8350_gpio = to_wm8350_gpio(chip);
92 struct wm8350 *wm8350 = wm8350_gpio->wm8350;
93
94 if (!wm8350->irq_base)
95 return -EINVAL;
96
97 return wm8350->irq_base + WM8350_IRQ_GPIO(offset);
98}
99
100static struct gpio_chip template_chip = {
101 .label = "wm8350",
102 .owner = THIS_MODULE,
103 .direction_input = wm8350_gpio_direction_in,
104 .get = wm8350_gpio_get,
105 .direction_output = wm8350_gpio_direction_out,
106 .set = wm8350_gpio_set,
107 .to_irq = wm8350_gpio_to_irq,
108 .can_sleep = 1,
109};
110
111static int __devinit wm8350_gpio_probe(struct platform_device *pdev)
112{
113 struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent);
114 struct wm8350_platform_data *pdata = wm8350->dev->platform_data;
115 struct wm8350_gpio_data *wm8350_gpio;
116 int ret;
117
118 wm8350_gpio = kzalloc(sizeof(*wm8350_gpio), GFP_KERNEL);
119 if (wm8350_gpio == NULL)
120 return -ENOMEM;
121
122 wm8350_gpio->wm8350 = wm8350;
123 wm8350_gpio->gpio_chip = template_chip;
124 wm8350_gpio->gpio_chip.ngpio = 13;
125 wm8350_gpio->gpio_chip.dev = &pdev->dev;
126 if (pdata && pdata->gpio_base)
127 wm8350_gpio->gpio_chip.base = pdata->gpio_base;
128 else
129 wm8350_gpio->gpio_chip.base = -1;
130
131 ret = gpiochip_add(&wm8350_gpio->gpio_chip);
132 if (ret < 0) {
133 dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
134 ret);
135 goto err;
136 }
137
138 platform_set_drvdata(pdev, wm8350_gpio);
139
140 return ret;
141
142err:
143 kfree(wm8350_gpio);
144 return ret;
145}
146
147static int __devexit wm8350_gpio_remove(struct platform_device *pdev)
148{
149 struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev);
150 int ret;
151
152 ret = gpiochip_remove(&wm8350_gpio->gpio_chip);
153 if (ret == 0)
154 kfree(wm8350_gpio);
155
156 return ret;
157}
158
159static struct platform_driver wm8350_gpio_driver = {
160 .driver.name = "wm8350-gpio",
161 .driver.owner = THIS_MODULE,
162 .probe = wm8350_gpio_probe,
163 .remove = __devexit_p(wm8350_gpio_remove),
164};
165
166static int __init wm8350_gpio_init(void)
167{
168 return platform_driver_register(&wm8350_gpio_driver);
169}
170subsys_initcall(wm8350_gpio_init);
171
172static void __exit wm8350_gpio_exit(void)
173{
174 platform_driver_unregister(&wm8350_gpio_driver);
175}
176module_exit(wm8350_gpio_exit);
177
178MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
179MODULE_DESCRIPTION("GPIO interface for WM8350 PMICs");
180MODULE_LICENSE("GPL");
181MODULE_ALIAS("platform:wm8350-gpio");
diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c
new file mode 100644
index 000000000000..de28b4a470ea
--- /dev/null
+++ b/drivers/gpio/wm8994-gpio.c
@@ -0,0 +1,204 @@
1/*
2 * wm8994-gpio.c -- gpiolib support for Wolfson WM8994
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/gpio.h>
18#include <linux/mfd/core.h>
19#include <linux/platform_device.h>
20#include <linux/seq_file.h>
21
22#include <linux/mfd/wm8994/core.h>
23#include <linux/mfd/wm8994/pdata.h>
24#include <linux/mfd/wm8994/gpio.h>
25#include <linux/mfd/wm8994/registers.h>
26
27struct wm8994_gpio {
28 struct wm8994 *wm8994;
29 struct gpio_chip gpio_chip;
30};
31
32static inline struct wm8994_gpio *to_wm8994_gpio(struct gpio_chip *chip)
33{
34 return container_of(chip, struct wm8994_gpio, gpio_chip);
35}
36
37static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
38{
39 struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
40 struct wm8994 *wm8994 = wm8994_gpio->wm8994;
41
42 return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset,
43 WM8994_GPN_DIR, WM8994_GPN_DIR);
44}
45
46static int wm8994_gpio_get(struct gpio_chip *chip, unsigned offset)
47{
48 struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
49 struct wm8994 *wm8994 = wm8994_gpio->wm8994;
50 int ret;
51
52 ret = wm8994_reg_read(wm8994, WM8994_GPIO_1 + offset);
53 if (ret < 0)
54 return ret;
55
56 if (ret & WM8994_GPN_LVL)
57 return 1;
58 else
59 return 0;
60}
61
62static int wm8994_gpio_direction_out(struct gpio_chip *chip,
63 unsigned offset, int value)
64{
65 struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
66 struct wm8994 *wm8994 = wm8994_gpio->wm8994;
67
68 return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset,
69 WM8994_GPN_DIR, 0);
70}
71
72static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
73{
74 struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
75 struct wm8994 *wm8994 = wm8994_gpio->wm8994;
76
77 if (value)
78 value = WM8994_GPN_LVL;
79
80 wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, WM8994_GPN_LVL, value);
81}
82
83#ifdef CONFIG_DEBUG_FS
84static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
85{
86 struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip);
87 struct wm8994 *wm8994 = wm8994_gpio->wm8994;
88 int i;
89
90 for (i = 0; i < chip->ngpio; i++) {
91 int gpio = i + chip->base;
92 int reg;
93 const char *label;
94
95 /* We report the GPIO even if it's not requested since
96 * we're also reporting things like alternate
97 * functions which apply even when the GPIO is not in
98 * use as a GPIO.
99 */
100 label = gpiochip_is_requested(chip, i);
101 if (!label)
102 label = "Unrequested";
103
104 seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label);
105
106 reg = wm8994_reg_read(wm8994, WM8994_GPIO_1 + i);
107 if (reg < 0) {
108 dev_err(wm8994->dev,
109 "GPIO control %d read failed: %d\n",
110 gpio, reg);
111 seq_printf(s, "\n");
112 continue;
113 }
114
115 /* No decode yet; note that GPIO2 is special */
116 seq_printf(s, "(%x)\n", reg);
117 }
118}
119#else
120#define wm8994_gpio_dbg_show NULL
121#endif
122
123static struct gpio_chip template_chip = {
124 .label = "wm8994",
125 .owner = THIS_MODULE,
126 .direction_input = wm8994_gpio_direction_in,
127 .get = wm8994_gpio_get,
128 .direction_output = wm8994_gpio_direction_out,
129 .set = wm8994_gpio_set,
130 .dbg_show = wm8994_gpio_dbg_show,
131 .can_sleep = 1,
132};
133
134static int __devinit wm8994_gpio_probe(struct platform_device *pdev)
135{
136 struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
137 struct wm8994_pdata *pdata = wm8994->dev->platform_data;
138 struct wm8994_gpio *wm8994_gpio;
139 int ret;
140
141 wm8994_gpio = kzalloc(sizeof(*wm8994_gpio), GFP_KERNEL);
142 if (wm8994_gpio == NULL)
143 return -ENOMEM;
144
145 wm8994_gpio->wm8994 = wm8994;
146 wm8994_gpio->gpio_chip = template_chip;
147 wm8994_gpio->gpio_chip.ngpio = WM8994_GPIO_MAX;
148 wm8994_gpio->gpio_chip.dev = &pdev->dev;
149 if (pdata && pdata->gpio_base)
150 wm8994_gpio->gpio_chip.base = pdata->gpio_base;
151 else
152 wm8994_gpio->gpio_chip.base = -1;
153
154 ret = gpiochip_add(&wm8994_gpio->gpio_chip);
155 if (ret < 0) {
156 dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
157 ret);
158 goto err;
159 }
160
161 platform_set_drvdata(pdev, wm8994_gpio);
162
163 return ret;
164
165err:
166 kfree(wm8994_gpio);
167 return ret;
168}
169
170static int __devexit wm8994_gpio_remove(struct platform_device *pdev)
171{
172 struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev);
173 int ret;
174
175 ret = gpiochip_remove(&wm8994_gpio->gpio_chip);
176 if (ret == 0)
177 kfree(wm8994_gpio);
178
179 return ret;
180}
181
182static struct platform_driver wm8994_gpio_driver = {
183 .driver.name = "wm8994-gpio",
184 .driver.owner = THIS_MODULE,
185 .probe = wm8994_gpio_probe,
186 .remove = __devexit_p(wm8994_gpio_remove),
187};
188
189static int __init wm8994_gpio_init(void)
190{
191 return platform_driver_register(&wm8994_gpio_driver);
192}
193subsys_initcall(wm8994_gpio_init);
194
195static void __exit wm8994_gpio_exit(void)
196{
197 platform_driver_unregister(&wm8994_gpio_driver);
198}
199module_exit(wm8994_gpio_exit);
200
201MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
202MODULE_DESCRIPTION("GPIO interface for WM8994");
203MODULE_LICENSE("GPL");
204MODULE_ALIAS("platform:wm8994-gpio");
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 68cf87749a42..e4595e6147b4 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -170,6 +170,16 @@ config SENSORS_ADM9240
170 This driver can also be built as a module. If so, the module 170 This driver can also be built as a module. If so, the module
171 will be called adm9240. 171 will be called adm9240.
172 172
173config SENSORS_ADT7411
174 tristate "Analog Devices ADT7411"
175 depends on I2C && EXPERIMENTAL
176 help
177 If you say yes here you get support for the Analog Devices
178 ADT7411 voltage and temperature monitoring chip.
179
180 This driver can also be built as a module. If so, the module
181 will be called adt7411.
182
173config SENSORS_ADT7462 183config SENSORS_ADT7462
174 tristate "Analog Devices ADT7462" 184 tristate "Analog Devices ADT7462"
175 depends on I2C && EXPERIMENTAL 185 depends on I2C && EXPERIMENTAL
@@ -190,20 +200,6 @@ config SENSORS_ADT7470
190 This driver can also be built as a module. If so, the module 200 This driver can also be built as a module. If so, the module
191 will be called adt7470. 201 will be called adt7470.
192 202
193config SENSORS_ADT7473
194 tristate "Analog Devices ADT7473 (DEPRECATED)"
195 depends on I2C && EXPERIMENTAL
196 select SENSORS_ADT7475
197 help
198 If you say yes here you get support for the Analog Devices
199 ADT7473 temperature monitoring chips.
200
201 This driver is deprecated, you should use the adt7475 driver
202 instead.
203
204 This driver can also be built as a module. If so, the module
205 will be called adt7473.
206
207config SENSORS_ADT7475 203config SENSORS_ADT7475
208 tristate "Analog Devices ADT7473, ADT7475, ADT7476 and ADT7490" 204 tristate "Analog Devices ADT7473, ADT7475, ADT7476 and ADT7490"
209 depends on I2C && EXPERIMENTAL 205 depends on I2C && EXPERIMENTAL
@@ -216,6 +212,19 @@ config SENSORS_ADT7475
216 This driver can also be build as a module. If so, the module 212 This driver can also be build as a module. If so, the module
217 will be called adt7475. 213 will be called adt7475.
218 214
215config SENSORS_ASC7621
216 tristate "Andigilog aSC7621"
217 depends on HWMON && I2C
218 help
219 If you say yes here you get support for the aSC7621
220 family of SMBus sensors chip found on most Intel X48, X38, 975,
221 965 and 945 desktop boards. Currently supported chips:
222 aSC7621
223 aSC7621a
224
225 This driver can also be built as a module. If so, the module
226 will be called asc7621.
227
219config SENSORS_K8TEMP 228config SENSORS_K8TEMP
220 tristate "AMD Athlon64/FX or Opteron temperature sensor" 229 tristate "AMD Athlon64/FX or Opteron temperature sensor"
221 depends on X86 && PCI && EXPERIMENTAL 230 depends on X86 && PCI && EXPERIMENTAL
@@ -563,9 +572,10 @@ config SENSORS_LM90
563 depends on I2C 572 depends on I2C
564 help 573 help
565 If you say yes here you get support for National Semiconductor LM90, 574 If you say yes here you get support for National Semiconductor LM90,
566 LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim 575 LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim
567 MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, 576 MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659,
568 MAX6680, MAX6681 and MAX6692 sensor chips. 577 MAX6680, MAX6681 and MAX6692, and Winbond/Nuvoton W83L771AWG/ASG
578 sensor chips.
569 579
570 This driver can also be built as a module. If so, the module 580 This driver can also be built as a module. If so, the module
571 will be called lm90. 581 will be called lm90.
@@ -909,7 +919,8 @@ config SENSORS_W83793
909 select HWMON_VID 919 select HWMON_VID
910 help 920 help
911 If you say yes here you get support for the Winbond W83793 921 If you say yes here you get support for the Winbond W83793
912 hardware monitoring chip. 922 hardware monitoring chip, including support for the integrated
923 watchdog.
913 924
914 This driver can also be built as a module. If so, the module 925 This driver can also be built as a module. If so, the module
915 will be called w83793. 926 will be called w83793.
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 4bc215c0953f..4aa1a3d112ad 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -29,12 +29,13 @@ obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o
29obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o 29obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
30obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o 30obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
31obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o 31obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o
32obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o
32obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o 33obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o
33obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o 34obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
34obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o
35obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o 35obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
36obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o 36obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
37obj-$(CONFIG_SENSORS_AMS) += ams/ 37obj-$(CONFIG_SENSORS_AMS) += ams/
38obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o
38obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o 39obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
39obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o 40obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
40obj-$(CONFIG_SENSORS_DME1737) += dme1737.o 41obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c
index 5e9e095f1136..74d9c5195e44 100644
--- a/drivers/hwmon/adcxx.c
+++ b/drivers/hwmon/adcxx.c
@@ -62,18 +62,23 @@ static ssize_t adcxx_read(struct device *dev,
62 struct spi_device *spi = to_spi_device(dev); 62 struct spi_device *spi = to_spi_device(dev);
63 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 63 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
64 struct adcxx *adc = dev_get_drvdata(&spi->dev); 64 struct adcxx *adc = dev_get_drvdata(&spi->dev);
65 u8 tx_buf[2] = { attr->index << 3 }; /* other bits are don't care */ 65 u8 tx_buf[2];
66 u8 rx_buf[2]; 66 u8 rx_buf[2];
67 int status; 67 int status;
68 int value; 68 u32 value;
69 69
70 if (mutex_lock_interruptible(&adc->lock)) 70 if (mutex_lock_interruptible(&adc->lock))
71 return -ERESTARTSYS; 71 return -ERESTARTSYS;
72 72
73 status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf), 73 if (adc->channels == 1) {
74 rx_buf, sizeof(rx_buf)); 74 status = spi_read(spi, rx_buf, sizeof(rx_buf));
75 } else {
76 tx_buf[0] = attr->index << 3; /* other bits are don't care */
77 status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf),
78 rx_buf, sizeof(rx_buf));
79 }
75 if (status < 0) { 80 if (status < 0) {
76 dev_warn(dev, "spi_write_then_read failed with status %d\n", 81 dev_warn(dev, "SPI synch. transfer failed with status %d\n",
77 status); 82 status);
78 goto out; 83 goto out;
79 } 84 }
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
new file mode 100644
index 000000000000..3471884e42d2
--- /dev/null
+++ b/drivers/hwmon/adt7411.c
@@ -0,0 +1,366 @@
1/*
2 * Driver for the ADT7411 (I2C/SPI 8 channel 10 bit ADC & temperature-sensor)
3 *
4 * Copyright (C) 2008, 2010 Pengutronix
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * TODO: SPI, support for external temperature sensor
11 * use power-down mode for suspend?, interrupt handling?
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/err.h>
18#include <linux/delay.h>
19#include <linux/mutex.h>
20#include <linux/jiffies.h>
21#include <linux/i2c.h>
22#include <linux/hwmon.h>
23#include <linux/hwmon-sysfs.h>
24
25#define ADT7411_REG_INT_TEMP_VDD_LSB 0x03
26#define ADT7411_REG_EXT_TEMP_AIN14_LSB 0x04
27#define ADT7411_REG_VDD_MSB 0x06
28#define ADT7411_REG_INT_TEMP_MSB 0x07
29#define ADT7411_REG_EXT_TEMP_AIN1_MSB 0x08
30
31#define ADT7411_REG_CFG1 0x18
32#define ADT7411_CFG1_START_MONITOR (1 << 0)
33
34#define ADT7411_REG_CFG2 0x19
35#define ADT7411_CFG2_DISABLE_AVG (1 << 5)
36
37#define ADT7411_REG_CFG3 0x1a
38#define ADT7411_CFG3_ADC_CLK_225 (1 << 0)
39#define ADT7411_CFG3_REF_VDD (1 << 4)
40
41#define ADT7411_REG_DEVICE_ID 0x4d
42#define ADT7411_REG_MANUFACTURER_ID 0x4e
43
44#define ADT7411_DEVICE_ID 0x2
45#define ADT7411_MANUFACTURER_ID 0x41
46
47static const unsigned short normal_i2c[] = { 0x48, 0x4a, 0x4b, I2C_CLIENT_END };
48
49struct adt7411_data {
50 struct mutex device_lock; /* for "atomic" device accesses */
51 struct mutex update_lock;
52 unsigned long next_update;
53 int vref_cached;
54 struct device *hwmon_dev;
55};
56
57/*
58 * When reading a register containing (up to 4) lsb, all associated
59 * msb-registers get locked by the hardware. After _one_ of those msb is read,
60 * _all_ are unlocked. In order to use this locking correctly, reading lsb/msb
61 * is protected here with a mutex, too.
62 */
63static int adt7411_read_10_bit(struct i2c_client *client, u8 lsb_reg,
64 u8 msb_reg, u8 lsb_shift)
65{
66 struct adt7411_data *data = i2c_get_clientdata(client);
67 int val, tmp;
68
69 mutex_lock(&data->device_lock);
70
71 val = i2c_smbus_read_byte_data(client, lsb_reg);
72 if (val < 0)
73 goto exit_unlock;
74
75 tmp = (val >> lsb_shift) & 3;
76 val = i2c_smbus_read_byte_data(client, msb_reg);
77
78 if (val >= 0)
79 val = (val << 2) | tmp;
80
81 exit_unlock:
82 mutex_unlock(&data->device_lock);
83
84 return val;
85}
86
87static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit,
88 bool flag)
89{
90 struct adt7411_data *data = i2c_get_clientdata(client);
91 int ret, val;
92
93 mutex_lock(&data->device_lock);
94
95 ret = i2c_smbus_read_byte_data(client, reg);
96 if (ret < 0)
97 goto exit_unlock;
98
99 if (flag)
100 val = ret | bit;
101 else
102 val = ret & ~bit;
103
104 ret = i2c_smbus_write_byte_data(client, reg, val);
105
106 exit_unlock:
107 mutex_unlock(&data->device_lock);
108 return ret;
109}
110
111static ssize_t adt7411_show_vdd(struct device *dev,
112 struct device_attribute *attr, char *buf)
113{
114 struct i2c_client *client = to_i2c_client(dev);
115 int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
116 ADT7411_REG_VDD_MSB, 2);
117
118 return ret < 0 ? ret : sprintf(buf, "%u\n", ret * 7000 / 1024);
119}
120
121static ssize_t adt7411_show_temp(struct device *dev,
122 struct device_attribute *attr, char *buf)
123{
124 struct i2c_client *client = to_i2c_client(dev);
125 int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
126 ADT7411_REG_INT_TEMP_MSB, 0);
127
128 if (val < 0)
129 return val;
130
131 val = val & 0x200 ? val - 0x400 : val; /* 10 bit signed */
132
133 return sprintf(buf, "%d\n", val * 250);
134}
135
136static ssize_t adt7411_show_input(struct device *dev,
137 struct device_attribute *attr, char *buf)
138{
139 int nr = to_sensor_dev_attr(attr)->index;
140 struct i2c_client *client = to_i2c_client(dev);
141 struct adt7411_data *data = i2c_get_clientdata(client);
142 int val;
143 u8 lsb_reg, lsb_shift;
144
145 mutex_lock(&data->update_lock);
146 if (time_after_eq(jiffies, data->next_update)) {
147 val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3);
148 if (val < 0)
149 goto exit_unlock;
150
151 if (val & ADT7411_CFG3_REF_VDD) {
152 val = adt7411_read_10_bit(client,
153 ADT7411_REG_INT_TEMP_VDD_LSB,
154 ADT7411_REG_VDD_MSB, 2);
155 if (val < 0)
156 goto exit_unlock;
157
158 data->vref_cached = val * 7000 / 1024;
159 } else {
160 data->vref_cached = 2250;
161 }
162
163 data->next_update = jiffies + HZ;
164 }
165
166 lsb_reg = ADT7411_REG_EXT_TEMP_AIN14_LSB + (nr >> 2);
167 lsb_shift = 2 * (nr & 0x03);
168 val = adt7411_read_10_bit(client, lsb_reg,
169 ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, lsb_shift);
170 if (val < 0)
171 goto exit_unlock;
172
173 val = sprintf(buf, "%u\n", val * data->vref_cached / 1024);
174 exit_unlock:
175 mutex_unlock(&data->update_lock);
176 return val;
177}
178
179static ssize_t adt7411_show_bit(struct device *dev,
180 struct device_attribute *attr, char *buf)
181{
182 struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
183 struct i2c_client *client = to_i2c_client(dev);
184 int ret = i2c_smbus_read_byte_data(client, attr2->index);
185
186 return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr));
187}
188
189static ssize_t adt7411_set_bit(struct device *dev,
190 struct device_attribute *attr, const char *buf,
191 size_t count)
192{
193 struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr);
194 struct i2c_client *client = to_i2c_client(dev);
195 struct adt7411_data *data = i2c_get_clientdata(client);
196 int ret;
197 unsigned long flag;
198
199 ret = strict_strtoul(buf, 0, &flag);
200 if (ret || flag > 1)
201 return -EINVAL;
202
203 ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag);
204
205 /* force update */
206 mutex_lock(&data->update_lock);
207 data->next_update = jiffies;
208 mutex_unlock(&data->update_lock);
209
210 return ret < 0 ? ret : count;
211}
212
213#define ADT7411_BIT_ATTR(__name, __reg, __bit) \
214 SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \
215 adt7411_set_bit, __bit, __reg)
216
217static DEVICE_ATTR(temp1_input, S_IRUGO, adt7411_show_temp, NULL);
218static DEVICE_ATTR(in0_input, S_IRUGO, adt7411_show_vdd, NULL);
219static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, adt7411_show_input, NULL, 0);
220static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, adt7411_show_input, NULL, 1);
221static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, adt7411_show_input, NULL, 2);
222static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, adt7411_show_input, NULL, 3);
223static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, adt7411_show_input, NULL, 4);
224static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, adt7411_show_input, NULL, 5);
225static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, adt7411_show_input, NULL, 6);
226static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, adt7411_show_input, NULL, 7);
227static ADT7411_BIT_ATTR(no_average, ADT7411_REG_CFG2, ADT7411_CFG2_DISABLE_AVG);
228static ADT7411_BIT_ATTR(fast_sampling, ADT7411_REG_CFG3, ADT7411_CFG3_ADC_CLK_225);
229static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD);
230
231static struct attribute *adt7411_attrs[] = {
232 &dev_attr_temp1_input.attr,
233 &dev_attr_in0_input.attr,
234 &sensor_dev_attr_in1_input.dev_attr.attr,
235 &sensor_dev_attr_in2_input.dev_attr.attr,
236 &sensor_dev_attr_in3_input.dev_attr.attr,
237 &sensor_dev_attr_in4_input.dev_attr.attr,
238 &sensor_dev_attr_in5_input.dev_attr.attr,
239 &sensor_dev_attr_in6_input.dev_attr.attr,
240 &sensor_dev_attr_in7_input.dev_attr.attr,
241 &sensor_dev_attr_in8_input.dev_attr.attr,
242 &sensor_dev_attr_no_average.dev_attr.attr,
243 &sensor_dev_attr_fast_sampling.dev_attr.attr,
244 &sensor_dev_attr_adc_ref_vdd.dev_attr.attr,
245 NULL
246};
247
248static const struct attribute_group adt7411_attr_grp = {
249 .attrs = adt7411_attrs,
250};
251
252static int adt7411_detect(struct i2c_client *client,
253 struct i2c_board_info *info)
254{
255 int val;
256
257 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
258 return -ENODEV;
259
260 val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID);
261 if (val < 0 || val != ADT7411_MANUFACTURER_ID) {
262 dev_dbg(&client->dev, "Wrong manufacturer ID. Got %d, "
263 "expected %d\n", val, ADT7411_MANUFACTURER_ID);
264 return -ENODEV;
265 }
266
267 val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID);
268 if (val < 0 || val != ADT7411_DEVICE_ID) {
269 dev_dbg(&client->dev, "Wrong device ID. Got %d, "
270 "expected %d\n", val, ADT7411_DEVICE_ID);
271 return -ENODEV;
272 }
273
274 strlcpy(info->type, "adt7411", I2C_NAME_SIZE);
275
276 return 0;
277}
278
279static int __devinit adt7411_probe(struct i2c_client *client,
280 const struct i2c_device_id *id)
281{
282 struct adt7411_data *data;
283 int ret;
284
285 data = kzalloc(sizeof(*data), GFP_KERNEL);
286 if (!data)
287 return -ENOMEM;
288
289 i2c_set_clientdata(client, data);
290 mutex_init(&data->device_lock);
291 mutex_init(&data->update_lock);
292
293 ret = adt7411_modify_bit(client, ADT7411_REG_CFG1,
294 ADT7411_CFG1_START_MONITOR, 1);
295 if (ret < 0)
296 goto exit_free;
297
298 /* force update on first occasion */
299 data->next_update = jiffies;
300
301 ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp);
302 if (ret)
303 goto exit_free;
304
305 data->hwmon_dev = hwmon_device_register(&client->dev);
306 if (IS_ERR(data->hwmon_dev)) {
307 ret = PTR_ERR(data->hwmon_dev);
308 goto exit_remove;
309 }
310
311 dev_info(&client->dev, "successfully registered\n");
312
313 return 0;
314
315 exit_remove:
316 sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
317 exit_free:
318 i2c_set_clientdata(client, NULL);
319 kfree(data);
320 return ret;
321}
322
323static int __devexit adt7411_remove(struct i2c_client *client)
324{
325 struct adt7411_data *data = i2c_get_clientdata(client);
326
327 hwmon_device_unregister(data->hwmon_dev);
328 sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
329 i2c_set_clientdata(client, NULL);
330 kfree(data);
331 return 0;
332}
333
334static const struct i2c_device_id adt7411_id[] = {
335 { "adt7411", 0 },
336 { }
337};
338
339static struct i2c_driver adt7411_driver = {
340 .driver = {
341 .name = "adt7411",
342 },
343 .probe = adt7411_probe,
344 .remove = __devexit_p(adt7411_remove),
345 .id_table = adt7411_id,
346 .detect = adt7411_detect,
347 .address_list = normal_i2c,
348 .class = I2C_CLASS_HWMON,
349};
350
351static int __init sensors_adt7411_init(void)
352{
353 return i2c_add_driver(&adt7411_driver);
354}
355module_init(sensors_adt7411_init)
356
357static void __exit sensors_adt7411_exit(void)
358{
359 i2c_del_driver(&adt7411_driver);
360}
361module_exit(sensors_adt7411_exit)
362
363MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de> and "
364 "Wolfram Sang <w.sang@pengutronix.de>");
365MODULE_DESCRIPTION("ADT7411 driver");
366MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c
deleted file mode 100644
index 434576f61c84..000000000000
--- a/drivers/hwmon/adt7473.c
+++ /dev/null
@@ -1,1180 +0,0 @@
1/*
2 * A hwmon driver for the Analog Devices ADT7473
3 * Copyright (C) 2007 IBM
4 *
5 * Author: Darrick J. Wong <djwong@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/module.h>
23#include <linux/jiffies.h>
24#include <linux/i2c.h>
25#include <linux/hwmon.h>
26#include <linux/hwmon-sysfs.h>
27#include <linux/err.h>
28#include <linux/mutex.h>
29#include <linux/delay.h>
30#include <linux/log2.h>
31
32/* Addresses to scan */
33static const unsigned short normal_i2c[] = { 0x2C, 0x2D, 0x2E, I2C_CLIENT_END };
34
35/* ADT7473 registers */
36#define ADT7473_REG_BASE_ADDR 0x20
37
38#define ADT7473_REG_VOLT_BASE_ADDR 0x21
39#define ADT7473_REG_VOLT_MIN_BASE_ADDR 0x46
40
41#define ADT7473_REG_TEMP_BASE_ADDR 0x25
42#define ADT7473_REG_TEMP_LIMITS_BASE_ADDR 0x4E
43#define ADT7473_REG_TEMP_TMIN_BASE_ADDR 0x67
44#define ADT7473_REG_TEMP_TMAX_BASE_ADDR 0x6A
45
46#define ADT7473_REG_FAN_BASE_ADDR 0x28
47#define ADT7473_REG_FAN_MIN_BASE_ADDR 0x54
48
49#define ADT7473_REG_PWM_BASE_ADDR 0x30
50#define ADT7473_REG_PWM_MIN_BASE_ADDR 0x64
51#define ADT7473_REG_PWM_MAX_BASE_ADDR 0x38
52#define ADT7473_REG_PWM_BHVR_BASE_ADDR 0x5C
53#define ADT7473_PWM_BHVR_MASK 0xE0
54#define ADT7473_PWM_BHVR_SHIFT 5
55
56#define ADT7473_REG_CFG1 0x40
57#define ADT7473_CFG1_START 0x01
58#define ADT7473_CFG1_READY 0x04
59#define ADT7473_REG_CFG2 0x73
60#define ADT7473_REG_CFG3 0x78
61#define ADT7473_REG_CFG4 0x7D
62#define ADT7473_CFG4_MAX_DUTY_AT_OVT 0x08
63#define ADT7473_REG_CFG5 0x7C
64#define ADT7473_CFG5_TEMP_TWOS 0x01
65#define ADT7473_CFG5_TEMP_OFFSET 0x02
66
67#define ADT7473_REG_DEVICE 0x3D
68#define ADT7473_VENDOR 0x41
69#define ADT7473_REG_VENDOR 0x3E
70#define ADT7473_DEVICE 0x73
71#define ADT7473_REG_REVISION 0x3F
72#define ADT7473_REV_68 0x68
73#define ADT7473_REV_69 0x69
74
75#define ADT7473_REG_ALARM1 0x41
76#define ADT7473_VCCP_ALARM 0x02
77#define ADT7473_VCC_ALARM 0x04
78#define ADT7473_R1T_ALARM 0x10
79#define ADT7473_LT_ALARM 0x20
80#define ADT7473_R2T_ALARM 0x40
81#define ADT7473_OOL 0x80
82#define ADT7473_REG_ALARM2 0x42
83#define ADT7473_OVT_ALARM 0x02
84#define ADT7473_FAN1_ALARM 0x04
85#define ADT7473_FAN2_ALARM 0x08
86#define ADT7473_FAN3_ALARM 0x10
87#define ADT7473_FAN4_ALARM 0x20
88#define ADT7473_R1T_SHORT 0x40
89#define ADT7473_R2T_SHORT 0x80
90
91#define ALARM2(x) ((x) << 8)
92
93#define ADT7473_VOLT_COUNT 2
94#define ADT7473_REG_VOLT(x) (ADT7473_REG_VOLT_BASE_ADDR + (x))
95#define ADT7473_REG_VOLT_MIN(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + ((x) * 2))
96#define ADT7473_REG_VOLT_MAX(x) (ADT7473_REG_VOLT_MIN_BASE_ADDR + \
97 ((x) * 2) + 1)
98
99#define ADT7473_TEMP_COUNT 3
100#define ADT7473_REG_TEMP(x) (ADT7473_REG_TEMP_BASE_ADDR + (x))
101#define ADT7473_REG_TEMP_MIN(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + ((x) * 2))
102#define ADT7473_REG_TEMP_MAX(x) (ADT7473_REG_TEMP_LIMITS_BASE_ADDR + \
103 ((x) * 2) + 1)
104#define ADT7473_REG_TEMP_TMIN(x) (ADT7473_REG_TEMP_TMIN_BASE_ADDR + (x))
105#define ADT7473_REG_TEMP_TMAX(x) (ADT7473_REG_TEMP_TMAX_BASE_ADDR + (x))
106
107#define ADT7473_FAN_COUNT 4
108#define ADT7473_REG_FAN(x) (ADT7473_REG_FAN_BASE_ADDR + ((x) * 2))
109#define ADT7473_REG_FAN_MIN(x) (ADT7473_REG_FAN_MIN_BASE_ADDR + ((x) * 2))
110
111#define ADT7473_PWM_COUNT 3
112#define ADT7473_REG_PWM(x) (ADT7473_REG_PWM_BASE_ADDR + (x))
113#define ADT7473_REG_PWM_MAX(x) (ADT7473_REG_PWM_MAX_BASE_ADDR + (x))
114#define ADT7473_REG_PWM_MIN(x) (ADT7473_REG_PWM_MIN_BASE_ADDR + (x))
115#define ADT7473_REG_PWM_BHVR(x) (ADT7473_REG_PWM_BHVR_BASE_ADDR + (x))
116
117/* How often do we reread sensors values? (In jiffies) */
118#define SENSOR_REFRESH_INTERVAL (2 * HZ)
119
120/* How often do we reread sensor limit values? (In jiffies) */
121#define LIMIT_REFRESH_INTERVAL (60 * HZ)
122
123/* datasheet says to divide this number by the fan reading to get fan rpm */
124#define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x))
125#define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM
126#define FAN_PERIOD_INVALID 65535
127#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)
128
129struct adt7473_data {
130 struct device *hwmon_dev;
131 struct attribute_group attrs;
132 struct mutex lock;
133 char sensors_valid;
134 char limits_valid;
135 unsigned long sensors_last_updated; /* In jiffies */
136 unsigned long limits_last_updated; /* In jiffies */
137
138 u8 volt[ADT7473_VOLT_COUNT];
139 s8 volt_min[ADT7473_VOLT_COUNT];
140 s8 volt_max[ADT7473_VOLT_COUNT];
141
142 s8 temp[ADT7473_TEMP_COUNT];
143 s8 temp_min[ADT7473_TEMP_COUNT];
144 s8 temp_max[ADT7473_TEMP_COUNT];
145 s8 temp_tmin[ADT7473_TEMP_COUNT];
146 /* This is called the !THERM limit in the datasheet */
147 s8 temp_tmax[ADT7473_TEMP_COUNT];
148
149 u16 fan[ADT7473_FAN_COUNT];
150 u16 fan_min[ADT7473_FAN_COUNT];
151
152 u8 pwm[ADT7473_PWM_COUNT];
153 u8 pwm_max[ADT7473_PWM_COUNT];
154 u8 pwm_min[ADT7473_PWM_COUNT];
155 u8 pwm_behavior[ADT7473_PWM_COUNT];
156
157 u8 temp_twos_complement;
158 u8 temp_offset;
159
160 u16 alarm;
161 u8 max_duty_at_overheat;
162};
163
164static int adt7473_probe(struct i2c_client *client,
165 const struct i2c_device_id *id);
166static int adt7473_detect(struct i2c_client *client,
167 struct i2c_board_info *info);
168static int adt7473_remove(struct i2c_client *client);
169
170static const struct i2c_device_id adt7473_id[] = {
171 { "adt7473", 0 },
172 { }
173};
174
175static struct i2c_driver adt7473_driver = {
176 .class = I2C_CLASS_HWMON,
177 .driver = {
178 .name = "adt7473",
179 },
180 .probe = adt7473_probe,
181 .remove = adt7473_remove,
182 .id_table = adt7473_id,
183 .detect = adt7473_detect,
184 .address_list = normal_i2c,
185};
186
187/*
188 * 16-bit registers on the ADT7473 are low-byte first. The data sheet says
189 * that the low byte must be read before the high byte.
190 */
191static inline int adt7473_read_word_data(struct i2c_client *client, u8 reg)
192{
193 u16 foo;
194 foo = i2c_smbus_read_byte_data(client, reg);
195 foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8);
196 return foo;
197}
198
199static inline int adt7473_write_word_data(struct i2c_client *client, u8 reg,
200 u16 value)
201{
202 return i2c_smbus_write_byte_data(client, reg, value & 0xFF)
203 && i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
204}
205
206static void adt7473_init_client(struct i2c_client *client)
207{
208 int reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG1);
209
210 if (!(reg & ADT7473_CFG1_READY)) {
211 dev_err(&client->dev, "Chip not ready.\n");
212 } else {
213 /* start monitoring */
214 i2c_smbus_write_byte_data(client, ADT7473_REG_CFG1,
215 reg | ADT7473_CFG1_START);
216 }
217}
218
219static struct adt7473_data *adt7473_update_device(struct device *dev)
220{
221 struct i2c_client *client = to_i2c_client(dev);
222 struct adt7473_data *data = i2c_get_clientdata(client);
223 unsigned long local_jiffies = jiffies;
224 u8 cfg;
225 int i;
226
227 mutex_lock(&data->lock);
228 if (time_before(local_jiffies, data->sensors_last_updated +
229 SENSOR_REFRESH_INTERVAL)
230 && data->sensors_valid)
231 goto no_sensor_update;
232
233 for (i = 0; i < ADT7473_VOLT_COUNT; i++)
234 data->volt[i] = i2c_smbus_read_byte_data(client,
235 ADT7473_REG_VOLT(i));
236
237 /* Determine temperature encoding */
238 cfg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG5);
239 data->temp_twos_complement = (cfg & ADT7473_CFG5_TEMP_TWOS);
240
241 /*
242 * What does this do? it implies a variable temperature sensor
243 * offset, but the datasheet doesn't say anything about this bit
244 * and other parts of the datasheet imply that "offset64" mode
245 * means that you shift temp values by -64 if the above bit was set.
246 */
247 data->temp_offset = (cfg & ADT7473_CFG5_TEMP_OFFSET);
248
249 for (i = 0; i < ADT7473_TEMP_COUNT; i++)
250 data->temp[i] = i2c_smbus_read_byte_data(client,
251 ADT7473_REG_TEMP(i));
252
253 for (i = 0; i < ADT7473_FAN_COUNT; i++)
254 data->fan[i] = adt7473_read_word_data(client,
255 ADT7473_REG_FAN(i));
256
257 for (i = 0; i < ADT7473_PWM_COUNT; i++)
258 data->pwm[i] = i2c_smbus_read_byte_data(client,
259 ADT7473_REG_PWM(i));
260
261 data->alarm = i2c_smbus_read_byte_data(client, ADT7473_REG_ALARM1);
262 if (data->alarm & ADT7473_OOL)
263 data->alarm |= ALARM2(i2c_smbus_read_byte_data(client,
264 ADT7473_REG_ALARM2));
265
266 data->sensors_last_updated = local_jiffies;
267 data->sensors_valid = 1;
268
269no_sensor_update:
270 if (time_before(local_jiffies, data->limits_last_updated +
271 LIMIT_REFRESH_INTERVAL)
272 && data->limits_valid)
273 goto out;
274
275 for (i = 0; i < ADT7473_VOLT_COUNT; i++) {
276 data->volt_min[i] = i2c_smbus_read_byte_data(client,
277 ADT7473_REG_VOLT_MIN(i));
278 data->volt_max[i] = i2c_smbus_read_byte_data(client,
279 ADT7473_REG_VOLT_MAX(i));
280 }
281
282 for (i = 0; i < ADT7473_TEMP_COUNT; i++) {
283 data->temp_min[i] = i2c_smbus_read_byte_data(client,
284 ADT7473_REG_TEMP_MIN(i));
285 data->temp_max[i] = i2c_smbus_read_byte_data(client,
286 ADT7473_REG_TEMP_MAX(i));
287 data->temp_tmin[i] = i2c_smbus_read_byte_data(client,
288 ADT7473_REG_TEMP_TMIN(i));
289 data->temp_tmax[i] = i2c_smbus_read_byte_data(client,
290 ADT7473_REG_TEMP_TMAX(i));
291 }
292
293 for (i = 0; i < ADT7473_FAN_COUNT; i++)
294 data->fan_min[i] = adt7473_read_word_data(client,
295 ADT7473_REG_FAN_MIN(i));
296
297 for (i = 0; i < ADT7473_PWM_COUNT; i++) {
298 data->pwm_max[i] = i2c_smbus_read_byte_data(client,
299 ADT7473_REG_PWM_MAX(i));
300 data->pwm_min[i] = i2c_smbus_read_byte_data(client,
301 ADT7473_REG_PWM_MIN(i));
302 data->pwm_behavior[i] = i2c_smbus_read_byte_data(client,
303 ADT7473_REG_PWM_BHVR(i));
304 }
305
306 i = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
307 data->max_duty_at_overheat = !!(i & ADT7473_CFG4_MAX_DUTY_AT_OVT);
308
309 data->limits_last_updated = local_jiffies;
310 data->limits_valid = 1;
311
312out:
313 mutex_unlock(&data->lock);
314 return data;
315}
316
317/*
318 * Conversions
319 */
320
321/* IN are scaled acording to built-in resistors */
322static const int adt7473_scaling[] = { /* .001 Volts */
323 2250, 3300
324};
325#define SCALE(val, from, to) (((val) * (to) + ((from) / 2)) / (from))
326
327static int decode_volt(int volt_index, u8 raw)
328{
329 return SCALE(raw, 192, adt7473_scaling[volt_index]);
330}
331
332static u8 encode_volt(int volt_index, int cooked)
333{
334 int raw = SCALE(cooked, adt7473_scaling[volt_index], 192);
335 return SENSORS_LIMIT(raw, 0, 255);
336}
337
338static ssize_t show_volt_min(struct device *dev,
339 struct device_attribute *devattr,
340 char *buf)
341{
342 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
343 struct adt7473_data *data = adt7473_update_device(dev);
344 return sprintf(buf, "%d\n",
345 decode_volt(attr->index, data->volt_min[attr->index]));
346}
347
348static ssize_t set_volt_min(struct device *dev,
349 struct device_attribute *devattr,
350 const char *buf,
351 size_t count)
352{
353 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
354 struct i2c_client *client = to_i2c_client(dev);
355 struct adt7473_data *data = i2c_get_clientdata(client);
356 long volt;
357
358 if (strict_strtol(buf, 10, &volt))
359 return -EINVAL;
360
361 volt = encode_volt(attr->index, volt);
362
363 mutex_lock(&data->lock);
364 data->volt_min[attr->index] = volt;
365 i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MIN(attr->index),
366 volt);
367 mutex_unlock(&data->lock);
368
369 return count;
370}
371
372static ssize_t show_volt_max(struct device *dev,
373 struct device_attribute *devattr,
374 char *buf)
375{
376 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
377 struct adt7473_data *data = adt7473_update_device(dev);
378 return sprintf(buf, "%d\n",
379 decode_volt(attr->index, data->volt_max[attr->index]));
380}
381
382static ssize_t set_volt_max(struct device *dev,
383 struct device_attribute *devattr,
384 const char *buf,
385 size_t count)
386{
387 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
388 struct i2c_client *client = to_i2c_client(dev);
389 struct adt7473_data *data = i2c_get_clientdata(client);
390 long volt;
391
392 if (strict_strtol(buf, 10, &volt))
393 return -EINVAL;
394
395 volt = encode_volt(attr->index, volt);
396
397 mutex_lock(&data->lock);
398 data->volt_max[attr->index] = volt;
399 i2c_smbus_write_byte_data(client, ADT7473_REG_VOLT_MAX(attr->index),
400 volt);
401 mutex_unlock(&data->lock);
402
403 return count;
404}
405
406static ssize_t show_volt(struct device *dev, struct device_attribute *devattr,
407 char *buf)
408{
409 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
410 struct adt7473_data *data = adt7473_update_device(dev);
411
412 return sprintf(buf, "%d\n",
413 decode_volt(attr->index, data->volt[attr->index]));
414}
415
416/*
417 * This chip can report temperature data either as a two's complement
418 * number in the range -128 to 127, or as an unsigned number that must
419 * be offset by 64.
420 */
421static int decode_temp(u8 twos_complement, u8 raw)
422{
423 return twos_complement ? (s8)raw : raw - 64;
424}
425
426static u8 encode_temp(u8 twos_complement, int cooked)
427{
428 u8 ret = twos_complement ? cooked & 0xFF : cooked + 64;
429 return SENSORS_LIMIT(ret, 0, 255);
430}
431
432static ssize_t show_temp_min(struct device *dev,
433 struct device_attribute *devattr,
434 char *buf)
435{
436 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
437 struct adt7473_data *data = adt7473_update_device(dev);
438 return sprintf(buf, "%d\n", 1000 * decode_temp(
439 data->temp_twos_complement,
440 data->temp_min[attr->index]));
441}
442
443static ssize_t set_temp_min(struct device *dev,
444 struct device_attribute *devattr,
445 const char *buf,
446 size_t count)
447{
448 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
449 struct i2c_client *client = to_i2c_client(dev);
450 struct adt7473_data *data = i2c_get_clientdata(client);
451 long temp;
452
453 if (strict_strtol(buf, 10, &temp))
454 return -EINVAL;
455
456 temp = DIV_ROUND_CLOSEST(temp, 1000);
457 temp = encode_temp(data->temp_twos_complement, temp);
458
459 mutex_lock(&data->lock);
460 data->temp_min[attr->index] = temp;
461 i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MIN(attr->index),
462 temp);
463 mutex_unlock(&data->lock);
464
465 return count;
466}
467
468static ssize_t show_temp_max(struct device *dev,
469 struct device_attribute *devattr,
470 char *buf)
471{
472 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
473 struct adt7473_data *data = adt7473_update_device(dev);
474 return sprintf(buf, "%d\n", 1000 * decode_temp(
475 data->temp_twos_complement,
476 data->temp_max[attr->index]));
477}
478
479static ssize_t set_temp_max(struct device *dev,
480 struct device_attribute *devattr,
481 const char *buf,
482 size_t count)
483{
484 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
485 struct i2c_client *client = to_i2c_client(dev);
486 struct adt7473_data *data = i2c_get_clientdata(client);
487 long temp;
488
489 if (strict_strtol(buf, 10, &temp))
490 return -EINVAL;
491
492 temp = DIV_ROUND_CLOSEST(temp, 1000);
493 temp = encode_temp(data->temp_twos_complement, temp);
494
495 mutex_lock(&data->lock);
496 data->temp_max[attr->index] = temp;
497 i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_MAX(attr->index),
498 temp);
499 mutex_unlock(&data->lock);
500
501 return count;
502}
503
504static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
505 char *buf)
506{
507 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
508 struct adt7473_data *data = adt7473_update_device(dev);
509 return sprintf(buf, "%d\n", 1000 * decode_temp(
510 data->temp_twos_complement,
511 data->temp[attr->index]));
512}
513
514static ssize_t show_fan_min(struct device *dev,
515 struct device_attribute *devattr,
516 char *buf)
517{
518 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
519 struct adt7473_data *data = adt7473_update_device(dev);
520
521 if (FAN_DATA_VALID(data->fan_min[attr->index]))
522 return sprintf(buf, "%d\n",
523 FAN_PERIOD_TO_RPM(data->fan_min[attr->index]));
524 else
525 return sprintf(buf, "0\n");
526}
527
528static ssize_t set_fan_min(struct device *dev,
529 struct device_attribute *devattr,
530 const char *buf, size_t count)
531{
532 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
533 struct i2c_client *client = to_i2c_client(dev);
534 struct adt7473_data *data = i2c_get_clientdata(client);
535 long temp;
536
537 if (strict_strtol(buf, 10, &temp) || !temp)
538 return -EINVAL;
539
540 temp = FAN_RPM_TO_PERIOD(temp);
541 temp = SENSORS_LIMIT(temp, 1, 65534);
542
543 mutex_lock(&data->lock);
544 data->fan_min[attr->index] = temp;
545 adt7473_write_word_data(client, ADT7473_REG_FAN_MIN(attr->index), temp);
546 mutex_unlock(&data->lock);
547
548 return count;
549}
550
551static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
552 char *buf)
553{
554 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
555 struct adt7473_data *data = adt7473_update_device(dev);
556
557 if (FAN_DATA_VALID(data->fan[attr->index]))
558 return sprintf(buf, "%d\n",
559 FAN_PERIOD_TO_RPM(data->fan[attr->index]));
560 else
561 return sprintf(buf, "0\n");
562}
563
564static ssize_t show_max_duty_at_crit(struct device *dev,
565 struct device_attribute *devattr,
566 char *buf)
567{
568 struct adt7473_data *data = adt7473_update_device(dev);
569 return sprintf(buf, "%d\n", data->max_duty_at_overheat);
570}
571
572static ssize_t set_max_duty_at_crit(struct device *dev,
573 struct device_attribute *devattr,
574 const char *buf,
575 size_t count)
576{
577 u8 reg;
578 struct i2c_client *client = to_i2c_client(dev);
579 struct adt7473_data *data = i2c_get_clientdata(client);
580 long temp;
581
582 if (strict_strtol(buf, 10, &temp))
583 return -EINVAL;
584
585 mutex_lock(&data->lock);
586 data->max_duty_at_overheat = !!temp;
587 reg = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
588 if (temp)
589 reg |= ADT7473_CFG4_MAX_DUTY_AT_OVT;
590 else
591 reg &= ~ADT7473_CFG4_MAX_DUTY_AT_OVT;
592 i2c_smbus_write_byte_data(client, ADT7473_REG_CFG4, reg);
593 mutex_unlock(&data->lock);
594
595 return count;
596}
597
598static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
599 char *buf)
600{
601 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
602 struct adt7473_data *data = adt7473_update_device(dev);
603 return sprintf(buf, "%d\n", data->pwm[attr->index]);
604}
605
606static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
607 const char *buf, size_t count)
608{
609 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
610 struct i2c_client *client = to_i2c_client(dev);
611 struct adt7473_data *data = i2c_get_clientdata(client);
612 long temp;
613
614 if (strict_strtol(buf, 10, &temp))
615 return -EINVAL;
616
617 temp = SENSORS_LIMIT(temp, 0, 255);
618
619 mutex_lock(&data->lock);
620 data->pwm[attr->index] = temp;
621 i2c_smbus_write_byte_data(client, ADT7473_REG_PWM(attr->index), temp);
622 mutex_unlock(&data->lock);
623
624 return count;
625}
626
627static ssize_t show_pwm_max(struct device *dev,
628 struct device_attribute *devattr,
629 char *buf)
630{
631 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
632 struct adt7473_data *data = adt7473_update_device(dev);
633 return sprintf(buf, "%d\n", data->pwm_max[attr->index]);
634}
635
636static ssize_t set_pwm_max(struct device *dev,
637 struct device_attribute *devattr,
638 const char *buf,
639 size_t count)
640{
641 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
642 struct i2c_client *client = to_i2c_client(dev);
643 struct adt7473_data *data = i2c_get_clientdata(client);
644 long temp;
645
646 if (strict_strtol(buf, 10, &temp))
647 return -EINVAL;
648
649 temp = SENSORS_LIMIT(temp, 0, 255);
650
651 mutex_lock(&data->lock);
652 data->pwm_max[attr->index] = temp;
653 i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MAX(attr->index),
654 temp);
655 mutex_unlock(&data->lock);
656
657 return count;
658}
659
660static ssize_t show_pwm_min(struct device *dev,
661 struct device_attribute *devattr,
662 char *buf)
663{
664 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
665 struct adt7473_data *data = adt7473_update_device(dev);
666 return sprintf(buf, "%d\n", data->pwm_min[attr->index]);
667}
668
669static ssize_t set_pwm_min(struct device *dev,
670 struct device_attribute *devattr,
671 const char *buf,
672 size_t count)
673{
674 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
675 struct i2c_client *client = to_i2c_client(dev);
676 struct adt7473_data *data = i2c_get_clientdata(client);
677 long temp;
678
679 if (strict_strtol(buf, 10, &temp))
680 return -EINVAL;
681
682 temp = SENSORS_LIMIT(temp, 0, 255);
683
684 mutex_lock(&data->lock);
685 data->pwm_min[attr->index] = temp;
686 i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_MIN(attr->index),
687 temp);
688 mutex_unlock(&data->lock);
689
690 return count;
691}
692
693static ssize_t show_temp_tmax(struct device *dev,
694 struct device_attribute *devattr,
695 char *buf)
696{
697 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
698 struct adt7473_data *data = adt7473_update_device(dev);
699 return sprintf(buf, "%d\n", 1000 * decode_temp(
700 data->temp_twos_complement,
701 data->temp_tmax[attr->index]));
702}
703
704static ssize_t set_temp_tmax(struct device *dev,
705 struct device_attribute *devattr,
706 const char *buf,
707 size_t count)
708{
709 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
710 struct i2c_client *client = to_i2c_client(dev);
711 struct adt7473_data *data = i2c_get_clientdata(client);
712 long temp;
713
714 if (strict_strtol(buf, 10, &temp))
715 return -EINVAL;
716
717 temp = DIV_ROUND_CLOSEST(temp, 1000);
718 temp = encode_temp(data->temp_twos_complement, temp);
719
720 mutex_lock(&data->lock);
721 data->temp_tmax[attr->index] = temp;
722 i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMAX(attr->index),
723 temp);
724 mutex_unlock(&data->lock);
725
726 return count;
727}
728
729static ssize_t show_temp_tmin(struct device *dev,
730 struct device_attribute *devattr,
731 char *buf)
732{
733 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
734 struct adt7473_data *data = adt7473_update_device(dev);
735 return sprintf(buf, "%d\n", 1000 * decode_temp(
736 data->temp_twos_complement,
737 data->temp_tmin[attr->index]));
738}
739
740static ssize_t set_temp_tmin(struct device *dev,
741 struct device_attribute *devattr,
742 const char *buf,
743 size_t count)
744{
745 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
746 struct i2c_client *client = to_i2c_client(dev);
747 struct adt7473_data *data = i2c_get_clientdata(client);
748 long temp;
749
750 if (strict_strtol(buf, 10, &temp))
751 return -EINVAL;
752
753 temp = DIV_ROUND_CLOSEST(temp, 1000);
754 temp = encode_temp(data->temp_twos_complement, temp);
755
756 mutex_lock(&data->lock);
757 data->temp_tmin[attr->index] = temp;
758 i2c_smbus_write_byte_data(client, ADT7473_REG_TEMP_TMIN(attr->index),
759 temp);
760 mutex_unlock(&data->lock);
761
762 return count;
763}
764
765static ssize_t show_pwm_enable(struct device *dev,
766 struct device_attribute *devattr,
767 char *buf)
768{
769 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
770 struct adt7473_data *data = adt7473_update_device(dev);
771
772 switch (data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT) {
773 case 3:
774 return sprintf(buf, "0\n");
775 case 7:
776 return sprintf(buf, "1\n");
777 default:
778 return sprintf(buf, "2\n");
779 }
780}
781
782static ssize_t set_pwm_enable(struct device *dev,
783 struct device_attribute *devattr,
784 const char *buf,
785 size_t count)
786{
787 u8 reg;
788 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
789 struct i2c_client *client = to_i2c_client(dev);
790 struct adt7473_data *data = i2c_get_clientdata(client);
791 long temp;
792
793 if (strict_strtol(buf, 10, &temp))
794 return -EINVAL;
795
796 switch (temp) {
797 case 0:
798 temp = 3;
799 break;
800 case 1:
801 temp = 7;
802 break;
803 case 2:
804 /* Enter automatic mode with fans off */
805 temp = 4;
806 break;
807 default:
808 return -EINVAL;
809 }
810
811 mutex_lock(&data->lock);
812 reg = i2c_smbus_read_byte_data(client,
813 ADT7473_REG_PWM_BHVR(attr->index));
814 reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
815 (reg & ~ADT7473_PWM_BHVR_MASK);
816 i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
817 reg);
818 data->pwm_behavior[attr->index] = reg;
819 mutex_unlock(&data->lock);
820
821 return count;
822}
823
824static ssize_t show_pwm_auto_temp(struct device *dev,
825 struct device_attribute *devattr,
826 char *buf)
827{
828 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
829 struct adt7473_data *data = adt7473_update_device(dev);
830 int bhvr = data->pwm_behavior[attr->index] >> ADT7473_PWM_BHVR_SHIFT;
831
832 switch (bhvr) {
833 case 3:
834 case 4:
835 case 7:
836 return sprintf(buf, "0\n");
837 case 0:
838 case 1:
839 case 5:
840 case 6:
841 return sprintf(buf, "%d\n", bhvr + 1);
842 case 2:
843 return sprintf(buf, "4\n");
844 }
845 /* shouldn't ever get here */
846 BUG();
847}
848
849static ssize_t set_pwm_auto_temp(struct device *dev,
850 struct device_attribute *devattr,
851 const char *buf,
852 size_t count)
853{
854 u8 reg;
855 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
856 struct i2c_client *client = to_i2c_client(dev);
857 struct adt7473_data *data = i2c_get_clientdata(client);
858 long temp;
859
860 if (strict_strtol(buf, 10, &temp))
861 return -EINVAL;
862
863 switch (temp) {
864 case 1:
865 case 2:
866 case 6:
867 case 7:
868 temp--;
869 break;
870 case 0:
871 temp = 4;
872 break;
873 default:
874 return -EINVAL;
875 }
876
877 mutex_lock(&data->lock);
878 reg = i2c_smbus_read_byte_data(client,
879 ADT7473_REG_PWM_BHVR(attr->index));
880 reg = (temp << ADT7473_PWM_BHVR_SHIFT) |
881 (reg & ~ADT7473_PWM_BHVR_MASK);
882 i2c_smbus_write_byte_data(client, ADT7473_REG_PWM_BHVR(attr->index),
883 reg);
884 data->pwm_behavior[attr->index] = reg;
885 mutex_unlock(&data->lock);
886
887 return count;
888}
889
890static ssize_t show_alarm(struct device *dev,
891 struct device_attribute *devattr,
892 char *buf)
893{
894 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
895 struct adt7473_data *data = adt7473_update_device(dev);
896
897 if (data->alarm & attr->index)
898 return sprintf(buf, "1\n");
899 else
900 return sprintf(buf, "0\n");
901}
902
903
904static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max,
905 set_volt_max, 0);
906static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max,
907 set_volt_max, 1);
908
909static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min,
910 set_volt_min, 0);
911static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min,
912 set_volt_min, 1);
913
914static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_volt, NULL, 0);
915static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_volt, NULL, 1);
916
917static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL,
918 ADT7473_VCCP_ALARM);
919static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL,
920 ADT7473_VCC_ALARM);
921
922static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
923 set_temp_max, 0);
924static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
925 set_temp_max, 1);
926static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max,
927 set_temp_max, 2);
928
929static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
930 set_temp_min, 0);
931static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
932 set_temp_min, 1);
933static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min,
934 set_temp_min, 2);
935
936static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
937static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
938static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
939
940static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL,
941 ADT7473_R1T_ALARM | ALARM2(ADT7473_R1T_SHORT));
942static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL,
943 ADT7473_LT_ALARM);
944static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL,
945 ADT7473_R2T_ALARM | ALARM2(ADT7473_R2T_SHORT));
946
947static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
948 set_fan_min, 0);
949static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
950 set_fan_min, 1);
951static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
952 set_fan_min, 2);
953static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
954 set_fan_min, 3);
955
956static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
957static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
958static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
959static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
960
961static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL,
962 ALARM2(ADT7473_FAN1_ALARM));
963static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL,
964 ALARM2(ADT7473_FAN2_ALARM));
965static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL,
966 ALARM2(ADT7473_FAN3_ALARM));
967static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL,
968 ALARM2(ADT7473_FAN4_ALARM));
969
970static SENSOR_DEVICE_ATTR(pwm_use_point2_pwm_at_crit, S_IWUSR | S_IRUGO,
971 show_max_duty_at_crit, set_max_duty_at_crit, 0);
972
973static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0);
974static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1);
975static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2);
976
977static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
978 show_pwm_min, set_pwm_min, 0);
979static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO,
980 show_pwm_min, set_pwm_min, 1);
981static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO,
982 show_pwm_min, set_pwm_min, 2);
983
984static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
985 show_pwm_max, set_pwm_max, 0);
986static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO,
987 show_pwm_max, set_pwm_max, 1);
988static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO,
989 show_pwm_max, set_pwm_max, 2);
990
991static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO,
992 show_temp_tmin, set_temp_tmin, 0);
993static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO,
994 show_temp_tmin, set_temp_tmin, 1);
995static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO,
996 show_temp_tmin, set_temp_tmin, 2);
997
998static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO,
999 show_temp_tmax, set_temp_tmax, 0);
1000static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
1001 show_temp_tmax, set_temp_tmax, 1);
1002static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO,
1003 show_temp_tmax, set_temp_tmax, 2);
1004
1005static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1006 set_pwm_enable, 0);
1007static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1008 set_pwm_enable, 1);
1009static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable,
1010 set_pwm_enable, 2);
1011
1012static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO,
1013 show_pwm_auto_temp, set_pwm_auto_temp, 0);
1014static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO,
1015 show_pwm_auto_temp, set_pwm_auto_temp, 1);
1016static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
1017 show_pwm_auto_temp, set_pwm_auto_temp, 2);
1018
1019static struct attribute *adt7473_attr[] =
1020{
1021 &sensor_dev_attr_in1_max.dev_attr.attr,
1022 &sensor_dev_attr_in2_max.dev_attr.attr,
1023 &sensor_dev_attr_in1_min.dev_attr.attr,
1024 &sensor_dev_attr_in2_min.dev_attr.attr,
1025 &sensor_dev_attr_in1_input.dev_attr.attr,
1026 &sensor_dev_attr_in2_input.dev_attr.attr,
1027 &sensor_dev_attr_in1_alarm.dev_attr.attr,
1028 &sensor_dev_attr_in2_alarm.dev_attr.attr,
1029
1030 &sensor_dev_attr_temp1_max.dev_attr.attr,
1031 &sensor_dev_attr_temp2_max.dev_attr.attr,
1032 &sensor_dev_attr_temp3_max.dev_attr.attr,
1033 &sensor_dev_attr_temp1_min.dev_attr.attr,
1034 &sensor_dev_attr_temp2_min.dev_attr.attr,
1035 &sensor_dev_attr_temp3_min.dev_attr.attr,
1036 &sensor_dev_attr_temp1_input.dev_attr.attr,
1037 &sensor_dev_attr_temp2_input.dev_attr.attr,
1038 &sensor_dev_attr_temp3_input.dev_attr.attr,
1039 &sensor_dev_attr_temp1_alarm.dev_attr.attr,
1040 &sensor_dev_attr_temp2_alarm.dev_attr.attr,
1041 &sensor_dev_attr_temp3_alarm.dev_attr.attr,
1042 &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
1043 &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
1044 &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr,
1045 &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
1046 &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
1047 &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
1048
1049 &sensor_dev_attr_fan1_min.dev_attr.attr,
1050 &sensor_dev_attr_fan2_min.dev_attr.attr,
1051 &sensor_dev_attr_fan3_min.dev_attr.attr,
1052 &sensor_dev_attr_fan4_min.dev_attr.attr,
1053 &sensor_dev_attr_fan1_input.dev_attr.attr,
1054 &sensor_dev_attr_fan2_input.dev_attr.attr,
1055 &sensor_dev_attr_fan3_input.dev_attr.attr,
1056 &sensor_dev_attr_fan4_input.dev_attr.attr,
1057 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1058 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1059 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
1060 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
1061
1062 &sensor_dev_attr_pwm_use_point2_pwm_at_crit.dev_attr.attr,
1063
1064 &sensor_dev_attr_pwm1.dev_attr.attr,
1065 &sensor_dev_attr_pwm2.dev_attr.attr,
1066 &sensor_dev_attr_pwm3.dev_attr.attr,
1067 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
1068 &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
1069 &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
1070 &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
1071 &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
1072 &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
1073
1074 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
1075 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1076 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1077 &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
1078 &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
1079 &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
1080
1081 NULL
1082};
1083
1084/* Return 0 if detection is successful, -ENODEV otherwise */
1085static int adt7473_detect(struct i2c_client *client,
1086 struct i2c_board_info *info)
1087{
1088 struct i2c_adapter *adapter = client->adapter;
1089 int vendor, device, revision;
1090
1091 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1092 return -ENODEV;
1093
1094 vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
1095 if (vendor != ADT7473_VENDOR)
1096 return -ENODEV;
1097
1098 device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
1099 if (device != ADT7473_DEVICE)
1100 return -ENODEV;
1101
1102 revision = i2c_smbus_read_byte_data(client, ADT7473_REG_REVISION);
1103 if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
1104 return -ENODEV;
1105
1106 strlcpy(info->type, "adt7473", I2C_NAME_SIZE);
1107
1108 return 0;
1109}
1110
1111static int adt7473_probe(struct i2c_client *client,
1112 const struct i2c_device_id *id)
1113{
1114 struct adt7473_data *data;
1115 int err;
1116
1117 data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL);
1118 if (!data) {
1119 err = -ENOMEM;
1120 goto exit;
1121 }
1122
1123 i2c_set_clientdata(client, data);
1124 mutex_init(&data->lock);
1125
1126 dev_info(&client->dev, "%s chip found\n", client->name);
1127
1128 /* Initialize the ADT7473 chip */
1129 adt7473_init_client(client);
1130
1131 /* Register sysfs hooks */
1132 data->attrs.attrs = adt7473_attr;
1133 err = sysfs_create_group(&client->dev.kobj, &data->attrs);
1134 if (err)
1135 goto exit_free;
1136
1137 data->hwmon_dev = hwmon_device_register(&client->dev);
1138 if (IS_ERR(data->hwmon_dev)) {
1139 err = PTR_ERR(data->hwmon_dev);
1140 goto exit_remove;
1141 }
1142
1143 return 0;
1144
1145exit_remove:
1146 sysfs_remove_group(&client->dev.kobj, &data->attrs);
1147exit_free:
1148 kfree(data);
1149exit:
1150 return err;
1151}
1152
1153static int adt7473_remove(struct i2c_client *client)
1154{
1155 struct adt7473_data *data = i2c_get_clientdata(client);
1156
1157 hwmon_device_unregister(data->hwmon_dev);
1158 sysfs_remove_group(&client->dev.kobj, &data->attrs);
1159 kfree(data);
1160 return 0;
1161}
1162
1163static int __init adt7473_init(void)
1164{
1165 pr_notice("The adt7473 driver is deprecated, please use the adt7475 "
1166 "driver instead\n");
1167 return i2c_add_driver(&adt7473_driver);
1168}
1169
1170static void __exit adt7473_exit(void)
1171{
1172 i2c_del_driver(&adt7473_driver);
1173}
1174
1175MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
1176MODULE_DESCRIPTION("ADT7473 driver");
1177MODULE_LICENSE("GPL");
1178
1179module_init(adt7473_init);
1180module_exit(adt7473_exit);
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
new file mode 100644
index 000000000000..7f948105d8ad
--- /dev/null
+++ b/drivers/hwmon/asc7621.c
@@ -0,0 +1,1255 @@
1/*
2 * asc7621.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
3 * Copyright (c) 2007, 2010 George Joseph <george.joseph@fairview5.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/jiffies.h>
24#include <linux/i2c.h>
25#include <linux/hwmon.h>
26#include <linux/hwmon-sysfs.h>
27#include <linux/err.h>
28#include <linux/mutex.h>
29
30/* Addresses to scan */
31static unsigned short normal_i2c[] = {
32 0x2c, 0x2d, 0x2e, I2C_CLIENT_END
33};
34
35enum asc7621_type {
36 asc7621,
37 asc7621a
38};
39
40#define INTERVAL_HIGH (HZ + HZ / 2)
41#define INTERVAL_LOW (1 * 60 * HZ)
42#define PRI_NONE 0
43#define PRI_LOW 1
44#define PRI_HIGH 2
45#define FIRST_CHIP asc7621
46#define LAST_CHIP asc7621a
47
48struct asc7621_chip {
49 char *name;
50 enum asc7621_type chip_type;
51 u8 company_reg;
52 u8 company_id;
53 u8 verstep_reg;
54 u8 verstep_id;
55 unsigned short *addresses;
56};
57
58static struct asc7621_chip asc7621_chips[] = {
59 {
60 .name = "asc7621",
61 .chip_type = asc7621,
62 .company_reg = 0x3e,
63 .company_id = 0x61,
64 .verstep_reg = 0x3f,
65 .verstep_id = 0x6c,
66 .addresses = normal_i2c,
67 },
68 {
69 .name = "asc7621a",
70 .chip_type = asc7621a,
71 .company_reg = 0x3e,
72 .company_id = 0x61,
73 .verstep_reg = 0x3f,
74 .verstep_id = 0x6d,
75 .addresses = normal_i2c,
76 },
77};
78
79/*
80 * Defines the highest register to be used, not the count.
81 * The actual count will probably be smaller because of gaps
82 * in the implementation (unused register locations).
83 * This define will safely set the array size of both the parameter
84 * and data arrays.
85 * This comes from the data sheet register description table.
86 */
87#define LAST_REGISTER 0xff
88
89struct asc7621_data {
90 struct i2c_client client;
91 struct device *class_dev;
92 struct mutex update_lock;
93 int valid; /* !=0 if following fields are valid */
94 unsigned long last_high_reading; /* In jiffies */
95 unsigned long last_low_reading; /* In jiffies */
96 /*
97 * Registers we care about occupy the corresponding index
98 * in the array. Registers we don't care about are left
99 * at 0.
100 */
101 u8 reg[LAST_REGISTER + 1];
102};
103
104/*
105 * Macro to get the parent asc7621_param structure
106 * from a sensor_device_attribute passed into the
107 * show/store functions.
108 */
109#define to_asc7621_param(_sda) \
110 container_of(_sda, struct asc7621_param, sda)
111
112/*
113 * Each parameter to be retrieved needs an asc7621_param structure
114 * allocated. It contains the sensor_device_attribute structure
115 * and the control info needed to retrieve the value from the register map.
116 */
117struct asc7621_param {
118 struct sensor_device_attribute sda;
119 u8 priority;
120 u8 msb[3];
121 u8 lsb[3];
122 u8 mask[3];
123 u8 shift[3];
124};
125
126/*
127 * This is the map that ultimately indicates whether we'll be
128 * retrieving a register value or not, and at what frequency.
129 */
130static u8 asc7621_register_priorities[255];
131
132static struct asc7621_data *asc7621_update_device(struct device *dev);
133
134static inline u8 read_byte(struct i2c_client *client, u8 reg)
135{
136 int res = i2c_smbus_read_byte_data(client, reg);
137 if (res < 0) {
138 dev_err(&client->dev,
139 "Unable to read from register 0x%02x.\n", reg);
140 return 0;
141 };
142 return res & 0xff;
143}
144
145static inline int write_byte(struct i2c_client *client, u8 reg, u8 data)
146{
147 int res = i2c_smbus_write_byte_data(client, reg, data);
148 if (res < 0) {
149 dev_err(&client->dev,
150 "Unable to write value 0x%02x to register 0x%02x.\n",
151 data, reg);
152 };
153 return res;
154}
155
156/*
157 * Data Handlers
158 * Each function handles the formatting, storage
159 * and retrieval of like parameters.
160 */
161
162#define SETUP_SHOW_data_param(d, a) \
163 struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
164 struct asc7621_data *data = asc7621_update_device(d); \
165 struct asc7621_param *param = to_asc7621_param(sda)
166
167#define SETUP_STORE_data_param(d, a) \
168 struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
169 struct i2c_client *client = to_i2c_client(d); \
170 struct asc7621_data *data = i2c_get_clientdata(client); \
171 struct asc7621_param *param = to_asc7621_param(sda)
172
173/*
174 * u8 is just what it sounds like...an unsigned byte with no
175 * special formatting.
176 */
177static ssize_t show_u8(struct device *dev, struct device_attribute *attr,
178 char *buf)
179{
180 SETUP_SHOW_data_param(dev, attr);
181
182 return sprintf(buf, "%u\n", data->reg[param->msb[0]]);
183}
184
185static ssize_t store_u8(struct device *dev, struct device_attribute *attr,
186 const char *buf, size_t count)
187{
188 SETUP_STORE_data_param(dev, attr);
189 long reqval;
190
191 if (strict_strtol(buf, 10, &reqval))
192 return -EINVAL;
193
194 reqval = SENSORS_LIMIT(reqval, 0, 255);
195
196 mutex_lock(&data->update_lock);
197 data->reg[param->msb[0]] = reqval;
198 write_byte(client, param->msb[0], reqval);
199 mutex_unlock(&data->update_lock);
200 return count;
201}
202
203/*
204 * Many of the config values occupy only a few bits of a register.
205 */
206static ssize_t show_bitmask(struct device *dev,
207 struct device_attribute *attr, char *buf)
208{
209 SETUP_SHOW_data_param(dev, attr);
210
211 return sprintf(buf, "%u\n",
212 (data->reg[param->msb[0]] >> param->
213 shift[0]) & param->mask[0]);
214}
215
216static ssize_t store_bitmask(struct device *dev,
217 struct device_attribute *attr,
218 const char *buf, size_t count)
219{
220 SETUP_STORE_data_param(dev, attr);
221 long reqval;
222 u8 currval;
223
224 if (strict_strtol(buf, 10, &reqval))
225 return -EINVAL;
226
227 reqval = SENSORS_LIMIT(reqval, 0, param->mask[0]);
228
229 reqval = (reqval & param->mask[0]) << param->shift[0];
230
231 mutex_lock(&data->update_lock);
232 currval = read_byte(client, param->msb[0]);
233 reqval |= (currval & ~(param->mask[0] << param->shift[0]));
234 data->reg[param->msb[0]] = reqval;
235 write_byte(client, param->msb[0], reqval);
236 mutex_unlock(&data->update_lock);
237 return count;
238}
239
240/*
241 * 16 bit fan rpm values
242 * reported by the device as the number of 11.111us periods (90khz)
243 * between full fan rotations. Therefore...
244 * RPM = (90000 * 60) / register value
245 */
246static ssize_t show_fan16(struct device *dev,
247 struct device_attribute *attr, char *buf)
248{
249 SETUP_SHOW_data_param(dev, attr);
250 u16 regval;
251
252 mutex_lock(&data->update_lock);
253 regval = (data->reg[param->msb[0]] << 8) | data->reg[param->lsb[0]];
254 mutex_unlock(&data->update_lock);
255
256 return sprintf(buf, "%u\n",
257 (regval == 0 ? -1 : (regval) ==
258 0xffff ? 0 : 5400000 / regval));
259}
260
261static ssize_t store_fan16(struct device *dev,
262 struct device_attribute *attr, const char *buf,
263 size_t count)
264{
265 SETUP_STORE_data_param(dev, attr);
266 long reqval;
267
268 if (strict_strtol(buf, 10, &reqval))
269 return -EINVAL;
270
271 reqval =
272 (SENSORS_LIMIT((reqval) <= 0 ? 0 : 5400000 / (reqval), 0, 65534));
273
274 mutex_lock(&data->update_lock);
275 data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
276 data->reg[param->lsb[0]] = reqval & 0xff;
277 write_byte(client, param->msb[0], data->reg[param->msb[0]]);
278 write_byte(client, param->lsb[0], data->reg[param->lsb[0]]);
279 mutex_unlock(&data->update_lock);
280
281 return count;
282}
283
284/*
285 * Voltages are scaled in the device so that the nominal voltage
286 * is 3/4ths of the 0-255 range (i.e. 192).
287 * If all voltages are 'normal' then all voltage registers will
288 * read 0xC0. This doesn't help us if we don't have a point of refernce.
289 * The data sheet however provides us with the full scale value for each
290 * which is stored in in_scaling. The sda->index parameter value provides
291 * the index into in_scaling.
292 *
293 * NOTE: The chip expects the first 2 inputs be 2.5 and 2.25 volts
294 * respectively. That doesn't mean that's what the motherboard provides. :)
295 */
296
297static int asc7621_in_scaling[] = {
298 3320, 3000, 4380, 6640, 16000
299};
300
301static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
302 char *buf)
303{
304 SETUP_SHOW_data_param(dev, attr);
305 u16 regval;
306 u8 nr = sda->index;
307
308 mutex_lock(&data->update_lock);
309 regval = (data->reg[param->msb[0]] * asc7621_in_scaling[nr]) / 256;
310
311 /* The LSB value is a 2-bit scaling of the MSB's LSbit value.
312 * I.E. If the maximim voltage for this input is 6640 millivolts then
313 * a MSB register value of 0 = 0mv and 255 = 6640mv.
314 * A 1 step change therefore represents 25.9mv (6640 / 256).
315 * The extra 2-bits therefore represent increments of 6.48mv.
316 */
317 regval += ((asc7621_in_scaling[nr] / 256) / 4) *
318 (data->reg[param->lsb[0]] >> 6);
319
320 mutex_unlock(&data->update_lock);
321
322 return sprintf(buf, "%u\n", regval);
323}
324
325/* 8 bit voltage values (the mins and maxs) */
326static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
327 char *buf)
328{
329 SETUP_SHOW_data_param(dev, attr);
330 u8 nr = sda->index;
331
332 return sprintf(buf, "%u\n",
333 ((data->reg[param->msb[0]] *
334 asc7621_in_scaling[nr]) / 256));
335}
336
337static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
338 const char *buf, size_t count)
339{
340 SETUP_STORE_data_param(dev, attr);
341 long reqval;
342 u8 nr = sda->index;
343
344 if (strict_strtol(buf, 10, &reqval))
345 return -EINVAL;
346
347 reqval = SENSORS_LIMIT(reqval, 0, asc7621_in_scaling[nr]);
348
349 reqval = (reqval * 255 + 128) / asc7621_in_scaling[nr];
350
351 mutex_lock(&data->update_lock);
352 data->reg[param->msb[0]] = reqval;
353 write_byte(client, param->msb[0], reqval);
354 mutex_unlock(&data->update_lock);
355
356 return count;
357}
358
359static ssize_t show_temp8(struct device *dev,
360 struct device_attribute *attr, char *buf)
361{
362 SETUP_SHOW_data_param(dev, attr);
363
364 return sprintf(buf, "%d\n", ((s8) data->reg[param->msb[0]]) * 1000);
365}
366
367static ssize_t store_temp8(struct device *dev,
368 struct device_attribute *attr, const char *buf,
369 size_t count)
370{
371 SETUP_STORE_data_param(dev, attr);
372 long reqval;
373 s8 temp;
374
375 if (strict_strtol(buf, 10, &reqval))
376 return -EINVAL;
377
378 reqval = SENSORS_LIMIT(reqval, -127000, 127000);
379
380 temp = reqval / 1000;
381
382 mutex_lock(&data->update_lock);
383 data->reg[param->msb[0]] = temp;
384 write_byte(client, param->msb[0], temp);
385 mutex_unlock(&data->update_lock);
386 return count;
387}
388
389/*
390 * Temperatures that occupy 2 bytes always have the whole
391 * number of degrees in the MSB with some part of the LSB
392 * indicating fractional degrees.
393 */
394
395/* mmmmmmmm.llxxxxxx */
396static ssize_t show_temp10(struct device *dev,
397 struct device_attribute *attr, char *buf)
398{
399 SETUP_SHOW_data_param(dev, attr);
400 u8 msb, lsb;
401 int temp;
402
403 mutex_lock(&data->update_lock);
404 msb = data->reg[param->msb[0]];
405 lsb = (data->reg[param->lsb[0]] >> 6) & 0x03;
406 temp = (((s8) msb) * 1000) + (lsb * 250);
407 mutex_unlock(&data->update_lock);
408
409 return sprintf(buf, "%d\n", temp);
410}
411
412/* mmmmmm.ll */
413static ssize_t show_temp62(struct device *dev,
414 struct device_attribute *attr, char *buf)
415{
416 SETUP_SHOW_data_param(dev, attr);
417 u8 regval = data->reg[param->msb[0]];
418 int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250);
419
420 return sprintf(buf, "%d\n", temp);
421}
422
423static ssize_t store_temp62(struct device *dev,
424 struct device_attribute *attr, const char *buf,
425 size_t count)
426{
427 SETUP_STORE_data_param(dev, attr);
428 long reqval, i, f;
429 s8 temp;
430
431 if (strict_strtol(buf, 10, &reqval))
432 return -EINVAL;
433
434 reqval = SENSORS_LIMIT(reqval, -32000, 31750);
435 i = reqval / 1000;
436 f = reqval - (i * 1000);
437 temp = i << 2;
438 temp |= f / 250;
439
440 mutex_lock(&data->update_lock);
441 data->reg[param->msb[0]] = temp;
442 write_byte(client, param->msb[0], temp);
443 mutex_unlock(&data->update_lock);
444 return count;
445}
446
447/*
448 * The aSC7621 doesn't provide an "auto_point2". Instead, you
449 * specify the auto_point1 and a range. To keep with the sysfs
450 * hwmon specs, we synthesize the auto_point_2 from them.
451 */
452
453static u32 asc7621_range_map[] = {
454 2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
455 13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
456};
457
458static ssize_t show_ap2_temp(struct device *dev,
459 struct device_attribute *attr, char *buf)
460{
461 SETUP_SHOW_data_param(dev, attr);
462 long auto_point1;
463 u8 regval;
464 int temp;
465
466 mutex_lock(&data->update_lock);
467 auto_point1 = ((s8) data->reg[param->msb[1]]) * 1000;
468 regval =
469 ((data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]);
470 temp = auto_point1 + asc7621_range_map[SENSORS_LIMIT(regval, 0, 15)];
471 mutex_unlock(&data->update_lock);
472
473 return sprintf(buf, "%d\n", temp);
474
475}
476
477static ssize_t store_ap2_temp(struct device *dev,
478 struct device_attribute *attr,
479 const char *buf, size_t count)
480{
481 SETUP_STORE_data_param(dev, attr);
482 long reqval, auto_point1;
483 int i;
484 u8 currval, newval = 0;
485
486 if (strict_strtol(buf, 10, &reqval))
487 return -EINVAL;
488
489 mutex_lock(&data->update_lock);
490 auto_point1 = data->reg[param->msb[1]] * 1000;
491 reqval = SENSORS_LIMIT(reqval, auto_point1 + 2000, auto_point1 + 80000);
492
493 for (i = ARRAY_SIZE(asc7621_range_map) - 1; i >= 0; i--) {
494 if (reqval >= auto_point1 + asc7621_range_map[i]) {
495 newval = i;
496 break;
497 }
498 }
499
500 newval = (newval & param->mask[0]) << param->shift[0];
501 currval = read_byte(client, param->msb[0]);
502 newval |= (currval & ~(param->mask[0] << param->shift[0]));
503 data->reg[param->msb[0]] = newval;
504 write_byte(client, param->msb[0], newval);
505 mutex_unlock(&data->update_lock);
506 return count;
507}
508
509static ssize_t show_pwm_ac(struct device *dev,
510 struct device_attribute *attr, char *buf)
511{
512 SETUP_SHOW_data_param(dev, attr);
513 u8 config, altbit, regval;
514 u8 map[] = {
515 0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
516 0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
517 };
518
519 mutex_lock(&data->update_lock);
520 config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
521 altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
522 regval = config | (altbit << 3);
523 mutex_unlock(&data->update_lock);
524
525 return sprintf(buf, "%u\n", map[SENSORS_LIMIT(regval, 0, 15)]);
526}
527
528static ssize_t store_pwm_ac(struct device *dev,
529 struct device_attribute *attr,
530 const char *buf, size_t count)
531{
532 SETUP_STORE_data_param(dev, attr);
533 unsigned long reqval;
534 u8 currval, config, altbit, newval;
535 u16 map[] = {
536 0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
537 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
538 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
539 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
540 };
541
542 if (strict_strtoul(buf, 10, &reqval))
543 return -EINVAL;
544
545 if (reqval > 31)
546 return -EINVAL;
547
548 reqval = map[reqval];
549 if (reqval == 0xff)
550 return -EINVAL;
551
552 config = reqval & 0x07;
553 altbit = (reqval >> 3) & 0x01;
554
555 config = (config & param->mask[0]) << param->shift[0];
556 altbit = (altbit & param->mask[1]) << param->shift[1];
557
558 mutex_lock(&data->update_lock);
559 currval = read_byte(client, param->msb[0]);
560 newval = config | (currval & ~(param->mask[0] << param->shift[0]));
561 newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
562 data->reg[param->msb[0]] = newval;
563 write_byte(client, param->msb[0], newval);
564 mutex_unlock(&data->update_lock);
565 return count;
566}
567
568static ssize_t show_pwm_enable(struct device *dev,
569 struct device_attribute *attr, char *buf)
570{
571 SETUP_SHOW_data_param(dev, attr);
572 u8 config, altbit, minoff, val, newval;
573
574 mutex_lock(&data->update_lock);
575 config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
576 altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
577 minoff = (data->reg[param->msb[2]] >> param->shift[2]) & param->mask[2];
578 mutex_unlock(&data->update_lock);
579
580 val = config | (altbit << 3);
581 newval = 0;
582
583 if (val == 3 || val >= 10)
584 newval = 255;
585 else if (val == 4)
586 newval = 0;
587 else if (val == 7)
588 newval = 1;
589 else if (minoff == 1)
590 newval = 2;
591 else
592 newval = 3;
593
594 return sprintf(buf, "%u\n", newval);
595}
596
597static ssize_t store_pwm_enable(struct device *dev,
598 struct device_attribute *attr,
599 const char *buf, size_t count)
600{
601 SETUP_STORE_data_param(dev, attr);
602 long reqval;
603 u8 currval, config, altbit, newval, minoff = 255;
604
605 if (strict_strtol(buf, 10, &reqval))
606 return -EINVAL;
607
608 switch (reqval) {
609 case 0:
610 newval = 0x04;
611 break;
612 case 1:
613 newval = 0x07;
614 break;
615 case 2:
616 newval = 0x00;
617 minoff = 1;
618 break;
619 case 3:
620 newval = 0x00;
621 minoff = 0;
622 break;
623 case 255:
624 newval = 0x03;
625 break;
626 default:
627 return -EINVAL;
628 }
629
630 config = newval & 0x07;
631 altbit = (newval >> 3) & 0x01;
632
633 mutex_lock(&data->update_lock);
634 config = (config & param->mask[0]) << param->shift[0];
635 altbit = (altbit & param->mask[1]) << param->shift[1];
636 currval = read_byte(client, param->msb[0]);
637 newval = config | (currval & ~(param->mask[0] << param->shift[0]));
638 newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
639 data->reg[param->msb[0]] = newval;
640 write_byte(client, param->msb[0], newval);
641 if (minoff < 255) {
642 minoff = (minoff & param->mask[2]) << param->shift[2];
643 currval = read_byte(client, param->msb[2]);
644 newval =
645 minoff | (currval & ~(param->mask[2] << param->shift[2]));
646 data->reg[param->msb[2]] = newval;
647 write_byte(client, param->msb[2], newval);
648 }
649 mutex_unlock(&data->update_lock);
650 return count;
651}
652
653static u32 asc7621_pwm_freq_map[] = {
654 10, 15, 23, 30, 38, 47, 62, 94,
655 23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
656};
657
658static ssize_t show_pwm_freq(struct device *dev,
659 struct device_attribute *attr, char *buf)
660{
661 SETUP_SHOW_data_param(dev, attr);
662 u8 regval =
663 (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
664
665 regval = SENSORS_LIMIT(regval, 0, 15);
666
667 return sprintf(buf, "%u\n", asc7621_pwm_freq_map[regval]);
668}
669
670static ssize_t store_pwm_freq(struct device *dev,
671 struct device_attribute *attr,
672 const char *buf, size_t count)
673{
674 SETUP_STORE_data_param(dev, attr);
675 unsigned long reqval;
676 u8 currval, newval = 255;
677 int i;
678
679 if (strict_strtoul(buf, 10, &reqval))
680 return -EINVAL;
681
682 for (i = 0; i < ARRAY_SIZE(asc7621_pwm_freq_map); i++) {
683 if (reqval == asc7621_pwm_freq_map[i]) {
684 newval = i;
685 break;
686 }
687 }
688 if (newval == 255)
689 return -EINVAL;
690
691 newval = (newval & param->mask[0]) << param->shift[0];
692
693 mutex_lock(&data->update_lock);
694 currval = read_byte(client, param->msb[0]);
695 newval |= (currval & ~(param->mask[0] << param->shift[0]));
696 data->reg[param->msb[0]] = newval;
697 write_byte(client, param->msb[0], newval);
698 mutex_unlock(&data->update_lock);
699 return count;
700}
701
702static u32 asc7621_pwm_auto_spinup_map[] = {
703 0, 100, 250, 400, 700, 1000, 2000, 4000
704};
705
706static ssize_t show_pwm_ast(struct device *dev,
707 struct device_attribute *attr, char *buf)
708{
709 SETUP_SHOW_data_param(dev, attr);
710 u8 regval =
711 (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
712
713 regval = SENSORS_LIMIT(regval, 0, 7);
714
715 return sprintf(buf, "%u\n", asc7621_pwm_auto_spinup_map[regval]);
716
717}
718
719static ssize_t store_pwm_ast(struct device *dev,
720 struct device_attribute *attr,
721 const char *buf, size_t count)
722{
723 SETUP_STORE_data_param(dev, attr);
724 long reqval;
725 u8 currval, newval = 255;
726 u32 i;
727
728 if (strict_strtol(buf, 10, &reqval))
729 return -EINVAL;
730
731 for (i = 0; i < ARRAY_SIZE(asc7621_pwm_auto_spinup_map); i++) {
732 if (reqval == asc7621_pwm_auto_spinup_map[i]) {
733 newval = i;
734 break;
735 }
736 }
737 if (newval == 255)
738 return -EINVAL;
739
740 newval = (newval & param->mask[0]) << param->shift[0];
741
742 mutex_lock(&data->update_lock);
743 currval = read_byte(client, param->msb[0]);
744 newval |= (currval & ~(param->mask[0] << param->shift[0]));
745 data->reg[param->msb[0]] = newval;
746 write_byte(client, param->msb[0], newval);
747 mutex_unlock(&data->update_lock);
748 return count;
749}
750
751static u32 asc7621_temp_smoothing_time_map[] = {
752 35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
753};
754
755static ssize_t show_temp_st(struct device *dev,
756 struct device_attribute *attr, char *buf)
757{
758 SETUP_SHOW_data_param(dev, attr);
759 u8 regval =
760 (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
761 regval = SENSORS_LIMIT(regval, 0, 7);
762
763 return sprintf(buf, "%u\n", asc7621_temp_smoothing_time_map[regval]);
764}
765
766static ssize_t store_temp_st(struct device *dev,
767 struct device_attribute *attr,
768 const char *buf, size_t count)
769{
770 SETUP_STORE_data_param(dev, attr);
771 long reqval;
772 u8 currval, newval = 255;
773 u32 i;
774
775 if (strict_strtol(buf, 10, &reqval))
776 return -EINVAL;
777
778 for (i = 0; i < ARRAY_SIZE(asc7621_temp_smoothing_time_map); i++) {
779 if (reqval == asc7621_temp_smoothing_time_map[i]) {
780 newval = i;
781 break;
782 }
783 }
784
785 if (newval == 255)
786 return -EINVAL;
787
788 newval = (newval & param->mask[0]) << param->shift[0];
789
790 mutex_lock(&data->update_lock);
791 currval = read_byte(client, param->msb[0]);
792 newval |= (currval & ~(param->mask[0] << param->shift[0]));
793 data->reg[param->msb[0]] = newval;
794 write_byte(client, param->msb[0], newval);
795 mutex_unlock(&data->update_lock);
796 return count;
797}
798
799/*
800 * End of data handlers
801 *
802 * These defines do nothing more than make the table easier
803 * to read when wrapped at column 80.
804 */
805
806/*
807 * Creates a variable length array inititalizer.
808 * VAA(1,3,5,7) would produce {1,3,5,7}
809 */
810#define VAA(args...) {args}
811
812#define PREAD(name, n, pri, rm, rl, m, s, r) \
813 {.sda = SENSOR_ATTR(name, S_IRUGO, show_##r, NULL, n), \
814 .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
815 .shift[0] = s,}
816
817#define PWRITE(name, n, pri, rm, rl, m, s, r) \
818 {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
819 .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
820 .shift[0] = s,}
821
822/*
823 * PWRITEM assumes that the initializers for the .msb, .lsb, .mask and .shift
824 * were created using the VAA macro.
825 */
826#define PWRITEM(name, n, pri, rm, rl, m, s, r) \
827 {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
828 .priority = pri, .msb = rm, .lsb = rl, .mask = m, .shift = s,}
829
830static struct asc7621_param asc7621_params[] = {
831 PREAD(in0_input, 0, PRI_HIGH, 0x20, 0x13, 0, 0, in10),
832 PREAD(in1_input, 1, PRI_HIGH, 0x21, 0x18, 0, 0, in10),
833 PREAD(in2_input, 2, PRI_HIGH, 0x22, 0x11, 0, 0, in10),
834 PREAD(in3_input, 3, PRI_HIGH, 0x23, 0x12, 0, 0, in10),
835 PREAD(in4_input, 4, PRI_HIGH, 0x24, 0x14, 0, 0, in10),
836
837 PWRITE(in0_min, 0, PRI_LOW, 0x44, 0, 0, 0, in8),
838 PWRITE(in1_min, 1, PRI_LOW, 0x46, 0, 0, 0, in8),
839 PWRITE(in2_min, 2, PRI_LOW, 0x48, 0, 0, 0, in8),
840 PWRITE(in3_min, 3, PRI_LOW, 0x4a, 0, 0, 0, in8),
841 PWRITE(in4_min, 4, PRI_LOW, 0x4c, 0, 0, 0, in8),
842
843 PWRITE(in0_max, 0, PRI_LOW, 0x45, 0, 0, 0, in8),
844 PWRITE(in1_max, 1, PRI_LOW, 0x47, 0, 0, 0, in8),
845 PWRITE(in2_max, 2, PRI_LOW, 0x49, 0, 0, 0, in8),
846 PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
847 PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
848
849 PREAD(in0_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 0, bitmask),
850 PREAD(in1_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 1, bitmask),
851 PREAD(in2_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 2, bitmask),
852 PREAD(in3_alarm, 3, PRI_LOW, 0x41, 0, 0x01, 3, bitmask),
853 PREAD(in4_alarm, 4, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
854
855 PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
856 PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
857 PREAD(fan3_input, 2, PRI_HIGH, 0x2d, 0x2c, 0, 0, fan16),
858 PREAD(fan4_input, 3, PRI_HIGH, 0x2f, 0x2e, 0, 0, fan16),
859
860 PWRITE(fan1_min, 0, PRI_LOW, 0x55, 0x54, 0, 0, fan16),
861 PWRITE(fan2_min, 1, PRI_LOW, 0x57, 0x56, 0, 0, fan16),
862 PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
863 PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
864
865 PREAD(fan1_alarm, 0, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
866 PREAD(fan2_alarm, 1, PRI_LOW, 0x42, 0, 0x01, 1, bitmask),
867 PREAD(fan3_alarm, 2, PRI_LOW, 0x42, 0, 0x01, 2, bitmask),
868 PREAD(fan4_alarm, 3, PRI_LOW, 0x42, 0, 0x01, 3, bitmask),
869
870 PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
871 PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
872 PREAD(temp3_input, 2, PRI_HIGH, 0x27, 0x16, 0, 0, temp10),
873 PREAD(temp4_input, 3, PRI_HIGH, 0x33, 0x17, 0, 0, temp10),
874 PREAD(temp5_input, 4, PRI_HIGH, 0xf7, 0xf6, 0, 0, temp10),
875 PREAD(temp6_input, 5, PRI_HIGH, 0xf9, 0xf8, 0, 0, temp10),
876 PREAD(temp7_input, 6, PRI_HIGH, 0xfb, 0xfa, 0, 0, temp10),
877 PREAD(temp8_input, 7, PRI_HIGH, 0xfd, 0xfc, 0, 0, temp10),
878
879 PWRITE(temp1_min, 0, PRI_LOW, 0x4e, 0, 0, 0, temp8),
880 PWRITE(temp2_min, 1, PRI_LOW, 0x50, 0, 0, 0, temp8),
881 PWRITE(temp3_min, 2, PRI_LOW, 0x52, 0, 0, 0, temp8),
882 PWRITE(temp4_min, 3, PRI_LOW, 0x34, 0, 0, 0, temp8),
883
884 PWRITE(temp1_max, 0, PRI_LOW, 0x4f, 0, 0, 0, temp8),
885 PWRITE(temp2_max, 1, PRI_LOW, 0x51, 0, 0, 0, temp8),
886 PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
887 PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
888
889 PREAD(temp1_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 4, bitmask),
890 PREAD(temp2_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 5, bitmask),
891 PREAD(temp3_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 6, bitmask),
892 PREAD(temp4_alarm, 3, PRI_LOW, 0x43, 0, 0x01, 0, bitmask),
893
894 PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
895 PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
896 PWRITE(temp3_source, 2, PRI_LOW, 0x03, 0, 0x07, 4, bitmask),
897 PWRITE(temp4_source, 3, PRI_LOW, 0x03, 0, 0x07, 0, bitmask),
898
899 PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
900 PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
901 PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x64, 0, 0x01, 3, bitmask),
902 PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
903
904 PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
905 PWRITE(temp2_smoothing_time, 1, PRI_LOW, 0x63, 0, 0x07, 4, temp_st),
906 PWRITE(temp3_smoothing_time, 2, PRI_LOW, 0x63, 0, 0x07, 0, temp_st),
907 PWRITE(temp4_smoothing_time, 3, PRI_LOW, 0x3c, 0, 0x07, 0, temp_st),
908
909 PWRITE(temp1_auto_point1_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
910 bitmask),
911 PWRITE(temp2_auto_point1_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
912 bitmask),
913 PWRITE(temp3_auto_point1_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
914 bitmask),
915 PWRITE(temp4_auto_point1_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
916 bitmask),
917
918 PREAD(temp1_auto_point2_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
919 bitmask),
920 PREAD(temp2_auto_point2_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
921 bitmask),
922 PREAD(temp3_auto_point2_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
923 bitmask),
924 PREAD(temp4_auto_point2_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
925 bitmask),
926
927 PWRITE(temp1_auto_point1_temp, 0, PRI_LOW, 0x67, 0, 0, 0, temp8),
928 PWRITE(temp2_auto_point1_temp, 1, PRI_LOW, 0x68, 0, 0, 0, temp8),
929 PWRITE(temp3_auto_point1_temp, 2, PRI_LOW, 0x69, 0, 0, 0, temp8),
930 PWRITE(temp4_auto_point1_temp, 3, PRI_LOW, 0x3b, 0, 0, 0, temp8),
931
932 PWRITEM(temp1_auto_point2_temp, 0, PRI_LOW, VAA(0x5f, 0x67), VAA(0),
933 VAA(0x0f), VAA(4), ap2_temp),
934 PWRITEM(temp2_auto_point2_temp, 1, PRI_LOW, VAA(0x60, 0x68), VAA(0),
935 VAA(0x0f), VAA(4), ap2_temp),
936 PWRITEM(temp3_auto_point2_temp, 2, PRI_LOW, VAA(0x61, 0x69), VAA(0),
937 VAA(0x0f), VAA(4), ap2_temp),
938 PWRITEM(temp4_auto_point2_temp, 3, PRI_LOW, VAA(0x3c, 0x3b), VAA(0),
939 VAA(0x0f), VAA(4), ap2_temp),
940
941 PWRITE(temp1_crit, 0, PRI_LOW, 0x6a, 0, 0, 0, temp8),
942 PWRITE(temp2_crit, 1, PRI_LOW, 0x6b, 0, 0, 0, temp8),
943 PWRITE(temp3_crit, 2, PRI_LOW, 0x6c, 0, 0, 0, temp8),
944 PWRITE(temp4_crit, 3, PRI_LOW, 0x3d, 0, 0, 0, temp8),
945
946 PWRITE(temp5_enable, 4, PRI_LOW, 0x0e, 0, 0x01, 0, bitmask),
947 PWRITE(temp6_enable, 5, PRI_LOW, 0x0e, 0, 0x01, 1, bitmask),
948 PWRITE(temp7_enable, 6, PRI_LOW, 0x0e, 0, 0x01, 2, bitmask),
949 PWRITE(temp8_enable, 7, PRI_LOW, 0x0e, 0, 0x01, 3, bitmask),
950
951 PWRITE(remote1_offset, 0, PRI_LOW, 0x1c, 0, 0, 0, temp62),
952 PWRITE(remote2_offset, 1, PRI_LOW, 0x1d, 0, 0, 0, temp62),
953
954 PWRITE(pwm1, 0, PRI_HIGH, 0x30, 0, 0, 0, u8),
955 PWRITE(pwm2, 1, PRI_HIGH, 0x31, 0, 0, 0, u8),
956 PWRITE(pwm3, 2, PRI_HIGH, 0x32, 0, 0, 0, u8),
957
958 PWRITE(pwm1_invert, 0, PRI_LOW, 0x5c, 0, 0x01, 4, bitmask),
959 PWRITE(pwm2_invert, 1, PRI_LOW, 0x5d, 0, 0x01, 4, bitmask),
960 PWRITE(pwm3_invert, 2, PRI_LOW, 0x5e, 0, 0x01, 4, bitmask),
961
962 PWRITEM(pwm1_enable, 0, PRI_LOW, VAA(0x5c, 0x5c, 0x62), VAA(0, 0, 0),
963 VAA(0x07, 0x01, 0x01), VAA(5, 3, 5), pwm_enable),
964 PWRITEM(pwm2_enable, 1, PRI_LOW, VAA(0x5d, 0x5d, 0x62), VAA(0, 0, 0),
965 VAA(0x07, 0x01, 0x01), VAA(5, 3, 6), pwm_enable),
966 PWRITEM(pwm3_enable, 2, PRI_LOW, VAA(0x5e, 0x5e, 0x62), VAA(0, 0, 0),
967 VAA(0x07, 0x01, 0x01), VAA(5, 3, 7), pwm_enable),
968
969 PWRITEM(pwm1_auto_channels, 0, PRI_LOW, VAA(0x5c, 0x5c), VAA(0, 0),
970 VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
971 PWRITEM(pwm2_auto_channels, 1, PRI_LOW, VAA(0x5d, 0x5d), VAA(0, 0),
972 VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
973 PWRITEM(pwm3_auto_channels, 2, PRI_LOW, VAA(0x5e, 0x5e), VAA(0, 0),
974 VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
975
976 PWRITE(pwm1_auto_point1_pwm, 0, PRI_LOW, 0x64, 0, 0, 0, u8),
977 PWRITE(pwm2_auto_point1_pwm, 1, PRI_LOW, 0x65, 0, 0, 0, u8),
978 PWRITE(pwm3_auto_point1_pwm, 2, PRI_LOW, 0x66, 0, 0, 0, u8),
979
980 PWRITE(pwm1_auto_point2_pwm, 0, PRI_LOW, 0x38, 0, 0, 0, u8),
981 PWRITE(pwm2_auto_point2_pwm, 1, PRI_LOW, 0x39, 0, 0, 0, u8),
982 PWRITE(pwm3_auto_point2_pwm, 2, PRI_LOW, 0x3a, 0, 0, 0, u8),
983
984 PWRITE(pwm1_freq, 0, PRI_LOW, 0x5f, 0, 0x0f, 0, pwm_freq),
985 PWRITE(pwm2_freq, 1, PRI_LOW, 0x60, 0, 0x0f, 0, pwm_freq),
986 PWRITE(pwm3_freq, 2, PRI_LOW, 0x61, 0, 0x0f, 0, pwm_freq),
987
988 PREAD(pwm1_auto_zone_assigned, 0, PRI_LOW, 0, 0, 0x03, 2, bitmask),
989 PREAD(pwm2_auto_zone_assigned, 1, PRI_LOW, 0, 0, 0x03, 4, bitmask),
990 PREAD(pwm3_auto_zone_assigned, 2, PRI_LOW, 0, 0, 0x03, 6, bitmask),
991
992 PWRITE(pwm1_auto_spinup_time, 0, PRI_LOW, 0x5c, 0, 0x07, 0, pwm_ast),
993 PWRITE(pwm2_auto_spinup_time, 1, PRI_LOW, 0x5d, 0, 0x07, 0, pwm_ast),
994 PWRITE(pwm3_auto_spinup_time, 2, PRI_LOW, 0x5e, 0, 0x07, 0, pwm_ast),
995
996 PWRITE(peci_enable, 0, PRI_LOW, 0x40, 0, 0x01, 4, bitmask),
997 PWRITE(peci_avg, 0, PRI_LOW, 0x36, 0, 0x07, 0, bitmask),
998 PWRITE(peci_domain, 0, PRI_LOW, 0x36, 0, 0x01, 3, bitmask),
999 PWRITE(peci_legacy, 0, PRI_LOW, 0x36, 0, 0x01, 4, bitmask),
1000 PWRITE(peci_diode, 0, PRI_LOW, 0x0e, 0, 0x07, 4, bitmask),
1001 PWRITE(peci_4domain, 0, PRI_LOW, 0x0e, 0, 0x01, 4, bitmask),
1002
1003};
1004
1005static struct asc7621_data *asc7621_update_device(struct device *dev)
1006{
1007 struct i2c_client *client = to_i2c_client(dev);
1008 struct asc7621_data *data = i2c_get_clientdata(client);
1009 int i;
1010
1011/*
1012 * The asc7621 chips guarantee consistent reads of multi-byte values
1013 * regardless of the order of the reads. No special logic is needed
1014 * so we can just read the registers in whatever order they appear
1015 * in the asc7621_params array.
1016 */
1017
1018 mutex_lock(&data->update_lock);
1019
1020 /* Read all the high priority registers */
1021
1022 if (!data->valid ||
1023 time_after(jiffies, data->last_high_reading + INTERVAL_HIGH)) {
1024
1025 for (i = 0; i < ARRAY_SIZE(asc7621_register_priorities); i++) {
1026 if (asc7621_register_priorities[i] == PRI_HIGH) {
1027 data->reg[i] =
1028 i2c_smbus_read_byte_data(client, i) & 0xff;
1029 }
1030 }
1031 data->last_high_reading = jiffies;
1032 }; /* last_reading */
1033
1034 /* Read all the low priority registers. */
1035
1036 if (!data->valid ||
1037 time_after(jiffies, data->last_low_reading + INTERVAL_LOW)) {
1038
1039 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1040 if (asc7621_register_priorities[i] == PRI_LOW) {
1041 data->reg[i] =
1042 i2c_smbus_read_byte_data(client, i) & 0xff;
1043 }
1044 }
1045 data->last_low_reading = jiffies;
1046 }; /* last_reading */
1047
1048 data->valid = 1;
1049
1050 mutex_unlock(&data->update_lock);
1051
1052 return data;
1053}
1054
1055/*
1056 * Standard detection and initialization below
1057 *
1058 * Helper function that checks if an address is valid
1059 * for a particular chip.
1060 */
1061
1062static inline int valid_address_for_chip(int chip_type, int address)
1063{
1064 int i;
1065
1066 for (i = 0; asc7621_chips[chip_type].addresses[i] != I2C_CLIENT_END;
1067 i++) {
1068 if (asc7621_chips[chip_type].addresses[i] == address)
1069 return 1;
1070 }
1071 return 0;
1072}
1073
1074static void asc7621_init_client(struct i2c_client *client)
1075{
1076 int value;
1077
1078 /* Warn if part was not "READY" */
1079
1080 value = read_byte(client, 0x40);
1081
1082 if (value & 0x02) {
1083 dev_err(&client->dev,
1084 "Client (%d,0x%02x) config is locked.\n",
1085 i2c_adapter_id(client->adapter), client->addr);
1086 };
1087 if (!(value & 0x04)) {
1088 dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
1089 i2c_adapter_id(client->adapter), client->addr);
1090 };
1091
1092/*
1093 * Start monitoring
1094 *
1095 * Try to clear LOCK, Set START, save everything else
1096 */
1097 value = (value & ~0x02) | 0x01;
1098 write_byte(client, 0x40, value & 0xff);
1099
1100}
1101
1102static int
1103asc7621_probe(struct i2c_client *client, const struct i2c_device_id *id)
1104{
1105 struct asc7621_data *data;
1106 int i, err;
1107
1108 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1109 return -EIO;
1110
1111 data = kzalloc(sizeof(struct asc7621_data), GFP_KERNEL);
1112 if (data == NULL)
1113 return -ENOMEM;
1114
1115 i2c_set_clientdata(client, data);
1116 data->valid = 0;
1117 mutex_init(&data->update_lock);
1118
1119 /* Initialize the asc7621 chip */
1120 asc7621_init_client(client);
1121
1122 /* Create the sysfs entries */
1123 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1124 err =
1125 device_create_file(&client->dev,
1126 &(asc7621_params[i].sda.dev_attr));
1127 if (err)
1128 goto exit_remove;
1129 }
1130
1131 data->class_dev = hwmon_device_register(&client->dev);
1132 if (IS_ERR(data->class_dev)) {
1133 err = PTR_ERR(data->class_dev);
1134 goto exit_remove;
1135 }
1136
1137 return 0;
1138
1139exit_remove:
1140 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1141 device_remove_file(&client->dev,
1142 &(asc7621_params[i].sda.dev_attr));
1143 }
1144
1145 i2c_set_clientdata(client, NULL);
1146 kfree(data);
1147 return err;
1148}
1149
1150static int asc7621_detect(struct i2c_client *client,
1151 struct i2c_board_info *info)
1152{
1153 struct i2c_adapter *adapter = client->adapter;
1154 int company, verstep, chip_index;
1155 struct device *dev;
1156
1157 dev = &client->dev;
1158
1159 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1160 return -ENODEV;
1161
1162 for (chip_index = FIRST_CHIP; chip_index <= LAST_CHIP; chip_index++) {
1163
1164 if (!valid_address_for_chip(chip_index, client->addr))
1165 continue;
1166
1167 company = read_byte(client,
1168 asc7621_chips[chip_index].company_reg);
1169 verstep = read_byte(client,
1170 asc7621_chips[chip_index].verstep_reg);
1171
1172 if (company == asc7621_chips[chip_index].company_id &&
1173 verstep == asc7621_chips[chip_index].verstep_id) {
1174 strlcpy(client->name, asc7621_chips[chip_index].name,
1175 I2C_NAME_SIZE);
1176 strlcpy(info->type, asc7621_chips[chip_index].name,
1177 I2C_NAME_SIZE);
1178
1179 dev_info(&adapter->dev, "Matched %s\n",
1180 asc7621_chips[chip_index].name);
1181 return 0;
1182 }
1183 }
1184
1185 return -ENODEV;
1186}
1187
1188static int asc7621_remove(struct i2c_client *client)
1189{
1190 struct asc7621_data *data = i2c_get_clientdata(client);
1191 int i;
1192
1193 hwmon_device_unregister(data->class_dev);
1194
1195 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1196 device_remove_file(&client->dev,
1197 &(asc7621_params[i].sda.dev_attr));
1198 }
1199
1200 i2c_set_clientdata(client, NULL);
1201 kfree(data);
1202 return 0;
1203}
1204
1205static const struct i2c_device_id asc7621_id[] = {
1206 {"asc7621", asc7621},
1207 {"asc7621a", asc7621a},
1208 {},
1209};
1210
1211MODULE_DEVICE_TABLE(i2c, asc7621_id);
1212
1213static struct i2c_driver asc7621_driver = {
1214 .class = I2C_CLASS_HWMON,
1215 .driver = {
1216 .name = "asc7621",
1217 },
1218 .probe = asc7621_probe,
1219 .remove = asc7621_remove,
1220 .id_table = asc7621_id,
1221 .detect = asc7621_detect,
1222 .address_list = normal_i2c,
1223};
1224
1225static int __init sm_asc7621_init(void)
1226{
1227 int i, j;
1228/*
1229 * Collect all the registers needed into a single array.
1230 * This way, if a register isn't actually used for anything,
1231 * we don't retrieve it.
1232 */
1233
1234 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1235 for (j = 0; j < ARRAY_SIZE(asc7621_params[i].msb); j++)
1236 asc7621_register_priorities[asc7621_params[i].msb[j]] =
1237 asc7621_params[i].priority;
1238 for (j = 0; j < ARRAY_SIZE(asc7621_params[i].lsb); j++)
1239 asc7621_register_priorities[asc7621_params[i].lsb[j]] =
1240 asc7621_params[i].priority;
1241 }
1242 return i2c_add_driver(&asc7621_driver);
1243}
1244
1245static void __exit sm_asc7621_exit(void)
1246{
1247 i2c_del_driver(&asc7621_driver);
1248}
1249
1250MODULE_LICENSE("GPL");
1251MODULE_AUTHOR("George Joseph");
1252MODULE_DESCRIPTION("Andigilog aSC7621 and aSC7621a driver");
1253
1254module_init(sm_asc7621_init);
1255module_exit(sm_asc7621_exit);
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index fa0728232e71..0627f7a5b9b8 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -267,7 +267,7 @@ struct fschmd_data {
267 struct list_head list; /* member of the watchdog_data_list */ 267 struct list_head list; /* member of the watchdog_data_list */
268 struct kref kref; 268 struct kref kref;
269 struct miscdevice watchdog_miscdev; 269 struct miscdevice watchdog_miscdev;
270 int kind; 270 enum chips kind;
271 unsigned long watchdog_is_open; 271 unsigned long watchdog_is_open;
272 char watchdog_expect_close; 272 char watchdog_expect_close;
273 char watchdog_name[10]; /* must be unique to avoid sysfs conflict */ 273 char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
@@ -325,8 +325,7 @@ static ssize_t show_in_value(struct device *dev,
325 int index = to_sensor_dev_attr(devattr)->index; 325 int index = to_sensor_dev_attr(devattr)->index;
326 struct fschmd_data *data = fschmd_update_device(dev); 326 struct fschmd_data *data = fschmd_update_device(dev);
327 327
328 /* fscher / fschrc - 1 as data->kind is an array index, not a chips */ 328 if (data->kind == fscher || data->kind >= fschrc)
329 if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1))
330 return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref * 329 return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref *
331 dmi_mult[index]) / 255 + dmi_offset[index]); 330 dmi_mult[index]) / 255 + dmi_offset[index]);
332 else 331 else
@@ -492,7 +491,7 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
492 int val = data->fan_min[index]; 491 int val = data->fan_min[index];
493 492
494 /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */ 493 /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
495 if (val || data->kind == fscsyl - 1) 494 if (val || data->kind == fscsyl)
496 val = val / 2 + 128; 495 val = val / 2 + 128;
497 496
498 return sprintf(buf, "%d\n", val); 497 return sprintf(buf, "%d\n", val);
@@ -506,7 +505,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
506 unsigned long v = simple_strtoul(buf, NULL, 10); 505 unsigned long v = simple_strtoul(buf, NULL, 10);
507 506
508 /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */ 507 /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
509 if (v || data->kind == fscsyl - 1) { 508 if (v || data->kind == fscsyl) {
510 v = SENSORS_LIMIT(v, 128, 255); 509 v = SENSORS_LIMIT(v, 128, 255);
511 v = (v - 128) * 2 + 1; 510 v = (v - 128) * 2 + 1;
512 } 511 }
@@ -1037,7 +1036,7 @@ static int fschmd_detect(struct i2c_client *client,
1037 else 1036 else
1038 return -ENODEV; 1037 return -ENODEV;
1039 1038
1040 strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE); 1039 strlcpy(info->type, fschmd_id[kind].name, I2C_NAME_SIZE);
1041 1040
1042 return 0; 1041 return 0;
1043} 1042}
@@ -1065,6 +1064,7 @@ static int fschmd_probe(struct i2c_client *client,
1065 (where the client is found through a data ptr instead of the 1064 (where the client is found through a data ptr instead of the
1066 otherway around) */ 1065 otherway around) */
1067 data->client = client; 1066 data->client = client;
1067 data->kind = kind;
1068 1068
1069 if (kind == fscpos) { 1069 if (kind == fscpos) {
1070 /* The Poseidon has hardwired temp limits, fill these 1070 /* The Poseidon has hardwired temp limits, fill these
@@ -1085,9 +1085,6 @@ static int fschmd_probe(struct i2c_client *client,
1085 } 1085 }
1086 } 1086 }
1087 1087
1088 /* i2c kind goes from 1-6, we want from 0-5 to address arrays */
1089 data->kind = kind - 1;
1090
1091 /* Read in some never changing registers */ 1088 /* Read in some never changing registers */
1092 data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); 1089 data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
1093 data->global_control = i2c_smbus_read_byte_data(client, 1090 data->global_control = i2c_smbus_read_byte_data(client,
diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c
index 19c01a49f6be..09ea12e0a551 100644
--- a/drivers/hwmon/g760a.c
+++ b/drivers/hwmon/g760a.c
@@ -68,7 +68,7 @@ struct g760a_data {
68#define PWM_FROM_CNT(cnt) (0xff-(cnt)) 68#define PWM_FROM_CNT(cnt) (0xff-(cnt))
69#define PWM_TO_CNT(pwm) (0xff-(pwm)) 69#define PWM_TO_CNT(pwm) (0xff-(pwm))
70 70
71unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div) 71static inline unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
72{ 72{
73 return ((val == 0x00) ? 0 : ((clk*30)/(val*div))); 73 return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
74} 74}
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 0ffe84d190bb..1002befd87d5 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1,40 +1,40 @@
1/* 1/*
2 it87.c - Part of lm_sensors, Linux kernel modules for hardware 2 * it87.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring. 3 * monitoring.
4 4 *
5 The IT8705F is an LPC-based Super I/O part that contains UARTs, a 5 * The IT8705F is an LPC-based Super I/O part that contains UARTs, a
6 parallel port, an IR port, a MIDI port, a floppy controller, etc., in 6 * parallel port, an IR port, a MIDI port, a floppy controller, etc., in
7 addition to an Environment Controller (Enhanced Hardware Monitor and 7 * addition to an Environment Controller (Enhanced Hardware Monitor and
8 Fan Controller) 8 * Fan Controller)
9 9 *
10 This driver supports only the Environment Controller in the IT8705F and 10 * This driver supports only the Environment Controller in the IT8705F and
11 similar parts. The other devices are supported by different drivers. 11 * similar parts. The other devices are supported by different drivers.
12 12 *
13 Supports: IT8705F Super I/O chip w/LPC interface 13 * Supports: IT8705F Super I/O chip w/LPC interface
14 IT8712F Super I/O chip w/LPC interface 14 * IT8712F Super I/O chip w/LPC interface
15 IT8716F Super I/O chip w/LPC interface 15 * IT8716F Super I/O chip w/LPC interface
16 IT8718F Super I/O chip w/LPC interface 16 * IT8718F Super I/O chip w/LPC interface
17 IT8720F Super I/O chip w/LPC interface 17 * IT8720F Super I/O chip w/LPC interface
18 IT8726F Super I/O chip w/LPC interface 18 * IT8726F Super I/O chip w/LPC interface
19 Sis950 A clone of the IT8705F 19 * Sis950 A clone of the IT8705F
20 20 *
21 Copyright (C) 2001 Chris Gauthron 21 * Copyright (C) 2001 Chris Gauthron
22 Copyright (C) 2005-2007 Jean Delvare <khali@linux-fr.org> 22 * Copyright (C) 2005-2010 Jean Delvare <khali@linux-fr.org>
23 23 *
24 This program is free software; you can redistribute it and/or modify 24 * This program is free software; you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by 25 * it under the terms of the GNU General Public License as published by
26 the Free Software Foundation; either version 2 of the License, or 26 * the Free Software Foundation; either version 2 of the License, or
27 (at your option) any later version. 27 * (at your option) any later version.
28 28 *
29 This program is distributed in the hope that it will be useful, 29 * This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of 30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details. 32 * GNU General Public License for more details.
33 33 *
34 You should have received a copy of the GNU General Public License 34 * You should have received a copy of the GNU General Public License
35 along with this program; if not, write to the Free Software 35 * along with this program; if not, write to the Free Software
36 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 36 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37*/ 37 */
38 38
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/init.h> 40#include <linux/init.h>
@@ -128,6 +128,7 @@ superio_exit(void)
128#define IT87_SIO_GPIO5_REG 0x29 128#define IT87_SIO_GPIO5_REG 0x29
129#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ 129#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */
130#define IT87_SIO_VID_REG 0xfc /* VID value */ 130#define IT87_SIO_VID_REG 0xfc /* VID value */
131#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */
131 132
132/* Update battery voltage after every reading if true */ 133/* Update battery voltage after every reading if true */
133static int update_vbat; 134static int update_vbat;
@@ -187,9 +188,13 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
187 188
188#define IT87_REG_VIN_ENABLE 0x50 189#define IT87_REG_VIN_ENABLE 0x50
189#define IT87_REG_TEMP_ENABLE 0x51 190#define IT87_REG_TEMP_ENABLE 0x51
191#define IT87_REG_BEEP_ENABLE 0x5c
190 192
191#define IT87_REG_CHIPID 0x58 193#define IT87_REG_CHIPID 0x58
192 194
195#define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i))
196#define IT87_REG_AUTO_PWM(nr, i) (0x65 + (nr) * 8 + (i))
197
193#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255)) 198#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255))
194#define IN_FROM_REG(val) ((val) * 16) 199#define IN_FROM_REG(val) ((val) * 16)
195 200
@@ -246,6 +251,7 @@ struct it87_sio_data {
246 /* Values read from Super-I/O config space */ 251 /* Values read from Super-I/O config space */
247 u8 revision; 252 u8 revision;
248 u8 vid_value; 253 u8 vid_value;
254 u8 beep_pin;
249 /* Features skipped based on config or DMI */ 255 /* Features skipped based on config or DMI */
250 u8 skip_vid; 256 u8 skip_vid;
251 u8 skip_fan; 257 u8 skip_fan;
@@ -279,9 +285,21 @@ struct it87_data {
279 u8 vid; /* Register encoding, combined */ 285 u8 vid; /* Register encoding, combined */
280 u8 vrm; 286 u8 vrm;
281 u32 alarms; /* Register encoding, combined */ 287 u32 alarms; /* Register encoding, combined */
288 u8 beeps; /* Register encoding */
282 u8 fan_main_ctrl; /* Register value */ 289 u8 fan_main_ctrl; /* Register value */
283 u8 fan_ctl; /* Register value */ 290 u8 fan_ctl; /* Register value */
284 u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ 291
292 /* The following 3 arrays correspond to the same registers. The
293 * meaning of bits 6-0 depends on the value of bit 7, and we want
294 * to preserve settings on mode changes, so we have to track all
295 * values separately. */
296 u8 pwm_ctrl[3]; /* Register value */
297 u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */
298 u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */
299
300 /* Automatic fan speed control registers */
301 u8 auto_pwm[3][4]; /* [nr][3] is hard-coded */
302 s8 auto_temp[3][5]; /* [nr][0] is point1_temp_hyst */
285}; 303};
286 304
287static inline int has_16bit_fans(const struct it87_data *data) 305static inline int has_16bit_fans(const struct it87_data *data)
@@ -296,6 +314,15 @@ static inline int has_16bit_fans(const struct it87_data *data)
296 || data->type == it8720; 314 || data->type == it8720;
297} 315}
298 316
317static inline int has_old_autopwm(const struct it87_data *data)
318{
319 /* The old automatic fan speed control interface is implemented
320 by IT8705F chips up to revision F and IT8712F chips up to
321 revision G. */
322 return (data->type == it87 && data->revision < 0x03)
323 || (data->type == it8712 && data->revision < 0x08);
324}
325
299static int it87_probe(struct platform_device *pdev); 326static int it87_probe(struct platform_device *pdev);
300static int __devexit it87_remove(struct platform_device *pdev); 327static int __devexit it87_remove(struct platform_device *pdev);
301 328
@@ -352,7 +379,10 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
352 int nr = sensor_attr->index; 379 int nr = sensor_attr->index;
353 380
354 struct it87_data *data = dev_get_drvdata(dev); 381 struct it87_data *data = dev_get_drvdata(dev);
355 unsigned long val = simple_strtoul(buf, NULL, 10); 382 unsigned long val;
383
384 if (strict_strtoul(buf, 10, &val) < 0)
385 return -EINVAL;
356 386
357 mutex_lock(&data->update_lock); 387 mutex_lock(&data->update_lock);
358 data->in_min[nr] = IN_TO_REG(val); 388 data->in_min[nr] = IN_TO_REG(val);
@@ -368,7 +398,10 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
368 int nr = sensor_attr->index; 398 int nr = sensor_attr->index;
369 399
370 struct it87_data *data = dev_get_drvdata(dev); 400 struct it87_data *data = dev_get_drvdata(dev);
371 unsigned long val = simple_strtoul(buf, NULL, 10); 401 unsigned long val;
402
403 if (strict_strtoul(buf, 10, &val) < 0)
404 return -EINVAL;
372 405
373 mutex_lock(&data->update_lock); 406 mutex_lock(&data->update_lock);
374 data->in_max[nr] = IN_TO_REG(val); 407 data->in_max[nr] = IN_TO_REG(val);
@@ -441,7 +474,10 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
441 int nr = sensor_attr->index; 474 int nr = sensor_attr->index;
442 475
443 struct it87_data *data = dev_get_drvdata(dev); 476 struct it87_data *data = dev_get_drvdata(dev);
444 int val = simple_strtol(buf, NULL, 10); 477 long val;
478
479 if (strict_strtol(buf, 10, &val) < 0)
480 return -EINVAL;
445 481
446 mutex_lock(&data->update_lock); 482 mutex_lock(&data->update_lock);
447 data->temp_high[nr] = TEMP_TO_REG(val); 483 data->temp_high[nr] = TEMP_TO_REG(val);
@@ -456,7 +492,10 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
456 int nr = sensor_attr->index; 492 int nr = sensor_attr->index;
457 493
458 struct it87_data *data = dev_get_drvdata(dev); 494 struct it87_data *data = dev_get_drvdata(dev);
459 int val = simple_strtol(buf, NULL, 10); 495 long val;
496
497 if (strict_strtol(buf, 10, &val) < 0)
498 return -EINVAL;
460 499
461 mutex_lock(&data->update_lock); 500 mutex_lock(&data->update_lock);
462 data->temp_low[nr] = TEMP_TO_REG(val); 501 data->temp_low[nr] = TEMP_TO_REG(val);
@@ -483,8 +522,9 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr,
483 int nr = sensor_attr->index; 522 int nr = sensor_attr->index;
484 523
485 struct it87_data *data = it87_update_device(dev); 524 struct it87_data *data = it87_update_device(dev);
486 u8 reg = data->sensor; /* In case the value is updated while we use it */ 525 u8 reg = data->sensor; /* In case the value is updated while
487 526 we use it */
527
488 if (reg & (1 << nr)) 528 if (reg & (1 << nr))
489 return sprintf(buf, "3\n"); /* thermal diode */ 529 return sprintf(buf, "3\n"); /* thermal diode */
490 if (reg & (8 << nr)) 530 if (reg & (8 << nr))
@@ -498,7 +538,10 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
498 int nr = sensor_attr->index; 538 int nr = sensor_attr->index;
499 539
500 struct it87_data *data = dev_get_drvdata(dev); 540 struct it87_data *data = dev_get_drvdata(dev);
501 int val = simple_strtol(buf, NULL, 10); 541 long val;
542
543 if (strict_strtol(buf, 10, &val) < 0)
544 return -EINVAL;
502 545
503 mutex_lock(&data->update_lock); 546 mutex_lock(&data->update_lock);
504 547
@@ -511,9 +554,9 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
511 } 554 }
512 /* 3 = thermal diode; 4 = thermistor; 0 = disabled */ 555 /* 3 = thermal diode; 4 = thermistor; 0 = disabled */
513 if (val == 3) 556 if (val == 3)
514 data->sensor |= 1 << nr; 557 data->sensor |= 1 << nr;
515 else if (val == 4) 558 else if (val == 4)
516 data->sensor |= 8 << nr; 559 data->sensor |= 8 << nr;
517 else if (val != 0) { 560 else if (val != 0) {
518 mutex_unlock(&data->update_lock); 561 mutex_unlock(&data->update_lock);
519 return -EINVAL; 562 return -EINVAL;
@@ -531,6 +574,19 @@ show_sensor_offset(2);
531show_sensor_offset(3); 574show_sensor_offset(3);
532 575
533/* 3 Fans */ 576/* 3 Fans */
577
578static int pwm_mode(const struct it87_data *data, int nr)
579{
580 int ctrl = data->fan_main_ctrl & (1 << nr);
581
582 if (ctrl == 0) /* Full speed */
583 return 0;
584 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
585 return 2;
586 else /* Manual mode */
587 return 1;
588}
589
534static ssize_t show_fan(struct device *dev, struct device_attribute *attr, 590static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
535 char *buf) 591 char *buf)
536{ 592{
@@ -538,7 +594,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
538 int nr = sensor_attr->index; 594 int nr = sensor_attr->index;
539 595
540 struct it87_data *data = it87_update_device(dev); 596 struct it87_data *data = it87_update_device(dev);
541 return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], 597 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
542 DIV_FROM_REG(data->fan_div[nr]))); 598 DIV_FROM_REG(data->fan_div[nr])));
543} 599}
544static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, 600static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
@@ -548,8 +604,8 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
548 int nr = sensor_attr->index; 604 int nr = sensor_attr->index;
549 605
550 struct it87_data *data = it87_update_device(dev); 606 struct it87_data *data = it87_update_device(dev);
551 return sprintf(buf,"%d\n", 607 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
552 FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]))); 608 DIV_FROM_REG(data->fan_div[nr])));
553} 609}
554static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr, 610static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
555 char *buf) 611 char *buf)
@@ -560,14 +616,14 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
560 struct it87_data *data = it87_update_device(dev); 616 struct it87_data *data = it87_update_device(dev);
561 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); 617 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
562} 618}
563static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, 619static ssize_t show_pwm_enable(struct device *dev,
564 char *buf) 620 struct device_attribute *attr, char *buf)
565{ 621{
566 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 622 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
567 int nr = sensor_attr->index; 623 int nr = sensor_attr->index;
568 624
569 struct it87_data *data = it87_update_device(dev); 625 struct it87_data *data = it87_update_device(dev);
570 return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0); 626 return sprintf(buf, "%d\n", pwm_mode(data, nr));
571} 627}
572static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, 628static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
573 char *buf) 629 char *buf)
@@ -576,7 +632,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
576 int nr = sensor_attr->index; 632 int nr = sensor_attr->index;
577 633
578 struct it87_data *data = it87_update_device(dev); 634 struct it87_data *data = it87_update_device(dev);
579 return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]); 635 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm_duty[nr]));
580} 636}
581static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, 637static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
582 char *buf) 638 char *buf)
@@ -593,15 +649,24 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
593 int nr = sensor_attr->index; 649 int nr = sensor_attr->index;
594 650
595 struct it87_data *data = dev_get_drvdata(dev); 651 struct it87_data *data = dev_get_drvdata(dev);
596 int val = simple_strtol(buf, NULL, 10); 652 long val;
597 u8 reg; 653 u8 reg;
598 654
655 if (strict_strtol(buf, 10, &val) < 0)
656 return -EINVAL;
657
599 mutex_lock(&data->update_lock); 658 mutex_lock(&data->update_lock);
600 reg = it87_read_value(data, IT87_REG_FAN_DIV); 659 reg = it87_read_value(data, IT87_REG_FAN_DIV);
601 switch (nr) { 660 switch (nr) {
602 case 0: data->fan_div[nr] = reg & 0x07; break; 661 case 0:
603 case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; 662 data->fan_div[nr] = reg & 0x07;
604 case 2: data->fan_div[nr] = (reg & 0x40) ? 3 : 1; break; 663 break;
664 case 1:
665 data->fan_div[nr] = (reg >> 3) & 0x07;
666 break;
667 case 2:
668 data->fan_div[nr] = (reg & 0x40) ? 3 : 1;
669 break;
605 } 670 }
606 671
607 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); 672 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -616,10 +681,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
616 int nr = sensor_attr->index; 681 int nr = sensor_attr->index;
617 682
618 struct it87_data *data = dev_get_drvdata(dev); 683 struct it87_data *data = dev_get_drvdata(dev);
619 unsigned long val = simple_strtoul(buf, NULL, 10); 684 unsigned long val;
620 int min; 685 int min;
621 u8 old; 686 u8 old;
622 687
688 if (strict_strtoul(buf, 10, &val) < 0)
689 return -EINVAL;
690
623 mutex_lock(&data->update_lock); 691 mutex_lock(&data->update_lock);
624 old = it87_read_value(data, IT87_REG_FAN_DIV); 692 old = it87_read_value(data, IT87_REG_FAN_DIV);
625 693
@@ -651,6 +719,32 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
651 mutex_unlock(&data->update_lock); 719 mutex_unlock(&data->update_lock);
652 return count; 720 return count;
653} 721}
722
723/* Returns 0 if OK, -EINVAL otherwise */
724static int check_trip_points(struct device *dev, int nr)
725{
726 const struct it87_data *data = dev_get_drvdata(dev);
727 int i, err = 0;
728
729 if (has_old_autopwm(data)) {
730 for (i = 0; i < 3; i++) {
731 if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
732 err = -EINVAL;
733 }
734 for (i = 0; i < 2; i++) {
735 if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
736 err = -EINVAL;
737 }
738 }
739
740 if (err) {
741 dev_err(dev, "Inconsistent trip points, not switching to "
742 "automatic mode\n");
743 dev_err(dev, "Adjust the trip points and try again\n");
744 }
745 return err;
746}
747
654static ssize_t set_pwm_enable(struct device *dev, 748static ssize_t set_pwm_enable(struct device *dev,
655 struct device_attribute *attr, const char *buf, size_t count) 749 struct device_attribute *attr, const char *buf, size_t count)
656{ 750{
@@ -658,7 +752,16 @@ static ssize_t set_pwm_enable(struct device *dev,
658 int nr = sensor_attr->index; 752 int nr = sensor_attr->index;
659 753
660 struct it87_data *data = dev_get_drvdata(dev); 754 struct it87_data *data = dev_get_drvdata(dev);
661 int val = simple_strtol(buf, NULL, 10); 755 long val;
756
757 if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 2)
758 return -EINVAL;
759
760 /* Check trip points before switching to automatic mode */
761 if (val == 2) {
762 if (check_trip_points(dev, nr) < 0)
763 return -EINVAL;
764 }
662 765
663 mutex_lock(&data->update_lock); 766 mutex_lock(&data->update_lock);
664 767
@@ -669,16 +772,18 @@ static ssize_t set_pwm_enable(struct device *dev,
669 it87_write_value(data, IT87_REG_FAN_CTL, tmp | (1 << nr)); 772 it87_write_value(data, IT87_REG_FAN_CTL, tmp | (1 << nr));
670 /* set on/off mode */ 773 /* set on/off mode */
671 data->fan_main_ctrl &= ~(1 << nr); 774 data->fan_main_ctrl &= ~(1 << nr);
672 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); 775 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
673 } else if (val == 1) { 776 data->fan_main_ctrl);
777 } else {
778 if (val == 1) /* Manual mode */
779 data->pwm_ctrl[nr] = data->pwm_duty[nr];
780 else /* Automatic mode */
781 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
782 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
674 /* set SmartGuardian mode */ 783 /* set SmartGuardian mode */
675 data->fan_main_ctrl |= (1 << nr); 784 data->fan_main_ctrl |= (1 << nr);
676 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); 785 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
677 /* set saved pwm value, clear FAN_CTLX PWM mode bit */ 786 data->fan_main_ctrl);
678 it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
679 } else {
680 mutex_unlock(&data->update_lock);
681 return -EINVAL;
682 } 787 }
683 788
684 mutex_unlock(&data->update_lock); 789 mutex_unlock(&data->update_lock);
@@ -691,15 +796,19 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
691 int nr = sensor_attr->index; 796 int nr = sensor_attr->index;
692 797
693 struct it87_data *data = dev_get_drvdata(dev); 798 struct it87_data *data = dev_get_drvdata(dev);
694 int val = simple_strtol(buf, NULL, 10); 799 long val;
695 800
696 if (val < 0 || val > 255) 801 if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255)
697 return -EINVAL; 802 return -EINVAL;
698 803
699 mutex_lock(&data->update_lock); 804 mutex_lock(&data->update_lock);
700 data->manual_pwm_ctl[nr] = val; 805 data->pwm_duty[nr] = PWM_TO_REG(val);
701 if (data->fan_main_ctrl & (1 << nr)) 806 /* If we are in manual mode, write the duty cycle immediately;
702 it87_write_value(data, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr])); 807 * otherwise, just store it for later use. */
808 if (!(data->pwm_ctrl[nr] & 0x80)) {
809 data->pwm_ctrl[nr] = data->pwm_duty[nr];
810 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
811 }
703 mutex_unlock(&data->update_lock); 812 mutex_unlock(&data->update_lock);
704 return count; 813 return count;
705} 814}
@@ -707,9 +816,12 @@ static ssize_t set_pwm_freq(struct device *dev,
707 struct device_attribute *attr, const char *buf, size_t count) 816 struct device_attribute *attr, const char *buf, size_t count)
708{ 817{
709 struct it87_data *data = dev_get_drvdata(dev); 818 struct it87_data *data = dev_get_drvdata(dev);
710 unsigned long val = simple_strtoul(buf, NULL, 10); 819 unsigned long val;
711 int i; 820 int i;
712 821
822 if (strict_strtoul(buf, 10, &val) < 0)
823 return -EINVAL;
824
713 /* Search for the nearest available frequency */ 825 /* Search for the nearest available frequency */
714 for (i = 0; i < 7; i++) { 826 for (i = 0; i < 7; i++) {
715 if (val > (pwm_freq[i] + pwm_freq[i+1]) / 2) 827 if (val > (pwm_freq[i] + pwm_freq[i+1]) / 2)
@@ -724,6 +836,132 @@ static ssize_t set_pwm_freq(struct device *dev,
724 836
725 return count; 837 return count;
726} 838}
839static ssize_t show_pwm_temp_map(struct device *dev,
840 struct device_attribute *attr, char *buf)
841{
842 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
843 int nr = sensor_attr->index;
844
845 struct it87_data *data = it87_update_device(dev);
846 int map;
847
848 if (data->pwm_temp_map[nr] < 3)
849 map = 1 << data->pwm_temp_map[nr];
850 else
851 map = 0; /* Should never happen */
852 return sprintf(buf, "%d\n", map);
853}
854static ssize_t set_pwm_temp_map(struct device *dev,
855 struct device_attribute *attr, const char *buf, size_t count)
856{
857 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
858 int nr = sensor_attr->index;
859
860 struct it87_data *data = dev_get_drvdata(dev);
861 long val;
862 u8 reg;
863
864 /* This check can go away if we ever support automatic fan speed
865 control on newer chips. */
866 if (!has_old_autopwm(data)) {
867 dev_notice(dev, "Mapping change disabled for safety reasons\n");
868 return -EINVAL;
869 }
870
871 if (strict_strtol(buf, 10, &val) < 0)
872 return -EINVAL;
873
874 switch (val) {
875 case (1 << 0):
876 reg = 0x00;
877 break;
878 case (1 << 1):
879 reg = 0x01;
880 break;
881 case (1 << 2):
882 reg = 0x02;
883 break;
884 default:
885 return -EINVAL;
886 }
887
888 mutex_lock(&data->update_lock);
889 data->pwm_temp_map[nr] = reg;
890 /* If we are in automatic mode, write the temp mapping immediately;
891 * otherwise, just store it for later use. */
892 if (data->pwm_ctrl[nr] & 0x80) {
893 data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
894 it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
895 }
896 mutex_unlock(&data->update_lock);
897 return count;
898}
899
900static ssize_t show_auto_pwm(struct device *dev,
901 struct device_attribute *attr, char *buf)
902{
903 struct it87_data *data = it87_update_device(dev);
904 struct sensor_device_attribute_2 *sensor_attr =
905 to_sensor_dev_attr_2(attr);
906 int nr = sensor_attr->nr;
907 int point = sensor_attr->index;
908
909 return sprintf(buf, "%d\n", PWM_FROM_REG(data->auto_pwm[nr][point]));
910}
911
912static ssize_t set_auto_pwm(struct device *dev,
913 struct device_attribute *attr, const char *buf, size_t count)
914{
915 struct it87_data *data = dev_get_drvdata(dev);
916 struct sensor_device_attribute_2 *sensor_attr =
917 to_sensor_dev_attr_2(attr);
918 int nr = sensor_attr->nr;
919 int point = sensor_attr->index;
920 long val;
921
922 if (strict_strtol(buf, 10, &val) < 0 || val < 0 || val > 255)
923 return -EINVAL;
924
925 mutex_lock(&data->update_lock);
926 data->auto_pwm[nr][point] = PWM_TO_REG(val);
927 it87_write_value(data, IT87_REG_AUTO_PWM(nr, point),
928 data->auto_pwm[nr][point]);
929 mutex_unlock(&data->update_lock);
930 return count;
931}
932
933static ssize_t show_auto_temp(struct device *dev,
934 struct device_attribute *attr, char *buf)
935{
936 struct it87_data *data = it87_update_device(dev);
937 struct sensor_device_attribute_2 *sensor_attr =
938 to_sensor_dev_attr_2(attr);
939 int nr = sensor_attr->nr;
940 int point = sensor_attr->index;
941
942 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->auto_temp[nr][point]));
943}
944
945static ssize_t set_auto_temp(struct device *dev,
946 struct device_attribute *attr, const char *buf, size_t count)
947{
948 struct it87_data *data = dev_get_drvdata(dev);
949 struct sensor_device_attribute_2 *sensor_attr =
950 to_sensor_dev_attr_2(attr);
951 int nr = sensor_attr->nr;
952 int point = sensor_attr->index;
953 long val;
954
955 if (strict_strtol(buf, 10, &val) < 0 || val < -128000 || val > 127000)
956 return -EINVAL;
957
958 mutex_lock(&data->update_lock);
959 data->auto_temp[nr][point] = TEMP_TO_REG(val);
960 it87_write_value(data, IT87_REG_AUTO_TEMP(nr, point),
961 data->auto_temp[nr][point]);
962 mutex_unlock(&data->update_lock);
963 return count;
964}
727 965
728#define show_fan_offset(offset) \ 966#define show_fan_offset(offset) \
729static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ 967static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
@@ -744,7 +982,36 @@ static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
744 show_pwm, set_pwm, offset - 1); \ 982 show_pwm, set_pwm, offset - 1); \
745static DEVICE_ATTR(pwm##offset##_freq, \ 983static DEVICE_ATTR(pwm##offset##_freq, \
746 (offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO), \ 984 (offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO), \
747 show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL)); 985 show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL)); \
986static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels_temp, \
987 S_IRUGO | S_IWUSR, show_pwm_temp_map, set_pwm_temp_map, \
988 offset - 1); \
989static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_pwm, \
990 S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \
991 offset - 1, 0); \
992static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_pwm, \
993 S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \
994 offset - 1, 1); \
995static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_pwm, \
996 S_IRUGO | S_IWUSR, show_auto_pwm, set_auto_pwm, \
997 offset - 1, 2); \
998static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_pwm, \
999 S_IRUGO, show_auto_pwm, NULL, offset - 1, 3); \
1000static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp, \
1001 S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
1002 offset - 1, 1); \
1003static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point1_temp_hyst, \
1004 S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
1005 offset - 1, 0); \
1006static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point2_temp, \
1007 S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
1008 offset - 1, 2); \
1009static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point3_temp, \
1010 S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
1011 offset - 1, 3); \
1012static SENSOR_DEVICE_ATTR_2(pwm##offset##_auto_point4_temp, \
1013 S_IRUGO | S_IWUSR, show_auto_temp, set_auto_temp, \
1014 offset - 1, 4);
748 1015
749show_pwm_offset(1); 1016show_pwm_offset(1);
750show_pwm_offset(2); 1017show_pwm_offset(2);
@@ -775,7 +1042,10 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr,
775 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); 1042 struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
776 int nr = sensor_attr->index; 1043 int nr = sensor_attr->index;
777 struct it87_data *data = dev_get_drvdata(dev); 1044 struct it87_data *data = dev_get_drvdata(dev);
778 int val = simple_strtol(buf, NULL, 10); 1045 long val;
1046
1047 if (strict_strtol(buf, 10, &val) < 0)
1048 return -EINVAL;
779 1049
780 mutex_lock(&data->update_lock); 1050 mutex_lock(&data->update_lock);
781 data->fan_min[nr] = FAN16_TO_REG(val); 1051 data->fan_min[nr] = FAN16_TO_REG(val);
@@ -805,7 +1075,8 @@ show_fan16_offset(4);
805show_fan16_offset(5); 1075show_fan16_offset(5);
806 1076
807/* Alarms */ 1077/* Alarms */
808static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) 1078static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
1079 char *buf)
809{ 1080{
810 struct it87_data *data = it87_update_device(dev); 1081 struct it87_data *data = it87_update_device(dev);
811 return sprintf(buf, "%u\n", data->alarms); 1082 return sprintf(buf, "%u\n", data->alarms);
@@ -836,27 +1107,78 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
836static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17); 1107static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
837static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18); 1108static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
838 1109
839static ssize_t 1110static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
840show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) 1111 char *buf)
1112{
1113 int bitnr = to_sensor_dev_attr(attr)->index;
1114 struct it87_data *data = it87_update_device(dev);
1115 return sprintf(buf, "%u\n", (data->beeps >> bitnr) & 1);
1116}
1117static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
1118 const char *buf, size_t count)
1119{
1120 int bitnr = to_sensor_dev_attr(attr)->index;
1121 struct it87_data *data = dev_get_drvdata(dev);
1122 long val;
1123
1124 if (strict_strtol(buf, 10, &val) < 0
1125 || (val != 0 && val != 1))
1126 return -EINVAL;
1127
1128 mutex_lock(&data->update_lock);
1129 data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
1130 if (val)
1131 data->beeps |= (1 << bitnr);
1132 else
1133 data->beeps &= ~(1 << bitnr);
1134 it87_write_value(data, IT87_REG_BEEP_ENABLE, data->beeps);
1135 mutex_unlock(&data->update_lock);
1136 return count;
1137}
1138
1139static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
1140 show_beep, set_beep, 1);
1141static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO, show_beep, NULL, 1);
1142static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO, show_beep, NULL, 1);
1143static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO, show_beep, NULL, 1);
1144static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO, show_beep, NULL, 1);
1145static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO, show_beep, NULL, 1);
1146static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO, show_beep, NULL, 1);
1147static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO, show_beep, NULL, 1);
1148/* fanX_beep writability is set later */
1149static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO, show_beep, set_beep, 0);
1150static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0);
1151static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
1152static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
1153static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
1154static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
1155 show_beep, set_beep, 2);
1156static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
1157static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);
1158
1159static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr,
1160 char *buf)
841{ 1161{
842 struct it87_data *data = dev_get_drvdata(dev); 1162 struct it87_data *data = dev_get_drvdata(dev);
843 return sprintf(buf, "%u\n", data->vrm); 1163 return sprintf(buf, "%u\n", data->vrm);
844} 1164}
845static ssize_t 1165static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
846store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 1166 const char *buf, size_t count)
847{ 1167{
848 struct it87_data *data = dev_get_drvdata(dev); 1168 struct it87_data *data = dev_get_drvdata(dev);
849 u32 val; 1169 unsigned long val;
1170
1171 if (strict_strtoul(buf, 10, &val) < 0)
1172 return -EINVAL;
850 1173
851 val = simple_strtoul(buf, NULL, 10);
852 data->vrm = val; 1174 data->vrm = val;
853 1175
854 return count; 1176 return count;
855} 1177}
856static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); 1178static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
857 1179
858static ssize_t 1180static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
859show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) 1181 char *buf)
860{ 1182{
861 struct it87_data *data = it87_update_device(dev); 1183 struct it87_data *data = it87_update_device(dev);
862 return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); 1184 return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
@@ -931,51 +1253,176 @@ static const struct attribute_group it87_group = {
931 .attrs = it87_attributes, 1253 .attrs = it87_attributes,
932}; 1254};
933 1255
934static struct attribute *it87_attributes_opt[] = { 1256static struct attribute *it87_attributes_beep[] = {
1257 &sensor_dev_attr_in0_beep.dev_attr.attr,
1258 &sensor_dev_attr_in1_beep.dev_attr.attr,
1259 &sensor_dev_attr_in2_beep.dev_attr.attr,
1260 &sensor_dev_attr_in3_beep.dev_attr.attr,
1261 &sensor_dev_attr_in4_beep.dev_attr.attr,
1262 &sensor_dev_attr_in5_beep.dev_attr.attr,
1263 &sensor_dev_attr_in6_beep.dev_attr.attr,
1264 &sensor_dev_attr_in7_beep.dev_attr.attr,
1265
1266 &sensor_dev_attr_temp1_beep.dev_attr.attr,
1267 &sensor_dev_attr_temp2_beep.dev_attr.attr,
1268 &sensor_dev_attr_temp3_beep.dev_attr.attr,
1269 NULL
1270};
1271
1272static const struct attribute_group it87_group_beep = {
1273 .attrs = it87_attributes_beep,
1274};
1275
1276static struct attribute *it87_attributes_fan16[5][3+1] = { {
935 &sensor_dev_attr_fan1_input16.dev_attr.attr, 1277 &sensor_dev_attr_fan1_input16.dev_attr.attr,
936 &sensor_dev_attr_fan1_min16.dev_attr.attr, 1278 &sensor_dev_attr_fan1_min16.dev_attr.attr,
1279 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1280 NULL
1281}, {
937 &sensor_dev_attr_fan2_input16.dev_attr.attr, 1282 &sensor_dev_attr_fan2_input16.dev_attr.attr,
938 &sensor_dev_attr_fan2_min16.dev_attr.attr, 1283 &sensor_dev_attr_fan2_min16.dev_attr.attr,
1284 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1285 NULL
1286}, {
939 &sensor_dev_attr_fan3_input16.dev_attr.attr, 1287 &sensor_dev_attr_fan3_input16.dev_attr.attr,
940 &sensor_dev_attr_fan3_min16.dev_attr.attr, 1288 &sensor_dev_attr_fan3_min16.dev_attr.attr,
1289 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
1290 NULL
1291}, {
941 &sensor_dev_attr_fan4_input16.dev_attr.attr, 1292 &sensor_dev_attr_fan4_input16.dev_attr.attr,
942 &sensor_dev_attr_fan4_min16.dev_attr.attr, 1293 &sensor_dev_attr_fan4_min16.dev_attr.attr,
1294 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
1295 NULL
1296}, {
943 &sensor_dev_attr_fan5_input16.dev_attr.attr, 1297 &sensor_dev_attr_fan5_input16.dev_attr.attr,
944 &sensor_dev_attr_fan5_min16.dev_attr.attr, 1298 &sensor_dev_attr_fan5_min16.dev_attr.attr,
1299 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
1300 NULL
1301} };
1302
1303static const struct attribute_group it87_group_fan16[5] = {
1304 { .attrs = it87_attributes_fan16[0] },
1305 { .attrs = it87_attributes_fan16[1] },
1306 { .attrs = it87_attributes_fan16[2] },
1307 { .attrs = it87_attributes_fan16[3] },
1308 { .attrs = it87_attributes_fan16[4] },
1309};
945 1310
1311static struct attribute *it87_attributes_fan[3][4+1] = { {
946 &sensor_dev_attr_fan1_input.dev_attr.attr, 1312 &sensor_dev_attr_fan1_input.dev_attr.attr,
947 &sensor_dev_attr_fan1_min.dev_attr.attr, 1313 &sensor_dev_attr_fan1_min.dev_attr.attr,
948 &sensor_dev_attr_fan1_div.dev_attr.attr, 1314 &sensor_dev_attr_fan1_div.dev_attr.attr,
1315 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
1316 NULL
1317}, {
949 &sensor_dev_attr_fan2_input.dev_attr.attr, 1318 &sensor_dev_attr_fan2_input.dev_attr.attr,
950 &sensor_dev_attr_fan2_min.dev_attr.attr, 1319 &sensor_dev_attr_fan2_min.dev_attr.attr,
951 &sensor_dev_attr_fan2_div.dev_attr.attr, 1320 &sensor_dev_attr_fan2_div.dev_attr.attr,
1321 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
1322 NULL
1323}, {
952 &sensor_dev_attr_fan3_input.dev_attr.attr, 1324 &sensor_dev_attr_fan3_input.dev_attr.attr,
953 &sensor_dev_attr_fan3_min.dev_attr.attr, 1325 &sensor_dev_attr_fan3_min.dev_attr.attr,
954 &sensor_dev_attr_fan3_div.dev_attr.attr, 1326 &sensor_dev_attr_fan3_div.dev_attr.attr,
955
956 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
957 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
958 &sensor_dev_attr_fan3_alarm.dev_attr.attr, 1327 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
959 &sensor_dev_attr_fan4_alarm.dev_attr.attr, 1328 NULL
960 &sensor_dev_attr_fan5_alarm.dev_attr.attr, 1329} };
1330
1331static const struct attribute_group it87_group_fan[3] = {
1332 { .attrs = it87_attributes_fan[0] },
1333 { .attrs = it87_attributes_fan[1] },
1334 { .attrs = it87_attributes_fan[2] },
1335};
1336
1337static const struct attribute_group *
1338it87_get_fan_group(const struct it87_data *data)
1339{
1340 return has_16bit_fans(data) ? it87_group_fan16 : it87_group_fan;
1341}
961 1342
1343static struct attribute *it87_attributes_pwm[3][4+1] = { {
962 &sensor_dev_attr_pwm1_enable.dev_attr.attr, 1344 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
963 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
964 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
965 &sensor_dev_attr_pwm1.dev_attr.attr, 1345 &sensor_dev_attr_pwm1.dev_attr.attr,
966 &sensor_dev_attr_pwm2.dev_attr.attr,
967 &sensor_dev_attr_pwm3.dev_attr.attr,
968 &dev_attr_pwm1_freq.attr, 1346 &dev_attr_pwm1_freq.attr,
1347 &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
1348 NULL
1349}, {
1350 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
1351 &sensor_dev_attr_pwm2.dev_attr.attr,
969 &dev_attr_pwm2_freq.attr, 1352 &dev_attr_pwm2_freq.attr,
1353 &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
1354 NULL
1355}, {
1356 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
1357 &sensor_dev_attr_pwm3.dev_attr.attr,
970 &dev_attr_pwm3_freq.attr, 1358 &dev_attr_pwm3_freq.attr,
1359 &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
1360 NULL
1361} };
1362
1363static const struct attribute_group it87_group_pwm[3] = {
1364 { .attrs = it87_attributes_pwm[0] },
1365 { .attrs = it87_attributes_pwm[1] },
1366 { .attrs = it87_attributes_pwm[2] },
1367};
971 1368
1369static struct attribute *it87_attributes_autopwm[3][9+1] = { {
1370 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
1371 &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
1372 &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
1373 &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
1374 &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
1375 &sensor_dev_attr_pwm1_auto_point1_temp_hyst.dev_attr.attr,
1376 &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
1377 &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
1378 &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
1379 NULL
1380}, {
1381 &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
1382 &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
1383 &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
1384 &sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr,
1385 &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
1386 &sensor_dev_attr_pwm2_auto_point1_temp_hyst.dev_attr.attr,
1387 &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
1388 &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
1389 &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
1390 NULL
1391}, {
1392 &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
1393 &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
1394 &sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr,
1395 &sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr,
1396 &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
1397 &sensor_dev_attr_pwm3_auto_point1_temp_hyst.dev_attr.attr,
1398 &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
1399 &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
1400 &sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr,
1401 NULL
1402} };
1403
1404static const struct attribute_group it87_group_autopwm[3] = {
1405 { .attrs = it87_attributes_autopwm[0] },
1406 { .attrs = it87_attributes_autopwm[1] },
1407 { .attrs = it87_attributes_autopwm[2] },
1408};
1409
1410static struct attribute *it87_attributes_fan_beep[] = {
1411 &sensor_dev_attr_fan1_beep.dev_attr.attr,
1412 &sensor_dev_attr_fan2_beep.dev_attr.attr,
1413 &sensor_dev_attr_fan3_beep.dev_attr.attr,
1414 &sensor_dev_attr_fan4_beep.dev_attr.attr,
1415 &sensor_dev_attr_fan5_beep.dev_attr.attr,
1416};
1417
1418static struct attribute *it87_attributes_vid[] = {
972 &dev_attr_vrm.attr, 1419 &dev_attr_vrm.attr,
973 &dev_attr_cpu0_vid.attr, 1420 &dev_attr_cpu0_vid.attr,
974 NULL 1421 NULL
975}; 1422};
976 1423
977static const struct attribute_group it87_group_opt = { 1424static const struct attribute_group it87_group_vid = {
978 .attrs = it87_attributes_opt, 1425 .attrs = it87_attributes_vid,
979}; 1426};
980 1427
981/* SuperIO detection - will change isa_address if a chip is found */ 1428/* SuperIO detection - will change isa_address if a chip is found */
@@ -1035,6 +1482,10 @@ static int __init it87_find(unsigned short *address,
1035 if (sio_data->type == it87) { 1482 if (sio_data->type == it87) {
1036 /* The IT8705F doesn't have VID pins at all */ 1483 /* The IT8705F doesn't have VID pins at all */
1037 sio_data->skip_vid = 1; 1484 sio_data->skip_vid = 1;
1485
1486 /* The IT8705F has a different LD number for GPIO */
1487 superio_select(5);
1488 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
1038 } else { 1489 } else {
1039 int reg; 1490 int reg;
1040 1491
@@ -1068,7 +1519,11 @@ static int __init it87_find(unsigned short *address,
1068 pr_info("it87: in3 is VCC (+5V)\n"); 1519 pr_info("it87: in3 is VCC (+5V)\n");
1069 if (reg & (1 << 1)) 1520 if (reg & (1 << 1))
1070 pr_info("it87: in7 is VCCH (+5V Stand-By)\n"); 1521 pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
1522
1523 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
1071 } 1524 }
1525 if (sio_data->beep_pin)
1526 pr_info("it87: Beeping is supported\n");
1072 1527
1073 /* Disable specific features based on DMI strings */ 1528 /* Disable specific features based on DMI strings */
1074 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); 1529 board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1093,14 +1548,46 @@ exit:
1093 return err; 1548 return err;
1094} 1549}
1095 1550
1551static void it87_remove_files(struct device *dev)
1552{
1553 struct it87_data *data = platform_get_drvdata(pdev);
1554 struct it87_sio_data *sio_data = dev->platform_data;
1555 const struct attribute_group *fan_group = it87_get_fan_group(data);
1556 int i;
1557
1558 sysfs_remove_group(&dev->kobj, &it87_group);
1559 if (sio_data->beep_pin)
1560 sysfs_remove_group(&dev->kobj, &it87_group_beep);
1561 for (i = 0; i < 5; i++) {
1562 if (!(data->has_fan & (1 << i)))
1563 continue;
1564 sysfs_remove_group(&dev->kobj, &fan_group[i]);
1565 if (sio_data->beep_pin)
1566 sysfs_remove_file(&dev->kobj,
1567 it87_attributes_fan_beep[i]);
1568 }
1569 for (i = 0; i < 3; i++) {
1570 if (sio_data->skip_pwm & (1 << 0))
1571 continue;
1572 sysfs_remove_group(&dev->kobj, &it87_group_pwm[i]);
1573 if (has_old_autopwm(data))
1574 sysfs_remove_group(&dev->kobj,
1575 &it87_group_autopwm[i]);
1576 }
1577 if (!sio_data->skip_vid)
1578 sysfs_remove_group(&dev->kobj, &it87_group_vid);
1579}
1580
1096static int __devinit it87_probe(struct platform_device *pdev) 1581static int __devinit it87_probe(struct platform_device *pdev)
1097{ 1582{
1098 struct it87_data *data; 1583 struct it87_data *data;
1099 struct resource *res; 1584 struct resource *res;
1100 struct device *dev = &pdev->dev; 1585 struct device *dev = &pdev->dev;
1101 struct it87_sio_data *sio_data = dev->platform_data; 1586 struct it87_sio_data *sio_data = dev->platform_data;
1102 int err = 0; 1587 const struct attribute_group *fan_group;
1588 int err = 0, i;
1103 int enable_pwm_interface; 1589 int enable_pwm_interface;
1590 int fan_beep_need_rw;
1104 static const char *names[] = { 1591 static const char *names[] = {
1105 "it87", 1592 "it87",
1106 "it8712", 1593 "it8712",
@@ -1118,7 +1605,8 @@ static int __devinit it87_probe(struct platform_device *pdev)
1118 goto ERROR0; 1605 goto ERROR0;
1119 } 1606 }
1120 1607
1121 if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) { 1608 data = kzalloc(sizeof(struct it87_data), GFP_KERNEL);
1609 if (!data) {
1122 err = -ENOMEM; 1610 err = -ENOMEM;
1123 goto ERROR1; 1611 goto ERROR1;
1124 } 1612 }
@@ -1146,120 +1634,60 @@ static int __devinit it87_probe(struct platform_device *pdev)
1146 it87_init_device(pdev); 1634 it87_init_device(pdev);
1147 1635
1148 /* Register sysfs hooks */ 1636 /* Register sysfs hooks */
1149 if ((err = sysfs_create_group(&dev->kobj, &it87_group))) 1637 err = sysfs_create_group(&dev->kobj, &it87_group);
1638 if (err)
1150 goto ERROR2; 1639 goto ERROR2;
1151 1640
1641 if (sio_data->beep_pin) {
1642 err = sysfs_create_group(&dev->kobj, &it87_group_beep);
1643 if (err)
1644 goto ERROR4;
1645 }
1646
1152 /* Do not create fan files for disabled fans */ 1647 /* Do not create fan files for disabled fans */
1153 if (has_16bit_fans(data)) { 1648 fan_group = it87_get_fan_group(data);
1154 /* 16-bit tachometers */ 1649 fan_beep_need_rw = 1;
1155 if (data->has_fan & (1 << 0)) { 1650 for (i = 0; i < 5; i++) {
1156 if ((err = device_create_file(dev, 1651 if (!(data->has_fan & (1 << i)))
1157 &sensor_dev_attr_fan1_input16.dev_attr)) 1652 continue;
1158 || (err = device_create_file(dev, 1653 err = sysfs_create_group(&dev->kobj, &fan_group[i]);
1159 &sensor_dev_attr_fan1_min16.dev_attr)) 1654 if (err)
1160 || (err = device_create_file(dev, 1655 goto ERROR4;
1161 &sensor_dev_attr_fan1_alarm.dev_attr))) 1656
1162 goto ERROR4; 1657 if (sio_data->beep_pin) {
1163 } 1658 err = sysfs_create_file(&dev->kobj,
1164 if (data->has_fan & (1 << 1)) { 1659 it87_attributes_fan_beep[i]);
1165 if ((err = device_create_file(dev, 1660 if (err)
1166 &sensor_dev_attr_fan2_input16.dev_attr))
1167 || (err = device_create_file(dev,
1168 &sensor_dev_attr_fan2_min16.dev_attr))
1169 || (err = device_create_file(dev,
1170 &sensor_dev_attr_fan2_alarm.dev_attr)))
1171 goto ERROR4;
1172 }
1173 if (data->has_fan & (1 << 2)) {
1174 if ((err = device_create_file(dev,
1175 &sensor_dev_attr_fan3_input16.dev_attr))
1176 || (err = device_create_file(dev,
1177 &sensor_dev_attr_fan3_min16.dev_attr))
1178 || (err = device_create_file(dev,
1179 &sensor_dev_attr_fan3_alarm.dev_attr)))
1180 goto ERROR4;
1181 }
1182 if (data->has_fan & (1 << 3)) {
1183 if ((err = device_create_file(dev,
1184 &sensor_dev_attr_fan4_input16.dev_attr))
1185 || (err = device_create_file(dev,
1186 &sensor_dev_attr_fan4_min16.dev_attr))
1187 || (err = device_create_file(dev,
1188 &sensor_dev_attr_fan4_alarm.dev_attr)))
1189 goto ERROR4;
1190 }
1191 if (data->has_fan & (1 << 4)) {
1192 if ((err = device_create_file(dev,
1193 &sensor_dev_attr_fan5_input16.dev_attr))
1194 || (err = device_create_file(dev,
1195 &sensor_dev_attr_fan5_min16.dev_attr))
1196 || (err = device_create_file(dev,
1197 &sensor_dev_attr_fan5_alarm.dev_attr)))
1198 goto ERROR4;
1199 }
1200 } else {
1201 /* 8-bit tachometers with clock divider */
1202 if (data->has_fan & (1 << 0)) {
1203 if ((err = device_create_file(dev,
1204 &sensor_dev_attr_fan1_input.dev_attr))
1205 || (err = device_create_file(dev,
1206 &sensor_dev_attr_fan1_min.dev_attr))
1207 || (err = device_create_file(dev,
1208 &sensor_dev_attr_fan1_div.dev_attr))
1209 || (err = device_create_file(dev,
1210 &sensor_dev_attr_fan1_alarm.dev_attr)))
1211 goto ERROR4;
1212 }
1213 if (data->has_fan & (1 << 1)) {
1214 if ((err = device_create_file(dev,
1215 &sensor_dev_attr_fan2_input.dev_attr))
1216 || (err = device_create_file(dev,
1217 &sensor_dev_attr_fan2_min.dev_attr))
1218 || (err = device_create_file(dev,
1219 &sensor_dev_attr_fan2_div.dev_attr))
1220 || (err = device_create_file(dev,
1221 &sensor_dev_attr_fan2_alarm.dev_attr)))
1222 goto ERROR4;
1223 }
1224 if (data->has_fan & (1 << 2)) {
1225 if ((err = device_create_file(dev,
1226 &sensor_dev_attr_fan3_input.dev_attr))
1227 || (err = device_create_file(dev,
1228 &sensor_dev_attr_fan3_min.dev_attr))
1229 || (err = device_create_file(dev,
1230 &sensor_dev_attr_fan3_div.dev_attr))
1231 || (err = device_create_file(dev,
1232 &sensor_dev_attr_fan3_alarm.dev_attr)))
1233 goto ERROR4; 1661 goto ERROR4;
1662 if (!fan_beep_need_rw)
1663 continue;
1664
1665 /* As we have a single beep enable bit for all fans,
1666 * only the first enabled fan has a writable attribute
1667 * for it. */
1668 if (sysfs_chmod_file(&dev->kobj,
1669 it87_attributes_fan_beep[i],
1670 S_IRUGO | S_IWUSR))
1671 dev_dbg(dev, "chmod +w fan%d_beep failed\n",
1672 i + 1);
1673 fan_beep_need_rw = 0;
1234 } 1674 }
1235 } 1675 }
1236 1676
1237 if (enable_pwm_interface) { 1677 if (enable_pwm_interface) {
1238 if (!(sio_data->skip_pwm & (1 << 0))) { 1678 for (i = 0; i < 3; i++) {
1239 if ((err = device_create_file(dev, 1679 if (sio_data->skip_pwm & (1 << i))
1240 &sensor_dev_attr_pwm1_enable.dev_attr)) 1680 continue;
1241 || (err = device_create_file(dev, 1681 err = sysfs_create_group(&dev->kobj,
1242 &sensor_dev_attr_pwm1.dev_attr)) 1682 &it87_group_pwm[i]);
1243 || (err = device_create_file(dev, 1683 if (err)
1244 &dev_attr_pwm1_freq)))
1245 goto ERROR4;
1246 }
1247 if (!(sio_data->skip_pwm & (1 << 1))) {
1248 if ((err = device_create_file(dev,
1249 &sensor_dev_attr_pwm2_enable.dev_attr))
1250 || (err = device_create_file(dev,
1251 &sensor_dev_attr_pwm2.dev_attr))
1252 || (err = device_create_file(dev,
1253 &dev_attr_pwm2_freq)))
1254 goto ERROR4; 1684 goto ERROR4;
1255 } 1685
1256 if (!(sio_data->skip_pwm & (1 << 2))) { 1686 if (!has_old_autopwm(data))
1257 if ((err = device_create_file(dev, 1687 continue;
1258 &sensor_dev_attr_pwm3_enable.dev_attr)) 1688 err = sysfs_create_group(&dev->kobj,
1259 || (err = device_create_file(dev, 1689 &it87_group_autopwm[i]);
1260 &sensor_dev_attr_pwm3.dev_attr)) 1690 if (err)
1261 || (err = device_create_file(dev,
1262 &dev_attr_pwm3_freq)))
1263 goto ERROR4; 1691 goto ERROR4;
1264 } 1692 }
1265 } 1693 }
@@ -1268,10 +1696,8 @@ static int __devinit it87_probe(struct platform_device *pdev)
1268 data->vrm = vid_which_vrm(); 1696 data->vrm = vid_which_vrm();
1269 /* VID reading from Super-I/O config space if available */ 1697 /* VID reading from Super-I/O config space if available */
1270 data->vid = sio_data->vid_value; 1698 data->vid = sio_data->vid_value;
1271 if ((err = device_create_file(dev, 1699 err = sysfs_create_group(&dev->kobj, &it87_group_vid);
1272 &dev_attr_vrm)) 1700 if (err)
1273 || (err = device_create_file(dev,
1274 &dev_attr_cpu0_vid)))
1275 goto ERROR4; 1701 goto ERROR4;
1276 } 1702 }
1277 1703
@@ -1284,8 +1710,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
1284 return 0; 1710 return 0;
1285 1711
1286ERROR4: 1712ERROR4:
1287 sysfs_remove_group(&dev->kobj, &it87_group); 1713 it87_remove_files(dev);
1288 sysfs_remove_group(&dev->kobj, &it87_group_opt);
1289ERROR2: 1714ERROR2:
1290 platform_set_drvdata(pdev, NULL); 1715 platform_set_drvdata(pdev, NULL);
1291 kfree(data); 1716 kfree(data);
@@ -1300,8 +1725,7 @@ static int __devexit it87_remove(struct platform_device *pdev)
1300 struct it87_data *data = platform_get_drvdata(pdev); 1725 struct it87_data *data = platform_get_drvdata(pdev);
1301 1726
1302 hwmon_device_unregister(data->hwmon_dev); 1727 hwmon_device_unregister(data->hwmon_dev);
1303 sysfs_remove_group(&pdev->dev.kobj, &it87_group); 1728 it87_remove_files(&pdev->dev);
1304 sysfs_remove_group(&pdev->dev.kobj, &it87_group_opt);
1305 1729
1306 release_region(data->addr, IT87_EC_EXTENT); 1730 release_region(data->addr, IT87_EC_EXTENT);
1307 platform_set_drvdata(pdev, NULL); 1731 platform_set_drvdata(pdev, NULL);
@@ -1387,15 +1811,18 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1387 int tmp, i; 1811 int tmp, i;
1388 u8 mask; 1812 u8 mask;
1389 1813
1390 /* initialize to sane defaults: 1814 /* For each PWM channel:
1391 * - if the chip is in manual pwm mode, this will be overwritten with 1815 * - If it is in automatic mode, setting to manual mode should set
1392 * the actual settings on the chip (so in this case, initialization 1816 * the fan to full speed by default.
1393 * is not needed) 1817 * - If it is in manual mode, we need a mapping to temperature
1394 * - if in automatic or on/off mode, we could switch to manual mode, 1818 * channels to use when later setting to automatic mode later.
1395 * read the registers and set manual_pwm_ctl accordingly, but currently 1819 * Use a 1:1 mapping by default (we are clueless.)
1396 * this is not implemented, so we initialize to something sane */ 1820 * In both cases, the value can (and should) be changed by the user
1821 * prior to switching to a different mode. */
1397 for (i = 0; i < 3; i++) { 1822 for (i = 0; i < 3; i++) {
1398 data->manual_pwm_ctl[i] = 0xff; 1823 data->pwm_temp_map[i] = i;
1824 data->pwm_duty[i] = 0x7f; /* Full speed */
1825 data->auto_pwm[i][3] = 0x7f; /* Full speed, hard-coded */
1399 } 1826 }
1400 1827
1401 /* Some chips seem to have default value 0xff for all limit 1828 /* Some chips seem to have default value 0xff for all limit
@@ -1436,7 +1863,8 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1436 if ((data->fan_main_ctrl & mask) == 0) { 1863 if ((data->fan_main_ctrl & mask) == 0) {
1437 /* Enable all fan tachometers */ 1864 /* Enable all fan tachometers */
1438 data->fan_main_ctrl |= mask; 1865 data->fan_main_ctrl |= mask;
1439 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); 1866 it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
1867 data->fan_main_ctrl);
1440 } 1868 }
1441 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; 1869 data->has_fan = (data->fan_main_ctrl >> 4) & 0x07;
1442 1870
@@ -1461,30 +1889,32 @@ static void __devinit it87_init_device(struct platform_device *pdev)
1461 /* Fan input pins may be used for alternative functions */ 1889 /* Fan input pins may be used for alternative functions */
1462 data->has_fan &= ~sio_data->skip_fan; 1890 data->has_fan &= ~sio_data->skip_fan;
1463 1891
1464 /* Set current fan mode registers and the default settings for the
1465 * other mode registers */
1466 for (i = 0; i < 3; i++) {
1467 if (data->fan_main_ctrl & (1 << i)) {
1468 /* pwm mode */
1469 tmp = it87_read_value(data, IT87_REG_PWM(i));
1470 if (tmp & 0x80) {
1471 /* automatic pwm - not yet implemented, but
1472 * leave the settings made by the BIOS alone
1473 * until a change is requested via the sysfs
1474 * interface */
1475 } else {
1476 /* manual pwm */
1477 data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
1478 }
1479 }
1480 }
1481
1482 /* Start monitoring */ 1892 /* Start monitoring */
1483 it87_write_value(data, IT87_REG_CONFIG, 1893 it87_write_value(data, IT87_REG_CONFIG,
1484 (it87_read_value(data, IT87_REG_CONFIG) & 0x36) 1894 (it87_read_value(data, IT87_REG_CONFIG) & 0x36)
1485 | (update_vbat ? 0x41 : 0x01)); 1895 | (update_vbat ? 0x41 : 0x01));
1486} 1896}
1487 1897
1898static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
1899{
1900 data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
1901 if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */
1902 data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
1903 else /* Manual mode */
1904 data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
1905
1906 if (has_old_autopwm(data)) {
1907 int i;
1908
1909 for (i = 0; i < 5 ; i++)
1910 data->auto_temp[nr][i] = it87_read_value(data,
1911 IT87_REG_AUTO_TEMP(nr, i));
1912 for (i = 0; i < 3 ; i++)
1913 data->auto_pwm[nr][i] = it87_read_value(data,
1914 IT87_REG_AUTO_PWM(nr, i));
1915 }
1916}
1917
1488static struct it87_data *it87_update_device(struct device *dev) 1918static struct it87_data *it87_update_device(struct device *dev)
1489{ 1919{
1490 struct it87_data *data = dev_get_drvdata(dev); 1920 struct it87_data *data = dev_get_drvdata(dev);
@@ -1494,24 +1924,22 @@ static struct it87_data *it87_update_device(struct device *dev)
1494 1924
1495 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 1925 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
1496 || !data->valid) { 1926 || !data->valid) {
1497
1498 if (update_vbat) { 1927 if (update_vbat) {
1499 /* Cleared after each update, so reenable. Value 1928 /* Cleared after each update, so reenable. Value
1500 returned by this read will be previous value */ 1929 returned by this read will be previous value */
1501 it87_write_value(data, IT87_REG_CONFIG, 1930 it87_write_value(data, IT87_REG_CONFIG,
1502 it87_read_value(data, IT87_REG_CONFIG) | 0x40); 1931 it87_read_value(data, IT87_REG_CONFIG) | 0x40);
1503 } 1932 }
1504 for (i = 0; i <= 7; i++) { 1933 for (i = 0; i <= 7; i++) {
1505 data->in[i] = 1934 data->in[i] =
1506 it87_read_value(data, IT87_REG_VIN(i)); 1935 it87_read_value(data, IT87_REG_VIN(i));
1507 data->in_min[i] = 1936 data->in_min[i] =
1508 it87_read_value(data, IT87_REG_VIN_MIN(i)); 1937 it87_read_value(data, IT87_REG_VIN_MIN(i));
1509 data->in_max[i] = 1938 data->in_max[i] =
1510 it87_read_value(data, IT87_REG_VIN_MAX(i)); 1939 it87_read_value(data, IT87_REG_VIN_MAX(i));
1511 } 1940 }
1512 /* in8 (battery) has no limit registers */ 1941 /* in8 (battery) has no limit registers */
1513 data->in[8] = 1942 data->in[8] = it87_read_value(data, IT87_REG_VIN(8));
1514 it87_read_value(data, IT87_REG_VIN(8));
1515 1943
1516 for (i = 0; i < 5; i++) { 1944 for (i = 0; i < 5; i++) {
1517 /* Skip disabled fans */ 1945 /* Skip disabled fans */
@@ -1519,7 +1947,7 @@ static struct it87_data *it87_update_device(struct device *dev)
1519 continue; 1947 continue;
1520 1948
1521 data->fan_min[i] = 1949 data->fan_min[i] =
1522 it87_read_value(data, IT87_REG_FAN_MIN[i]); 1950 it87_read_value(data, IT87_REG_FAN_MIN[i]);
1523 data->fan[i] = it87_read_value(data, 1951 data->fan[i] = it87_read_value(data,
1524 IT87_REG_FAN[i]); 1952 IT87_REG_FAN[i]);
1525 /* Add high byte if in 16-bit mode */ 1953 /* Add high byte if in 16-bit mode */
@@ -1532,11 +1960,11 @@ static struct it87_data *it87_update_device(struct device *dev)
1532 } 1960 }
1533 for (i = 0; i < 3; i++) { 1961 for (i = 0; i < 3; i++) {
1534 data->temp[i] = 1962 data->temp[i] =
1535 it87_read_value(data, IT87_REG_TEMP(i)); 1963 it87_read_value(data, IT87_REG_TEMP(i));
1536 data->temp_high[i] = 1964 data->temp_high[i] =
1537 it87_read_value(data, IT87_REG_TEMP_HIGH(i)); 1965 it87_read_value(data, IT87_REG_TEMP_HIGH(i));
1538 data->temp_low[i] = 1966 data->temp_low[i] =
1539 it87_read_value(data, IT87_REG_TEMP_LOW(i)); 1967 it87_read_value(data, IT87_REG_TEMP_LOW(i));
1540 } 1968 }
1541 1969
1542 /* Newer chips don't have clock dividers */ 1970 /* Newer chips don't have clock dividers */
@@ -1551,9 +1979,13 @@ static struct it87_data *it87_update_device(struct device *dev)
1551 it87_read_value(data, IT87_REG_ALARM1) | 1979 it87_read_value(data, IT87_REG_ALARM1) |
1552 (it87_read_value(data, IT87_REG_ALARM2) << 8) | 1980 (it87_read_value(data, IT87_REG_ALARM2) << 8) |
1553 (it87_read_value(data, IT87_REG_ALARM3) << 16); 1981 (it87_read_value(data, IT87_REG_ALARM3) << 16);
1982 data->beeps = it87_read_value(data, IT87_REG_BEEP_ENABLE);
1983
1554 data->fan_main_ctrl = it87_read_value(data, 1984 data->fan_main_ctrl = it87_read_value(data,
1555 IT87_REG_FAN_MAIN_CTRL); 1985 IT87_REG_FAN_MAIN_CTRL);
1556 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL); 1986 data->fan_ctl = it87_read_value(data, IT87_REG_FAN_CTL);
1987 for (i = 0; i < 3; i++)
1988 it87_update_pwm_ctrl(data, i);
1557 1989
1558 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE); 1990 data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
1559 /* The 8705 does not have VID capability. 1991 /* The 8705 does not have VID capability.
@@ -1628,7 +2060,7 @@ exit:
1628static int __init sm_it87_init(void) 2060static int __init sm_it87_init(void)
1629{ 2061{
1630 int err; 2062 int err;
1631 unsigned short isa_address=0; 2063 unsigned short isa_address = 0;
1632 struct it87_sio_data sio_data; 2064 struct it87_sio_data sio_data;
1633 2065
1634 memset(&sio_data, 0, sizeof(struct it87_sio_data)); 2066 memset(&sio_data, 0, sizeof(struct it87_sio_data));
@@ -1640,7 +2072,7 @@ static int __init sm_it87_init(void)
1640 return err; 2072 return err;
1641 2073
1642 err = it87_device_add(isa_address, &sio_data); 2074 err = it87_device_add(isa_address, &sio_data);
1643 if (err){ 2075 if (err) {
1644 platform_driver_unregister(&it87_driver); 2076 platform_driver_unregister(&it87_driver);
1645 return err; 2077 return err;
1646 } 2078 }
@@ -1661,7 +2093,8 @@ MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F/8720F/8726F, SiS950 driver");
1661module_param(update_vbat, bool, 0); 2093module_param(update_vbat, bool, 0);
1662MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); 2094MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
1663module_param(fix_pwm_polarity, bool, 0); 2095module_param(fix_pwm_polarity, bool, 0);
1664MODULE_PARM_DESC(fix_pwm_polarity, "Force PWM polarity to active high (DANGEROUS)"); 2096MODULE_PARM_DESC(fix_pwm_polarity,
2097 "Force PWM polarity to active high (DANGEROUS)");
1665MODULE_LICENSE("GPL"); 2098MODULE_LICENSE("GPL");
1666 2099
1667module_init(sm_it87_init); 2100module_init(sm_it87_init);
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 7c9bdc167426..7cc2708871ab 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * lm90.c - Part of lm_sensors, Linux kernel modules for hardware 2 * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
3 * monitoring 3 * monitoring
4 * Copyright (C) 2003-2009 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
5 * 5 *
6 * Based on the lm83 driver. The LM90 is a sensor chip made by National 6 * Based on the lm83 driver. The LM90 is a sensor chip made by National
7 * Semiconductor. It reports up to two temperatures (its own plus up to 7 * Semiconductor. It reports up to two temperatures (its own plus up to
@@ -93,7 +93,8 @@
93static const unsigned short normal_i2c[] = { 93static const unsigned short normal_i2c[] = {
94 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END }; 94 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
95 95
96enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646 }; 96enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646,
97 w83l771 };
97 98
98/* 99/*
99 * The LM90 registers 100 * The LM90 registers
@@ -151,6 +152,7 @@ static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info);
151static int lm90_probe(struct i2c_client *client, 152static int lm90_probe(struct i2c_client *client,
152 const struct i2c_device_id *id); 153 const struct i2c_device_id *id);
153static void lm90_init_client(struct i2c_client *client); 154static void lm90_init_client(struct i2c_client *client);
155static void lm90_alert(struct i2c_client *client, unsigned int flag);
154static int lm90_remove(struct i2c_client *client); 156static int lm90_remove(struct i2c_client *client);
155static struct lm90_data *lm90_update_device(struct device *dev); 157static struct lm90_data *lm90_update_device(struct device *dev);
156 158
@@ -173,6 +175,7 @@ static const struct i2c_device_id lm90_id[] = {
173 { "max6659", max6657 }, 175 { "max6659", max6657 },
174 { "max6680", max6680 }, 176 { "max6680", max6680 },
175 { "max6681", max6680 }, 177 { "max6681", max6680 },
178 { "w83l771", w83l771 },
176 { } 179 { }
177}; 180};
178MODULE_DEVICE_TABLE(i2c, lm90_id); 181MODULE_DEVICE_TABLE(i2c, lm90_id);
@@ -184,6 +187,7 @@ static struct i2c_driver lm90_driver = {
184 }, 187 },
185 .probe = lm90_probe, 188 .probe = lm90_probe,
186 .remove = lm90_remove, 189 .remove = lm90_remove,
190 .alert = lm90_alert,
187 .id_table = lm90_id, 191 .id_table = lm90_id,
188 .detect = lm90_detect, 192 .detect = lm90_detect,
189 .address_list = normal_i2c, 193 .address_list = normal_i2c,
@@ -201,6 +205,9 @@ struct lm90_data {
201 int kind; 205 int kind;
202 int flags; 206 int flags;
203 207
208 u8 config_orig; /* Original configuration register value */
209 u8 alert_alarms; /* Which alarm bits trigger ALERT# */
210
204 /* registers values */ 211 /* registers values */
205 s8 temp8[4]; /* 0: local low limit 212 s8 temp8[4]; /* 0: local low limit
206 1: local high limit 213 1: local high limit
@@ -758,6 +765,14 @@ static int lm90_detect(struct i2c_client *new_client,
758 && reg_convrate <= 0x07) { 765 && reg_convrate <= 0x07) {
759 name = "max6646"; 766 name = "max6646";
760 } 767 }
768 } else
769 if (address == 0x4C
770 && man_id == 0x5C) { /* Winbond/Nuvoton */
771 if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
772 && (reg_config1 & 0x2A) == 0x00
773 && reg_convrate <= 0x08) {
774 name = "w83l771";
775 }
761 } 776 }
762 777
763 if (!name) { /* identification failed */ 778 if (!name) { /* identification failed */
@@ -794,6 +809,19 @@ static int lm90_probe(struct i2c_client *new_client,
794 new_client->flags &= ~I2C_CLIENT_PEC; 809 new_client->flags &= ~I2C_CLIENT_PEC;
795 } 810 }
796 811
812 /* Different devices have different alarm bits triggering the
813 * ALERT# output */
814 switch (data->kind) {
815 case lm90:
816 case lm99:
817 case lm86:
818 data->alert_alarms = 0x7b;
819 break;
820 default:
821 data->alert_alarms = 0x7c;
822 break;
823 }
824
797 /* Initialize the LM90 chip */ 825 /* Initialize the LM90 chip */
798 lm90_init_client(new_client); 826 lm90_init_client(new_client);
799 827
@@ -830,7 +858,7 @@ exit:
830 858
831static void lm90_init_client(struct i2c_client *client) 859static void lm90_init_client(struct i2c_client *client)
832{ 860{
833 u8 config, config_orig; 861 u8 config;
834 struct lm90_data *data = i2c_get_clientdata(client); 862 struct lm90_data *data = i2c_get_clientdata(client);
835 863
836 /* 864 /*
@@ -842,7 +870,7 @@ static void lm90_init_client(struct i2c_client *client)
842 dev_warn(&client->dev, "Initialization failed!\n"); 870 dev_warn(&client->dev, "Initialization failed!\n");
843 return; 871 return;
844 } 872 }
845 config_orig = config; 873 data->config_orig = config;
846 874
847 /* Check Temperature Range Select */ 875 /* Check Temperature Range Select */
848 if (data->kind == adt7461) { 876 if (data->kind == adt7461) {
@@ -860,7 +888,7 @@ static void lm90_init_client(struct i2c_client *client)
860 } 888 }
861 889
862 config &= 0xBF; /* run */ 890 config &= 0xBF; /* run */
863 if (config != config_orig) /* Only write if changed */ 891 if (config != data->config_orig) /* Only write if changed */
864 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); 892 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
865} 893}
866 894
@@ -875,10 +903,46 @@ static int lm90_remove(struct i2c_client *client)
875 device_remove_file(&client->dev, 903 device_remove_file(&client->dev,
876 &sensor_dev_attr_temp2_offset.dev_attr); 904 &sensor_dev_attr_temp2_offset.dev_attr);
877 905
906 /* Restore initial configuration */
907 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
908 data->config_orig);
909
878 kfree(data); 910 kfree(data);
879 return 0; 911 return 0;
880} 912}
881 913
914static void lm90_alert(struct i2c_client *client, unsigned int flag)
915{
916 struct lm90_data *data = i2c_get_clientdata(client);
917 u8 config, alarms;
918
919 lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
920 if ((alarms & 0x7f) == 0) {
921 dev_info(&client->dev, "Everything OK\n");
922 } else {
923 if (alarms & 0x61)
924 dev_warn(&client->dev,
925 "temp%d out of range, please check!\n", 1);
926 if (alarms & 0x1a)
927 dev_warn(&client->dev,
928 "temp%d out of range, please check!\n", 2);
929 if (alarms & 0x04)
930 dev_warn(&client->dev,
931 "temp%d diode open, please check!\n", 2);
932
933 /* Disable ALERT# output, because these chips don't implement
934 SMBus alert correctly; they should only hold the alert line
935 low briefly. */
936 if ((data->kind == adm1032 || data->kind == adt7461)
937 && (alarms & data->alert_alarms)) {
938 dev_dbg(&client->dev, "Disabling ALERT#\n");
939 lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
940 i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
941 config | 0x80);
942 }
943 }
944}
945
882static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) 946static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
883{ 947{
884 int err; 948 int err;
@@ -966,6 +1030,21 @@ static struct lm90_data *lm90_update_device(struct device *dev)
966 } 1030 }
967 lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); 1031 lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
968 1032
1033 /* Re-enable ALERT# output if it was originally enabled and
1034 * relevant alarms are all clear */
1035 if ((data->config_orig & 0x80) == 0
1036 && (data->alarms & data->alert_alarms) == 0) {
1037 u8 config;
1038
1039 lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
1040 if (config & 0x80) {
1041 dev_dbg(&client->dev, "Re-enabling ALERT#\n");
1042 i2c_smbus_write_byte_data(client,
1043 LM90_REG_W_CONFIG1,
1044 config & ~0x80);
1045 }
1046 }
1047
969 data->last_updated = jiffies; 1048 data->last_updated = jiffies;
970 data->valid = 1; 1049 data->valid = 1;
971 } 1050 }
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
index a13b30e8d8d8..d14a1af9f550 100644
--- a/drivers/hwmon/tmp401.c
+++ b/drivers/hwmon/tmp401.c
@@ -134,7 +134,7 @@ struct tmp401_data {
134 struct mutex update_lock; 134 struct mutex update_lock;
135 char valid; /* zero until following fields are valid */ 135 char valid; /* zero until following fields are valid */
136 unsigned long last_updated; /* in jiffies */ 136 unsigned long last_updated; /* in jiffies */
137 int kind; 137 enum chips kind;
138 138
139 /* register values */ 139 /* register values */
140 u8 status; 140 u8 status;
@@ -524,7 +524,7 @@ static int tmp401_detect(struct i2c_client *client,
524 if (reg > 15) 524 if (reg > 15)
525 return -ENODEV; 525 return -ENODEV;
526 526
527 strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE); 527 strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);
528 528
529 return 0; 529 return 0;
530} 530}
@@ -572,8 +572,7 @@ static int tmp401_probe(struct i2c_client *client,
572 goto exit_remove; 572 goto exit_remove;
573 } 573 }
574 574
575 dev_info(&client->dev, "Detected TI %s chip\n", 575 dev_info(&client->dev, "Detected TI %s chip\n", names[data->kind]);
576 names[data->kind - 1]);
577 576
578 return 0; 577 return 0;
579 578
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index 4f7c051e2d7b..738c472ece27 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -61,9 +61,9 @@ static const u8 TMP421_TEMP_LSB[4] = { 0x10, 0x11, 0x12, 0x13 };
61#define TMP423_DEVICE_ID 0x23 61#define TMP423_DEVICE_ID 0x23
62 62
63static const struct i2c_device_id tmp421_id[] = { 63static const struct i2c_device_id tmp421_id[] = {
64 { "tmp421", tmp421 }, 64 { "tmp421", 2 },
65 { "tmp422", tmp422 }, 65 { "tmp422", 3 },
66 { "tmp423", tmp423 }, 66 { "tmp423", 4 },
67 { } 67 { }
68}; 68};
69MODULE_DEVICE_TABLE(i2c, tmp421_id); 69MODULE_DEVICE_TABLE(i2c, tmp421_id);
@@ -73,21 +73,23 @@ struct tmp421_data {
73 struct mutex update_lock; 73 struct mutex update_lock;
74 char valid; 74 char valid;
75 unsigned long last_updated; 75 unsigned long last_updated;
76 int kind; 76 int channels;
77 u8 config; 77 u8 config;
78 s16 temp[4]; 78 s16 temp[4];
79}; 79};
80 80
81static int temp_from_s16(s16 reg) 81static int temp_from_s16(s16 reg)
82{ 82{
83 int temp = reg; 83 /* Mask out status bits */
84 int temp = reg & ~0xf;
84 85
85 return (temp * 1000 + 128) / 256; 86 return (temp * 1000 + 128) / 256;
86} 87}
87 88
88static int temp_from_u16(u16 reg) 89static int temp_from_u16(u16 reg)
89{ 90{
90 int temp = reg; 91 /* Mask out status bits */
92 int temp = reg & ~0xf;
91 93
92 /* Add offset for extended temperature range. */ 94 /* Add offset for extended temperature range. */
93 temp -= 64 * 256; 95 temp -= 64 * 256;
@@ -107,7 +109,7 @@ static struct tmp421_data *tmp421_update_device(struct device *dev)
107 data->config = i2c_smbus_read_byte_data(client, 109 data->config = i2c_smbus_read_byte_data(client,
108 TMP421_CONFIG_REG_1); 110 TMP421_CONFIG_REG_1);
109 111
110 for (i = 0; i <= data->kind; i++) { 112 for (i = 0; i < data->channels; i++) {
111 data->temp[i] = i2c_smbus_read_byte_data(client, 113 data->temp[i] = i2c_smbus_read_byte_data(client,
112 TMP421_TEMP_MSB[i]) << 8; 114 TMP421_TEMP_MSB[i]) << 8;
113 data->temp[i] |= i2c_smbus_read_byte_data(client, 115 data->temp[i] |= i2c_smbus_read_byte_data(client,
@@ -166,7 +168,7 @@ static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
166 devattr = container_of(a, struct device_attribute, attr); 168 devattr = container_of(a, struct device_attribute, attr);
167 index = to_sensor_dev_attr(devattr)->index; 169 index = to_sensor_dev_attr(devattr)->index;
168 170
169 if (data->kind > index) 171 if (index < data->channels)
170 return a->mode; 172 return a->mode;
171 173
172 return 0; 174 return 0;
@@ -252,9 +254,9 @@ static int tmp421_detect(struct i2c_client *client,
252 return -ENODEV; 254 return -ENODEV;
253 } 255 }
254 256
255 strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE); 257 strlcpy(info->type, tmp421_id[kind].name, I2C_NAME_SIZE);
256 dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n", 258 dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
257 names[kind - 1], client->addr); 259 names[kind], client->addr);
258 260
259 return 0; 261 return 0;
260} 262}
@@ -271,7 +273,7 @@ static int tmp421_probe(struct i2c_client *client,
271 273
272 i2c_set_clientdata(client, data); 274 i2c_set_clientdata(client, data);
273 mutex_init(&data->update_lock); 275 mutex_init(&data->update_lock);
274 data->kind = id->driver_data; 276 data->channels = id->driver_data;
275 277
276 err = tmp421_init_client(client); 278 err = tmp421_init_client(client);
277 if (err) 279 if (err)
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index d47b4c9949c2..e6078c9f0e27 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -948,8 +948,7 @@ static int __devinit vt8231_pci_probe(struct pci_dev *dev,
948 948
949 address = val & ~(VT8231_EXTENT - 1); 949 address = val & ~(VT8231_EXTENT - 1);
950 if (address == 0) { 950 if (address == 0) {
951 dev_err(&dev->dev, "base address not set -\ 951 dev_err(&dev->dev, "base address not set - upgrade BIOS or use force_addr=0xaddr\n");
952 upgrade BIOS or use force_addr=0xaddr\n");
953 return -ENODEV; 952 return -ENODEV;
954 } 953 }
955 954
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 9a2022b67495..9de81a4c15a2 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -3,6 +3,10 @@
3 Copyright (C) 2006 Winbond Electronics Corp. 3 Copyright (C) 2006 Winbond Electronics Corp.
4 Yuan Mu 4 Yuan Mu
5 Rudolf Marek <r.marek@assembler.cz> 5 Rudolf Marek <r.marek@assembler.cz>
6 Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG.
7 Watchdog driver part
8 (Based partially on fschmd driver,
9 Copyright 2007-2008 by Hans de Goede)
6 10
7 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
@@ -35,6 +39,16 @@
35#include <linux/hwmon-sysfs.h> 39#include <linux/hwmon-sysfs.h>
36#include <linux/err.h> 40#include <linux/err.h>
37#include <linux/mutex.h> 41#include <linux/mutex.h>
42#include <linux/fs.h>
43#include <linux/watchdog.h>
44#include <linux/miscdevice.h>
45#include <linux/uaccess.h>
46#include <linux/kref.h>
47#include <linux/notifier.h>
48#include <linux/reboot.h>
49
50/* Default values */
51#define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */
38 52
39/* Addresses to scan */ 53/* Addresses to scan */
40static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, 54static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
@@ -51,6 +65,18 @@ static int reset;
51module_param(reset, bool, 0); 65module_param(reset, bool, 0);
52MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); 66MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
53 67
68static int timeout = WATCHDOG_TIMEOUT; /* default timeout in minutes */
69module_param(timeout, int, 0);
70MODULE_PARM_DESC(timeout,
71 "Watchdog timeout in minutes. 2<= timeout <=255 (default="
72 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
73
74static int nowayout = WATCHDOG_NOWAYOUT;
75module_param(nowayout, int, 0);
76MODULE_PARM_DESC(nowayout,
77 "Watchdog cannot be stopped once started (default="
78 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
79
54/* 80/*
55 Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved 81 Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
56 as ID, Bank Select registers 82 as ID, Bank Select registers
@@ -72,6 +98,11 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
72#define W83793_REG_VID_LATCHB 0x08 98#define W83793_REG_VID_LATCHB 0x08
73#define W83793_REG_VID_CTRL 0x59 99#define W83793_REG_VID_CTRL 0x59
74 100
101#define W83793_REG_WDT_LOCK 0x01
102#define W83793_REG_WDT_ENABLE 0x02
103#define W83793_REG_WDT_STATUS 0x03
104#define W83793_REG_WDT_TIMEOUT 0x04
105
75static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f }; 106static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f };
76 107
77#define TEMP_READ 0 108#define TEMP_READ 0
@@ -223,8 +254,37 @@ struct w83793_data {
223 u8 tolerance[3]; /* Temp tolerance(Smart Fan I/II) */ 254 u8 tolerance[3]; /* Temp tolerance(Smart Fan I/II) */
224 u8 sf2_pwm[6][7]; /* Smart FanII: Fan duty cycle */ 255 u8 sf2_pwm[6][7]; /* Smart FanII: Fan duty cycle */
225 u8 sf2_temp[6][7]; /* Smart FanII: Temp level point */ 256 u8 sf2_temp[6][7]; /* Smart FanII: Temp level point */
257
258 /* watchdog */
259 struct i2c_client *client;
260 struct mutex watchdog_lock;
261 struct list_head list; /* member of the watchdog_data_list */
262 struct kref kref;
263 struct miscdevice watchdog_miscdev;
264 unsigned long watchdog_is_open;
265 char watchdog_expect_close;
266 char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
267 unsigned int watchdog_caused_reboot;
268 int watchdog_timeout; /* watchdog timeout in minutes */
226}; 269};
227 270
271/* Somewhat ugly :( global data pointer list with all devices, so that
272 we can find our device data as when using misc_register. There is no
273 other method to get to one's device data from the open file-op and
274 for usage in the reboot notifier callback. */
275static LIST_HEAD(watchdog_data_list);
276
277/* Note this lock not only protect list access, but also data.kref access */
278static DEFINE_MUTEX(watchdog_data_mutex);
279
280/* Release our data struct when we're detached from the i2c client *and* all
281 references to our watchdog device are released */
282static void w83793_release_resources(struct kref *ref)
283{
284 struct w83793_data *data = container_of(ref, struct w83793_data, kref);
285 kfree(data);
286}
287
228static u8 w83793_read_value(struct i2c_client *client, u16 reg); 288static u8 w83793_read_value(struct i2c_client *client, u16 reg);
229static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value); 289static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
230static int w83793_probe(struct i2c_client *client, 290static int w83793_probe(struct i2c_client *client,
@@ -1063,14 +1123,349 @@ static void w83793_init_client(struct i2c_client *client)
1063 /* Start monitoring */ 1123 /* Start monitoring */
1064 w83793_write_value(client, W83793_REG_CONFIG, 1124 w83793_write_value(client, W83793_REG_CONFIG,
1065 w83793_read_value(client, W83793_REG_CONFIG) | 0x01); 1125 w83793_read_value(client, W83793_REG_CONFIG) | 0x01);
1126}
1127
1128/*
1129 * Watchdog routines
1130 */
1131
1132static int watchdog_set_timeout(struct w83793_data *data, int timeout)
1133{
1134 int ret, mtimeout;
1135
1136 mtimeout = DIV_ROUND_UP(timeout, 60);
1137
1138 if (mtimeout > 255)
1139 return -EINVAL;
1140
1141 mutex_lock(&data->watchdog_lock);
1142 if (!data->client) {
1143 ret = -ENODEV;
1144 goto leave;
1145 }
1146
1147 data->watchdog_timeout = mtimeout;
1148
1149 /* Set Timeout value (in Minutes) */
1150 w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
1151 data->watchdog_timeout);
1152
1153 ret = mtimeout * 60;
1154
1155leave:
1156 mutex_unlock(&data->watchdog_lock);
1157 return ret;
1158}
1159
1160static int watchdog_get_timeout(struct w83793_data *data)
1161{
1162 int timeout;
1163
1164 mutex_lock(&data->watchdog_lock);
1165 timeout = data->watchdog_timeout * 60;
1166 mutex_unlock(&data->watchdog_lock);
1167
1168 return timeout;
1169}
1170
1171static int watchdog_trigger(struct w83793_data *data)
1172{
1173 int ret = 0;
1174
1175 mutex_lock(&data->watchdog_lock);
1176 if (!data->client) {
1177 ret = -ENODEV;
1178 goto leave;
1179 }
1180
1181 /* Set Timeout value (in Minutes) */
1182 w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
1183 data->watchdog_timeout);
1184
1185leave:
1186 mutex_unlock(&data->watchdog_lock);
1187 return ret;
1188}
1189
1190static int watchdog_enable(struct w83793_data *data)
1191{
1192 int ret = 0;
1193
1194 mutex_lock(&data->watchdog_lock);
1195 if (!data->client) {
1196 ret = -ENODEV;
1197 goto leave;
1198 }
1199
1200 /* Set initial timeout */
1201 w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
1202 data->watchdog_timeout);
1203
1204 /* Enable Soft Watchdog */
1205 w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0x55);
1206
1207leave:
1208 mutex_unlock(&data->watchdog_lock);
1209 return ret;
1210}
1211
1212static int watchdog_disable(struct w83793_data *data)
1213{
1214 int ret = 0;
1215
1216 mutex_lock(&data->watchdog_lock);
1217 if (!data->client) {
1218 ret = -ENODEV;
1219 goto leave;
1220 }
1221
1222 /* Disable Soft Watchdog */
1223 w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0xAA);
1224
1225leave:
1226 mutex_unlock(&data->watchdog_lock);
1227 return ret;
1228}
1229
1230static int watchdog_open(struct inode *inode, struct file *filp)
1231{
1232 struct w83793_data *pos, *data = NULL;
1233 int watchdog_is_open;
1234
1235 /* We get called from drivers/char/misc.c with misc_mtx hold, and we
1236 call misc_register() from w83793_probe() with watchdog_data_mutex
1237 hold, as misc_register() takes the misc_mtx lock, this is a possible
1238 deadlock, so we use mutex_trylock here. */
1239 if (!mutex_trylock(&watchdog_data_mutex))
1240 return -ERESTARTSYS;
1241 list_for_each_entry(pos, &watchdog_data_list, list) {
1242 if (pos->watchdog_miscdev.minor == iminor(inode)) {
1243 data = pos;
1244 break;
1245 }
1246 }
1247
1248 /* Check, if device is already open */
1249 watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
1250
1251 /* Increase data reference counter (if not already done).
1252 Note we can never not have found data, so we don't check for this */
1253 if (!watchdog_is_open)
1254 kref_get(&data->kref);
1255
1256 mutex_unlock(&watchdog_data_mutex);
1257
1258 /* Check, if device is already open and possibly issue error */
1259 if (watchdog_is_open)
1260 return -EBUSY;
1261
1262 /* Enable Soft Watchdog */
1263 watchdog_enable(data);
1264
1265 /* Store pointer to data into filp's private data */
1266 filp->private_data = data;
1267
1268 return nonseekable_open(inode, filp);
1269}
1270
1271static int watchdog_close(struct inode *inode, struct file *filp)
1272{
1273 struct w83793_data *data = filp->private_data;
1066 1274
1275 if (data->watchdog_expect_close) {
1276 watchdog_disable(data);
1277 data->watchdog_expect_close = 0;
1278 } else {
1279 watchdog_trigger(data);
1280 dev_crit(&data->client->dev,
1281 "unexpected close, not stopping watchdog!\n");
1282 }
1283
1284 clear_bit(0, &data->watchdog_is_open);
1285
1286 /* Decrease data reference counter */
1287 mutex_lock(&watchdog_data_mutex);
1288 kref_put(&data->kref, w83793_release_resources);
1289 mutex_unlock(&watchdog_data_mutex);
1290
1291 return 0;
1292}
1293
1294static ssize_t watchdog_write(struct file *filp, const char __user *buf,
1295 size_t count, loff_t *offset)
1296{
1297 size_t ret;
1298 struct w83793_data *data = filp->private_data;
1299
1300 if (count) {
1301 if (!nowayout) {
1302 size_t i;
1303
1304 /* Clear it in case it was set with a previous write */
1305 data->watchdog_expect_close = 0;
1306
1307 for (i = 0; i != count; i++) {
1308 char c;
1309 if (get_user(c, buf + i))
1310 return -EFAULT;
1311 if (c == 'V')
1312 data->watchdog_expect_close = 1;
1313 }
1314 }
1315 ret = watchdog_trigger(data);
1316 if (ret < 0)
1317 return ret;
1318 }
1319 return count;
1320}
1321
1322static int watchdog_ioctl(struct inode *inode, struct file *filp,
1323 unsigned int cmd, unsigned long arg)
1324{
1325 static struct watchdog_info ident = {
1326 .options = WDIOF_KEEPALIVEPING |
1327 WDIOF_SETTIMEOUT |
1328 WDIOF_CARDRESET,
1329 .identity = "w83793 watchdog"
1330 };
1331
1332 int val, ret = 0;
1333 struct w83793_data *data = filp->private_data;
1334
1335 switch (cmd) {
1336 case WDIOC_GETSUPPORT:
1337 if (!nowayout)
1338 ident.options |= WDIOF_MAGICCLOSE;
1339 if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
1340 ret = -EFAULT;
1341 break;
1342
1343 case WDIOC_GETSTATUS:
1344 val = data->watchdog_caused_reboot ? WDIOF_CARDRESET : 0;
1345 ret = put_user(val, (int __user *)arg);
1346 break;
1347
1348 case WDIOC_GETBOOTSTATUS:
1349 ret = put_user(0, (int __user *)arg);
1350 break;
1351
1352 case WDIOC_KEEPALIVE:
1353 ret = watchdog_trigger(data);
1354 break;
1355
1356 case WDIOC_GETTIMEOUT:
1357 val = watchdog_get_timeout(data);
1358 ret = put_user(val, (int __user *)arg);
1359 break;
1360
1361 case WDIOC_SETTIMEOUT:
1362 if (get_user(val, (int __user *)arg)) {
1363 ret = -EFAULT;
1364 break;
1365 }
1366 ret = watchdog_set_timeout(data, val);
1367 if (ret > 0)
1368 ret = put_user(ret, (int __user *)arg);
1369 break;
1370
1371 case WDIOC_SETOPTIONS:
1372 if (get_user(val, (int __user *)arg)) {
1373 ret = -EFAULT;
1374 break;
1375 }
1376
1377 if (val & WDIOS_DISABLECARD)
1378 ret = watchdog_disable(data);
1379 else if (val & WDIOS_ENABLECARD)
1380 ret = watchdog_enable(data);
1381 else
1382 ret = -EINVAL;
1383
1384 break;
1385 default:
1386 ret = -ENOTTY;
1387 }
1388
1389 return ret;
1390}
1391
1392static const struct file_operations watchdog_fops = {
1393 .owner = THIS_MODULE,
1394 .llseek = no_llseek,
1395 .open = watchdog_open,
1396 .release = watchdog_close,
1397 .write = watchdog_write,
1398 .ioctl = watchdog_ioctl,
1399};
1400
1401/*
1402 * Notifier for system down
1403 */
1404
1405static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
1406 void *unused)
1407{
1408 struct w83793_data *data = NULL;
1409
1410 if (code == SYS_DOWN || code == SYS_HALT) {
1411
1412 /* Disable each registered watchdog */
1413 mutex_lock(&watchdog_data_mutex);
1414 list_for_each_entry(data, &watchdog_data_list, list) {
1415 if (data->watchdog_miscdev.minor)
1416 watchdog_disable(data);
1417 }
1418 mutex_unlock(&watchdog_data_mutex);
1419 }
1420
1421 return NOTIFY_DONE;
1067} 1422}
1068 1423
1424/*
1425 * The WDT needs to learn about soft shutdowns in order to
1426 * turn the timebomb registers off.
1427 */
1428
1429static struct notifier_block watchdog_notifier = {
1430 .notifier_call = watchdog_notify_sys,
1431};
1432
1433/*
1434 * Init / remove routines
1435 */
1436
1069static int w83793_remove(struct i2c_client *client) 1437static int w83793_remove(struct i2c_client *client)
1070{ 1438{
1071 struct w83793_data *data = i2c_get_clientdata(client); 1439 struct w83793_data *data = i2c_get_clientdata(client);
1072 struct device *dev = &client->dev; 1440 struct device *dev = &client->dev;
1073 int i; 1441 int i, tmp;
1442
1443 /* Unregister the watchdog (if registered) */
1444 if (data->watchdog_miscdev.minor) {
1445 misc_deregister(&data->watchdog_miscdev);
1446
1447 if (data->watchdog_is_open) {
1448 dev_warn(&client->dev,
1449 "i2c client detached with watchdog open! "
1450 "Stopping watchdog.\n");
1451 watchdog_disable(data);
1452 }
1453
1454 mutex_lock(&watchdog_data_mutex);
1455 list_del(&data->list);
1456 mutex_unlock(&watchdog_data_mutex);
1457
1458 /* Tell the watchdog code the client is gone */
1459 mutex_lock(&data->watchdog_lock);
1460 data->client = NULL;
1461 mutex_unlock(&data->watchdog_lock);
1462 }
1463
1464 /* Reset Configuration Register to Disable Watch Dog Registers */
1465 tmp = w83793_read_value(client, W83793_REG_CONFIG);
1466 w83793_write_value(client, W83793_REG_CONFIG, tmp & ~0x04);
1467
1468 unregister_reboot_notifier(&watchdog_notifier);
1074 1469
1075 hwmon_device_unregister(data->hwmon_dev); 1470 hwmon_device_unregister(data->hwmon_dev);
1076 1471
@@ -1099,7 +1494,10 @@ static int w83793_remove(struct i2c_client *client)
1099 if (data->lm75[1] != NULL) 1494 if (data->lm75[1] != NULL)
1100 i2c_unregister_device(data->lm75[1]); 1495 i2c_unregister_device(data->lm75[1]);
1101 1496
1102 kfree(data); 1497 /* Decrease data reference counter */
1498 mutex_lock(&watchdog_data_mutex);
1499 kref_put(&data->kref, w83793_release_resources);
1500 mutex_unlock(&watchdog_data_mutex);
1103 1501
1104 return 0; 1502 return 0;
1105} 1503}
@@ -1203,6 +1601,7 @@ static int w83793_probe(struct i2c_client *client,
1203 const struct i2c_device_id *id) 1601 const struct i2c_device_id *id)
1204{ 1602{
1205 struct device *dev = &client->dev; 1603 struct device *dev = &client->dev;
1604 const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
1206 struct w83793_data *data; 1605 struct w83793_data *data;
1207 int i, tmp, val, err; 1606 int i, tmp, val, err;
1208 int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; 1607 int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
@@ -1218,6 +1617,14 @@ static int w83793_probe(struct i2c_client *client,
1218 i2c_set_clientdata(client, data); 1617 i2c_set_clientdata(client, data);
1219 data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); 1618 data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
1220 mutex_init(&data->update_lock); 1619 mutex_init(&data->update_lock);
1620 mutex_init(&data->watchdog_lock);
1621 INIT_LIST_HEAD(&data->list);
1622 kref_init(&data->kref);
1623
1624 /* Store client pointer in our data struct for watchdog usage
1625 (where the client is found through a data ptr instead of the
1626 otherway around) */
1627 data->client = client;
1221 1628
1222 err = w83793_detect_subclients(client); 1629 err = w83793_detect_subclients(client);
1223 if (err) 1630 if (err)
@@ -1380,8 +1787,77 @@ static int w83793_probe(struct i2c_client *client,
1380 goto exit_remove; 1787 goto exit_remove;
1381 } 1788 }
1382 1789
1790 /* Watchdog initialization */
1791
1792 /* Register boot notifier */
1793 err = register_reboot_notifier(&watchdog_notifier);
1794 if (err != 0) {
1795 dev_err(&client->dev,
1796 "cannot register reboot notifier (err=%d)\n", err);
1797 goto exit_devunreg;
1798 }
1799
1800 /* Enable Watchdog registers.
1801 Set Configuration Register to Enable Watch Dog Registers
1802 (Bit 2) = XXXX, X1XX. */
1803 tmp = w83793_read_value(client, W83793_REG_CONFIG);
1804 w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04);
1805
1806 /* Set the default watchdog timeout */
1807 data->watchdog_timeout = timeout;
1808
1809 /* Check, if last reboot was caused by watchdog */
1810 data->watchdog_caused_reboot =
1811 w83793_read_value(data->client, W83793_REG_WDT_STATUS) & 0x01;
1812
1813 /* Disable Soft Watchdog during initialiation */
1814 watchdog_disable(data);
1815
1816 /* We take the data_mutex lock early so that watchdog_open() cannot
1817 run when misc_register() has completed, but we've not yet added
1818 our data to the watchdog_data_list (and set the default timeout) */
1819 mutex_lock(&watchdog_data_mutex);
1820 for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
1821 /* Register our watchdog part */
1822 snprintf(data->watchdog_name, sizeof(data->watchdog_name),
1823 "watchdog%c", (i == 0) ? '\0' : ('0' + i));
1824 data->watchdog_miscdev.name = data->watchdog_name;
1825 data->watchdog_miscdev.fops = &watchdog_fops;
1826 data->watchdog_miscdev.minor = watchdog_minors[i];
1827
1828 err = misc_register(&data->watchdog_miscdev);
1829 if (err == -EBUSY)
1830 continue;
1831 if (err) {
1832 data->watchdog_miscdev.minor = 0;
1833 dev_err(&client->dev,
1834 "Registering watchdog chardev: %d\n", err);
1835 break;
1836 }
1837
1838 list_add(&data->list, &watchdog_data_list);
1839
1840 dev_info(&client->dev,
1841 "Registered watchdog chardev major 10, minor: %d\n",
1842 watchdog_minors[i]);
1843 break;
1844 }
1845 if (i == ARRAY_SIZE(watchdog_minors)) {
1846 data->watchdog_miscdev.minor = 0;
1847 dev_warn(&client->dev, "Couldn't register watchdog chardev "
1848 "(due to no free minor)\n");
1849 }
1850
1851 mutex_unlock(&watchdog_data_mutex);
1852
1383 return 0; 1853 return 0;
1384 1854
1855 /* Unregister hwmon device */
1856
1857exit_devunreg:
1858
1859 hwmon_device_unregister(data->hwmon_dev);
1860
1385 /* Unregister sysfs hooks */ 1861 /* Unregister sysfs hooks */
1386 1862
1387exit_remove: 1863exit_remove:
@@ -1628,7 +2104,7 @@ static void __exit sensors_w83793_exit(void)
1628 i2c_del_driver(&w83793_driver); 2104 i2c_del_driver(&w83793_driver);
1629} 2105}
1630 2106
1631MODULE_AUTHOR("Yuan Mu"); 2107MODULE_AUTHOR("Yuan Mu, Sven Anders");
1632MODULE_DESCRIPTION("w83793 driver"); 2108MODULE_DESCRIPTION("w83793 driver");
1633MODULE_LICENSE("GPL"); 2109MODULE_LICENSE("GPL");
1634 2110
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 4cc3807bd31c..9c6170cd9aac 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -106,6 +106,8 @@ config I2C_I801
106config I2C_ISCH 106config I2C_ISCH
107 tristate "Intel SCH SMBus 1.0" 107 tristate "Intel SCH SMBus 1.0"
108 depends on PCI 108 depends on PCI
109 select MFD_CORE
110 select LPC_SCH
109 help 111 help
110 Say Y here if you want to use SMBus controller on the Intel SCH 112 Say Y here if you want to use SMBus controller on the Intel SCH
111 based systems. 113 based systems.
@@ -419,13 +421,12 @@ config I2C_IXP2000
419 instead. 421 instead.
420 422
421config I2C_MPC 423config I2C_MPC
422 tristate "MPC107/824x/85xx/52xx/86xx" 424 tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
423 depends on PPC32 425 depends on PPC32
424 help 426 help
425 If you say yes to this option, support will be included for the 427 If you say yes to this option, support will be included for the
426 built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and 428 built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
427 MPC85xx/MPC8641 family processors. The driver may also work on 52xx 429 MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors.
428 family processors, though interrupts are known not to work.
429 430
430 This driver can also be built as a module. If so, the module 431 This driver can also be built as a module. If so, the module
431 will be called i2c-mpc. 432 will be called i2c-mpc.
@@ -440,6 +441,13 @@ config I2C_MV64XXX
440 This driver can also be built as a module. If so, the module 441 This driver can also be built as a module. If so, the module
441 will be called i2c-mv64xxx. 442 will be called i2c-mv64xxx.
442 443
444config I2C_NOMADIK
445 tristate "ST-Ericsson Nomadik/Ux500 I2C Controller"
446 depends on PLAT_NOMADIK
447 help
448 If you say yes to this option, support will be included for the
449 I2C interface from ST-Ericsson's Nomadik and Ux500 architectures.
450
443config I2C_OCORES 451config I2C_OCORES
444 tristate "OpenCores I2C Controller" 452 tristate "OpenCores I2C Controller"
445 depends on EXPERIMENTAL 453 depends on EXPERIMENTAL
@@ -575,6 +583,16 @@ config I2C_OCTEON
575 This driver can also be built as a module. If so, the module 583 This driver can also be built as a module. If so, the module
576 will be called i2c-octeon. 584 will be called i2c-octeon.
577 585
586config I2C_XILINX
587 tristate "Xilinx I2C Controller"
588 depends on EXPERIMENTAL && HAS_IOMEM
589 help
590 If you say yes to this option, support will be included for the
591 Xilinx I2C controller.
592
593 This driver can also be built as a module. If so, the module
594 will be called xilinx_i2c.
595
578comment "External I2C/SMBus adapter drivers" 596comment "External I2C/SMBus adapter drivers"
579 597
580config I2C_PARPORT 598config I2C_PARPORT
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index c2c4ea1908d8..097236f631e8 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
42obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o 42obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
43obj-$(CONFIG_I2C_MPC) += i2c-mpc.o 43obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
44obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o 44obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
45obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
45obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o 46obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
46obj-$(CONFIG_I2C_OMAP) += i2c-omap.o 47obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
47obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o 48obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
@@ -55,6 +56,7 @@ obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
55obj-$(CONFIG_I2C_STU300) += i2c-stu300.o 56obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
56obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o 57obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
57obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o 58obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
59obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
58 60
59# External I2C/SMBus adapter drivers 61# External I2C/SMBus adapter drivers
60obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o 62obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c
index 9e18ef97f156..3e72b69aa7f8 100644
--- a/drivers/i2c/busses/i2c-designware.c
+++ b/drivers/i2c/busses/i2c-designware.c
@@ -497,13 +497,13 @@ static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
497 int i; 497 int i;
498 498
499 if (abort_source & DW_IC_TX_ABRT_NOACK) { 499 if (abort_source & DW_IC_TX_ABRT_NOACK) {
500 for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) 500 for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
501 dev_dbg(dev->dev, 501 dev_dbg(dev->dev,
502 "%s: %s\n", __func__, abort_sources[i]); 502 "%s: %s\n", __func__, abort_sources[i]);
503 return -EREMOTEIO; 503 return -EREMOTEIO;
504 } 504 }
505 505
506 for_each_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) 506 for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources))
507 dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); 507 dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]);
508 508
509 if (abort_source & DW_IC_TX_ARB_LOST) 509 if (abort_source & DW_IC_TX_ARB_LOST)
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 75bf820e7ccb..32375bddae7d 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -627,7 +627,6 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)
627} 627}
628 628
629static struct platform_driver i2c_imx_driver = { 629static struct platform_driver i2c_imx_driver = {
630 .probe = i2c_imx_probe,
631 .remove = __exit_p(i2c_imx_remove), 630 .remove = __exit_p(i2c_imx_remove),
632 .driver = { 631 .driver = {
633 .name = DRIVER_NAME, 632 .name = DRIVER_NAME,
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 69c22f79f231..ddc258edb34f 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -27,7 +27,7 @@
27*/ 27*/
28 28
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/pci.h> 30#include <linux/platform_device.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/stddef.h> 33#include <linux/stddef.h>
@@ -46,12 +46,6 @@
46#define SMBHSTDAT1 (7 + sch_smba) 46#define SMBHSTDAT1 (7 + sch_smba)
47#define SMBBLKDAT (0x20 + sch_smba) 47#define SMBBLKDAT (0x20 + sch_smba)
48 48
49/* count for request_region */
50#define SMBIOSIZE 64
51
52/* PCI Address Constants */
53#define SMBBA_SCH 0x40
54
55/* Other settings */ 49/* Other settings */
56#define MAX_TIMEOUT 500 50#define MAX_TIMEOUT 500
57 51
@@ -63,7 +57,6 @@
63#define SCH_BLOCK_DATA 0x05 57#define SCH_BLOCK_DATA 0x05
64 58
65static unsigned short sch_smba; 59static unsigned short sch_smba;
66static struct pci_driver sch_driver;
67static struct i2c_adapter sch_adapter; 60static struct i2c_adapter sch_adapter;
68 61
69/* 62/*
@@ -256,37 +249,23 @@ static struct i2c_adapter sch_adapter = {
256 .algo = &smbus_algorithm, 249 .algo = &smbus_algorithm,
257}; 250};
258 251
259static const struct pci_device_id sch_ids[] = { 252static int __devinit smbus_sch_probe(struct platform_device *dev)
260 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
261 { 0, }
262};
263
264MODULE_DEVICE_TABLE(pci, sch_ids);
265
266static int __devinit sch_probe(struct pci_dev *dev,
267 const struct pci_device_id *id)
268{ 253{
254 struct resource *res;
269 int retval; 255 int retval;
270 unsigned int smba;
271 256
272 pci_read_config_dword(dev, SMBBA_SCH, &smba); 257 res = platform_get_resource(dev, IORESOURCE_IO, 0);
273 if (!(smba & (1 << 31))) { 258 if (!res)
274 dev_err(&dev->dev, "SMBus I/O space disabled!\n"); 259 return -EBUSY;
275 return -ENODEV;
276 }
277 260
278 sch_smba = (unsigned short)smba; 261 if (!request_region(res->start, resource_size(res), dev->name)) {
279 if (sch_smba == 0) {
280 dev_err(&dev->dev, "SMBus base address uninitialized!\n");
281 return -ENODEV;
282 }
283 if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
284 return -ENODEV;
285 if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
286 dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", 262 dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
287 sch_smba); 263 sch_smba);
288 return -EBUSY; 264 return -EBUSY;
289 } 265 }
266
267 sch_smba = res->start;
268
290 dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba); 269 dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba);
291 270
292 /* set up the sysfs linkage to our parent device */ 271 /* set up the sysfs linkage to our parent device */
@@ -298,37 +277,43 @@ static int __devinit sch_probe(struct pci_dev *dev,
298 retval = i2c_add_adapter(&sch_adapter); 277 retval = i2c_add_adapter(&sch_adapter);
299 if (retval) { 278 if (retval) {
300 dev_err(&dev->dev, "Couldn't register adapter!\n"); 279 dev_err(&dev->dev, "Couldn't register adapter!\n");
301 release_region(sch_smba, SMBIOSIZE); 280 release_region(res->start, resource_size(res));
302 sch_smba = 0; 281 sch_smba = 0;
303 } 282 }
304 283
305 return retval; 284 return retval;
306} 285}
307 286
308static void __devexit sch_remove(struct pci_dev *dev) 287static int __devexit smbus_sch_remove(struct platform_device *pdev)
309{ 288{
289 struct resource *res;
310 if (sch_smba) { 290 if (sch_smba) {
311 i2c_del_adapter(&sch_adapter); 291 i2c_del_adapter(&sch_adapter);
312 release_region(sch_smba, SMBIOSIZE); 292 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
293 release_region(res->start, resource_size(res));
313 sch_smba = 0; 294 sch_smba = 0;
314 } 295 }
296
297 return 0;
315} 298}
316 299
317static struct pci_driver sch_driver = { 300static struct platform_driver smbus_sch_driver = {
318 .name = "isch_smbus", 301 .driver = {
319 .id_table = sch_ids, 302 .name = "isch_smbus",
320 .probe = sch_probe, 303 .owner = THIS_MODULE,
321 .remove = __devexit_p(sch_remove), 304 },
305 .probe = smbus_sch_probe,
306 .remove = __devexit_p(smbus_sch_remove),
322}; 307};
323 308
324static int __init i2c_sch_init(void) 309static int __init i2c_sch_init(void)
325{ 310{
326 return pci_register_driver(&sch_driver); 311 return platform_driver_register(&smbus_sch_driver);
327} 312}
328 313
329static void __exit i2c_sch_exit(void) 314static void __exit i2c_sch_exit(void)
330{ 315{
331 pci_unregister_driver(&sch_driver); 316 platform_driver_unregister(&smbus_sch_driver);
332} 317}
333 318
334MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>"); 319MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
@@ -337,3 +322,4 @@ MODULE_LICENSE("GPL");
337 322
338module_init(i2c_sch_init); 323module_init(i2c_sch_init);
339module_exit(i2c_sch_exit); 324module_exit(i2c_sch_exit);
325MODULE_ALIAS("platform:isch_smbus");
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index f627001108b8..78a15af32942 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -31,6 +31,9 @@
31 31
32#define DRV_NAME "mpc-i2c" 32#define DRV_NAME "mpc-i2c"
33 33
34#define MPC_I2C_CLOCK_LEGACY 0
35#define MPC_I2C_CLOCK_PRESERVE (~0U)
36
34#define MPC_I2C_FDR 0x04 37#define MPC_I2C_FDR 0x04
35#define MPC_I2C_CR 0x08 38#define MPC_I2C_CR 0x08
36#define MPC_I2C_SR 0x0c 39#define MPC_I2C_SR 0x0c
@@ -66,10 +69,9 @@ struct mpc_i2c_divider {
66 u16 fdr; /* including dfsrr */ 69 u16 fdr; /* including dfsrr */
67}; 70};
68 71
69struct mpc_i2c_match_data { 72struct mpc_i2c_data {
70 void (*setclock)(struct device_node *node, 73 void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
71 struct mpc_i2c *i2c, 74 u32 clock, u32 prescaler);
72 u32 clock, u32 prescaler);
73 u32 prescaler; 75 u32 prescaler;
74}; 76};
75 77
@@ -164,8 +166,8 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
164 return 0; 166 return 0;
165} 167}
166 168
167#ifdef CONFIG_PPC_MPC52xx 169#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
168static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { 170static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
169 {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, 171 {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
170 {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02}, 172 {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
171 {36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28}, 173 {36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
@@ -186,14 +188,15 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
186 {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f} 188 {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
187}; 189};
188 190
189int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler) 191static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
192 int prescaler)
190{ 193{
191 const struct mpc_i2c_divider *div = NULL; 194 const struct mpc_i2c_divider *div = NULL;
192 unsigned int pvr = mfspr(SPRN_PVR); 195 unsigned int pvr = mfspr(SPRN_PVR);
193 u32 divider; 196 u32 divider;
194 int i; 197 int i;
195 198
196 if (!clock) 199 if (clock == MPC_I2C_CLOCK_LEGACY)
197 return -EINVAL; 200 return -EINVAL;
198 201
199 /* Determine divider value */ 202 /* Determine divider value */
@@ -215,12 +218,18 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
215 return div ? (int)div->fdr : -EINVAL; 218 return div ? (int)div->fdr : -EINVAL;
216} 219}
217 220
218static void mpc_i2c_setclock_52xx(struct device_node *node, 221static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
219 struct mpc_i2c *i2c, 222 struct mpc_i2c *i2c,
220 u32 clock, u32 prescaler) 223 u32 clock, u32 prescaler)
221{ 224{
222 int ret, fdr; 225 int ret, fdr;
223 226
227 if (clock == MPC_I2C_CLOCK_PRESERVE) {
228 dev_dbg(i2c->dev, "using fdr %d\n",
229 readb(i2c->base + MPC_I2C_FDR));
230 return;
231 }
232
224 ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); 233 ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
225 fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ 234 fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
226 235
@@ -229,16 +238,52 @@ static void mpc_i2c_setclock_52xx(struct device_node *node,
229 if (ret >= 0) 238 if (ret >= 0)
230 dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); 239 dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
231} 240}
232#else /* !CONFIG_PPC_MPC52xx */ 241#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
233static void mpc_i2c_setclock_52xx(struct device_node *node, 242static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
234 struct mpc_i2c *i2c, 243 struct mpc_i2c *i2c,
235 u32 clock, u32 prescaler) 244 u32 clock, u32 prescaler)
245{
246}
247#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
248
249#ifdef CONFIG_PPC_MPC512x
250static void __devinit mpc_i2c_setup_512x(struct device_node *node,
251 struct mpc_i2c *i2c,
252 u32 clock, u32 prescaler)
253{
254 struct device_node *node_ctrl;
255 void __iomem *ctrl;
256 const u32 *pval;
257 u32 idx;
258
259 /* Enable I2C interrupts for mpc5121 */
260 node_ctrl = of_find_compatible_node(NULL, NULL,
261 "fsl,mpc5121-i2c-ctrl");
262 if (node_ctrl) {
263 ctrl = of_iomap(node_ctrl, 0);
264 if (ctrl) {
265 /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */
266 pval = of_get_property(node, "reg", NULL);
267 idx = (*pval & 0xff) / 0x20;
268 setbits32(ctrl, 1 << (24 + idx * 2));
269 iounmap(ctrl);
270 }
271 of_node_put(node_ctrl);
272 }
273
274 /* The clock setup for the 52xx works also fine for the 512x */
275 mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
276}
277#else /* CONFIG_PPC_MPC512x */
278static void __devinit mpc_i2c_setup_512x(struct device_node *node,
279 struct mpc_i2c *i2c,
280 u32 clock, u32 prescaler)
236{ 281{
237} 282}
238#endif /* CONFIG_PPC_MPC52xx*/ 283#endif /* CONFIG_PPC_MPC512x */
239 284
240#ifdef CONFIG_FSL_SOC 285#ifdef CONFIG_FSL_SOC
241static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = { 286static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = {
242 {160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123}, 287 {160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
243 {288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102}, 288 {288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
244 {416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127}, 289 {416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
@@ -258,7 +303,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
258 {49152, 0x011e}, {61440, 0x011f} 303 {49152, 0x011e}, {61440, 0x011f}
259}; 304};
260 305
261u32 mpc_i2c_get_sec_cfg_8xxx(void) 306static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
262{ 307{
263 struct device_node *node = NULL; 308 struct device_node *node = NULL;
264 u32 __iomem *reg; 309 u32 __iomem *reg;
@@ -287,13 +332,14 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void)
287 return val; 332 return val;
288} 333}
289 334
290int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler) 335static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
336 u32 prescaler)
291{ 337{
292 const struct mpc_i2c_divider *div = NULL; 338 const struct mpc_i2c_divider *div = NULL;
293 u32 divider; 339 u32 divider;
294 int i; 340 int i;
295 341
296 if (!clock) 342 if (clock == MPC_I2C_CLOCK_LEGACY)
297 return -EINVAL; 343 return -EINVAL;
298 344
299 /* Determine proper divider value */ 345 /* Determine proper divider value */
@@ -320,12 +366,19 @@ int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
320 return div ? (int)div->fdr : -EINVAL; 366 return div ? (int)div->fdr : -EINVAL;
321} 367}
322 368
323static void mpc_i2c_setclock_8xxx(struct device_node *node, 369static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
324 struct mpc_i2c *i2c, 370 struct mpc_i2c *i2c,
325 u32 clock, u32 prescaler) 371 u32 clock, u32 prescaler)
326{ 372{
327 int ret, fdr; 373 int ret, fdr;
328 374
375 if (clock == MPC_I2C_CLOCK_PRESERVE) {
376 dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n",
377 readb(i2c->base + MPC_I2C_DFSRR),
378 readb(i2c->base + MPC_I2C_FDR));
379 return;
380 }
381
329 ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); 382 ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
330 fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ 383 fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
331 384
@@ -338,9 +391,9 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node,
338} 391}
339 392
340#else /* !CONFIG_FSL_SOC */ 393#else /* !CONFIG_FSL_SOC */
341static void mpc_i2c_setclock_8xxx(struct device_node *node, 394static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
342 struct mpc_i2c *i2c, 395 struct mpc_i2c *i2c,
343 u32 clock, u32 prescaler) 396 u32 clock, u32 prescaler)
344{ 397{
345} 398}
346#endif /* CONFIG_FSL_SOC */ 399#endif /* CONFIG_FSL_SOC */
@@ -494,7 +547,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
494{ 547{
495 struct mpc_i2c *i2c; 548 struct mpc_i2c *i2c;
496 const u32 *prop; 549 const u32 *prop;
497 u32 clock = 0; 550 u32 clock = MPC_I2C_CLOCK_LEGACY;
498 int result = 0; 551 int result = 0;
499 int plen; 552 int plen;
500 553
@@ -523,21 +576,21 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
523 } 576 }
524 } 577 }
525 578
526 if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) { 579 if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
580 clock = MPC_I2C_CLOCK_PRESERVE;
581 } else {
527 prop = of_get_property(op->node, "clock-frequency", &plen); 582 prop = of_get_property(op->node, "clock-frequency", &plen);
528 if (prop && plen == sizeof(u32)) 583 if (prop && plen == sizeof(u32))
529 clock = *prop; 584 clock = *prop;
585 }
530 586
531 if (match->data) { 587 if (match->data) {
532 struct mpc_i2c_match_data *data = 588 struct mpc_i2c_data *data = match->data;
533 (struct mpc_i2c_match_data *)match->data; 589 data->setup(op->node, i2c, clock, data->prescaler);
534 data->setclock(op->node, i2c, clock, data->prescaler); 590 } else {
535 } else { 591 /* Backwards compatibility */
536 /* Backwards compatibility */ 592 if (of_get_property(op->node, "dfsrr", NULL))
537 if (of_get_property(op->node, "dfsrr", NULL)) 593 mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
538 mpc_i2c_setclock_8xxx(op->node, i2c,
539 clock, 0);
540 }
541 } 594 }
542 595
543 dev_set_drvdata(&op->dev, i2c); 596 dev_set_drvdata(&op->dev, i2c);
@@ -582,47 +635,42 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
582 return 0; 635 return 0;
583}; 636};
584 637
638static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = {
639 .setup = mpc_i2c_setup_512x,
640};
641
642static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
643 .setup = mpc_i2c_setup_52xx,
644};
645
646static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = {
647 .setup = mpc_i2c_setup_8xxx,
648};
649
650static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = {
651 .setup = mpc_i2c_setup_8xxx,
652 .prescaler = 2,
653};
654
655static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = {
656 .setup = mpc_i2c_setup_8xxx,
657 .prescaler = 3,
658};
659
585static const struct of_device_id mpc_i2c_of_match[] = { 660static const struct of_device_id mpc_i2c_of_match[] = {
586 {.compatible = "mpc5200-i2c", 661 {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
587 .data = &(struct mpc_i2c_match_data) { 662 {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
588 .setclock = mpc_i2c_setclock_52xx, 663 {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
589 }, 664 {.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
590 }, 665 {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
591 {.compatible = "fsl,mpc5200b-i2c", 666 {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
592 .data = &(struct mpc_i2c_match_data) { 667 {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
593 .setclock = mpc_i2c_setclock_52xx,
594 },
595 },
596 {.compatible = "fsl,mpc5200-i2c",
597 .data = &(struct mpc_i2c_match_data) {
598 .setclock = mpc_i2c_setclock_52xx,
599 },
600 },
601 {.compatible = "fsl,mpc8313-i2c",
602 .data = &(struct mpc_i2c_match_data) {
603 .setclock = mpc_i2c_setclock_8xxx,
604 },
605 },
606 {.compatible = "fsl,mpc8543-i2c",
607 .data = &(struct mpc_i2c_match_data) {
608 .setclock = mpc_i2c_setclock_8xxx,
609 .prescaler = 2,
610 },
611 },
612 {.compatible = "fsl,mpc8544-i2c",
613 .data = &(struct mpc_i2c_match_data) {
614 .setclock = mpc_i2c_setclock_8xxx,
615 .prescaler = 3,
616 },
617 /* Backward compatibility */ 668 /* Backward compatibility */
618 },
619 {.compatible = "fsl-i2c", }, 669 {.compatible = "fsl-i2c", },
620 {}, 670 {},
621}; 671};
622
623MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); 672MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
624 673
625
626/* Structure for a device driver */ 674/* Structure for a device driver */
627static struct of_platform_driver mpc_i2c_driver = { 675static struct of_platform_driver mpc_i2c_driver = {
628 .match_table = mpc_i2c_of_match, 676 .match_table = mpc_i2c_of_match,
@@ -655,5 +703,5 @@ module_exit(fsl_i2c_exit);
655 703
656MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); 704MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
657MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and " 705MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
658 "MPC824x/85xx/52xx processors"); 706 "MPC824x/83xx/85xx/86xx/512x/52xx processors");
659MODULE_LICENSE("GPL"); 707MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
new file mode 100644
index 000000000000..a15f731fa451
--- /dev/null
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -0,0 +1,959 @@
1/*
2 * Copyright (C) 2009 ST-Ericsson
3 * Copyright (C) 2009 STMicroelectronics
4 *
5 * I2C master mode controller driver, used in Nomadik 8815
6 * and Ux500 platforms.
7 *
8 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
9 * Author: Sachin Verma <sachin.verma@st.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2, as
13 * published by the Free Software Foundation.
14 */
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/delay.h>
19#include <linux/interrupt.h>
20#include <linux/i2c.h>
21#include <linux/err.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24
25#include <plat/i2c.h>
26
27#define DRIVER_NAME "nmk-i2c"
28
29/* I2C Controller register offsets */
30#define I2C_CR (0x000)
31#define I2C_SCR (0x004)
32#define I2C_HSMCR (0x008)
33#define I2C_MCR (0x00C)
34#define I2C_TFR (0x010)
35#define I2C_SR (0x014)
36#define I2C_RFR (0x018)
37#define I2C_TFTR (0x01C)
38#define I2C_RFTR (0x020)
39#define I2C_DMAR (0x024)
40#define I2C_BRCR (0x028)
41#define I2C_IMSCR (0x02C)
42#define I2C_RISR (0x030)
43#define I2C_MISR (0x034)
44#define I2C_ICR (0x038)
45
46/* Control registers */
47#define I2C_CR_PE (0x1 << 0) /* Peripheral Enable */
48#define I2C_CR_OM (0x3 << 1) /* Operating mode */
49#define I2C_CR_SAM (0x1 << 3) /* Slave addressing mode */
50#define I2C_CR_SM (0x3 << 4) /* Speed mode */
51#define I2C_CR_SGCM (0x1 << 6) /* Slave general call mode */
52#define I2C_CR_FTX (0x1 << 7) /* Flush Transmit */
53#define I2C_CR_FRX (0x1 << 8) /* Flush Receive */
54#define I2C_CR_DMA_TX_EN (0x1 << 9) /* DMA Tx enable */
55#define I2C_CR_DMA_RX_EN (0x1 << 10) /* DMA Rx Enable */
56#define I2C_CR_DMA_SLE (0x1 << 11) /* DMA sync. logic enable */
57#define I2C_CR_LM (0x1 << 12) /* Loopback mode */
58#define I2C_CR_FON (0x3 << 13) /* Filtering on */
59#define I2C_CR_FS (0x3 << 15) /* Force stop enable */
60
61/* Master controller (MCR) register */
62#define I2C_MCR_OP (0x1 << 0) /* Operation */
63#define I2C_MCR_A7 (0x7f << 1) /* 7-bit address */
64#define I2C_MCR_EA10 (0x7 << 8) /* 10-bit Extended address */
65#define I2C_MCR_SB (0x1 << 11) /* Extended address */
66#define I2C_MCR_AM (0x3 << 12) /* Address type */
67#define I2C_MCR_STOP (0x1 << 14) /* Stop condition */
68#define I2C_MCR_LENGTH (0x7ff << 15) /* Transaction length */
69
70/* Status register (SR) */
71#define I2C_SR_OP (0x3 << 0) /* Operation */
72#define I2C_SR_STATUS (0x3 << 2) /* controller status */
73#define I2C_SR_CAUSE (0x7 << 4) /* Abort cause */
74#define I2C_SR_TYPE (0x3 << 7) /* Receive type */
75#define I2C_SR_LENGTH (0x7ff << 9) /* Transfer length */
76
77/* Interrupt mask set/clear (IMSCR) bits */
78#define I2C_IT_TXFE (0x1 << 0)
79#define I2C_IT_TXFNE (0x1 << 1)
80#define I2C_IT_TXFF (0x1 << 2)
81#define I2C_IT_TXFOVR (0x1 << 3)
82#define I2C_IT_RXFE (0x1 << 4)
83#define I2C_IT_RXFNF (0x1 << 5)
84#define I2C_IT_RXFF (0x1 << 6)
85#define I2C_IT_RFSR (0x1 << 16)
86#define I2C_IT_RFSE (0x1 << 17)
87#define I2C_IT_WTSR (0x1 << 18)
88#define I2C_IT_MTD (0x1 << 19)
89#define I2C_IT_STD (0x1 << 20)
90#define I2C_IT_MAL (0x1 << 24)
91#define I2C_IT_BERR (0x1 << 25)
92#define I2C_IT_MTDWS (0x1 << 28)
93
94#define GEN_MASK(val, mask, sb) (((val) << (sb)) & (mask))
95
96/* some bits in ICR are reserved */
97#define I2C_CLEAR_ALL_INTS 0x131f007f
98
99/* first three msb bits are reserved */
100#define IRQ_MASK(mask) (mask & 0x1fffffff)
101
102/* maximum threshold value */
103#define MAX_I2C_FIFO_THRESHOLD 15
104
105enum i2c_status {
106 I2C_NOP,
107 I2C_ON_GOING,
108 I2C_OK,
109 I2C_ABORT
110};
111
112/* operation */
113enum i2c_operation {
114 I2C_NO_OPERATION = 0xff,
115 I2C_WRITE = 0x00,
116 I2C_READ = 0x01
117};
118
119/* controller response timeout in ms */
120#define I2C_TIMEOUT_MS 500
121
122/**
123 * struct i2c_nmk_client - client specific data
124 * @slave_adr: 7-bit slave address
125 * @count: no. bytes to be transfered
126 * @buffer: client data buffer
127 * @xfer_bytes: bytes transfered till now
128 * @operation: current I2C operation
129 */
130struct i2c_nmk_client {
131 unsigned short slave_adr;
132 unsigned long count;
133 unsigned char *buffer;
134 unsigned long xfer_bytes;
135 enum i2c_operation operation;
136};
137
138/**
139 * struct nmk_i2c_dev - private data structure of the controller
140 * @pdev: parent platform device
141 * @adap: corresponding I2C adapter
142 * @irq: interrupt line for the controller
143 * @virtbase: virtual io memory area
144 * @clk: hardware i2c block clock
145 * @cfg: machine provided controller configuration
146 * @cli: holder of client specific data
147 * @stop: stop condition
148 * @xfer_complete: acknowledge completion for a I2C message
149 * @result: controller propogated result
150 */
151struct nmk_i2c_dev {
152 struct platform_device *pdev;
153 struct i2c_adapter adap;
154 int irq;
155 void __iomem *virtbase;
156 struct clk *clk;
157 struct nmk_i2c_controller cfg;
158 struct i2c_nmk_client cli;
159 int stop;
160 struct completion xfer_complete;
161 int result;
162};
163
164/* controller's abort causes */
165static const char *abort_causes[] = {
166 "no ack received after address transmission",
167 "no ack received during data phase",
168 "ack received after xmission of master code",
169 "master lost arbitration",
170 "slave restarts",
171 "slave reset",
172 "overflow, maxsize is 2047 bytes",
173};
174
175static inline void i2c_set_bit(void __iomem *reg, u32 mask)
176{
177 writel(readl(reg) | mask, reg);
178}
179
180static inline void i2c_clr_bit(void __iomem *reg, u32 mask)
181{
182 writel(readl(reg) & ~mask, reg);
183}
184
185/**
186 * flush_i2c_fifo() - This function flushes the I2C FIFO
187 * @dev: private data of I2C Driver
188 *
189 * This function flushes the I2C Tx and Rx FIFOs. It returns
190 * 0 on successful flushing of FIFO
191 */
192static int flush_i2c_fifo(struct nmk_i2c_dev *dev)
193{
194#define LOOP_ATTEMPTS 10
195 int i;
196 unsigned long timeout;
197
198 /*
199 * flush the transmit and receive FIFO. The flushing
200 * operation takes several cycles before to be completed.
201 * On the completion, the I2C internal logic clears these
202 * bits, until then no one must access Tx, Rx FIFO and
203 * should poll on these bits waiting for the completion.
204 */
205 writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR);
206
207 for (i = 0; i < LOOP_ATTEMPTS; i++) {
208 timeout = jiffies + msecs_to_jiffies(I2C_TIMEOUT_MS);
209
210 while (!time_after(jiffies, timeout)) {
211 if ((readl(dev->virtbase + I2C_CR) &
212 (I2C_CR_FTX | I2C_CR_FRX)) == 0)
213 return 0;
214 }
215 }
216
217 dev_err(&dev->pdev->dev, "flushing operation timed out "
218 "giving up after %d attempts", LOOP_ATTEMPTS);
219
220 return -ETIMEDOUT;
221}
222
223/**
224 * disable_all_interrupts() - Disable all interrupts of this I2c Bus
225 * @dev: private data of I2C Driver
226 */
227static void disable_all_interrupts(struct nmk_i2c_dev *dev)
228{
229 u32 mask = IRQ_MASK(0);
230 writel(mask, dev->virtbase + I2C_IMSCR);
231}
232
233/**
234 * clear_all_interrupts() - Clear all interrupts of I2C Controller
235 * @dev: private data of I2C Driver
236 */
237static void clear_all_interrupts(struct nmk_i2c_dev *dev)
238{
239 u32 mask;
240 mask = IRQ_MASK(I2C_CLEAR_ALL_INTS);
241 writel(mask, dev->virtbase + I2C_ICR);
242}
243
244/**
245 * init_hw() - initialize the I2C hardware
246 * @dev: private data of I2C Driver
247 */
248static int init_hw(struct nmk_i2c_dev *dev)
249{
250 int stat;
251
252 stat = flush_i2c_fifo(dev);
253 if (stat)
254 return stat;
255
256 /* disable the controller */
257 i2c_clr_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
258
259 disable_all_interrupts(dev);
260
261 clear_all_interrupts(dev);
262
263 dev->cli.operation = I2C_NO_OPERATION;
264
265 return 0;
266}
267
268/* enable peripheral, master mode operation */
269#define DEFAULT_I2C_REG_CR ((1 << 1) | I2C_CR_PE)
270
271/**
272 * load_i2c_mcr_reg() - load the MCR register
273 * @dev: private data of controller
274 */
275static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev)
276{
277 u32 mcr = 0;
278
279 /* 7-bit address transaction */
280 mcr |= GEN_MASK(1, I2C_MCR_AM, 12);
281 mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1);
282
283 /* start byte procedure not applied */
284 mcr |= GEN_MASK(0, I2C_MCR_SB, 11);
285
286 /* check the operation, master read/write? */
287 if (dev->cli.operation == I2C_WRITE)
288 mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0);
289 else
290 mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0);
291
292 /* stop or repeated start? */
293 if (dev->stop)
294 mcr |= GEN_MASK(1, I2C_MCR_STOP, 14);
295 else
296 mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14));
297
298 mcr |= GEN_MASK(dev->cli.count, I2C_MCR_LENGTH, 15);
299
300 return mcr;
301}
302
303/**
304 * setup_i2c_controller() - setup the controller
305 * @dev: private data of controller
306 */
307static void setup_i2c_controller(struct nmk_i2c_dev *dev)
308{
309 u32 brcr1, brcr2;
310 u32 i2c_clk, div;
311
312 writel(0x0, dev->virtbase + I2C_CR);
313 writel(0x0, dev->virtbase + I2C_HSMCR);
314 writel(0x0, dev->virtbase + I2C_TFTR);
315 writel(0x0, dev->virtbase + I2C_RFTR);
316 writel(0x0, dev->virtbase + I2C_DMAR);
317
318 /*
319 * set the slsu:
320 *
321 * slsu defines the data setup time after SCL clock
322 * stretching in terms of i2c clk cycles. The
323 * needed setup time for the three modes are 250ns,
324 * 100ns, 10ns repectively thus leading to the values
325 * of 14, 6, 2 for a 48 MHz i2c clk.
326 */
327 writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR);
328
329 i2c_clk = clk_get_rate(dev->clk);
330
331 /* fallback to std. mode if machine has not provided it */
332 if (dev->cfg.clk_freq == 0)
333 dev->cfg.clk_freq = 100000;
334
335 /*
336 * The spec says, in case of std. mode the divider is
337 * 2 whereas it is 3 for fast and fastplus mode of
338 * operation. TODO - high speed support.
339 */
340 div = (dev->cfg.clk_freq > 100000) ? 3 : 2;
341
342 /*
343 * generate the mask for baud rate counters. The controller
344 * has two baud rate counters. One is used for High speed
345 * operation, and the other is for std, fast mode, fast mode
346 * plus operation. Currently we do not supprt high speed mode
347 * so set brcr1 to 0.
348 */
349 brcr1 = 0 << 16;
350 brcr2 = (i2c_clk/(dev->cfg.clk_freq * div)) & 0xffff;
351
352 /* set the baud rate counter register */
353 writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
354
355 /*
356 * set the speed mode. Currently we support
357 * only standard and fast mode of operation
358 * TODO - support for fast mode plus (upto 1Mb/s)
359 * and high speed (up to 3.4 Mb/s)
360 */
361 if (dev->cfg.sm > I2C_FREQ_MODE_FAST) {
362 dev_err(&dev->pdev->dev, "do not support this mode "
363 "defaulting to std. mode\n");
364 brcr2 = i2c_clk/(100000 * 2) & 0xffff;
365 writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
366 writel(I2C_FREQ_MODE_STANDARD << 4,
367 dev->virtbase + I2C_CR);
368 }
369 writel(dev->cfg.sm << 4, dev->virtbase + I2C_CR);
370
371 /* set the Tx and Rx FIFO threshold */
372 writel(dev->cfg.tft, dev->virtbase + I2C_TFTR);
373 writel(dev->cfg.rft, dev->virtbase + I2C_RFTR);
374}
375
376/**
377 * read_i2c() - Read from I2C client device
378 * @dev: private data of I2C Driver
379 *
380 * This function reads from i2c client device when controller is in
381 * master mode. There is a completion timeout. If there is no transfer
382 * before timeout error is returned.
383 */
384static int read_i2c(struct nmk_i2c_dev *dev)
385{
386 u32 status = 0;
387 u32 mcr;
388 u32 irq_mask = 0;
389 int timeout;
390
391 mcr = load_i2c_mcr_reg(dev);
392 writel(mcr, dev->virtbase + I2C_MCR);
393
394 /* load the current CR value */
395 writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
396 dev->virtbase + I2C_CR);
397
398 /* enable the controller */
399 i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
400
401 init_completion(&dev->xfer_complete);
402
403 /* enable interrupts by setting the mask */
404 irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
405 I2C_IT_MAL | I2C_IT_BERR);
406
407 if (dev->stop)
408 irq_mask |= I2C_IT_MTD;
409 else
410 irq_mask |= I2C_IT_MTDWS;
411
412 irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
413
414 writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
415 dev->virtbase + I2C_IMSCR);
416
417 timeout = wait_for_completion_interruptible_timeout(
418 &dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
419
420 if (timeout < 0) {
421 dev_err(&dev->pdev->dev,
422 "wait_for_completion_interruptible_timeout"
423 "returned %d waiting for event\n", timeout);
424 status = timeout;
425 }
426
427 if (timeout == 0) {
428 /* controler has timedout, re-init the h/w */
429 dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
430 (void) init_hw(dev);
431 status = -ETIMEDOUT;
432 }
433
434 return status;
435}
436
437/**
438 * write_i2c() - Write data to I2C client.
439 * @dev: private data of I2C Driver
440 *
441 * This function writes data to I2C client
442 */
443static int write_i2c(struct nmk_i2c_dev *dev)
444{
445 u32 status = 0;
446 u32 mcr;
447 u32 irq_mask = 0;
448 int timeout;
449
450 mcr = load_i2c_mcr_reg(dev);
451
452 writel(mcr, dev->virtbase + I2C_MCR);
453
454 /* load the current CR value */
455 writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR,
456 dev->virtbase + I2C_CR);
457
458 /* enable the controller */
459 i2c_set_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
460
461 init_completion(&dev->xfer_complete);
462
463 /* enable interrupts by settings the masks */
464 irq_mask = (I2C_IT_TXFNE | I2C_IT_TXFOVR |
465 I2C_IT_MAL | I2C_IT_BERR);
466
467 /*
468 * check if we want to transfer a single or multiple bytes, if so
469 * set the MTDWS bit (Master Transaction Done Without Stop)
470 * to start repeated start operation
471 */
472 if (dev->stop)
473 irq_mask |= I2C_IT_MTD;
474 else
475 irq_mask |= I2C_IT_MTDWS;
476
477 irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask);
478
479 writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask,
480 dev->virtbase + I2C_IMSCR);
481
482 timeout = wait_for_completion_interruptible_timeout(
483 &dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
484
485 if (timeout < 0) {
486 dev_err(&dev->pdev->dev,
487 "wait_for_completion_interruptible_timeout"
488 "returned %d waiting for event\n", timeout);
489 status = timeout;
490 }
491
492 if (timeout == 0) {
493 /* controler has timedout, re-init the h/w */
494 dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
495 (void) init_hw(dev);
496 status = -ETIMEDOUT;
497 }
498
499 return status;
500}
501
502/**
503 * nmk_i2c_xfer() - I2C transfer function used by kernel framework
504 * @i2c_adap - Adapter pointer to the controller
505 * @msgs[] - Pointer to data to be written.
506 * @num_msgs - Number of messages to be executed
507 *
508 * This is the function called by the generic kernel i2c_transfer()
509 * or i2c_smbus...() API calls. Note that this code is protected by the
510 * semaphore set in the kernel i2c_transfer() function.
511 *
512 * NOTE:
513 * READ TRANSFER : We impose a restriction of the first message to be the
514 * index message for any read transaction.
515 * - a no index is coded as '0',
516 * - 2byte big endian index is coded as '3'
517 * !!! msg[0].buf holds the actual index.
518 * This is compatible with generic messages of smbus emulator
519 * that send a one byte index.
520 * eg. a I2C transation to read 2 bytes from index 0
521 * idx = 0;
522 * msg[0].addr = client->addr;
523 * msg[0].flags = 0x0;
524 * msg[0].len = 1;
525 * msg[0].buf = &idx;
526 *
527 * msg[1].addr = client->addr;
528 * msg[1].flags = I2C_M_RD;
529 * msg[1].len = 2;
530 * msg[1].buf = rd_buff
531 * i2c_transfer(adap, msg, 2);
532 *
533 * WRITE TRANSFER : The I2C standard interface interprets all data as payload.
534 * If you want to emulate an SMBUS write transaction put the
535 * index as first byte(or first and second) in the payload.
536 * eg. a I2C transation to write 2 bytes from index 1
537 * wr_buff[0] = 0x1;
538 * wr_buff[1] = 0x23;
539 * wr_buff[2] = 0x46;
540 * msg[0].flags = 0x0;
541 * msg[0].len = 3;
542 * msg[0].buf = wr_buff;
543 * i2c_transfer(adap, msg, 1);
544 *
545 * To read or write a block of data (multiple bytes) using SMBUS emulation
546 * please use the i2c_smbus_read_i2c_block_data()
547 * or i2c_smbus_write_i2c_block_data() API
548 */
549static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
550 struct i2c_msg msgs[], int num_msgs)
551{
552 int status;
553 int i;
554 u32 cause;
555 struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
556
557 status = init_hw(dev);
558 if (status)
559 return status;
560
561 /* setup the i2c controller */
562 setup_i2c_controller(dev);
563
564 for (i = 0; i < num_msgs; i++) {
565 if (unlikely(msgs[i].flags & I2C_M_TEN)) {
566 dev_err(&dev->pdev->dev, "10 bit addressing"
567 "not supported\n");
568 return -EINVAL;
569 }
570 dev->cli.slave_adr = msgs[i].addr;
571 dev->cli.buffer = msgs[i].buf;
572 dev->cli.count = msgs[i].len;
573 dev->stop = (i < (num_msgs - 1)) ? 0 : 1;
574 dev->result = 0;
575
576 if (msgs[i].flags & I2C_M_RD) {
577 /* it is a read operation */
578 dev->cli.operation = I2C_READ;
579 status = read_i2c(dev);
580 } else {
581 /* write operation */
582 dev->cli.operation = I2C_WRITE;
583 status = write_i2c(dev);
584 }
585 if (status || (dev->result)) {
586 /* get the abort cause */
587 cause = (readl(dev->virtbase + I2C_SR) >> 4) & 0x7;
588 dev_err(&dev->pdev->dev, "error during I2C"
589 "message xfer: %d\n", cause);
590 dev_err(&dev->pdev->dev, "%s\n",
591 cause >= ARRAY_SIZE(abort_causes)
592 ? "unknown reason" : abort_causes[cause]);
593 return status;
594 }
595 mdelay(1);
596 }
597 /* return the no. messages processed */
598 if (status)
599 return status;
600 else
601 return num_msgs;
602}
603
604/**
605 * disable_interrupts() - disable the interrupts
606 * @dev: private data of controller
607 */
608static int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq)
609{
610 irq = IRQ_MASK(irq);
611 writel(readl(dev->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq),
612 dev->virtbase + I2C_IMSCR);
613 return 0;
614}
615
616/**
617 * i2c_irq_handler() - interrupt routine
618 * @irq: interrupt number
619 * @arg: data passed to the handler
620 *
621 * This is the interrupt handler for the i2c driver. Currently
622 * it handles the major interrupts like Rx & Tx FIFO management
623 * interrupts, master transaction interrupts, arbitration and
624 * bus error interrupts. The rest of the interrupts are treated as
625 * unhandled.
626 */
627static irqreturn_t i2c_irq_handler(int irq, void *arg)
628{
629 struct nmk_i2c_dev *dev = arg;
630 u32 tft, rft;
631 u32 count;
632 u32 misr;
633 u32 src = 0;
634
635 /* load Tx FIFO and Rx FIFO threshold values */
636 tft = readl(dev->virtbase + I2C_TFTR);
637 rft = readl(dev->virtbase + I2C_RFTR);
638
639 /* read interrupt status register */
640 misr = readl(dev->virtbase + I2C_MISR);
641
642 src = __ffs(misr);
643 switch ((1 << src)) {
644
645 /* Transmit FIFO nearly empty interrupt */
646 case I2C_IT_TXFNE:
647 {
648 if (dev->cli.operation == I2C_READ) {
649 /*
650 * in read operation why do we care for writing?
651 * so disable the Transmit FIFO interrupt
652 */
653 disable_interrupts(dev, I2C_IT_TXFNE);
654 } else {
655 for (count = (MAX_I2C_FIFO_THRESHOLD - tft - 2);
656 (count > 0) &&
657 (dev->cli.count != 0);
658 count--) {
659 /* write to the Tx FIFO */
660 writeb(*dev->cli.buffer,
661 dev->virtbase + I2C_TFR);
662 dev->cli.buffer++;
663 dev->cli.count--;
664 dev->cli.xfer_bytes++;
665 }
666 /*
667 * if done, close the transfer by disabling the
668 * corresponding TXFNE interrupt
669 */
670 if (dev->cli.count == 0)
671 disable_interrupts(dev, I2C_IT_TXFNE);
672 }
673 }
674 break;
675
676 /*
677 * Rx FIFO nearly full interrupt.
678 * This is set when the numer of entries in Rx FIFO is
679 * greater or equal than the threshold value programmed
680 * in RFT
681 */
682 case I2C_IT_RXFNF:
683 for (count = rft; count > 0; count--) {
684 /* Read the Rx FIFO */
685 *dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
686 dev->cli.buffer++;
687 }
688 dev->cli.count -= rft;
689 dev->cli.xfer_bytes += rft;
690 break;
691
692 /* Rx FIFO full */
693 case I2C_IT_RXFF:
694 for (count = MAX_I2C_FIFO_THRESHOLD; count > 0; count--) {
695 *dev->cli.buffer = readb(dev->virtbase + I2C_RFR);
696 dev->cli.buffer++;
697 }
698 dev->cli.count -= MAX_I2C_FIFO_THRESHOLD;
699 dev->cli.xfer_bytes += MAX_I2C_FIFO_THRESHOLD;
700 break;
701
702 /* Master Transaction Done with/without stop */
703 case I2C_IT_MTD:
704 case I2C_IT_MTDWS:
705 if (dev->cli.operation == I2C_READ) {
706 while (!readl(dev->virtbase + I2C_RISR) & I2C_IT_RXFE) {
707 if (dev->cli.count == 0)
708 break;
709 *dev->cli.buffer =
710 readb(dev->virtbase + I2C_RFR);
711 dev->cli.buffer++;
712 dev->cli.count--;
713 dev->cli.xfer_bytes++;
714 }
715 }
716
717 i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTD);
718 i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MTDWS);
719
720 disable_interrupts(dev,
721 (I2C_IT_TXFNE | I2C_IT_TXFE | I2C_IT_TXFF
722 | I2C_IT_TXFOVR | I2C_IT_RXFNF
723 | I2C_IT_RXFF | I2C_IT_RXFE));
724
725 if (dev->cli.count) {
726 dev->result = -1;
727 dev_err(&dev->pdev->dev, "%lu bytes still remain to be"
728 "xfered\n", dev->cli.count);
729 (void) init_hw(dev);
730 }
731 complete(&dev->xfer_complete);
732
733 break;
734
735 /* Master Arbitration lost interrupt */
736 case I2C_IT_MAL:
737 dev->result = -1;
738 (void) init_hw(dev);
739
740 i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL);
741 complete(&dev->xfer_complete);
742
743 break;
744
745 /*
746 * Bus Error interrupt.
747 * This happens when an unexpected start/stop condition occurs
748 * during the transaction.
749 */
750 case I2C_IT_BERR:
751 dev->result = -1;
752 /* get the status */
753 if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
754 (void) init_hw(dev);
755
756 i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_BERR);
757 complete(&dev->xfer_complete);
758
759 break;
760
761 /*
762 * Tx FIFO overrun interrupt.
763 * This is set when a write operation in Tx FIFO is performed and
764 * the Tx FIFO is full.
765 */
766 case I2C_IT_TXFOVR:
767 dev->result = -1;
768 (void) init_hw(dev);
769
770 dev_err(&dev->pdev->dev, "Tx Fifo Over run\n");
771 complete(&dev->xfer_complete);
772
773 break;
774
775 /* unhandled interrupts by this driver - TODO*/
776 case I2C_IT_TXFE:
777 case I2C_IT_TXFF:
778 case I2C_IT_RXFE:
779 case I2C_IT_RFSR:
780 case I2C_IT_RFSE:
781 case I2C_IT_WTSR:
782 case I2C_IT_STD:
783 dev_err(&dev->pdev->dev, "unhandled Interrupt\n");
784 break;
785 default:
786 dev_err(&dev->pdev->dev, "spurious Interrupt..\n");
787 break;
788 }
789
790 return IRQ_HANDLED;
791}
792
793static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
794{
795 return I2C_FUNC_I2C
796 | I2C_FUNC_SMBUS_BYTE_DATA
797 | I2C_FUNC_SMBUS_WORD_DATA
798 | I2C_FUNC_SMBUS_I2C_BLOCK;
799}
800
801static const struct i2c_algorithm nmk_i2c_algo = {
802 .master_xfer = nmk_i2c_xfer,
803 .functionality = nmk_i2c_functionality
804};
805
806static int __devinit nmk_i2c_probe(struct platform_device *pdev)
807{
808 int ret = 0;
809 struct resource *res;
810 struct nmk_i2c_controller *pdata =
811 pdev->dev.platform_data;
812 struct nmk_i2c_dev *dev;
813 struct i2c_adapter *adap;
814
815 dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
816 if (!dev) {
817 dev_err(&pdev->dev, "cannot allocate memory\n");
818 ret = -ENOMEM;
819 goto err_no_mem;
820 }
821
822 dev->pdev = pdev;
823 platform_set_drvdata(pdev, dev);
824
825 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
826 if (!res) {
827 ret = -ENOENT;
828 goto err_no_resource;
829 }
830
831 if (request_mem_region(res->start, resource_size(res),
832 DRIVER_NAME "I/O region") == NULL) {
833 ret = -EBUSY;
834 goto err_no_region;
835 }
836
837 dev->virtbase = ioremap(res->start, resource_size(res));
838 if (!dev->virtbase) {
839 ret = -ENOMEM;
840 goto err_no_ioremap;
841 }
842
843 dev->irq = platform_get_irq(pdev, 0);
844 ret = request_irq(dev->irq, i2c_irq_handler, IRQF_DISABLED,
845 DRIVER_NAME, dev);
846 if (ret) {
847 dev_err(&pdev->dev, "cannot claim the irq %d\n", dev->irq);
848 goto err_irq;
849 }
850
851 dev->clk = clk_get(&pdev->dev, NULL);
852 if (IS_ERR(dev->clk)) {
853 dev_err(&pdev->dev, "could not get i2c clock\n");
854 ret = PTR_ERR(dev->clk);
855 goto err_no_clk;
856 }
857
858 clk_enable(dev->clk);
859
860 adap = &dev->adap;
861 adap->dev.parent = &pdev->dev;
862 adap->owner = THIS_MODULE;
863 adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
864 adap->algo = &nmk_i2c_algo;
865
866 /* fetch the controller id */
867 adap->nr = pdev->id;
868
869 /* fetch the controller configuration from machine */
870 dev->cfg.clk_freq = pdata->clk_freq;
871 dev->cfg.slsu = pdata->slsu;
872 dev->cfg.tft = pdata->tft;
873 dev->cfg.rft = pdata->rft;
874 dev->cfg.sm = pdata->sm;
875
876 i2c_set_adapdata(adap, dev);
877
878 ret = init_hw(dev);
879 if (ret != 0) {
880 dev_err(&pdev->dev, "error in initializing i2c hardware\n");
881 goto err_init_hw;
882 }
883
884 dev_dbg(&pdev->dev, "initialize I2C%d bus on virtual "
885 "base %p\n", pdev->id, dev->virtbase);
886
887 ret = i2c_add_numbered_adapter(adap);
888 if (ret) {
889 dev_err(&pdev->dev, "failed to add adapter\n");
890 goto err_add_adap;
891 }
892
893 return 0;
894
895 err_init_hw:
896 clk_disable(dev->clk);
897 err_add_adap:
898 clk_put(dev->clk);
899 err_no_clk:
900 free_irq(dev->irq, dev);
901 err_irq:
902 iounmap(dev->virtbase);
903 err_no_ioremap:
904 release_mem_region(res->start, resource_size(res));
905 err_no_region:
906 platform_set_drvdata(pdev, NULL);
907 err_no_resource:
908 kfree(dev);
909 err_no_mem:
910
911 return ret;
912}
913
914static int __devexit nmk_i2c_remove(struct platform_device *pdev)
915{
916 struct nmk_i2c_dev *dev = platform_get_drvdata(pdev);
917
918 i2c_del_adapter(&dev->adap);
919 flush_i2c_fifo(dev);
920 disable_all_interrupts(dev);
921 clear_all_interrupts(dev);
922 /* disable the controller */
923 i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
924 free_irq(dev->irq, dev);
925 iounmap(dev->virtbase);
926 clk_disable(dev->clk);
927 clk_put(dev->clk);
928 platform_set_drvdata(pdev, NULL);
929 kfree(dev);
930
931 return 0;
932}
933
934static struct platform_driver nmk_i2c_driver = {
935 .driver = {
936 .owner = THIS_MODULE,
937 .name = DRIVER_NAME,
938 },
939 .probe = nmk_i2c_probe,
940 .remove = __devexit_p(nmk_i2c_remove),
941};
942
943static int __init nmk_i2c_init(void)
944{
945 return platform_driver_register(&nmk_i2c_driver);
946}
947
948static void __exit nmk_i2c_exit(void)
949{
950 platform_driver_unregister(&nmk_i2c_driver);
951}
952
953subsys_initcall(nmk_i2c_init);
954module_exit(nmk_i2c_exit);
955
956MODULE_AUTHOR("Sachin Verma, Srinidhi KASAGAR");
957MODULE_DESCRIPTION("Nomadik/Ux500 I2C driver");
958MODULE_LICENSE("GPL");
959MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0037e31076ba..913abd7c172f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -49,24 +49,24 @@
49#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) 49#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
50 50
51#define OMAP_I2C_REV_REG 0x00 51#define OMAP_I2C_REV_REG 0x00
52#define OMAP_I2C_IE_REG 0x04 52#define OMAP_I2C_IE_REG 0x01
53#define OMAP_I2C_STAT_REG 0x08 53#define OMAP_I2C_STAT_REG 0x02
54#define OMAP_I2C_IV_REG 0x0c 54#define OMAP_I2C_IV_REG 0x03
55/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ 55/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
56#define OMAP_I2C_WE_REG 0x0c 56#define OMAP_I2C_WE_REG 0x03
57#define OMAP_I2C_SYSS_REG 0x10 57#define OMAP_I2C_SYSS_REG 0x04
58#define OMAP_I2C_BUF_REG 0x14 58#define OMAP_I2C_BUF_REG 0x05
59#define OMAP_I2C_CNT_REG 0x18 59#define OMAP_I2C_CNT_REG 0x06
60#define OMAP_I2C_DATA_REG 0x1c 60#define OMAP_I2C_DATA_REG 0x07
61#define OMAP_I2C_SYSC_REG 0x20 61#define OMAP_I2C_SYSC_REG 0x08
62#define OMAP_I2C_CON_REG 0x24 62#define OMAP_I2C_CON_REG 0x09
63#define OMAP_I2C_OA_REG 0x28 63#define OMAP_I2C_OA_REG 0x0a
64#define OMAP_I2C_SA_REG 0x2c 64#define OMAP_I2C_SA_REG 0x0b
65#define OMAP_I2C_PSC_REG 0x30 65#define OMAP_I2C_PSC_REG 0x0c
66#define OMAP_I2C_SCLL_REG 0x34 66#define OMAP_I2C_SCLL_REG 0x0d
67#define OMAP_I2C_SCLH_REG 0x38 67#define OMAP_I2C_SCLH_REG 0x0e
68#define OMAP_I2C_SYSTEST_REG 0x3c 68#define OMAP_I2C_SYSTEST_REG 0x0f
69#define OMAP_I2C_BUFSTAT_REG 0x40 69#define OMAP_I2C_BUFSTAT_REG 0x10
70 70
71/* I2C Interrupt Enable Register (OMAP_I2C_IE): */ 71/* I2C Interrupt Enable Register (OMAP_I2C_IE): */
72#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */ 72#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */
@@ -161,6 +161,7 @@ struct omap_i2c_dev {
161 struct device *dev; 161 struct device *dev;
162 void __iomem *base; /* virtual */ 162 void __iomem *base; /* virtual */
163 int irq; 163 int irq;
164 int reg_shift; /* bit shift for I2C register addresses */
164 struct clk *iclk; /* Interface clock */ 165 struct clk *iclk; /* Interface clock */
165 struct clk *fclk; /* Functional clock */ 166 struct clk *fclk; /* Functional clock */
166 struct completion cmd_complete; 167 struct completion cmd_complete;
@@ -189,12 +190,12 @@ struct omap_i2c_dev {
189static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev, 190static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
190 int reg, u16 val) 191 int reg, u16 val)
191{ 192{
192 __raw_writew(val, i2c_dev->base + reg); 193 __raw_writew(val, i2c_dev->base + (reg << i2c_dev->reg_shift));
193} 194}
194 195
195static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) 196static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
196{ 197{
197 return __raw_readw(i2c_dev->base + reg); 198 return __raw_readw(i2c_dev->base + (reg << i2c_dev->reg_shift));
198} 199}
199 200
200static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) 201static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
@@ -924,6 +925,11 @@ omap_i2c_probe(struct platform_device *pdev)
924 dev->b_hw = 1; /* Enable hardware fixes */ 925 dev->b_hw = 1; /* Enable hardware fixes */
925 } 926 }
926 927
928 if (cpu_is_omap7xx())
929 dev->reg_shift = 1;
930 else
931 dev->reg_shift = 2;
932
927 /* reset ASAP, clearing any IRQs */ 933 /* reset ASAP, clearing any IRQs */
928 omap_i2c_init(dev); 934 omap_i2c_init(dev);
929 935
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 2b0bd0b042d6..9532dee6b580 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -172,12 +172,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
172 /* We still have something to talk about... */ 172 /* We still have something to talk about... */
173 val = *alg_data->mif.buf++; 173 val = *alg_data->mif.buf++;
174 174
175 if (alg_data->mif.len == 1) {
176 val |= stop_bit;
177 if (!alg_data->last)
178 val |= start_bit;
179 }
180
181 alg_data->mif.len--; 175 alg_data->mif.len--;
182 iowrite32(val, I2C_REG_TX(alg_data)); 176 iowrite32(val, I2C_REG_TX(alg_data));
183 177
@@ -251,11 +245,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
251 __func__); 245 __func__);
252 246
253 if (alg_data->mif.len == 1) { 247 if (alg_data->mif.len == 1) {
254 /* Last byte, do not acknowledge next rcv. */
255 val |= stop_bit;
256 if (!alg_data->last)
257 val |= start_bit;
258
259 /* 248 /*
260 * Enable interrupt RFDAIE (data in Rx fifo), 249 * Enable interrupt RFDAIE (data in Rx fifo),
261 * and disable DRMIE (need data for Tx) 250 * and disable DRMIE (need data for Tx)
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
new file mode 100644
index 000000000000..eece39a5a30e
--- /dev/null
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -0,0 +1,824 @@
1/*
2 * i2c-xiic.c
3 * Copyright (c) 2002-2007 Xilinx Inc.
4 * Copyright (c) 2009-2010 Intel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *
20 * This code was implemented by Mocean Laboratories AB when porting linux
21 * to the automotive development board Russellville. The copyright holder
22 * as seen in the header is Intel corporation.
23 * Mocean Laboratories forked off the GNU/Linux platform work into a
24 * separate company called Pelagicore AB, which commited the code to the
25 * kernel.
26 */
27
28/* Supports:
29 * Xilinx IIC
30 */
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/init.h>
34#include <linux/errno.h>
35#include <linux/platform_device.h>
36#include <linux/i2c.h>
37#include <linux/interrupt.h>
38#include <linux/wait.h>
39#include <linux/i2c-xiic.h>
40#include <linux/io.h>
41
42#define DRIVER_NAME "xiic-i2c"
43
44enum xilinx_i2c_state {
45 STATE_DONE,
46 STATE_ERROR,
47 STATE_START
48};
49
50/**
51 * struct xiic_i2c - Internal representation of the XIIC I2C bus
52 * @base: Memory base of the HW registers
53 * @wait: Wait queue for callers
54 * @adap: Kernel adapter representation
55 * @tx_msg: Messages from above to be sent
56 * @lock: Mutual exclusion
57 * @tx_pos: Current pos in TX message
58 * @nmsgs: Number of messages in tx_msg
59 * @state: See STATE_
60 * @rx_msg: Current RX message
61 * @rx_pos: Position within current RX message
62 */
63struct xiic_i2c {
64 void __iomem *base;
65 wait_queue_head_t wait;
66 struct i2c_adapter adap;
67 struct i2c_msg *tx_msg;
68 spinlock_t lock;
69 unsigned int tx_pos;
70 unsigned int nmsgs;
71 enum xilinx_i2c_state state;
72 struct i2c_msg *rx_msg;
73 int rx_pos;
74};
75
76
77#define XIIC_MSB_OFFSET 0
78#define XIIC_REG_OFFSET (0x100+XIIC_MSB_OFFSET)
79
80/*
81 * Register offsets in bytes from RegisterBase. Three is added to the
82 * base offset to access LSB (IBM style) of the word
83 */
84#define XIIC_CR_REG_OFFSET (0x00+XIIC_REG_OFFSET) /* Control Register */
85#define XIIC_SR_REG_OFFSET (0x04+XIIC_REG_OFFSET) /* Status Register */
86#define XIIC_DTR_REG_OFFSET (0x08+XIIC_REG_OFFSET) /* Data Tx Register */
87#define XIIC_DRR_REG_OFFSET (0x0C+XIIC_REG_OFFSET) /* Data Rx Register */
88#define XIIC_ADR_REG_OFFSET (0x10+XIIC_REG_OFFSET) /* Address Register */
89#define XIIC_TFO_REG_OFFSET (0x14+XIIC_REG_OFFSET) /* Tx FIFO Occupancy */
90#define XIIC_RFO_REG_OFFSET (0x18+XIIC_REG_OFFSET) /* Rx FIFO Occupancy */
91#define XIIC_TBA_REG_OFFSET (0x1C+XIIC_REG_OFFSET) /* 10 Bit Address reg */
92#define XIIC_RFD_REG_OFFSET (0x20+XIIC_REG_OFFSET) /* Rx FIFO Depth reg */
93#define XIIC_GPO_REG_OFFSET (0x24+XIIC_REG_OFFSET) /* Output Register */
94
95/* Control Register masks */
96#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */
97#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */
98#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */
99#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */
100#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */
101#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */
102#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */
103
104/* Status Register masks */
105#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */
106#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */
107#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */
108#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */
109#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */
110#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */
111#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */
112#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x80 /* 1 = Tx FIFO empty */
113
114/* Interrupt Status Register masks Interrupt occurs when... */
115#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */
116#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete */
117#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */
118#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level */
119#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */
120#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */
121#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */
122#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */
123
124/* The following constants specify the depth of the FIFOs */
125#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */
126#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */
127
128/* The following constants specify groups of interrupts that are typically
129 * enabled or disables at the same time
130 */
131#define XIIC_TX_INTERRUPTS \
132(XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)
133
134#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)
135
136/* The following constants are used with the following macros to specify the
137 * operation, a read or write operation.
138 */
139#define XIIC_READ_OPERATION 1
140#define XIIC_WRITE_OPERATION 0
141
142/*
143 * Tx Fifo upper bit masks.
144 */
145#define XIIC_TX_DYN_START_MASK 0x0100 /* 1 = Set dynamic start */
146#define XIIC_TX_DYN_STOP_MASK 0x0200 /* 1 = Set dynamic stop */
147
148/*
149 * The following constants define the register offsets for the Interrupt
150 * registers. There are some holes in the memory map for reserved addresses
151 * to allow other registers to be added and still match the memory map of the
152 * interrupt controller registers
153 */
154#define XIIC_DGIER_OFFSET 0x1C /* Device Global Interrupt Enable Register */
155#define XIIC_IISR_OFFSET 0x20 /* Interrupt Status Register */
156#define XIIC_IIER_OFFSET 0x28 /* Interrupt Enable Register */
157#define XIIC_RESETR_OFFSET 0x40 /* Reset Register */
158
159#define XIIC_RESET_MASK 0xAUL
160
161/*
162 * The following constant is used for the device global interrupt enable
163 * register, to enable all interrupts for the device, this is the only bit
164 * in the register
165 */
166#define XIIC_GINTR_ENABLE_MASK 0x80000000UL
167
168#define xiic_tx_space(i2c) ((i2c)->tx_msg->len - (i2c)->tx_pos)
169#define xiic_rx_space(i2c) ((i2c)->rx_msg->len - (i2c)->rx_pos)
170
171static void xiic_start_xfer(struct xiic_i2c *i2c);
172static void __xiic_start_xfer(struct xiic_i2c *i2c);
173
174static inline void xiic_setreg8(struct xiic_i2c *i2c, int reg, u8 value)
175{
176 iowrite8(value, i2c->base + reg);
177}
178
179static inline u8 xiic_getreg8(struct xiic_i2c *i2c, int reg)
180{
181 return ioread8(i2c->base + reg);
182}
183
184static inline void xiic_setreg16(struct xiic_i2c *i2c, int reg, u16 value)
185{
186 iowrite16(value, i2c->base + reg);
187}
188
189static inline void xiic_setreg32(struct xiic_i2c *i2c, int reg, int value)
190{
191 iowrite32(value, i2c->base + reg);
192}
193
194static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg)
195{
196 return ioread32(i2c->base + reg);
197}
198
199static inline void xiic_irq_dis(struct xiic_i2c *i2c, u32 mask)
200{
201 u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
202 xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier & ~mask);
203}
204
205static inline void xiic_irq_en(struct xiic_i2c *i2c, u32 mask)
206{
207 u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
208 xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier | mask);
209}
210
211static inline void xiic_irq_clr(struct xiic_i2c *i2c, u32 mask)
212{
213 u32 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
214 xiic_setreg32(i2c, XIIC_IISR_OFFSET, isr & mask);
215}
216
217static inline void xiic_irq_clr_en(struct xiic_i2c *i2c, u32 mask)
218{
219 xiic_irq_clr(i2c, mask);
220 xiic_irq_en(i2c, mask);
221}
222
223static void xiic_clear_rx_fifo(struct xiic_i2c *i2c)
224{
225 u8 sr;
226 for (sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
227 !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK);
228 sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET))
229 xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
230}
231
232static void xiic_reinit(struct xiic_i2c *i2c)
233{
234 xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
235
236 /* Set receive Fifo depth to maximum (zero based). */
237 xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, IIC_RX_FIFO_DEPTH - 1);
238
239 /* Reset Tx Fifo. */
240 xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_TX_FIFO_RESET_MASK);
241
242 /* Enable IIC Device, remove Tx Fifo reset & disable general call. */
243 xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
244
245 /* make sure RX fifo is empty */
246 xiic_clear_rx_fifo(i2c);
247
248 /* Enable interrupts */
249 xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
250
251 xiic_irq_clr_en(i2c, XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
252}
253
254static void xiic_deinit(struct xiic_i2c *i2c)
255{
256 u8 cr;
257
258 xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
259
260 /* Disable IIC Device. */
261 cr = xiic_getreg8(i2c, XIIC_CR_REG_OFFSET);
262 xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, cr & ~XIIC_CR_ENABLE_DEVICE_MASK);
263}
264
265static void xiic_read_rx(struct xiic_i2c *i2c)
266{
267 u8 bytes_in_fifo;
268 int i;
269
270 bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
271
272 dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d"
273 ", SR: 0x%x, CR: 0x%x\n",
274 __func__, bytes_in_fifo, xiic_rx_space(i2c),
275 xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
276 xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
277
278 if (bytes_in_fifo > xiic_rx_space(i2c))
279 bytes_in_fifo = xiic_rx_space(i2c);
280
281 for (i = 0; i < bytes_in_fifo; i++)
282 i2c->rx_msg->buf[i2c->rx_pos++] =
283 xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
284
285 xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET,
286 (xiic_rx_space(i2c) > IIC_RX_FIFO_DEPTH) ?
287 IIC_RX_FIFO_DEPTH - 1 : xiic_rx_space(i2c) - 1);
288}
289
290static int xiic_tx_fifo_space(struct xiic_i2c *i2c)
291{
292 /* return the actual space left in the FIFO */
293 return IIC_TX_FIFO_DEPTH - xiic_getreg8(i2c, XIIC_TFO_REG_OFFSET) - 1;
294}
295
296static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)
297{
298 u8 fifo_space = xiic_tx_fifo_space(i2c);
299 int len = xiic_tx_space(i2c);
300
301 len = (len > fifo_space) ? fifo_space : len;
302
303 dev_dbg(i2c->adap.dev.parent, "%s entry, len: %d, fifo space: %d\n",
304 __func__, len, fifo_space);
305
306 while (len--) {
307 u16 data = i2c->tx_msg->buf[i2c->tx_pos++];
308 if ((xiic_tx_space(i2c) == 0) && (i2c->nmsgs == 1)) {
309 /* last message in transfer -> STOP */
310 data |= XIIC_TX_DYN_STOP_MASK;
311 dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__);
312
313 xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
314 } else
315 xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data);
316 }
317}
318
319static void xiic_wakeup(struct xiic_i2c *i2c, int code)
320{
321 i2c->tx_msg = NULL;
322 i2c->rx_msg = NULL;
323 i2c->nmsgs = 0;
324 i2c->state = code;
325 wake_up(&i2c->wait);
326}
327
328static void xiic_process(struct xiic_i2c *i2c)
329{
330 u32 pend, isr, ier;
331 u32 clr = 0;
332
333 /* Get the interrupt Status from the IPIF. There is no clearing of
334 * interrupts in the IPIF. Interrupts must be cleared at the source.
335 * To find which interrupts are pending; AND interrupts pending with
336 * interrupts masked.
337 */
338 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
339 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
340 pend = isr & ier;
341
342 dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, "
343 "pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n",
344 __func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
345 i2c->tx_msg, i2c->nmsgs);
346
347 /* Do not processes a devices interrupts if the device has no
348 * interrupts pending
349 */
350 if (!pend)
351 return;
352
353 /* Service requesting interrupt */
354 if ((pend & XIIC_INTR_ARB_LOST_MASK) ||
355 ((pend & XIIC_INTR_TX_ERROR_MASK) &&
356 !(pend & XIIC_INTR_RX_FULL_MASK))) {
357 /* bus arbritration lost, or...
358 * Transmit error _OR_ RX completed
359 * if this happens when RX_FULL is not set
360 * this is probably a TX error
361 */
362
363 dev_dbg(i2c->adap.dev.parent, "%s error\n", __func__);
364
365 /* dynamic mode seem to suffer from problems if we just flushes
366 * fifos and the next message is a TX with len 0 (only addr)
367 * reset the IP instead of just flush fifos
368 */
369 xiic_reinit(i2c);
370
371 if (i2c->tx_msg)
372 xiic_wakeup(i2c, STATE_ERROR);
373
374 } else if (pend & XIIC_INTR_RX_FULL_MASK) {
375 /* Receive register/FIFO is full */
376
377 clr = XIIC_INTR_RX_FULL_MASK;
378 if (!i2c->rx_msg) {
379 dev_dbg(i2c->adap.dev.parent,
380 "%s unexpexted RX IRQ\n", __func__);
381 xiic_clear_rx_fifo(i2c);
382 goto out;
383 }
384
385 xiic_read_rx(i2c);
386 if (xiic_rx_space(i2c) == 0) {
387 /* this is the last part of the message */
388 i2c->rx_msg = NULL;
389
390 /* also clear TX error if there (RX complete) */
391 clr |= (isr & XIIC_INTR_TX_ERROR_MASK);
392
393 dev_dbg(i2c->adap.dev.parent,
394 "%s end of message, nmsgs: %d\n",
395 __func__, i2c->nmsgs);
396
397 /* send next message if this wasn't the last,
398 * otherwise the transfer will be finialise when
399 * receiving the bus not busy interrupt
400 */
401 if (i2c->nmsgs > 1) {
402 i2c->nmsgs--;
403 i2c->tx_msg++;
404 dev_dbg(i2c->adap.dev.parent,
405 "%s will start next...\n", __func__);
406
407 __xiic_start_xfer(i2c);
408 }
409 }
410 } else if (pend & XIIC_INTR_BNB_MASK) {
411 /* IIC bus has transitioned to not busy */
412 clr = XIIC_INTR_BNB_MASK;
413
414 /* The bus is not busy, disable BusNotBusy interrupt */
415 xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK);
416
417 if (!i2c->tx_msg)
418 goto out;
419
420 if ((i2c->nmsgs == 1) && !i2c->rx_msg &&
421 xiic_tx_space(i2c) == 0)
422 xiic_wakeup(i2c, STATE_DONE);
423 else
424 xiic_wakeup(i2c, STATE_ERROR);
425
426 } else if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
427 /* Transmit register/FIFO is empty or ½ empty */
428
429 clr = pend &
430 (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK);
431
432 if (!i2c->tx_msg) {
433 dev_dbg(i2c->adap.dev.parent,
434 "%s unexpexted TX IRQ\n", __func__);
435 goto out;
436 }
437
438 xiic_fill_tx_fifo(i2c);
439
440 /* current message sent and there is space in the fifo */
441 if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
442 dev_dbg(i2c->adap.dev.parent,
443 "%s end of message sent, nmsgs: %d\n",
444 __func__, i2c->nmsgs);
445 if (i2c->nmsgs > 1) {
446 i2c->nmsgs--;
447 i2c->tx_msg++;
448 __xiic_start_xfer(i2c);
449 } else {
450 xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
451
452 dev_dbg(i2c->adap.dev.parent,
453 "%s Got TX IRQ but no more to do...\n",
454 __func__);
455 }
456 } else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
457 /* current frame is sent and is last,
458 * make sure to disable tx half
459 */
460 xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
461 } else {
462 /* got IRQ which is not acked */
463 dev_err(i2c->adap.dev.parent, "%s Got unexpected IRQ\n",
464 __func__);
465 clr = pend;
466 }
467out:
468 dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
469
470 xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
471}
472
473static int xiic_bus_busy(struct xiic_i2c *i2c)
474{
475 u8 sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
476
477 return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0;
478}
479
480static int xiic_busy(struct xiic_i2c *i2c)
481{
482 int tries = 3;
483 int err;
484
485 if (i2c->tx_msg)
486 return -EBUSY;
487
488 /* for instance if previous transfer was terminated due to TX error
489 * it might be that the bus is on it's way to become available
490 * give it at most 3 ms to wake
491 */
492 err = xiic_bus_busy(i2c);
493 while (err && tries--) {
494 mdelay(1);
495 err = xiic_bus_busy(i2c);
496 }
497
498 return err;
499}
500
501static void xiic_start_recv(struct xiic_i2c *i2c)
502{
503 u8 rx_watermark;
504 struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg;
505
506 /* Clear and enable Rx full interrupt. */
507 xiic_irq_clr_en(i2c, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK);
508
509 /* we want to get all but last byte, because the TX_ERROR IRQ is used
510 * to inidicate error ACK on the address, and negative ack on the last
511 * received byte, so to not mix them receive all but last.
512 * In the case where there is only one byte to receive
513 * we can check if ERROR and RX full is set at the same time
514 */
515 rx_watermark = msg->len;
516 if (rx_watermark > IIC_RX_FIFO_DEPTH)
517 rx_watermark = IIC_RX_FIFO_DEPTH;
518 xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1);
519
520 if (!(msg->flags & I2C_M_NOSTART))
521 /* write the address */
522 xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
523 (msg->addr << 1) | XIIC_READ_OPERATION |
524 XIIC_TX_DYN_START_MASK);
525
526 xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
527
528 xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET,
529 msg->len | ((i2c->nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0));
530 if (i2c->nmsgs == 1)
531 /* very last, enable bus not busy as well */
532 xiic_irq_clr_en(i2c, XIIC_INTR_BNB_MASK);
533
534 /* the message is tx:ed */
535 i2c->tx_pos = msg->len;
536}
537
538static void xiic_start_send(struct xiic_i2c *i2c)
539{
540 struct i2c_msg *msg = i2c->tx_msg;
541
542 xiic_irq_clr(i2c, XIIC_INTR_TX_ERROR_MASK);
543
544 dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, "
545 "ISR: 0x%x, CR: 0x%x\n",
546 __func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
547 xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
548
549 if (!(msg->flags & I2C_M_NOSTART)) {
550 /* write the address */
551 u16 data = ((msg->addr << 1) & 0xfe) | XIIC_WRITE_OPERATION |
552 XIIC_TX_DYN_START_MASK;
553 if ((i2c->nmsgs == 1) && msg->len == 0)
554 /* no data and last message -> add STOP */
555 data |= XIIC_TX_DYN_STOP_MASK;
556
557 xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);
558 }
559
560 xiic_fill_tx_fifo(i2c);
561
562 /* Clear any pending Tx empty, Tx Error and then enable them. */
563 xiic_irq_clr_en(i2c, XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK |
564 XIIC_INTR_BNB_MASK);
565}
566
567static irqreturn_t xiic_isr(int irq, void *dev_id)
568{
569 struct xiic_i2c *i2c = dev_id;
570
571 spin_lock(&i2c->lock);
572 /* disable interrupts globally */
573 xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
574
575 dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__);
576
577 xiic_process(i2c);
578
579 xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
580 spin_unlock(&i2c->lock);
581
582 return IRQ_HANDLED;
583}
584
585static void __xiic_start_xfer(struct xiic_i2c *i2c)
586{
587 int first = 1;
588 int fifo_space = xiic_tx_fifo_space(i2c);
589 dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n",
590 __func__, i2c->tx_msg, fifo_space);
591
592 if (!i2c->tx_msg)
593 return;
594
595 i2c->rx_pos = 0;
596 i2c->tx_pos = 0;
597 i2c->state = STATE_START;
598 while ((fifo_space >= 2) && (first || (i2c->nmsgs > 1))) {
599 if (!first) {
600 i2c->nmsgs--;
601 i2c->tx_msg++;
602 i2c->tx_pos = 0;
603 } else
604 first = 0;
605
606 if (i2c->tx_msg->flags & I2C_M_RD) {
607 /* we dont date putting several reads in the FIFO */
608 xiic_start_recv(i2c);
609 return;
610 } else {
611 xiic_start_send(i2c);
612 if (xiic_tx_space(i2c) != 0) {
613 /* the message could not be completely sent */
614 break;
615 }
616 }
617
618 fifo_space = xiic_tx_fifo_space(i2c);
619 }
620
621 /* there are more messages or the current one could not be completely
622 * put into the FIFO, also enable the half empty interrupt
623 */
624 if (i2c->nmsgs > 1 || xiic_tx_space(i2c))
625 xiic_irq_clr_en(i2c, XIIC_INTR_TX_HALF_MASK);
626
627}
628
629static void xiic_start_xfer(struct xiic_i2c *i2c)
630{
631 unsigned long flags;
632
633 spin_lock_irqsave(&i2c->lock, flags);
634 xiic_reinit(i2c);
635 /* disable interrupts globally */
636 xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
637 spin_unlock_irqrestore(&i2c->lock, flags);
638
639 __xiic_start_xfer(i2c);
640 xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
641}
642
643static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
644{
645 struct xiic_i2c *i2c = i2c_get_adapdata(adap);
646 int err;
647
648 dev_dbg(adap->dev.parent, "%s entry SR: 0x%x\n", __func__,
649 xiic_getreg8(i2c, XIIC_SR_REG_OFFSET));
650
651 err = xiic_busy(i2c);
652 if (err)
653 return err;
654
655 i2c->tx_msg = msgs;
656 i2c->nmsgs = num;
657
658 xiic_start_xfer(i2c);
659
660 if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
661 (i2c->state == STATE_DONE), HZ))
662 return (i2c->state == STATE_DONE) ? num : -EIO;
663 else {
664 i2c->tx_msg = NULL;
665 i2c->rx_msg = NULL;
666 i2c->nmsgs = 0;
667 return -ETIMEDOUT;
668 }
669}
670
671static u32 xiic_func(struct i2c_adapter *adap)
672{
673 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
674}
675
676static const struct i2c_algorithm xiic_algorithm = {
677 .master_xfer = xiic_xfer,
678 .functionality = xiic_func,
679};
680
681static struct i2c_adapter xiic_adapter = {
682 .owner = THIS_MODULE,
683 .name = DRIVER_NAME,
684 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
685 .algo = &xiic_algorithm,
686};
687
688
689static int __devinit xiic_i2c_probe(struct platform_device *pdev)
690{
691 struct xiic_i2c *i2c;
692 struct xiic_i2c_platform_data *pdata;
693 struct resource *res;
694 int ret, irq;
695 u8 i;
696
697 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
698 if (!res)
699 goto resource_missing;
700
701 irq = platform_get_irq(pdev, 0);
702 if (irq < 0)
703 goto resource_missing;
704
705 pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;
706 if (!pdata)
707 return -EINVAL;
708
709 i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
710 if (!i2c)
711 return -ENOMEM;
712
713 if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
714 dev_err(&pdev->dev, "Memory region busy\n");
715 ret = -EBUSY;
716 goto request_mem_failed;
717 }
718
719 i2c->base = ioremap(res->start, resource_size(res));
720 if (!i2c->base) {
721 dev_err(&pdev->dev, "Unable to map registers\n");
722 ret = -EIO;
723 goto map_failed;
724 }
725
726 /* hook up driver to tree */
727 platform_set_drvdata(pdev, i2c);
728 i2c->adap = xiic_adapter;
729 i2c_set_adapdata(&i2c->adap, i2c);
730 i2c->adap.dev.parent = &pdev->dev;
731
732 xiic_reinit(i2c);
733
734 spin_lock_init(&i2c->lock);
735 init_waitqueue_head(&i2c->wait);
736 ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
737 if (ret) {
738 dev_err(&pdev->dev, "Cannot claim IRQ\n");
739 goto request_irq_failed;
740 }
741
742 /* add i2c adapter to i2c tree */
743 ret = i2c_add_adapter(&i2c->adap);
744 if (ret) {
745 dev_err(&pdev->dev, "Failed to add adapter\n");
746 goto add_adapter_failed;
747 }
748
749 /* add in known devices to the bus */
750 for (i = 0; i < pdata->num_devices; i++)
751 i2c_new_device(&i2c->adap, pdata->devices + i);
752
753 return 0;
754
755add_adapter_failed:
756 free_irq(irq, i2c);
757request_irq_failed:
758 xiic_deinit(i2c);
759 iounmap(i2c->base);
760map_failed:
761 release_mem_region(res->start, resource_size(res));
762request_mem_failed:
763 kfree(i2c);
764
765 return ret;
766resource_missing:
767 dev_err(&pdev->dev, "IRQ or Memory resource is missing\n");
768 return -ENOENT;
769}
770
771static int __devexit xiic_i2c_remove(struct platform_device* pdev)
772{
773 struct xiic_i2c *i2c = platform_get_drvdata(pdev);
774 struct resource *res;
775
776 /* remove adapter & data */
777 i2c_del_adapter(&i2c->adap);
778
779 xiic_deinit(i2c);
780
781 platform_set_drvdata(pdev, NULL);
782
783 free_irq(platform_get_irq(pdev, 0), i2c);
784
785 iounmap(i2c->base);
786
787 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
788 if (res)
789 release_mem_region(res->start, resource_size(res));
790
791 kfree(i2c);
792
793 return 0;
794}
795
796
797/* work with hotplug and coldplug */
798MODULE_ALIAS("platform:"DRIVER_NAME);
799
800static struct platform_driver xiic_i2c_driver = {
801 .probe = xiic_i2c_probe,
802 .remove = __devexit_p(xiic_i2c_remove),
803 .driver = {
804 .owner = THIS_MODULE,
805 .name = DRIVER_NAME,
806 },
807};
808
809static int __init xiic_i2c_init(void)
810{
811 return platform_driver_register(&xiic_i2c_driver);
812}
813
814static void __exit xiic_i2c_exit(void)
815{
816 platform_driver_unregister(&xiic_i2c_driver);
817}
818
819module_init(xiic_i2c_init);
820module_exit(xiic_i2c_exit);
821
822MODULE_AUTHOR("info@mocean-labs.com");
823MODULE_DESCRIPTION("Xilinx I2C bus driver");
824MODULE_LICENSE("GPL v2");
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 7522008fda86..58463da814d1 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1193,10 +1193,7 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method,
1193{ 1193{
1194 int i; 1194 int i;
1195 1195
1196 for (i = find_first_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS); 1196 for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS) {
1197 i < IB_MGMT_MAX_METHODS;
1198 i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
1199 1+i)) {
1200 if ((*method)->agent[i]) { 1197 if ((*method)->agent[i]) {
1201 printk(KERN_ERR PFX "Method %d already in use\n", i); 1198 printk(KERN_ERR PFX "Method %d already in use\n", i);
1202 return -EINVAL; 1199 return -EINVAL;
@@ -1330,13 +1327,9 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
1330 goto error3; 1327 goto error3;
1331 1328
1332 /* Finally, add in methods being registered */ 1329 /* Finally, add in methods being registered */
1333 for (i = find_first_bit(mad_reg_req->method_mask, 1330 for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS)
1334 IB_MGMT_MAX_METHODS);
1335 i < IB_MGMT_MAX_METHODS;
1336 i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
1337 1+i)) {
1338 (*method)->agent[i] = agent_priv; 1331 (*method)->agent[i] = agent_priv;
1339 } 1332
1340 return 0; 1333 return 0;
1341 1334
1342error3: 1335error3:
@@ -1429,13 +1422,9 @@ check_in_use:
1429 goto error4; 1422 goto error4;
1430 1423
1431 /* Finally, add in methods being registered */ 1424 /* Finally, add in methods being registered */
1432 for (i = find_first_bit(mad_reg_req->method_mask, 1425 for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS)
1433 IB_MGMT_MAX_METHODS);
1434 i < IB_MGMT_MAX_METHODS;
1435 i = find_next_bit(mad_reg_req->method_mask, IB_MGMT_MAX_METHODS,
1436 1+i)) {
1437 (*method)->agent[i] = agent_priv; 1426 (*method)->agent[i] = agent_priv;
1438 } 1427
1439 return 0; 1428 return 0;
1440 1429
1441error4: 1430error4:
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c
new file mode 100644
index 000000000000..69a48e8701b9
--- /dev/null
+++ b/drivers/input/misc/88pm860x_onkey.c
@@ -0,0 +1,155 @@
1/*
2 * 88pm860x_onkey.c - Marvell 88PM860x ONKEY driver
3 *
4 * Copyright (C) 2009-2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file "COPYING" in the main directory of this
9 * archive for more details.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/i2c.h>
25#include <linux/input.h>
26#include <linux/interrupt.h>
27#include <linux/mfd/88pm860x.h>
28
29#define PM8607_WAKEUP 0x0b
30
31#define LONG_ONKEY_EN (1 << 1)
32#define ONKEY_STATUS (1 << 0)
33
34struct pm860x_onkey_info {
35 struct input_dev *idev;
36 struct pm860x_chip *chip;
37 struct i2c_client *i2c;
38 struct device *dev;
39 int irq;
40};
41
42/* 88PM860x gives us an interrupt when ONKEY is held */
43static irqreturn_t pm860x_onkey_handler(int irq, void *data)
44{
45 struct pm860x_onkey_info *info = data;
46 int ret;
47
48 ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
49 ret &= ONKEY_STATUS;
50 input_report_key(info->idev, KEY_POWER, ret);
51 input_sync(info->idev);
52
53 /* Enable 8-second long onkey detection */
54 pm860x_set_bits(info->i2c, PM8607_WAKEUP, 3, LONG_ONKEY_EN);
55 return IRQ_HANDLED;
56}
57
58static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
59{
60 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
61 struct pm860x_onkey_info *info;
62 int irq, ret;
63
64 irq = platform_get_irq(pdev, 0);
65 if (irq < 0) {
66 dev_err(&pdev->dev, "No IRQ resource!\n");
67 return -EINVAL;
68 }
69
70 info = kzalloc(sizeof(struct pm860x_onkey_info), GFP_KERNEL);
71 if (!info)
72 return -ENOMEM;
73 info->chip = chip;
74 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
75 info->dev = &pdev->dev;
76 info->irq = irq + chip->irq_base;
77
78 info->idev = input_allocate_device();
79 if (!info->idev) {
80 dev_err(chip->dev, "Failed to allocate input dev\n");
81 ret = -ENOMEM;
82 goto out;
83 }
84
85 info->idev->name = "88pm860x_on";
86 info->idev->phys = "88pm860x_on/input0";
87 info->idev->id.bustype = BUS_I2C;
88 info->idev->dev.parent = &pdev->dev;
89 info->irq = irq;
90 info->idev->evbit[0] = BIT_MASK(EV_KEY);
91 info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
92
93 ret = input_register_device(info->idev);
94 if (ret) {
95 dev_err(chip->dev, "Can't register input device: %d\n", ret);
96 goto out_reg;
97 }
98
99 ret = request_threaded_irq(info->irq, NULL, pm860x_onkey_handler,
100 IRQF_ONESHOT, "onkey", info);
101 if (ret < 0) {
102 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
103 info->irq, ret);
104 goto out_irq;
105 }
106
107 platform_set_drvdata(pdev, info);
108 return 0;
109
110out_irq:
111 input_unregister_device(info->idev);
112 kfree(info);
113 return ret;
114
115out_reg:
116 input_free_device(info->idev);
117out:
118 kfree(info);
119 return ret;
120}
121
122static int __devexit pm860x_onkey_remove(struct platform_device *pdev)
123{
124 struct pm860x_onkey_info *info = platform_get_drvdata(pdev);
125
126 free_irq(info->irq, info);
127 input_unregister_device(info->idev);
128 kfree(info);
129 return 0;
130}
131
132static struct platform_driver pm860x_onkey_driver = {
133 .driver = {
134 .name = "88pm860x-onkey",
135 .owner = THIS_MODULE,
136 },
137 .probe = pm860x_onkey_probe,
138 .remove = __devexit_p(pm860x_onkey_remove),
139};
140
141static int __init pm860x_onkey_init(void)
142{
143 return platform_driver_register(&pm860x_onkey_driver);
144}
145module_init(pm860x_onkey_init);
146
147static void __exit pm860x_onkey_exit(void)
148{
149 platform_driver_unregister(&pm860x_onkey_driver);
150}
151module_exit(pm860x_onkey_exit);
152
153MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver");
154MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
155MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 16ec5233441c..7097bfe581d7 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -12,6 +12,16 @@ menuconfig INPUT_MISC
12 12
13if INPUT_MISC 13if INPUT_MISC
14 14
15config INPUT_88PM860X_ONKEY
16 tristate "88PM860x ONKEY support"
17 depends on MFD_88PM860X
18 help
19 Support the ONKEY of Marvell 88PM860x PMICs as an input device
20 reporting power button status.
21
22 To compile this driver as a module, choose M here: the module
23 will be called 88pm860x_onkey.
24
15config INPUT_PCSPKR 25config INPUT_PCSPKR
16 tristate "PC Speaker support" 26 tristate "PC Speaker support"
17 depends on PCSPKR_PLATFORM 27 depends on PCSPKR_PLATFORM
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index a8b84854fb7b..b611615e24ad 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
7obj-$(CONFIG_INPUT_APANEL) += apanel.o 8obj-$(CONFIG_INPUT_APANEL) += apanel.o
8obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o 9obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
9obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o 10obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
new file mode 100644
index 000000000000..286bb490a9f2
--- /dev/null
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -0,0 +1,236 @@
1/*
2 * Touchscreen driver for Marvell 88PM860x
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/i2c.h>
15#include <linux/input.h>
16#include <linux/mfd/88pm860x.h>
17
18#define MEAS_LEN (8)
19#define ACCURATE_BIT (12)
20
21/* touch register */
22#define MEAS_EN3 (0x52)
23
24#define MEAS_TSIX_1 (0x8D)
25#define MEAS_TSIX_2 (0x8E)
26#define MEAS_TSIY_1 (0x8F)
27#define MEAS_TSIY_2 (0x90)
28#define MEAS_TSIZ1_1 (0x91)
29#define MEAS_TSIZ1_2 (0x92)
30#define MEAS_TSIZ2_1 (0x93)
31#define MEAS_TSIZ2_2 (0x94)
32
33/* bit definitions of touch */
34#define MEAS_PD_EN (1 << 3)
35#define MEAS_TSIX_EN (1 << 4)
36#define MEAS_TSIY_EN (1 << 5)
37#define MEAS_TSIZ1_EN (1 << 6)
38#define MEAS_TSIZ2_EN (1 << 7)
39
40struct pm860x_touch {
41 struct input_dev *idev;
42 struct i2c_client *i2c;
43 struct pm860x_chip *chip;
44 int irq;
45 int res_x; /* resistor of Xplate */
46};
47
48static irqreturn_t pm860x_touch_handler(int irq, void *data)
49{
50 struct pm860x_touch *touch = data;
51 struct pm860x_chip *chip = touch->chip;
52 unsigned char buf[MEAS_LEN];
53 int x, y, pen_down;
54 int z1, z2, rt = 0;
55 int ret;
56
57 ret = pm860x_bulk_read(touch->i2c, MEAS_TSIX_1, MEAS_LEN, buf);
58 if (ret < 0)
59 goto out;
60
61 pen_down = buf[1] & (1 << 6);
62 x = ((buf[0] & 0xFF) << 4) | (buf[1] & 0x0F);
63 y = ((buf[2] & 0xFF) << 4) | (buf[3] & 0x0F);
64 z1 = ((buf[4] & 0xFF) << 4) | (buf[5] & 0x0F);
65 z2 = ((buf[6] & 0xFF) << 4) | (buf[7] & 0x0F);
66
67 if (pen_down) {
68 if ((x != 0) && (z1 != 0) && (touch->res_x != 0)) {
69 rt = z2 / z1 - 1;
70 rt = (rt * touch->res_x * x) >> ACCURATE_BIT;
71 dev_dbg(chip->dev, "z1:%d, z2:%d, rt:%d\n",
72 z1, z2, rt);
73 }
74 input_report_abs(touch->idev, ABS_X, x);
75 input_report_abs(touch->idev, ABS_Y, y);
76 input_report_abs(touch->idev, ABS_PRESSURE, rt);
77 input_report_key(touch->idev, BTN_TOUCH, 1);
78 dev_dbg(chip->dev, "pen down at [%d, %d].\n", x, y);
79 } else {
80 input_report_abs(touch->idev, ABS_PRESSURE, 0);
81 input_report_key(touch->idev, BTN_TOUCH, 0);
82 dev_dbg(chip->dev, "pen release\n");
83 }
84 input_sync(touch->idev);
85
86out:
87 return IRQ_HANDLED;
88}
89
90static int pm860x_touch_open(struct input_dev *dev)
91{
92 struct pm860x_touch *touch = input_get_drvdata(dev);
93 int data, ret;
94
95 data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
96 | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
97 ret = pm860x_set_bits(touch->i2c, MEAS_EN3, data, data);
98 if (ret < 0)
99 goto out;
100 return 0;
101out:
102 return ret;
103}
104
105static void pm860x_touch_close(struct input_dev *dev)
106{
107 struct pm860x_touch *touch = input_get_drvdata(dev);
108 int data;
109
110 data = MEAS_PD_EN | MEAS_TSIX_EN | MEAS_TSIY_EN
111 | MEAS_TSIZ1_EN | MEAS_TSIZ2_EN;
112 pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
113}
114
115static int __devinit pm860x_touch_probe(struct platform_device *pdev)
116{
117 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
118 struct pm860x_platform_data *pm860x_pdata = \
119 pdev->dev.parent->platform_data;
120 struct pm860x_touch_pdata *pdata = NULL;
121 struct pm860x_touch *touch;
122 int irq, ret;
123
124 irq = platform_get_irq(pdev, 0);
125 if (irq < 0) {
126 dev_err(&pdev->dev, "No IRQ resource!\n");
127 return -EINVAL;
128 }
129
130 if (!pm860x_pdata) {
131 dev_err(&pdev->dev, "platform data is missing\n");
132 return -EINVAL;
133 }
134
135 pdata = pm860x_pdata->touch;
136 if (!pdata) {
137 dev_err(&pdev->dev, "touchscreen data is missing\n");
138 return -EINVAL;
139 }
140
141 touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
142 if (touch == NULL)
143 return -ENOMEM;
144 dev_set_drvdata(&pdev->dev, touch);
145
146 touch->idev = input_allocate_device();
147 if (touch->idev == NULL) {
148 dev_err(&pdev->dev, "Failed to allocate input device!\n");
149 ret = -ENOMEM;
150 goto out;
151 }
152
153 touch->idev->name = "88pm860x-touch";
154 touch->idev->phys = "88pm860x/input0";
155 touch->idev->id.bustype = BUS_I2C;
156 touch->idev->dev.parent = &pdev->dev;
157 touch->idev->open = pm860x_touch_open;
158 touch->idev->close = pm860x_touch_close;
159 touch->chip = chip;
160 touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
161 touch->irq = irq + chip->irq_base;
162 touch->res_x = pdata->res_x;
163 input_set_drvdata(touch->idev, touch);
164
165 ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
166 IRQF_ONESHOT, "touch", touch);
167 if (ret < 0)
168 goto out_irq;
169
170 __set_bit(EV_ABS, touch->idev->evbit);
171 __set_bit(ABS_X, touch->idev->absbit);
172 __set_bit(ABS_Y, touch->idev->absbit);
173 __set_bit(ABS_PRESSURE, touch->idev->absbit);
174 __set_bit(EV_SYN, touch->idev->evbit);
175 __set_bit(EV_KEY, touch->idev->evbit);
176 __set_bit(BTN_TOUCH, touch->idev->keybit);
177
178 input_set_abs_params(touch->idev, ABS_X, 0, 1 << ACCURATE_BIT, 0, 0);
179 input_set_abs_params(touch->idev, ABS_Y, 0, 1 << ACCURATE_BIT, 0, 0);
180 input_set_abs_params(touch->idev, ABS_PRESSURE, 0, 1 << ACCURATE_BIT,
181 0, 0);
182
183 ret = input_register_device(touch->idev);
184 if (ret < 0) {
185 dev_err(chip->dev, "Failed to register touch!\n");
186 goto out_rg;
187 }
188
189 platform_set_drvdata(pdev, touch);
190 return 0;
191out_rg:
192 free_irq(touch->irq, touch);
193out_irq:
194 input_free_device(touch->idev);
195out:
196 kfree(touch);
197 return ret;
198}
199
200static int __devexit pm860x_touch_remove(struct platform_device *pdev)
201{
202 struct pm860x_touch *touch = platform_get_drvdata(pdev);
203
204 input_unregister_device(touch->idev);
205 free_irq(touch->irq, touch);
206 platform_set_drvdata(pdev, NULL);
207 kfree(touch);
208 return 0;
209}
210
211static struct platform_driver pm860x_touch_driver = {
212 .driver = {
213 .name = "88pm860x-touch",
214 .owner = THIS_MODULE,
215 },
216 .probe = pm860x_touch_probe,
217 .remove = __devexit_p(pm860x_touch_remove),
218};
219
220static int __init pm860x_touch_init(void)
221{
222 return platform_driver_register(&pm860x_touch_driver);
223}
224module_init(pm860x_touch_init);
225
226static void __exit pm860x_touch_exit(void)
227{
228 platform_driver_unregister(&pm860x_touch_driver);
229}
230module_exit(pm860x_touch_exit);
231
232MODULE_DESCRIPTION("Touchscreen driver for Marvell Semiconductor 88PM860x");
233MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
234MODULE_LICENSE("GPL");
235MODULE_ALIAS("platform:88pm860x-touch");
236
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6457e060ae49..7208654a94ae 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -11,6 +11,18 @@ menuconfig INPUT_TOUCHSCREEN
11 11
12if INPUT_TOUCHSCREEN 12if INPUT_TOUCHSCREEN
13 13
14config TOUCHSCREEN_88PM860X
15 tristate "Marvell 88PM860x touchscreen"
16 depends on MFD_88PM860X
17 help
18 Say Y here if you have a 88PM860x PMIC and want to enable
19 support for the built-in touchscreen.
20
21 If unsure, say N.
22
23 To compile this driver as a module, choose M here: the
24 module will be called 88pm860x-ts.
25
14config TOUCHSCREEN_ADS7846 26config TOUCHSCREEN_ADS7846
15 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" 27 tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
16 depends on SPI_MASTER 28 depends on SPI_MASTER
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index d61a3b4def9a..7fef7d5cca23 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,6 +6,7 @@
6 6
7wm97xx-ts-y := wm97xx-core.o 7wm97xx-ts-y := wm97xx-core.o
8 8
9obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
9obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o 10obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
10obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o 11obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
11obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o 12obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index be115b3b65eb..be54fd639aca 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -44,7 +44,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data)
44{ 44{
45 struct mc13783_ts_priv *priv = data; 45 struct mc13783_ts_priv *priv = data;
46 46
47 mc13783_ackirq(priv->mc13783, irq); 47 mc13783_irq_ack(priv->mc13783, irq);
48 48
49 /* 49 /*
50 * Kick off reading coordinates. Note that if work happens already 50 * Kick off reading coordinates. Note that if work happens already
@@ -135,7 +135,7 @@ static int mc13783_ts_open(struct input_dev *dev)
135 135
136 mc13783_lock(priv->mc13783); 136 mc13783_lock(priv->mc13783);
137 137
138 mc13783_ackirq(priv->mc13783, MC13783_IRQ_TS); 138 mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TS);
139 139
140 ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS, 140 ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_TS,
141 mc13783_ts_handler, MC13783_TS_NAME, priv); 141 mc13783_ts_handler, MC13783_TS_NAME, priv);
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 8a0e1ec95e4a..e0b64312e66a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -17,6 +17,13 @@ config LEDS_CLASS
17 17
18comment "LED drivers" 18comment "LED drivers"
19 19
20config LEDS_88PM860X
21 tristate "LED Support for Marvell 88PM860x PMIC"
22 depends on LEDS_CLASS && MFD_88PM860X
23 help
24 This option enables support for on-chip LED drivers found on Marvell
25 Semiconductor 88PM8606 PMIC.
26
20config LEDS_ATMEL_PWM 27config LEDS_ATMEL_PWM
21 tristate "LED Support using Atmel PWM outputs" 28 tristate "LED Support using Atmel PWM outputs"
22 depends on LEDS_CLASS && ATMEL_PWM 29 depends on LEDS_CLASS && ATMEL_PWM
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 9e63869d7c0d..d76fb32b77c0 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_LEDS_CLASS) += led-class.o
5obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o 5obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
6 6
7# LED Platform Drivers 7# LED Platform Drivers
8obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
8obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o 9obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
9obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o 10obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
10obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o 11obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
new file mode 100644
index 000000000000..d196073a6aeb
--- /dev/null
+++ b/drivers/leds/leds-88pm860x.c
@@ -0,0 +1,325 @@
1/*
2 * LED driver for Marvell 88PM860x
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/i2c.h>
17#include <linux/leds.h>
18#include <linux/workqueue.h>
19#include <linux/mfd/88pm860x.h>
20
21#define LED_PWM_SHIFT (3)
22#define LED_PWM_MASK (0x1F)
23#define LED_CURRENT_MASK (0x07 << 5)
24
25#define LED_BLINK_ON_MASK (0x07)
26#define LED_BLINK_PERIOD_MASK (0x0F << 3)
27#define LED_BLINK_MASK (0x7F)
28
29#define LED_BLINK_ON(x) ((x & 0x7) * 66 + 66)
30#define LED_BLINK_PERIOD(x) ((x & 0xF) * 530 + 930)
31#define LED_BLINK_ON_MIN LED_BLINK_ON(0)
32#define LED_BLINK_ON_MAX LED_BLINK_ON(0x7)
33#define LED_BLINK_PERIOD_MIN LED_BLINK_PERIOD(0)
34#define LED_BLINK_PERIOD_MAX LED_BLINK_PERIOD(0xE)
35#define LED_TO_ON(x) ((x - 66) / 66)
36#define LED_TO_PERIOD(x) ((x - 930) / 530)
37
38#define LED1_BLINK_EN (1 << 1)
39#define LED2_BLINK_EN (1 << 2)
40
41enum {
42 SET_BRIGHTNESS,
43 SET_BLINK,
44};
45
46struct pm860x_led {
47 struct led_classdev cdev;
48 struct i2c_client *i2c;
49 struct work_struct work;
50 struct pm860x_chip *chip;
51 struct mutex lock;
52 char name[MFD_NAME_SIZE];
53
54 int port;
55 int iset;
56 int command;
57 int offset;
58 unsigned char brightness;
59 unsigned char current_brightness;
60
61 int blink_data;
62 int blink_time;
63 int blink_on;
64 int blink_off;
65};
66
67/* return offset of color register */
68static inline int __led_off(int port)
69{
70 int ret = -EINVAL;
71
72 switch (port) {
73 case PM8606_LED1_RED:
74 case PM8606_LED1_GREEN:
75 case PM8606_LED1_BLUE:
76 ret = port - PM8606_LED1_RED + PM8606_RGB1B;
77 break;
78 case PM8606_LED2_RED:
79 case PM8606_LED2_GREEN:
80 case PM8606_LED2_BLUE:
81 ret = port - PM8606_LED2_RED + PM8606_RGB2B;
82 break;
83 }
84 return ret;
85}
86
87/* return offset of blink register */
88static inline int __blink_off(int port)
89{
90 int ret = -EINVAL;
91
92 switch (port) {
93 case PM8606_LED1_RED:
94 case PM8606_LED1_GREEN:
95 case PM8606_LED1_BLUE:
96 ret = PM8606_RGB1A;
97 case PM8606_LED2_RED:
98 case PM8606_LED2_GREEN:
99 case PM8606_LED2_BLUE:
100 ret = PM8606_RGB2A;
101 }
102 return ret;
103}
104
105static inline int __blink_ctl_mask(int port)
106{
107 int ret = -EINVAL;
108
109 switch (port) {
110 case PM8606_LED1_RED:
111 case PM8606_LED1_GREEN:
112 case PM8606_LED1_BLUE:
113 ret = LED1_BLINK_EN;
114 break;
115 case PM8606_LED2_RED:
116 case PM8606_LED2_GREEN:
117 case PM8606_LED2_BLUE:
118 ret = LED2_BLINK_EN;
119 break;
120 }
121 return ret;
122}
123
124static int __led_set(struct pm860x_led *led, int command)
125{
126 struct pm860x_chip *chip = led->chip;
127 int mask, ret;
128
129 mutex_lock(&led->lock);
130 switch (command) {
131 case SET_BRIGHTNESS:
132 if ((led->current_brightness == 0) && led->brightness) {
133 if (led->iset) {
134 ret = pm860x_set_bits(led->i2c, led->offset,
135 LED_CURRENT_MASK, led->iset);
136 if (ret < 0)
137 goto out;
138 }
139 } else if (led->brightness == 0) {
140 ret = pm860x_set_bits(led->i2c, led->offset,
141 LED_CURRENT_MASK, 0);
142 if (ret < 0)
143 goto out;
144 }
145 ret = pm860x_set_bits(led->i2c, led->offset, LED_PWM_MASK,
146 led->brightness);
147 if (ret < 0)
148 goto out;
149 led->current_brightness = led->brightness;
150 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
151 led->offset, led->brightness);
152 break;
153 case SET_BLINK:
154 ret = pm860x_set_bits(led->i2c, led->offset,
155 LED_BLINK_MASK, led->blink_data);
156 if (ret < 0)
157 goto out;
158
159 mask = __blink_ctl_mask(led->port);
160 ret = pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
161 if (ret < 0)
162 goto out;
163 dev_dbg(chip->dev, "LED blink delay on:%dms, delay off:%dms\n",
164 led->blink_on, led->blink_off);
165 break;
166 }
167out:
168 mutex_unlock(&led->lock);
169 return 0;
170}
171
172static void pm860x_led_work(struct work_struct *work)
173{
174 struct pm860x_led *led;
175
176 led = container_of(work, struct pm860x_led, work);
177 __led_set(led, led->command);
178}
179
180static void pm860x_led_set(struct led_classdev *cdev,
181 enum led_brightness value)
182{
183 struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev);
184
185 data->offset = __led_off(data->port);
186 data->brightness = value >> 3;
187 data->command = SET_BRIGHTNESS;
188 schedule_work(&data->work);
189}
190
191static int pm860x_led_blink(struct led_classdev *cdev,
192 unsigned long *delay_on,
193 unsigned long *delay_off)
194{
195 struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev);
196 int period, on;
197
198 on = *delay_on;
199 if ((on < LED_BLINK_ON_MIN) || (on > LED_BLINK_ON_MAX))
200 return -EINVAL;
201
202 on = LED_TO_ON(on);
203 on = LED_BLINK_ON(on);
204
205 period = on + *delay_off;
206 if ((period < LED_BLINK_PERIOD_MIN) || (period > LED_BLINK_PERIOD_MAX))
207 return -EINVAL;
208 period = LED_TO_PERIOD(period);
209 period = LED_BLINK_PERIOD(period);
210
211 data->offset = __blink_off(data->port);
212 data->blink_on = on;
213 data->blink_off = period - data->blink_on;
214 data->blink_data = (period << 3) | data->blink_on;
215 data->command = SET_BLINK;
216 schedule_work(&data->work);
217
218 return 0;
219}
220
221static int __check_device(struct pm860x_led_pdata *pdata, char *name)
222{
223 struct pm860x_led_pdata *p = pdata;
224 int ret = -EINVAL;
225
226 while (p && p->id) {
227 if ((p->id != PM8606_ID_LED) || (p->flags < 0))
228 break;
229
230 if (!strncmp(name, pm860x_led_name[p->flags],
231 MFD_NAME_SIZE)) {
232 ret = (int)p->flags;
233 break;
234 }
235 p++;
236 }
237 return ret;
238}
239
240static int pm860x_led_probe(struct platform_device *pdev)
241{
242 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
243 struct pm860x_platform_data *pm860x_pdata;
244 struct pm860x_led_pdata *pdata;
245 struct pm860x_led *data;
246 struct resource *res;
247 int ret;
248
249 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
250 if (res == NULL) {
251 dev_err(&pdev->dev, "No I/O resource!\n");
252 return -EINVAL;
253 }
254
255 if (pdev->dev.parent->platform_data) {
256 pm860x_pdata = pdev->dev.parent->platform_data;
257 pdata = pm860x_pdata->led;
258 } else
259 pdata = NULL;
260
261 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
262 if (data == NULL)
263 return -ENOMEM;
264 strncpy(data->name, res->name, MFD_NAME_SIZE);
265 dev_set_drvdata(&pdev->dev, data);
266 data->chip = chip;
267 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
268 data->iset = pdata->iset;
269 data->port = __check_device(pdata, data->name);
270 if (data->port < 0)
271 return -EINVAL;
272
273 data->current_brightness = 0;
274 data->cdev.name = data->name;
275 data->cdev.brightness_set = pm860x_led_set;
276 data->cdev.blink_set = pm860x_led_blink;
277 mutex_init(&data->lock);
278 INIT_WORK(&data->work, pm860x_led_work);
279
280 ret = led_classdev_register(chip->dev, &data->cdev);
281 if (ret < 0) {
282 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
283 goto out;
284 }
285 return 0;
286out:
287 kfree(data);
288 return ret;
289}
290
291static int pm860x_led_remove(struct platform_device *pdev)
292{
293 struct pm860x_led *data = platform_get_drvdata(pdev);
294
295 led_classdev_unregister(&data->cdev);
296 kfree(data);
297
298 return 0;
299}
300
301static struct platform_driver pm860x_led_driver = {
302 .driver = {
303 .name = "88pm860x-led",
304 .owner = THIS_MODULE,
305 },
306 .probe = pm860x_led_probe,
307 .remove = pm860x_led_remove,
308};
309
310static int __devinit pm860x_led_init(void)
311{
312 return platform_driver_register(&pm860x_led_driver);
313}
314module_init(pm860x_led_init);
315
316static void __devexit pm860x_led_exit(void)
317{
318 platform_driver_unregister(&pm860x_led_driver);
319}
320module_exit(pm860x_led_exit);
321
322MODULE_DESCRIPTION("LED driver for Marvell PM860x");
323MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
324MODULE_LICENSE("GPL");
325MODULE_ALIAS("platform:88pm860x-led");
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index a93637223c8d..3bdbb6115702 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1160,8 +1160,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1160 } 1160 }
1161 cc->start = tmpll; 1161 cc->start = tmpll;
1162 1162
1163 if (dm_get_device(ti, argv[3], cc->start, ti->len, 1163 if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &cc->dev)) {
1164 dm_table_get_mode(ti->table), &cc->dev)) {
1165 ti->error = "Device lookup failed"; 1164 ti->error = "Device lookup failed";
1166 goto bad_device; 1165 goto bad_device;
1167 } 1166 }
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index ebe7381f47c8..852052880d7a 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -156,8 +156,8 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
156 goto bad; 156 goto bad;
157 } 157 }
158 158
159 if (dm_get_device(ti, argv[0], dc->start_read, ti->len, 159 if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
160 dm_table_get_mode(ti->table), &dc->dev_read)) { 160 &dc->dev_read)) {
161 ti->error = "Device lookup failed"; 161 ti->error = "Device lookup failed";
162 goto bad; 162 goto bad;
163 } 163 }
@@ -177,8 +177,8 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
177 goto bad_dev_read; 177 goto bad_dev_read;
178 } 178 }
179 179
180 if (dm_get_device(ti, argv[3], dc->start_write, ti->len, 180 if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table),
181 dm_table_get_mode(ti->table), &dc->dev_write)) { 181 &dc->dev_write)) {
182 ti->error = "Write device lookup failed"; 182 ti->error = "Write device lookup failed";
183 goto bad_dev_read; 183 goto bad_dev_read;
184 } 184 }
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 1d669322b27c..d7500e1c26f2 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -285,7 +285,8 @@ retry:
285 up_write(&_hash_lock); 285 up_write(&_hash_lock);
286} 286}
287 287
288static int dm_hash_rename(uint32_t cookie, const char *old, const char *new) 288static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
289 const char *new)
289{ 290{
290 char *new_name, *old_name; 291 char *new_name, *old_name;
291 struct hash_cell *hc; 292 struct hash_cell *hc;
@@ -344,7 +345,8 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
344 dm_table_put(table); 345 dm_table_put(table);
345 } 346 }
346 347
347 dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie); 348 if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie))
349 *flags |= DM_UEVENT_GENERATED_FLAG;
348 350
349 dm_put(hc->md); 351 dm_put(hc->md);
350 up_write(&_hash_lock); 352 up_write(&_hash_lock);
@@ -736,10 +738,10 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size)
736 __hash_remove(hc); 738 __hash_remove(hc);
737 up_write(&_hash_lock); 739 up_write(&_hash_lock);
738 740
739 dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr); 741 if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr))
742 param->flags |= DM_UEVENT_GENERATED_FLAG;
740 743
741 dm_put(md); 744 dm_put(md);
742 param->data_size = 0;
743 return 0; 745 return 0;
744} 746}
745 747
@@ -773,7 +775,9 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
773 return r; 775 return r;
774 776
775 param->data_size = 0; 777 param->data_size = 0;
776 return dm_hash_rename(param->event_nr, param->name, new_name); 778
779 return dm_hash_rename(param->event_nr, &param->flags, param->name,
780 new_name);
777} 781}
778 782
779static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) 783static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
@@ -897,16 +901,17 @@ static int do_resume(struct dm_ioctl *param)
897 set_disk_ro(dm_disk(md), 1); 901 set_disk_ro(dm_disk(md), 1);
898 } 902 }
899 903
900 if (dm_suspended_md(md)) 904 if (dm_suspended_md(md)) {
901 r = dm_resume(md); 905 r = dm_resume(md);
906 if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr))
907 param->flags |= DM_UEVENT_GENERATED_FLAG;
908 }
902 909
903 if (old_map) 910 if (old_map)
904 dm_table_destroy(old_map); 911 dm_table_destroy(old_map);
905 912
906 if (!r) { 913 if (!r)
907 dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr);
908 r = __dev_status(md, param); 914 r = __dev_status(md, param);
909 }
910 915
911 dm_put(md); 916 dm_put(md);
912 return r; 917 return r;
@@ -1476,6 +1481,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
1476{ 1481{
1477 /* Always clear this flag */ 1482 /* Always clear this flag */
1478 param->flags &= ~DM_BUFFER_FULL_FLAG; 1483 param->flags &= ~DM_BUFFER_FULL_FLAG;
1484 param->flags &= ~DM_UEVENT_GENERATED_FLAG;
1479 1485
1480 /* Ignores parameters */ 1486 /* Ignores parameters */
1481 if (cmd == DM_REMOVE_ALL_CMD || 1487 if (cmd == DM_REMOVE_ALL_CMD ||
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 82f7d6e6b1ea..9200dbf2391a 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -47,8 +47,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
47 } 47 }
48 lc->start = tmp; 48 lc->start = tmp;
49 49
50 if (dm_get_device(ti, argv[0], lc->start, ti->len, 50 if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev)) {
51 dm_table_get_mode(ti->table), &lc->dev)) {
52 ti->error = "dm-linear: Device lookup failed"; 51 ti->error = "dm-linear: Device lookup failed";
53 goto bad; 52 goto bad;
54 } 53 }
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 7035582786fb..5a08be0222db 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -543,8 +543,7 @@ static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
543 return -EINVAL; 543 return -EINVAL;
544 } 544 }
545 545
546 r = dm_get_device(ti, argv[0], 0, 0 /* FIXME */, 546 r = dm_get_device(ti, argv[0], FMODE_READ | FMODE_WRITE, &dev);
547 FMODE_READ | FMODE_WRITE, &dev);
548 if (r) 547 if (r)
549 return r; 548 return r;
550 549
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index e81345a1d08f..826bce7343b3 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -69,6 +69,7 @@ struct multipath {
69 struct list_head priority_groups; 69 struct list_head priority_groups;
70 unsigned pg_init_required; /* pg_init needs calling? */ 70 unsigned pg_init_required; /* pg_init needs calling? */
71 unsigned pg_init_in_progress; /* Only one pg_init allowed at once */ 71 unsigned pg_init_in_progress; /* Only one pg_init allowed at once */
72 wait_queue_head_t pg_init_wait; /* Wait for pg_init completion */
72 73
73 unsigned nr_valid_paths; /* Total number of usable paths */ 74 unsigned nr_valid_paths; /* Total number of usable paths */
74 struct pgpath *current_pgpath; 75 struct pgpath *current_pgpath;
@@ -95,8 +96,6 @@ struct multipath {
95 mempool_t *mpio_pool; 96 mempool_t *mpio_pool;
96 97
97 struct mutex work_mutex; 98 struct mutex work_mutex;
98
99 unsigned suspended; /* Don't create new I/O internally when set. */
100}; 99};
101 100
102/* 101/*
@@ -202,6 +201,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti)
202 m->queue_io = 1; 201 m->queue_io = 1;
203 INIT_WORK(&m->process_queued_ios, process_queued_ios); 202 INIT_WORK(&m->process_queued_ios, process_queued_ios);
204 INIT_WORK(&m->trigger_event, trigger_event); 203 INIT_WORK(&m->trigger_event, trigger_event);
204 init_waitqueue_head(&m->pg_init_wait);
205 mutex_init(&m->work_mutex); 205 mutex_init(&m->work_mutex);
206 m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); 206 m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache);
207 if (!m->mpio_pool) { 207 if (!m->mpio_pool) {
@@ -235,6 +235,21 @@ static void free_multipath(struct multipath *m)
235 * Path selection 235 * Path selection
236 *-----------------------------------------------*/ 236 *-----------------------------------------------*/
237 237
238static void __pg_init_all_paths(struct multipath *m)
239{
240 struct pgpath *pgpath;
241
242 m->pg_init_count++;
243 m->pg_init_required = 0;
244 list_for_each_entry(pgpath, &m->current_pg->pgpaths, list) {
245 /* Skip failed paths */
246 if (!pgpath->is_active)
247 continue;
248 if (queue_work(kmpath_handlerd, &pgpath->activate_path))
249 m->pg_init_in_progress++;
250 }
251}
252
238static void __switch_pg(struct multipath *m, struct pgpath *pgpath) 253static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
239{ 254{
240 m->current_pg = pgpath->pg; 255 m->current_pg = pgpath->pg;
@@ -439,7 +454,7 @@ static void process_queued_ios(struct work_struct *work)
439{ 454{
440 struct multipath *m = 455 struct multipath *m =
441 container_of(work, struct multipath, process_queued_ios); 456 container_of(work, struct multipath, process_queued_ios);
442 struct pgpath *pgpath = NULL, *tmp; 457 struct pgpath *pgpath = NULL;
443 unsigned must_queue = 1; 458 unsigned must_queue = 1;
444 unsigned long flags; 459 unsigned long flags;
445 460
@@ -457,14 +472,9 @@ static void process_queued_ios(struct work_struct *work)
457 (!pgpath && !m->queue_if_no_path)) 472 (!pgpath && !m->queue_if_no_path))
458 must_queue = 0; 473 must_queue = 0;
459 474
460 if (m->pg_init_required && !m->pg_init_in_progress && pgpath) { 475 if (m->pg_init_required && !m->pg_init_in_progress && pgpath)
461 m->pg_init_count++; 476 __pg_init_all_paths(m);
462 m->pg_init_required = 0; 477
463 list_for_each_entry(tmp, &pgpath->pg->pgpaths, list) {
464 if (queue_work(kmpath_handlerd, &tmp->activate_path))
465 m->pg_init_in_progress++;
466 }
467 }
468out: 478out:
469 spin_unlock_irqrestore(&m->lock, flags); 479 spin_unlock_irqrestore(&m->lock, flags);
470 if (!must_queue) 480 if (!must_queue)
@@ -597,8 +607,8 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
597 if (!p) 607 if (!p)
598 return ERR_PTR(-ENOMEM); 608 return ERR_PTR(-ENOMEM);
599 609
600 r = dm_get_device(ti, shift(as), ti->begin, ti->len, 610 r = dm_get_device(ti, shift(as), dm_table_get_mode(ti->table),
601 dm_table_get_mode(ti->table), &p->path.dev); 611 &p->path.dev);
602 if (r) { 612 if (r) {
603 ti->error = "error getting device"; 613 ti->error = "error getting device";
604 goto bad; 614 goto bad;
@@ -890,9 +900,34 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
890 return r; 900 return r;
891} 901}
892 902
893static void flush_multipath_work(void) 903static void multipath_wait_for_pg_init_completion(struct multipath *m)
904{
905 DECLARE_WAITQUEUE(wait, current);
906 unsigned long flags;
907
908 add_wait_queue(&m->pg_init_wait, &wait);
909
910 while (1) {
911 set_current_state(TASK_UNINTERRUPTIBLE);
912
913 spin_lock_irqsave(&m->lock, flags);
914 if (!m->pg_init_in_progress) {
915 spin_unlock_irqrestore(&m->lock, flags);
916 break;
917 }
918 spin_unlock_irqrestore(&m->lock, flags);
919
920 io_schedule();
921 }
922 set_current_state(TASK_RUNNING);
923
924 remove_wait_queue(&m->pg_init_wait, &wait);
925}
926
927static void flush_multipath_work(struct multipath *m)
894{ 928{
895 flush_workqueue(kmpath_handlerd); 929 flush_workqueue(kmpath_handlerd);
930 multipath_wait_for_pg_init_completion(m);
896 flush_workqueue(kmultipathd); 931 flush_workqueue(kmultipathd);
897 flush_scheduled_work(); 932 flush_scheduled_work();
898} 933}
@@ -901,7 +936,7 @@ static void multipath_dtr(struct dm_target *ti)
901{ 936{
902 struct multipath *m = ti->private; 937 struct multipath *m = ti->private;
903 938
904 flush_multipath_work(); 939 flush_multipath_work(m);
905 free_multipath(m); 940 free_multipath(m);
906} 941}
907 942
@@ -1128,8 +1163,7 @@ static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
1128 1163
1129static void pg_init_done(void *data, int errors) 1164static void pg_init_done(void *data, int errors)
1130{ 1165{
1131 struct dm_path *path = data; 1166 struct pgpath *pgpath = data;
1132 struct pgpath *pgpath = path_to_pgpath(path);
1133 struct priority_group *pg = pgpath->pg; 1167 struct priority_group *pg = pgpath->pg;
1134 struct multipath *m = pg->m; 1168 struct multipath *m = pg->m;
1135 unsigned long flags; 1169 unsigned long flags;
@@ -1143,8 +1177,8 @@ static void pg_init_done(void *data, int errors)
1143 errors = 0; 1177 errors = 0;
1144 break; 1178 break;
1145 } 1179 }
1146 DMERR("Cannot failover device because scsi_dh_%s was not " 1180 DMERR("Could not failover the device: Handler scsi_dh_%s "
1147 "loaded.", m->hw_handler_name); 1181 "Error %d.", m->hw_handler_name, errors);
1148 /* 1182 /*
1149 * Fail path for now, so we do not ping pong 1183 * Fail path for now, so we do not ping pong
1150 */ 1184 */
@@ -1181,14 +1215,24 @@ static void pg_init_done(void *data, int errors)
1181 m->current_pgpath = NULL; 1215 m->current_pgpath = NULL;
1182 m->current_pg = NULL; 1216 m->current_pg = NULL;
1183 } 1217 }
1184 } else if (!m->pg_init_required) { 1218 } else if (!m->pg_init_required)
1185 m->queue_io = 0;
1186 pg->bypassed = 0; 1219 pg->bypassed = 0;
1187 }
1188 1220
1189 m->pg_init_in_progress--; 1221 if (--m->pg_init_in_progress)
1190 if (!m->pg_init_in_progress) 1222 /* Activations of other paths are still on going */
1191 queue_work(kmultipathd, &m->process_queued_ios); 1223 goto out;
1224
1225 if (!m->pg_init_required)
1226 m->queue_io = 0;
1227
1228 queue_work(kmultipathd, &m->process_queued_ios);
1229
1230 /*
1231 * Wake up any thread waiting to suspend.
1232 */
1233 wake_up(&m->pg_init_wait);
1234
1235out:
1192 spin_unlock_irqrestore(&m->lock, flags); 1236 spin_unlock_irqrestore(&m->lock, flags);
1193} 1237}
1194 1238
@@ -1198,7 +1242,7 @@ static void activate_path(struct work_struct *work)
1198 container_of(work, struct pgpath, activate_path); 1242 container_of(work, struct pgpath, activate_path);
1199 1243
1200 scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev), 1244 scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
1201 pg_init_done, &pgpath->path); 1245 pg_init_done, pgpath);
1202} 1246}
1203 1247
1204/* 1248/*
@@ -1276,8 +1320,7 @@ static void multipath_postsuspend(struct dm_target *ti)
1276 struct multipath *m = ti->private; 1320 struct multipath *m = ti->private;
1277 1321
1278 mutex_lock(&m->work_mutex); 1322 mutex_lock(&m->work_mutex);
1279 m->suspended = 1; 1323 flush_multipath_work(m);
1280 flush_multipath_work();
1281 mutex_unlock(&m->work_mutex); 1324 mutex_unlock(&m->work_mutex);
1282} 1325}
1283 1326
@@ -1289,10 +1332,6 @@ static void multipath_resume(struct dm_target *ti)
1289 struct multipath *m = (struct multipath *) ti->private; 1332 struct multipath *m = (struct multipath *) ti->private;
1290 unsigned long flags; 1333 unsigned long flags;
1291 1334
1292 mutex_lock(&m->work_mutex);
1293 m->suspended = 0;
1294 mutex_unlock(&m->work_mutex);
1295
1296 spin_lock_irqsave(&m->lock, flags); 1335 spin_lock_irqsave(&m->lock, flags);
1297 m->queue_if_no_path = m->saved_queue_if_no_path; 1336 m->queue_if_no_path = m->saved_queue_if_no_path;
1298 spin_unlock_irqrestore(&m->lock, flags); 1337 spin_unlock_irqrestore(&m->lock, flags);
@@ -1428,11 +1467,6 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
1428 1467
1429 mutex_lock(&m->work_mutex); 1468 mutex_lock(&m->work_mutex);
1430 1469
1431 if (m->suspended) {
1432 r = -EBUSY;
1433 goto out;
1434 }
1435
1436 if (dm_suspended(ti)) { 1470 if (dm_suspended(ti)) {
1437 r = -EBUSY; 1471 r = -EBUSY;
1438 goto out; 1472 goto out;
@@ -1471,8 +1505,7 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
1471 goto out; 1505 goto out;
1472 } 1506 }
1473 1507
1474 r = dm_get_device(ti, argv[1], ti->begin, ti->len, 1508 r = dm_get_device(ti, argv[1], dm_table_get_mode(ti->table), &dev);
1475 dm_table_get_mode(ti->table), &dev);
1476 if (r) { 1509 if (r) {
1477 DMWARN("message: error getting device %s", 1510 DMWARN("message: error getting device %s",
1478 argv[1]); 1511 argv[1]);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 6c1046df81f6..ddda531723dc 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -465,9 +465,17 @@ static void map_region(struct dm_io_region *io, struct mirror *m,
465static void hold_bio(struct mirror_set *ms, struct bio *bio) 465static void hold_bio(struct mirror_set *ms, struct bio *bio)
466{ 466{
467 /* 467 /*
468 * If device is suspended, complete the bio. 468 * Lock is required to avoid race condition during suspend
469 * process.
469 */ 470 */
471 spin_lock_irq(&ms->lock);
472
470 if (atomic_read(&ms->suspend)) { 473 if (atomic_read(&ms->suspend)) {
474 spin_unlock_irq(&ms->lock);
475
476 /*
477 * If device is suspended, complete the bio.
478 */
471 if (dm_noflush_suspending(ms->ti)) 479 if (dm_noflush_suspending(ms->ti))
472 bio_endio(bio, DM_ENDIO_REQUEUE); 480 bio_endio(bio, DM_ENDIO_REQUEUE);
473 else 481 else
@@ -478,7 +486,6 @@ static void hold_bio(struct mirror_set *ms, struct bio *bio)
478 /* 486 /*
479 * Hold bio until the suspend is complete. 487 * Hold bio until the suspend is complete.
480 */ 488 */
481 spin_lock_irq(&ms->lock);
482 bio_list_add(&ms->holds, bio); 489 bio_list_add(&ms->holds, bio);
483 spin_unlock_irq(&ms->lock); 490 spin_unlock_irq(&ms->lock);
484} 491}
@@ -737,9 +744,12 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
737 dm_rh_delay(ms->rh, bio); 744 dm_rh_delay(ms->rh, bio);
738 745
739 while ((bio = bio_list_pop(&nosync))) { 746 while ((bio = bio_list_pop(&nosync))) {
740 if (unlikely(ms->leg_failure) && errors_handled(ms)) 747 if (unlikely(ms->leg_failure) && errors_handled(ms)) {
741 hold_bio(ms, bio); 748 spin_lock_irq(&ms->lock);
742 else { 749 bio_list_add(&ms->failures, bio);
750 spin_unlock_irq(&ms->lock);
751 wakeup_mirrord(ms);
752 } else {
743 map_bio(get_default_mirror(ms), bio); 753 map_bio(get_default_mirror(ms), bio);
744 generic_make_request(bio); 754 generic_make_request(bio);
745 } 755 }
@@ -917,8 +927,7 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
917 return -EINVAL; 927 return -EINVAL;
918 } 928 }
919 929
920 if (dm_get_device(ti, argv[0], offset, ti->len, 930 if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
921 dm_table_get_mode(ti->table),
922 &ms->mirror[mirror].dev)) { 931 &ms->mirror[mirror].dev)) {
923 ti->error = "Device lookup failure"; 932 ti->error = "Device lookup failure";
924 return -ENXIO; 933 return -ENXIO;
@@ -1259,6 +1268,20 @@ static void mirror_presuspend(struct dm_target *ti)
1259 atomic_set(&ms->suspend, 1); 1268 atomic_set(&ms->suspend, 1);
1260 1269
1261 /* 1270 /*
1271 * Process bios in the hold list to start recovery waiting
1272 * for bios in the hold list. After the process, no bio has
1273 * a chance to be added in the hold list because ms->suspend
1274 * is set.
1275 */
1276 spin_lock_irq(&ms->lock);
1277 holds = ms->holds;
1278 bio_list_init(&ms->holds);
1279 spin_unlock_irq(&ms->lock);
1280
1281 while ((bio = bio_list_pop(&holds)))
1282 hold_bio(ms, bio);
1283
1284 /*
1262 * We must finish up all the work that we've 1285 * We must finish up all the work that we've
1263 * generated (i.e. recovery work). 1286 * generated (i.e. recovery work).
1264 */ 1287 */
@@ -1278,22 +1301,6 @@ static void mirror_presuspend(struct dm_target *ti)
1278 * we know that all of our I/O has been pushed. 1301 * we know that all of our I/O has been pushed.
1279 */ 1302 */
1280 flush_workqueue(ms->kmirrord_wq); 1303 flush_workqueue(ms->kmirrord_wq);
1281
1282 /*
1283 * Now set ms->suspend is set and the workqueue flushed, no more
1284 * entries can be added to ms->hold list, so process it.
1285 *
1286 * Bios can still arrive concurrently with or after this
1287 * presuspend function, but they cannot join the hold list
1288 * because ms->suspend is set.
1289 */
1290 spin_lock_irq(&ms->lock);
1291 holds = ms->holds;
1292 bio_list_init(&ms->holds);
1293 spin_unlock_irq(&ms->lock);
1294
1295 while ((bio = bio_list_pop(&holds)))
1296 hold_bio(ms, bio);
1297} 1304}
1298 1305
1299static void mirror_postsuspend(struct dm_target *ti) 1306static void mirror_postsuspend(struct dm_target *ti)
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index ee8eb283650d..54853773510c 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -83,10 +83,10 @@ struct dm_snapshot {
83 /* Whether or not owning mapped_device is suspended */ 83 /* Whether or not owning mapped_device is suspended */
84 int suspended; 84 int suspended;
85 85
86 mempool_t *pending_pool;
87
88 atomic_t pending_exceptions_count; 86 atomic_t pending_exceptions_count;
89 87
88 mempool_t *pending_pool;
89
90 struct dm_exception_table pending; 90 struct dm_exception_table pending;
91 struct dm_exception_table complete; 91 struct dm_exception_table complete;
92 92
@@ -96,6 +96,11 @@ struct dm_snapshot {
96 */ 96 */
97 spinlock_t pe_lock; 97 spinlock_t pe_lock;
98 98
99 /* Chunks with outstanding reads */
100 spinlock_t tracked_chunk_lock;
101 mempool_t *tracked_chunk_pool;
102 struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
103
99 /* The on disk metadata handler */ 104 /* The on disk metadata handler */
100 struct dm_exception_store *store; 105 struct dm_exception_store *store;
101 106
@@ -105,10 +110,12 @@ struct dm_snapshot {
105 struct bio_list queued_bios; 110 struct bio_list queued_bios;
106 struct work_struct queued_bios_work; 111 struct work_struct queued_bios_work;
107 112
108 /* Chunks with outstanding reads */ 113 /* Wait for events based on state_bits */
109 mempool_t *tracked_chunk_pool; 114 unsigned long state_bits;
110 spinlock_t tracked_chunk_lock; 115
111 struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; 116 /* Range of chunks currently being merged. */
117 chunk_t first_merging_chunk;
118 int num_merging_chunks;
112 119
113 /* 120 /*
114 * The merge operation failed if this flag is set. 121 * The merge operation failed if this flag is set.
@@ -125,13 +132,6 @@ struct dm_snapshot {
125 */ 132 */
126 int merge_failed; 133 int merge_failed;
127 134
128 /* Wait for events based on state_bits */
129 unsigned long state_bits;
130
131 /* Range of chunks currently being merged. */
132 chunk_t first_merging_chunk;
133 int num_merging_chunks;
134
135 /* 135 /*
136 * Incoming bios that overlap with chunks being merged must wait 136 * Incoming bios that overlap with chunks being merged must wait
137 * for them to be committed. 137 * for them to be committed.
@@ -1081,8 +1081,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1081 argv++; 1081 argv++;
1082 argc--; 1082 argc--;
1083 1083
1084 r = dm_get_device(ti, cow_path, 0, 0, 1084 r = dm_get_device(ti, cow_path, FMODE_READ | FMODE_WRITE, &s->cow);
1085 FMODE_READ | FMODE_WRITE, &s->cow);
1086 if (r) { 1085 if (r) {
1087 ti->error = "Cannot get COW device"; 1086 ti->error = "Cannot get COW device";
1088 goto bad_cow; 1087 goto bad_cow;
@@ -1098,7 +1097,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1098 argv += args_used; 1097 argv += args_used;
1099 argc -= args_used; 1098 argc -= args_used;
1100 1099
1101 r = dm_get_device(ti, origin_path, 0, ti->len, origin_mode, &s->origin); 1100 r = dm_get_device(ti, origin_path, origin_mode, &s->origin);
1102 if (r) { 1101 if (r) {
1103 ti->error = "Cannot get origin device"; 1102 ti->error = "Cannot get origin device";
1104 goto bad_origin; 1103 goto bad_origin;
@@ -2100,8 +2099,7 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
2100 return -EINVAL; 2099 return -EINVAL;
2101 } 2100 }
2102 2101
2103 r = dm_get_device(ti, argv[0], 0, ti->len, 2102 r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &dev);
2104 dm_table_get_mode(ti->table), &dev);
2105 if (r) { 2103 if (r) {
2106 ti->error = "Cannot get target device"; 2104 ti->error = "Cannot get target device";
2107 return r; 2105 return r;
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index bd58703ee8f6..e610725db766 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -80,8 +80,7 @@ static int get_stripe(struct dm_target *ti, struct stripe_c *sc,
80 if (sscanf(argv[1], "%llu", &start) != 1) 80 if (sscanf(argv[1], "%llu", &start) != 1)
81 return -EINVAL; 81 return -EINVAL;
82 82
83 if (dm_get_device(ti, argv[0], start, sc->stripe_width, 83 if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
84 dm_table_get_mode(ti->table),
85 &sc->stripe[stripe].dev)) 84 &sc->stripe[stripe].dev))
86 return -ENXIO; 85 return -ENXIO;
87 86
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 4b22feb01a0c..9924ea23032d 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -429,8 +429,7 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
429 * it's already present. 429 * it's already present.
430 */ 430 */
431static int __table_get_device(struct dm_table *t, struct dm_target *ti, 431static int __table_get_device(struct dm_table *t, struct dm_target *ti,
432 const char *path, sector_t start, sector_t len, 432 const char *path, fmode_t mode, struct dm_dev **result)
433 fmode_t mode, struct dm_dev **result)
434{ 433{
435 int r; 434 int r;
436 dev_t uninitialized_var(dev); 435 dev_t uninitialized_var(dev);
@@ -527,11 +526,10 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
527} 526}
528EXPORT_SYMBOL_GPL(dm_set_device_limits); 527EXPORT_SYMBOL_GPL(dm_set_device_limits);
529 528
530int dm_get_device(struct dm_target *ti, const char *path, sector_t start, 529int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
531 sector_t len, fmode_t mode, struct dm_dev **result) 530 struct dm_dev **result)
532{ 531{
533 return __table_get_device(ti->table, ti, path, 532 return __table_get_device(ti->table, ti, path, mode, result);
534 start, len, mode, result);
535} 533}
536 534
537 535
@@ -1231,8 +1229,6 @@ void dm_table_unplug_all(struct dm_table *t)
1231 1229
1232struct mapped_device *dm_table_get_md(struct dm_table *t) 1230struct mapped_device *dm_table_get_md(struct dm_table *t)
1233{ 1231{
1234 dm_get(t->md);
1235
1236 return t->md; 1232 return t->md;
1237} 1233}
1238 1234
diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c
index c7c555a8c7b2..6b1e3b61b25e 100644
--- a/drivers/md/dm-uevent.c
+++ b/drivers/md/dm-uevent.c
@@ -187,7 +187,7 @@ void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
187 187
188 if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) { 188 if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
189 DMERR("%s: Invalid event_type %d", __func__, event_type); 189 DMERR("%s: Invalid event_type %d", __func__, event_type);
190 goto out; 190 return;
191 } 191 }
192 192
193 event = dm_build_path_uevent(md, ti, 193 event = dm_build_path_uevent(md, ti,
@@ -195,12 +195,9 @@ void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
195 _dm_uevent_type_names[event_type].name, 195 _dm_uevent_type_names[event_type].name,
196 path, nr_valid_paths); 196 path, nr_valid_paths);
197 if (IS_ERR(event)) 197 if (IS_ERR(event))
198 goto out; 198 return;
199 199
200 dm_uevent_add(md, &event->elist); 200 dm_uevent_add(md, &event->elist);
201
202out:
203 dm_put(md);
204} 201}
205EXPORT_SYMBOL_GPL(dm_path_uevent); 202EXPORT_SYMBOL_GPL(dm_path_uevent);
206 203
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index aa4e2aa86d49..d21e1284604f 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -635,8 +635,10 @@ static void dec_pending(struct dm_io *io, int error)
635 if (!md->barrier_error && io_error != -EOPNOTSUPP) 635 if (!md->barrier_error && io_error != -EOPNOTSUPP)
636 md->barrier_error = io_error; 636 md->barrier_error = io_error;
637 end_io_acct(io); 637 end_io_acct(io);
638 free_io(md, io);
638 } else { 639 } else {
639 end_io_acct(io); 640 end_io_acct(io);
641 free_io(md, io);
640 642
641 if (io_error != DM_ENDIO_REQUEUE) { 643 if (io_error != DM_ENDIO_REQUEUE) {
642 trace_block_bio_complete(md->queue, bio); 644 trace_block_bio_complete(md->queue, bio);
@@ -644,8 +646,6 @@ static void dec_pending(struct dm_io *io, int error)
644 bio_endio(bio, io_error); 646 bio_endio(bio, io_error);
645 } 647 }
646 } 648 }
647
648 free_io(md, io);
649 } 649 }
650} 650}
651 651
@@ -2618,18 +2618,19 @@ out:
2618/*----------------------------------------------------------------- 2618/*-----------------------------------------------------------------
2619 * Event notification. 2619 * Event notification.
2620 *---------------------------------------------------------------*/ 2620 *---------------------------------------------------------------*/
2621void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action, 2621int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
2622 unsigned cookie) 2622 unsigned cookie)
2623{ 2623{
2624 char udev_cookie[DM_COOKIE_LENGTH]; 2624 char udev_cookie[DM_COOKIE_LENGTH];
2625 char *envp[] = { udev_cookie, NULL }; 2625 char *envp[] = { udev_cookie, NULL };
2626 2626
2627 if (!cookie) 2627 if (!cookie)
2628 kobject_uevent(&disk_to_dev(md->disk)->kobj, action); 2628 return kobject_uevent(&disk_to_dev(md->disk)->kobj, action);
2629 else { 2629 else {
2630 snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u", 2630 snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u",
2631 DM_COOKIE_ENV_VAR_NAME, cookie); 2631 DM_COOKIE_ENV_VAR_NAME, cookie);
2632 kobject_uevent_env(&disk_to_dev(md->disk)->kobj, action, envp); 2632 return kobject_uevent_env(&disk_to_dev(md->disk)->kobj,
2633 action, envp);
2633 } 2634 }
2634} 2635}
2635 2636
@@ -2699,23 +2700,13 @@ int dm_suspended_md(struct mapped_device *md)
2699 2700
2700int dm_suspended(struct dm_target *ti) 2701int dm_suspended(struct dm_target *ti)
2701{ 2702{
2702 struct mapped_device *md = dm_table_get_md(ti->table); 2703 return dm_suspended_md(dm_table_get_md(ti->table));
2703 int r = dm_suspended_md(md);
2704
2705 dm_put(md);
2706
2707 return r;
2708} 2704}
2709EXPORT_SYMBOL_GPL(dm_suspended); 2705EXPORT_SYMBOL_GPL(dm_suspended);
2710 2706
2711int dm_noflush_suspending(struct dm_target *ti) 2707int dm_noflush_suspending(struct dm_target *ti)
2712{ 2708{
2713 struct mapped_device *md = dm_table_get_md(ti->table); 2709 return __noflush_suspending(dm_table_get_md(ti->table));
2714 int r = __noflush_suspending(md);
2715
2716 dm_put(md);
2717
2718 return r;
2719} 2710}
2720EXPORT_SYMBOL_GPL(dm_noflush_suspending); 2711EXPORT_SYMBOL_GPL(dm_noflush_suspending);
2721 2712
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 8dadaa5bc396..bad1724d4869 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -125,8 +125,8 @@ void dm_stripe_exit(void);
125int dm_open_count(struct mapped_device *md); 125int dm_open_count(struct mapped_device *md);
126int dm_lock_for_deletion(struct mapped_device *md); 126int dm_lock_for_deletion(struct mapped_device *md);
127 127
128void dm_kobject_uevent(struct mapped_device *md, enum kobject_action action, 128int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action,
129 unsigned cookie); 129 unsigned cookie);
130 130
131int dm_io_init(void); 131int dm_io_init(void);
132void dm_io_exit(void); 132void dm_io_exit(void);
diff --git a/drivers/mfd/88pm8607.c b/drivers/mfd/88pm8607.c
deleted file mode 100644
index 7e3f65907993..000000000000
--- a/drivers/mfd/88pm8607.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 * Base driver for Marvell 88PM8607
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16#include <linux/i2c.h>
17#include <linux/mfd/core.h>
18#include <linux/mfd/88pm8607.h>
19
20
21#define PM8607_REG_RESOURCE(_start, _end) \
22{ \
23 .start = PM8607_##_start, \
24 .end = PM8607_##_end, \
25 .flags = IORESOURCE_IO, \
26}
27
28static struct resource pm8607_regulator_resources[] = {
29 PM8607_REG_RESOURCE(BUCK1, BUCK1),
30 PM8607_REG_RESOURCE(BUCK2, BUCK2),
31 PM8607_REG_RESOURCE(BUCK3, BUCK3),
32 PM8607_REG_RESOURCE(LDO1, LDO1),
33 PM8607_REG_RESOURCE(LDO2, LDO2),
34 PM8607_REG_RESOURCE(LDO3, LDO3),
35 PM8607_REG_RESOURCE(LDO4, LDO4),
36 PM8607_REG_RESOURCE(LDO5, LDO5),
37 PM8607_REG_RESOURCE(LDO6, LDO6),
38 PM8607_REG_RESOURCE(LDO7, LDO7),
39 PM8607_REG_RESOURCE(LDO8, LDO8),
40 PM8607_REG_RESOURCE(LDO9, LDO9),
41 PM8607_REG_RESOURCE(LDO10, LDO10),
42 PM8607_REG_RESOURCE(LDO12, LDO12),
43 PM8607_REG_RESOURCE(LDO14, LDO14),
44};
45
46#define PM8607_REG_DEVS(_name, _id) \
47{ \
48 .name = "88pm8607-" #_name, \
49 .num_resources = 1, \
50 .resources = &pm8607_regulator_resources[PM8607_ID_##_id], \
51}
52
53static struct mfd_cell pm8607_devs[] = {
54 PM8607_REG_DEVS(buck1, BUCK1),
55 PM8607_REG_DEVS(buck2, BUCK2),
56 PM8607_REG_DEVS(buck3, BUCK3),
57 PM8607_REG_DEVS(ldo1, LDO1),
58 PM8607_REG_DEVS(ldo2, LDO2),
59 PM8607_REG_DEVS(ldo3, LDO3),
60 PM8607_REG_DEVS(ldo4, LDO4),
61 PM8607_REG_DEVS(ldo5, LDO5),
62 PM8607_REG_DEVS(ldo6, LDO6),
63 PM8607_REG_DEVS(ldo7, LDO7),
64 PM8607_REG_DEVS(ldo8, LDO8),
65 PM8607_REG_DEVS(ldo9, LDO9),
66 PM8607_REG_DEVS(ldo10, LDO10),
67 PM8607_REG_DEVS(ldo12, LDO12),
68 PM8607_REG_DEVS(ldo14, LDO14),
69};
70
71static inline int pm8607_read_device(struct pm8607_chip *chip,
72 int reg, int bytes, void *dest)
73{
74 struct i2c_client *i2c = chip->client;
75 unsigned char data;
76 int ret;
77
78 data = (unsigned char)reg;
79 ret = i2c_master_send(i2c, &data, 1);
80 if (ret < 0)
81 return ret;
82
83 ret = i2c_master_recv(i2c, dest, bytes);
84 if (ret < 0)
85 return ret;
86 return 0;
87}
88
89static inline int pm8607_write_device(struct pm8607_chip *chip,
90 int reg, int bytes, void *src)
91{
92 struct i2c_client *i2c = chip->client;
93 unsigned char buf[bytes + 1];
94 int ret;
95
96 buf[0] = (unsigned char)reg;
97 memcpy(&buf[1], src, bytes);
98
99 ret = i2c_master_send(i2c, buf, bytes + 1);
100 if (ret < 0)
101 return ret;
102 return 0;
103}
104
105int pm8607_reg_read(struct pm8607_chip *chip, int reg)
106{
107 unsigned char data;
108 int ret;
109
110 mutex_lock(&chip->io_lock);
111 ret = chip->read(chip, reg, 1, &data);
112 mutex_unlock(&chip->io_lock);
113
114 if (ret < 0)
115 return ret;
116 else
117 return (int)data;
118}
119EXPORT_SYMBOL(pm8607_reg_read);
120
121int pm8607_reg_write(struct pm8607_chip *chip, int reg,
122 unsigned char data)
123{
124 int ret;
125
126 mutex_lock(&chip->io_lock);
127 ret = chip->write(chip, reg, 1, &data);
128 mutex_unlock(&chip->io_lock);
129
130 return ret;
131}
132EXPORT_SYMBOL(pm8607_reg_write);
133
134int pm8607_bulk_read(struct pm8607_chip *chip, int reg,
135 int count, unsigned char *buf)
136{
137 int ret;
138
139 mutex_lock(&chip->io_lock);
140 ret = chip->read(chip, reg, count, buf);
141 mutex_unlock(&chip->io_lock);
142
143 return ret;
144}
145EXPORT_SYMBOL(pm8607_bulk_read);
146
147int pm8607_bulk_write(struct pm8607_chip *chip, int reg,
148 int count, unsigned char *buf)
149{
150 int ret;
151
152 mutex_lock(&chip->io_lock);
153 ret = chip->write(chip, reg, count, buf);
154 mutex_unlock(&chip->io_lock);
155
156 return ret;
157}
158EXPORT_SYMBOL(pm8607_bulk_write);
159
160int pm8607_set_bits(struct pm8607_chip *chip, int reg,
161 unsigned char mask, unsigned char data)
162{
163 unsigned char value;
164 int ret;
165
166 mutex_lock(&chip->io_lock);
167 ret = chip->read(chip, reg, 1, &value);
168 if (ret < 0)
169 goto out;
170 value &= ~mask;
171 value |= data;
172 ret = chip->write(chip, reg, 1, &value);
173out:
174 mutex_unlock(&chip->io_lock);
175 return ret;
176}
177EXPORT_SYMBOL(pm8607_set_bits);
178
179
180static const struct i2c_device_id pm8607_id_table[] = {
181 { "88PM8607", 0 },
182 {}
183};
184MODULE_DEVICE_TABLE(i2c, pm8607_id_table);
185
186
187static int __devinit pm8607_probe(struct i2c_client *client,
188 const struct i2c_device_id *id)
189{
190 struct pm8607_platform_data *pdata = client->dev.platform_data;
191 struct pm8607_chip *chip;
192 int i, count;
193 int ret;
194
195 chip = kzalloc(sizeof(struct pm8607_chip), GFP_KERNEL);
196 if (chip == NULL)
197 return -ENOMEM;
198
199 chip->client = client;
200 chip->dev = &client->dev;
201 chip->read = pm8607_read_device;
202 chip->write = pm8607_write_device;
203 i2c_set_clientdata(client, chip);
204
205 mutex_init(&chip->io_lock);
206 dev_set_drvdata(chip->dev, chip);
207
208 ret = pm8607_reg_read(chip, PM8607_CHIP_ID);
209 if (ret < 0) {
210 dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
211 goto out;
212 }
213 if ((ret & CHIP_ID_MASK) == CHIP_ID)
214 dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
215 ret);
216 else {
217 dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
218 "Chip ID: %02x\n", ret);
219 goto out;
220 }
221 chip->chip_id = ret;
222
223 ret = pm8607_reg_read(chip, PM8607_BUCK3);
224 if (ret < 0) {
225 dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
226 goto out;
227 }
228 if (ret & PM8607_BUCK3_DOUBLE)
229 chip->buck3_double = 1;
230
231 ret = pm8607_reg_read(chip, PM8607_MISC1);
232 if (ret < 0) {
233 dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
234 goto out;
235 }
236 if (pdata->i2c_port == PI2C_PORT)
237 ret |= PM8607_MISC1_PI2C;
238 else
239 ret &= ~PM8607_MISC1_PI2C;
240 ret = pm8607_reg_write(chip, PM8607_MISC1, ret);
241 if (ret < 0) {
242 dev_err(chip->dev, "Failed to write MISC1 register: %d\n", ret);
243 goto out;
244 }
245
246
247 count = ARRAY_SIZE(pm8607_devs);
248 for (i = 0; i < count; i++) {
249 ret = mfd_add_devices(chip->dev, i, &pm8607_devs[i],
250 1, NULL, 0);
251 if (ret != 0) {
252 dev_err(chip->dev, "Failed to add subdevs\n");
253 goto out;
254 }
255 }
256
257 return 0;
258
259out:
260 i2c_set_clientdata(client, NULL);
261 kfree(chip);
262 return ret;
263}
264
265static int __devexit pm8607_remove(struct i2c_client *client)
266{
267 struct pm8607_chip *chip = i2c_get_clientdata(client);
268
269 mfd_remove_devices(chip->dev);
270 kfree(chip);
271 return 0;
272}
273
274static struct i2c_driver pm8607_driver = {
275 .driver = {
276 .name = "88PM8607",
277 .owner = THIS_MODULE,
278 },
279 .probe = pm8607_probe,
280 .remove = __devexit_p(pm8607_remove),
281 .id_table = pm8607_id_table,
282};
283
284static int __init pm8607_init(void)
285{
286 int ret;
287 ret = i2c_add_driver(&pm8607_driver);
288 if (ret != 0)
289 pr_err("Failed to register 88PM8607 I2C driver: %d\n", ret);
290 return ret;
291}
292subsys_initcall(pm8607_init);
293
294static void __exit pm8607_exit(void)
295{
296 i2c_del_driver(&pm8607_driver);
297}
298module_exit(pm8607_exit);
299
300MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM8607");
301MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
302MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
new file mode 100644
index 000000000000..6a14d2b1ccf0
--- /dev/null
+++ b/drivers/mfd/88pm860x-core.c
@@ -0,0 +1,740 @@
1/*
2 * Base driver for Marvell 88PM8607
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/i2c.h>
15#include <linux/irq.h>
16#include <linux/interrupt.h>
17#include <linux/platform_device.h>
18#include <linux/mfd/core.h>
19#include <linux/mfd/88pm860x.h>
20
21#define INT_STATUS_NUM 3
22
23char pm860x_backlight_name[][MFD_NAME_SIZE] = {
24 "backlight-0",
25 "backlight-1",
26 "backlight-2",
27};
28EXPORT_SYMBOL(pm860x_backlight_name);
29
30char pm860x_led_name[][MFD_NAME_SIZE] = {
31 "led0-red",
32 "led0-green",
33 "led0-blue",
34 "led1-red",
35 "led1-green",
36 "led1-blue",
37};
38EXPORT_SYMBOL(pm860x_led_name);
39
40#define PM8606_BACKLIGHT_RESOURCE(_i, _x) \
41{ \
42 .name = pm860x_backlight_name[_i], \
43 .start = PM8606_##_x, \
44 .end = PM8606_##_x, \
45 .flags = IORESOURCE_IO, \
46}
47
48static struct resource backlight_resources[] = {
49 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT1, WLED1A),
50 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT2, WLED2A),
51 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT3, WLED3A),
52};
53
54#define PM8606_BACKLIGHT_DEVS(_i) \
55{ \
56 .name = "88pm860x-backlight", \
57 .num_resources = 1, \
58 .resources = &backlight_resources[_i], \
59 .id = _i, \
60}
61
62static struct mfd_cell backlight_devs[] = {
63 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT1),
64 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT2),
65 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT3),
66};
67
68#define PM8606_LED_RESOURCE(_i, _x) \
69{ \
70 .name = pm860x_led_name[_i], \
71 .start = PM8606_##_x, \
72 .end = PM8606_##_x, \
73 .flags = IORESOURCE_IO, \
74}
75
76static struct resource led_resources[] = {
77 PM8606_LED_RESOURCE(PM8606_LED1_RED, RGB2B),
78 PM8606_LED_RESOURCE(PM8606_LED1_GREEN, RGB2C),
79 PM8606_LED_RESOURCE(PM8606_LED1_BLUE, RGB2D),
80 PM8606_LED_RESOURCE(PM8606_LED2_RED, RGB1B),
81 PM8606_LED_RESOURCE(PM8606_LED2_GREEN, RGB1C),
82 PM8606_LED_RESOURCE(PM8606_LED2_BLUE, RGB1D),
83};
84
85#define PM8606_LED_DEVS(_i) \
86{ \
87 .name = "88pm860x-led", \
88 .num_resources = 1, \
89 .resources = &led_resources[_i], \
90 .id = _i, \
91}
92
93static struct mfd_cell led_devs[] = {
94 PM8606_LED_DEVS(PM8606_LED1_RED),
95 PM8606_LED_DEVS(PM8606_LED1_GREEN),
96 PM8606_LED_DEVS(PM8606_LED1_BLUE),
97 PM8606_LED_DEVS(PM8606_LED2_RED),
98 PM8606_LED_DEVS(PM8606_LED2_GREEN),
99 PM8606_LED_DEVS(PM8606_LED2_BLUE),
100};
101
102static struct resource touch_resources[] = {
103 {
104 .start = PM8607_IRQ_PEN,
105 .end = PM8607_IRQ_PEN,
106 .flags = IORESOURCE_IRQ,
107 },
108};
109
110static struct mfd_cell touch_devs[] = {
111 {
112 .name = "88pm860x-touch",
113 .num_resources = 1,
114 .resources = &touch_resources[0],
115 },
116};
117
118#define PM8607_REG_RESOURCE(_start, _end) \
119{ \
120 .start = PM8607_##_start, \
121 .end = PM8607_##_end, \
122 .flags = IORESOURCE_IO, \
123}
124
125static struct resource power_supply_resources[] = {
126 {
127 .name = "88pm860x-power",
128 .start = PM8607_IRQ_CHG,
129 .end = PM8607_IRQ_CHG,
130 .flags = IORESOURCE_IRQ,
131 },
132};
133
134static struct mfd_cell power_devs[] = {
135 {
136 .name = "88pm860x-power",
137 .num_resources = 1,
138 .resources = &power_supply_resources[0],
139 .id = -1,
140 },
141};
142
143static struct resource onkey_resources[] = {
144 {
145 .name = "88pm860x-onkey",
146 .start = PM8607_IRQ_ONKEY,
147 .end = PM8607_IRQ_ONKEY,
148 .flags = IORESOURCE_IRQ,
149 },
150};
151
152static struct mfd_cell onkey_devs[] = {
153 {
154 .name = "88pm860x-onkey",
155 .num_resources = 1,
156 .resources = &onkey_resources[0],
157 .id = -1,
158 },
159};
160
161static struct resource regulator_resources[] = {
162 PM8607_REG_RESOURCE(BUCK1, BUCK1),
163 PM8607_REG_RESOURCE(BUCK2, BUCK2),
164 PM8607_REG_RESOURCE(BUCK3, BUCK3),
165 PM8607_REG_RESOURCE(LDO1, LDO1),
166 PM8607_REG_RESOURCE(LDO2, LDO2),
167 PM8607_REG_RESOURCE(LDO3, LDO3),
168 PM8607_REG_RESOURCE(LDO4, LDO4),
169 PM8607_REG_RESOURCE(LDO5, LDO5),
170 PM8607_REG_RESOURCE(LDO6, LDO6),
171 PM8607_REG_RESOURCE(LDO7, LDO7),
172 PM8607_REG_RESOURCE(LDO8, LDO8),
173 PM8607_REG_RESOURCE(LDO9, LDO9),
174 PM8607_REG_RESOURCE(LDO10, LDO10),
175 PM8607_REG_RESOURCE(LDO12, LDO12),
176 PM8607_REG_RESOURCE(LDO14, LDO14),
177};
178
179#define PM8607_REG_DEVS(_name, _id) \
180{ \
181 .name = "88pm8607-" #_name, \
182 .num_resources = 1, \
183 .resources = &regulator_resources[PM8607_ID_##_id], \
184 .id = PM8607_ID_##_id, \
185}
186
187static struct mfd_cell regulator_devs[] = {
188 PM8607_REG_DEVS(buck1, BUCK1),
189 PM8607_REG_DEVS(buck2, BUCK2),
190 PM8607_REG_DEVS(buck3, BUCK3),
191 PM8607_REG_DEVS(ldo1, LDO1),
192 PM8607_REG_DEVS(ldo2, LDO2),
193 PM8607_REG_DEVS(ldo3, LDO3),
194 PM8607_REG_DEVS(ldo4, LDO4),
195 PM8607_REG_DEVS(ldo5, LDO5),
196 PM8607_REG_DEVS(ldo6, LDO6),
197 PM8607_REG_DEVS(ldo7, LDO7),
198 PM8607_REG_DEVS(ldo8, LDO8),
199 PM8607_REG_DEVS(ldo9, LDO9),
200 PM8607_REG_DEVS(ldo10, LDO10),
201 PM8607_REG_DEVS(ldo12, LDO12),
202 PM8607_REG_DEVS(ldo14, LDO14),
203};
204
205struct pm860x_irq_data {
206 int reg;
207 int mask_reg;
208 int enable; /* enable or not */
209 int offs; /* bit offset in mask register */
210};
211
212static struct pm860x_irq_data pm860x_irqs[] = {
213 [PM8607_IRQ_ONKEY] = {
214 .reg = PM8607_INT_STATUS1,
215 .mask_reg = PM8607_INT_MASK_1,
216 .offs = 1 << 0,
217 },
218 [PM8607_IRQ_EXTON] = {
219 .reg = PM8607_INT_STATUS1,
220 .mask_reg = PM8607_INT_MASK_1,
221 .offs = 1 << 1,
222 },
223 [PM8607_IRQ_CHG] = {
224 .reg = PM8607_INT_STATUS1,
225 .mask_reg = PM8607_INT_MASK_1,
226 .offs = 1 << 2,
227 },
228 [PM8607_IRQ_BAT] = {
229 .reg = PM8607_INT_STATUS1,
230 .mask_reg = PM8607_INT_MASK_1,
231 .offs = 1 << 3,
232 },
233 [PM8607_IRQ_RTC] = {
234 .reg = PM8607_INT_STATUS1,
235 .mask_reg = PM8607_INT_MASK_1,
236 .offs = 1 << 4,
237 },
238 [PM8607_IRQ_CC] = {
239 .reg = PM8607_INT_STATUS1,
240 .mask_reg = PM8607_INT_MASK_1,
241 .offs = 1 << 5,
242 },
243 [PM8607_IRQ_VBAT] = {
244 .reg = PM8607_INT_STATUS2,
245 .mask_reg = PM8607_INT_MASK_2,
246 .offs = 1 << 0,
247 },
248 [PM8607_IRQ_VCHG] = {
249 .reg = PM8607_INT_STATUS2,
250 .mask_reg = PM8607_INT_MASK_2,
251 .offs = 1 << 1,
252 },
253 [PM8607_IRQ_VSYS] = {
254 .reg = PM8607_INT_STATUS2,
255 .mask_reg = PM8607_INT_MASK_2,
256 .offs = 1 << 2,
257 },
258 [PM8607_IRQ_TINT] = {
259 .reg = PM8607_INT_STATUS2,
260 .mask_reg = PM8607_INT_MASK_2,
261 .offs = 1 << 3,
262 },
263 [PM8607_IRQ_GPADC0] = {
264 .reg = PM8607_INT_STATUS2,
265 .mask_reg = PM8607_INT_MASK_2,
266 .offs = 1 << 4,
267 },
268 [PM8607_IRQ_GPADC1] = {
269 .reg = PM8607_INT_STATUS2,
270 .mask_reg = PM8607_INT_MASK_2,
271 .offs = 1 << 5,
272 },
273 [PM8607_IRQ_GPADC2] = {
274 .reg = PM8607_INT_STATUS2,
275 .mask_reg = PM8607_INT_MASK_2,
276 .offs = 1 << 6,
277 },
278 [PM8607_IRQ_GPADC3] = {
279 .reg = PM8607_INT_STATUS2,
280 .mask_reg = PM8607_INT_MASK_2,
281 .offs = 1 << 7,
282 },
283 [PM8607_IRQ_AUDIO_SHORT] = {
284 .reg = PM8607_INT_STATUS3,
285 .mask_reg = PM8607_INT_MASK_3,
286 .offs = 1 << 0,
287 },
288 [PM8607_IRQ_PEN] = {
289 .reg = PM8607_INT_STATUS3,
290 .mask_reg = PM8607_INT_MASK_3,
291 .offs = 1 << 1,
292 },
293 [PM8607_IRQ_HEADSET] = {
294 .reg = PM8607_INT_STATUS3,
295 .mask_reg = PM8607_INT_MASK_3,
296 .offs = 1 << 2,
297 },
298 [PM8607_IRQ_HOOK] = {
299 .reg = PM8607_INT_STATUS3,
300 .mask_reg = PM8607_INT_MASK_3,
301 .offs = 1 << 3,
302 },
303 [PM8607_IRQ_MICIN] = {
304 .reg = PM8607_INT_STATUS3,
305 .mask_reg = PM8607_INT_MASK_3,
306 .offs = 1 << 4,
307 },
308 [PM8607_IRQ_CHG_FAIL] = {
309 .reg = PM8607_INT_STATUS3,
310 .mask_reg = PM8607_INT_MASK_3,
311 .offs = 1 << 5,
312 },
313 [PM8607_IRQ_CHG_DONE] = {
314 .reg = PM8607_INT_STATUS3,
315 .mask_reg = PM8607_INT_MASK_3,
316 .offs = 1 << 6,
317 },
318 [PM8607_IRQ_CHG_FAULT] = {
319 .reg = PM8607_INT_STATUS3,
320 .mask_reg = PM8607_INT_MASK_3,
321 .offs = 1 << 7,
322 },
323};
324
325static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip,
326 int irq)
327{
328 return &pm860x_irqs[irq - chip->irq_base];
329}
330
331static irqreturn_t pm860x_irq(int irq, void *data)
332{
333 struct pm860x_chip *chip = data;
334 struct pm860x_irq_data *irq_data;
335 struct i2c_client *i2c;
336 int read_reg = -1, value = 0;
337 int i;
338
339 i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
340 for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
341 irq_data = &pm860x_irqs[i];
342 if (read_reg != irq_data->reg) {
343 read_reg = irq_data->reg;
344 value = pm860x_reg_read(i2c, irq_data->reg);
345 }
346 if (value & irq_data->enable)
347 handle_nested_irq(chip->irq_base + i);
348 }
349 return IRQ_HANDLED;
350}
351
352static void pm860x_irq_lock(unsigned int irq)
353{
354 struct pm860x_chip *chip = get_irq_chip_data(irq);
355
356 mutex_lock(&chip->irq_lock);
357}
358
359static void pm860x_irq_sync_unlock(unsigned int irq)
360{
361 struct pm860x_chip *chip = get_irq_chip_data(irq);
362 struct pm860x_irq_data *irq_data;
363 struct i2c_client *i2c;
364 static unsigned char cached[3] = {0x0, 0x0, 0x0};
365 unsigned char mask[3];
366 int i;
367
368 i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
369 /* Load cached value. In initial, all IRQs are masked */
370 for (i = 0; i < 3; i++)
371 mask[i] = cached[i];
372 for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
373 irq_data = &pm860x_irqs[i];
374 switch (irq_data->mask_reg) {
375 case PM8607_INT_MASK_1:
376 mask[0] &= ~irq_data->offs;
377 mask[0] |= irq_data->enable;
378 break;
379 case PM8607_INT_MASK_2:
380 mask[1] &= ~irq_data->offs;
381 mask[1] |= irq_data->enable;
382 break;
383 case PM8607_INT_MASK_3:
384 mask[2] &= ~irq_data->offs;
385 mask[2] |= irq_data->enable;
386 break;
387 default:
388 dev_err(chip->dev, "wrong IRQ\n");
389 break;
390 }
391 }
392 /* update mask into registers */
393 for (i = 0; i < 3; i++) {
394 if (mask[i] != cached[i]) {
395 cached[i] = mask[i];
396 pm860x_reg_write(i2c, PM8607_INT_MASK_1 + i, mask[i]);
397 }
398 }
399
400 mutex_unlock(&chip->irq_lock);
401}
402
403static void pm860x_irq_enable(unsigned int irq)
404{
405 struct pm860x_chip *chip = get_irq_chip_data(irq);
406 pm860x_irqs[irq - chip->irq_base].enable
407 = pm860x_irqs[irq - chip->irq_base].offs;
408}
409
410static void pm860x_irq_disable(unsigned int irq)
411{
412 struct pm860x_chip *chip = get_irq_chip_data(irq);
413 pm860x_irqs[irq - chip->irq_base].enable = 0;
414}
415
416static struct irq_chip pm860x_irq_chip = {
417 .name = "88pm860x",
418 .bus_lock = pm860x_irq_lock,
419 .bus_sync_unlock = pm860x_irq_sync_unlock,
420 .enable = pm860x_irq_enable,
421 .disable = pm860x_irq_disable,
422};
423
424static int __devinit device_gpadc_init(struct pm860x_chip *chip,
425 struct pm860x_platform_data *pdata)
426{
427 struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
428 : chip->companion;
429 int use_gpadc = 0, data, ret;
430
431 /* initialize GPADC without activating it */
432
433 if (pdata && pdata->touch) {
434 /* set GPADC MISC1 register */
435 data = 0;
436 data |= (pdata->touch->gpadc_prebias << 1)
437 & PM8607_GPADC_PREBIAS_MASK;
438 data |= (pdata->touch->slot_cycle << 3)
439 & PM8607_GPADC_SLOT_CYCLE_MASK;
440 data |= (pdata->touch->off_scale << 5)
441 & PM8607_GPADC_OFF_SCALE_MASK;
442 data |= (pdata->touch->sw_cal << 7)
443 & PM8607_GPADC_SW_CAL_MASK;
444 if (data) {
445 ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
446 if (ret < 0)
447 goto out;
448 }
449 /* set tsi prebias time */
450 if (pdata->touch->tsi_prebias) {
451 data = pdata->touch->tsi_prebias;
452 ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
453 if (ret < 0)
454 goto out;
455 }
456 /* set prebias & prechg time of pen detect */
457 data = 0;
458 data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
459 data |= (pdata->touch->pen_prechg << 5)
460 & PM8607_PD_PRECHG_MASK;
461 if (data) {
462 ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
463 if (ret < 0)
464 goto out;
465 }
466
467 use_gpadc = 1;
468 }
469
470 /* turn on GPADC */
471 if (use_gpadc) {
472 ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
473 PM8607_GPADC_EN, PM8607_GPADC_EN);
474 }
475out:
476 return ret;
477}
478
479static int __devinit device_irq_init(struct pm860x_chip *chip,
480 struct pm860x_platform_data *pdata)
481{
482 struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
483 : chip->companion;
484 unsigned char status_buf[INT_STATUS_NUM];
485 unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
486 struct irq_desc *desc;
487 int i, data, mask, ret = -EINVAL;
488 int __irq;
489
490 if (!pdata || !pdata->irq_base) {
491 dev_warn(chip->dev, "No interrupt support on IRQ base\n");
492 return -EINVAL;
493 }
494
495 mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
496 | PM8607_B0_MISC1_INT_MASK;
497 data = 0;
498 chip->irq_mode = 0;
499 if (pdata && pdata->irq_mode) {
500 /*
501 * irq_mode defines the way of clearing interrupt. If it's 1,
502 * clear IRQ by write. Otherwise, clear it by read.
503 * This control bit is valid from 88PM8607 B0 steping.
504 */
505 data |= PM8607_B0_MISC1_INT_CLEAR;
506 chip->irq_mode = 1;
507 }
508 ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, mask, data);
509 if (ret < 0)
510 goto out;
511
512 /* mask all IRQs */
513 memset(status_buf, 0, INT_STATUS_NUM);
514 ret = pm860x_bulk_write(i2c, PM8607_INT_MASK_1,
515 INT_STATUS_NUM, status_buf);
516 if (ret < 0)
517 goto out;
518
519 if (chip->irq_mode) {
520 /* clear interrupt status by write */
521 memset(status_buf, 0xFF, INT_STATUS_NUM);
522 ret = pm860x_bulk_write(i2c, PM8607_INT_STATUS1,
523 INT_STATUS_NUM, status_buf);
524 } else {
525 /* clear interrupt status by read */
526 ret = pm860x_bulk_read(i2c, PM8607_INT_STATUS1,
527 INT_STATUS_NUM, status_buf);
528 }
529 if (ret < 0)
530 goto out;
531
532 mutex_init(&chip->irq_lock);
533 chip->irq_base = pdata->irq_base;
534 chip->core_irq = i2c->irq;
535 if (!chip->core_irq)
536 goto out;
537
538 desc = irq_to_desc(chip->core_irq);
539
540 /* register IRQ by genirq */
541 for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
542 __irq = i + chip->irq_base;
543 set_irq_chip_data(__irq, chip);
544 set_irq_chip_and_handler(__irq, &pm860x_irq_chip,
545 handle_edge_irq);
546 set_irq_nested_thread(__irq, 1);
547#ifdef CONFIG_ARM
548 set_irq_flags(__irq, IRQF_VALID);
549#else
550 set_irq_noprobe(__irq);
551#endif
552 }
553
554 ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags,
555 "88pm860x", chip);
556 if (ret) {
557 dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
558 chip->core_irq = 0;
559 }
560
561 return 0;
562out:
563 chip->core_irq = 0;
564 return ret;
565}
566
567static void __devexit device_irq_exit(struct pm860x_chip *chip)
568{
569 if (chip->core_irq)
570 free_irq(chip->core_irq, chip);
571}
572
573static void __devinit device_8606_init(struct pm860x_chip *chip,
574 struct i2c_client *i2c,
575 struct pm860x_platform_data *pdata)
576{
577 int ret;
578
579 if (pdata && pdata->backlight) {
580 ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
581 ARRAY_SIZE(backlight_devs),
582 &backlight_resources[0], 0);
583 if (ret < 0) {
584 dev_err(chip->dev, "Failed to add backlight "
585 "subdev\n");
586 goto out_dev;
587 }
588 }
589
590 if (pdata && pdata->led) {
591 ret = mfd_add_devices(chip->dev, 0, &led_devs[0],
592 ARRAY_SIZE(led_devs),
593 &led_resources[0], 0);
594 if (ret < 0) {
595 dev_err(chip->dev, "Failed to add led "
596 "subdev\n");
597 goto out_dev;
598 }
599 }
600 return;
601out_dev:
602 mfd_remove_devices(chip->dev);
603 device_irq_exit(chip);
604}
605
606static void __devinit device_8607_init(struct pm860x_chip *chip,
607 struct i2c_client *i2c,
608 struct pm860x_platform_data *pdata)
609{
610 int data, ret;
611
612 ret = pm860x_reg_read(i2c, PM8607_CHIP_ID);
613 if (ret < 0) {
614 dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
615 goto out;
616 }
617 if ((ret & PM8607_VERSION_MASK) == PM8607_VERSION)
618 dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
619 ret);
620 else {
621 dev_err(chip->dev, "Failed to detect Marvell 88PM8607. "
622 "Chip ID: %02x\n", ret);
623 goto out;
624 }
625
626 ret = pm860x_reg_read(i2c, PM8607_BUCK3);
627 if (ret < 0) {
628 dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
629 goto out;
630 }
631 if (ret & PM8607_BUCK3_DOUBLE)
632 chip->buck3_double = 1;
633
634 ret = pm860x_reg_read(i2c, PM8607_B0_MISC1);
635 if (ret < 0) {
636 dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
637 goto out;
638 }
639
640 if (pdata && (pdata->i2c_port == PI2C_PORT))
641 data = PM8607_B0_MISC1_PI2C;
642 else
643 data = 0;
644 ret = pm860x_set_bits(i2c, PM8607_B0_MISC1, PM8607_B0_MISC1_PI2C, data);
645 if (ret < 0) {
646 dev_err(chip->dev, "Failed to access MISC1:%d\n", ret);
647 goto out;
648 }
649
650 ret = device_gpadc_init(chip, pdata);
651 if (ret < 0)
652 goto out;
653
654 ret = device_irq_init(chip, pdata);
655 if (ret < 0)
656 goto out;
657
658 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
659 ARRAY_SIZE(regulator_devs),
660 &regulator_resources[0], 0);
661 if (ret < 0) {
662 dev_err(chip->dev, "Failed to add regulator subdev\n");
663 goto out_dev;
664 }
665
666 if (pdata && pdata->touch) {
667 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
668 ARRAY_SIZE(touch_devs),
669 &touch_resources[0], 0);
670 if (ret < 0) {
671 dev_err(chip->dev, "Failed to add touch "
672 "subdev\n");
673 goto out_dev;
674 }
675 }
676
677 if (pdata && pdata->power) {
678 ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
679 ARRAY_SIZE(power_devs),
680 &power_supply_resources[0], 0);
681 if (ret < 0) {
682 dev_err(chip->dev, "Failed to add power supply "
683 "subdev\n");
684 goto out_dev;
685 }
686 }
687
688 ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
689 ARRAY_SIZE(onkey_devs),
690 &onkey_resources[0], 0);
691 if (ret < 0) {
692 dev_err(chip->dev, "Failed to add onkey subdev\n");
693 goto out_dev;
694 }
695
696 return;
697out_dev:
698 mfd_remove_devices(chip->dev);
699 device_irq_exit(chip);
700out:
701 return;
702}
703
704int pm860x_device_init(struct pm860x_chip *chip,
705 struct pm860x_platform_data *pdata)
706{
707 chip->core_irq = 0;
708
709 switch (chip->id) {
710 case CHIP_PM8606:
711 device_8606_init(chip, chip->client, pdata);
712 break;
713 case CHIP_PM8607:
714 device_8607_init(chip, chip->client, pdata);
715 break;
716 }
717
718 if (chip->companion) {
719 switch (chip->id) {
720 case CHIP_PM8607:
721 device_8606_init(chip, chip->companion, pdata);
722 break;
723 case CHIP_PM8606:
724 device_8607_init(chip, chip->companion, pdata);
725 break;
726 }
727 }
728
729 return 0;
730}
731
732void pm860x_device_exit(struct pm860x_chip *chip)
733{
734 device_irq_exit(chip);
735 mfd_remove_devices(chip->dev);
736}
737
738MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
739MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
740MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
new file mode 100644
index 000000000000..c37e12bf3004
--- /dev/null
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -0,0 +1,236 @@
1/*
2 * I2C driver for Marvell 88PM860x
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/i2c.h>
15#include <linux/mfd/88pm860x.h>
16
17static inline int pm860x_read_device(struct i2c_client *i2c,
18 int reg, int bytes, void *dest)
19{
20 unsigned char data;
21 int ret;
22
23 data = (unsigned char)reg;
24 ret = i2c_master_send(i2c, &data, 1);
25 if (ret < 0)
26 return ret;
27
28 ret = i2c_master_recv(i2c, dest, bytes);
29 if (ret < 0)
30 return ret;
31 return 0;
32}
33
34static inline int pm860x_write_device(struct i2c_client *i2c,
35 int reg, int bytes, void *src)
36{
37 unsigned char buf[bytes + 1];
38 int ret;
39
40 buf[0] = (unsigned char)reg;
41 memcpy(&buf[1], src, bytes);
42
43 ret = i2c_master_send(i2c, buf, bytes + 1);
44 if (ret < 0)
45 return ret;
46 return 0;
47}
48
49int pm860x_reg_read(struct i2c_client *i2c, int reg)
50{
51 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
52 unsigned char data;
53 int ret;
54
55 mutex_lock(&chip->io_lock);
56 ret = pm860x_read_device(i2c, reg, 1, &data);
57 mutex_unlock(&chip->io_lock);
58
59 if (ret < 0)
60 return ret;
61 else
62 return (int)data;
63}
64EXPORT_SYMBOL(pm860x_reg_read);
65
66int pm860x_reg_write(struct i2c_client *i2c, int reg,
67 unsigned char data)
68{
69 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
70 int ret;
71
72 mutex_lock(&chip->io_lock);
73 ret = pm860x_write_device(i2c, reg, 1, &data);
74 mutex_unlock(&chip->io_lock);
75
76 return ret;
77}
78EXPORT_SYMBOL(pm860x_reg_write);
79
80int pm860x_bulk_read(struct i2c_client *i2c, int reg,
81 int count, unsigned char *buf)
82{
83 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
84 int ret;
85
86 mutex_lock(&chip->io_lock);
87 ret = pm860x_read_device(i2c, reg, count, buf);
88 mutex_unlock(&chip->io_lock);
89
90 return ret;
91}
92EXPORT_SYMBOL(pm860x_bulk_read);
93
94int pm860x_bulk_write(struct i2c_client *i2c, int reg,
95 int count, unsigned char *buf)
96{
97 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
98 int ret;
99
100 mutex_lock(&chip->io_lock);
101 ret = pm860x_write_device(i2c, reg, count, buf);
102 mutex_unlock(&chip->io_lock);
103
104 return ret;
105}
106EXPORT_SYMBOL(pm860x_bulk_write);
107
108int pm860x_set_bits(struct i2c_client *i2c, int reg,
109 unsigned char mask, unsigned char data)
110{
111 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
112 unsigned char value;
113 int ret;
114
115 mutex_lock(&chip->io_lock);
116 ret = pm860x_read_device(i2c, reg, 1, &value);
117 if (ret < 0)
118 goto out;
119 value &= ~mask;
120 value |= data;
121 ret = pm860x_write_device(i2c, reg, 1, &value);
122out:
123 mutex_unlock(&chip->io_lock);
124 return ret;
125}
126EXPORT_SYMBOL(pm860x_set_bits);
127
128
129static const struct i2c_device_id pm860x_id_table[] = {
130 { "88PM860x", 0 },
131 {}
132};
133MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
134
135static int verify_addr(struct i2c_client *i2c)
136{
137 unsigned short addr_8607[] = {0x30, 0x34};
138 unsigned short addr_8606[] = {0x10, 0x11};
139 int size, i;
140
141 if (i2c == NULL)
142 return 0;
143 size = ARRAY_SIZE(addr_8606);
144 for (i = 0; i < size; i++) {
145 if (i2c->addr == *(addr_8606 + i))
146 return CHIP_PM8606;
147 }
148 size = ARRAY_SIZE(addr_8607);
149 for (i = 0; i < size; i++) {
150 if (i2c->addr == *(addr_8607 + i))
151 return CHIP_PM8607;
152 }
153 return 0;
154}
155
156static int __devinit pm860x_probe(struct i2c_client *client,
157 const struct i2c_device_id *id)
158{
159 struct pm860x_platform_data *pdata = client->dev.platform_data;
160 struct pm860x_chip *chip;
161
162 if (!pdata) {
163 pr_info("No platform data in %s!\n", __func__);
164 return -EINVAL;
165 }
166
167 chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
168 if (chip == NULL)
169 return -ENOMEM;
170
171 chip->id = verify_addr(client);
172 chip->client = client;
173 i2c_set_clientdata(client, chip);
174 chip->dev = &client->dev;
175 mutex_init(&chip->io_lock);
176 dev_set_drvdata(chip->dev, chip);
177
178 /*
179 * Both client and companion client shares same platform driver.
180 * Driver distinguishes them by pdata->companion_addr.
181 * pdata->companion_addr is only assigned if companion chip exists.
182 * At the same time, the companion_addr shouldn't equal to client
183 * address.
184 */
185 if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
186 chip->companion_addr = pdata->companion_addr;
187 chip->companion = i2c_new_dummy(chip->client->adapter,
188 chip->companion_addr);
189 i2c_set_clientdata(chip->companion, chip);
190 }
191
192 pm860x_device_init(chip, pdata);
193 return 0;
194}
195
196static int __devexit pm860x_remove(struct i2c_client *client)
197{
198 struct pm860x_chip *chip = i2c_get_clientdata(client);
199
200 pm860x_device_exit(chip);
201 i2c_unregister_device(chip->companion);
202 i2c_set_clientdata(chip->companion, NULL);
203 i2c_set_clientdata(chip->client, NULL);
204 kfree(chip);
205 return 0;
206}
207
208static struct i2c_driver pm860x_driver = {
209 .driver = {
210 .name = "88PM860x",
211 .owner = THIS_MODULE,
212 },
213 .probe = pm860x_probe,
214 .remove = __devexit_p(pm860x_remove),
215 .id_table = pm860x_id_table,
216};
217
218static int __init pm860x_i2c_init(void)
219{
220 int ret;
221 ret = i2c_add_driver(&pm860x_driver);
222 if (ret != 0)
223 pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
224 return ret;
225}
226subsys_initcall(pm860x_i2c_init);
227
228static void __exit pm860x_i2c_exit(void)
229{
230 i2c_del_driver(&pm860x_driver);
231}
232module_exit(pm860x_i2c_exit);
233
234MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x");
235MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
236MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b670d10d5c92..951fa9b93fbe 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -9,6 +9,16 @@ config MFD_CORE
9 tristate 9 tristate
10 default n 10 default n
11 11
12config MFD_88PM860X
13 bool "Support Marvell 88PM8606/88PM8607"
14 depends on I2C=y
15 select MFD_CORE
16 help
17 This supports for Marvell 88PM8606/88PM8607 Power Management IC.
18 This includes the I2C driver and the core APIs _only_, you have to
19 select individual components like voltage regulators, RTC and
20 battery-charger under the corresponding menus.
21
12config MFD_SM501 22config MFD_SM501
13 tristate "Support for Silicon Motion SM501" 23 tristate "Support for Silicon Motion SM501"
14 ---help--- 24 ---help---
@@ -37,7 +47,7 @@ config MFD_ASIC3
37 47
38config MFD_SH_MOBILE_SDHI 48config MFD_SH_MOBILE_SDHI
39 bool "Support for SuperH Mobile SDHI" 49 bool "Support for SuperH Mobile SDHI"
40 depends on SUPERH 50 depends on SUPERH || ARCH_SHMOBILE
41 select MFD_CORE 51 select MFD_CORE
42 ---help--- 52 ---help---
43 This driver supports the SDHI hardware block found in many 53 This driver supports the SDHI hardware block found in many
@@ -68,6 +78,15 @@ config HTC_PASIC3
68 HTC Magician devices, respectively. Actual functionality is 78 HTC Magician devices, respectively. Actual functionality is
69 handled by the leds-pasic3 and ds1wm drivers. 79 handled by the leds-pasic3 and ds1wm drivers.
70 80
81config HTC_I2CPLD
82 bool "HTC I2C PLD chip support"
83 depends on I2C=y && GPIOLIB
84 help
85 If you say yes here you get support for the supposed CPLD
86 found on omap850 HTC devices like the HTC Wizard and HTC Herald.
87 This device provides input and output GPIOs through an I2C
88 interface to one or more sub-chips.
89
71config UCB1400_CORE 90config UCB1400_CORE
72 tristate "Philips UCB1400 Core driver" 91 tristate "Philips UCB1400 Core driver"
73 depends on AC97_BUS 92 depends on AC97_BUS
@@ -184,6 +203,16 @@ config PMIC_ADP5520
184 individual components like LCD backlight, LEDs, GPIOs and Kepad 203 individual components like LCD backlight, LEDs, GPIOs and Kepad
185 under the corresponding menus. 204 under the corresponding menus.
186 205
206config MFD_MAX8925
207 bool "Maxim Semiconductor MAX8925 PMIC Support"
208 depends on I2C=y
209 select MFD_CORE
210 help
211 Say yes here to support for Maxim Semiconductor MAX8925. This is
212 a Power Management IC. This driver provies common support for
213 accessing the device, additional drivers must be enabled in order
214 to use the functionality of the device.
215
187config MFD_WM8400 216config MFD_WM8400
188 tristate "Support Wolfson Microelectronics WM8400" 217 tristate "Support Wolfson Microelectronics WM8400"
189 select MFD_CORE 218 select MFD_CORE
@@ -205,7 +234,7 @@ config MFD_WM831X
205 functionality of the device. 234 functionality of the device.
206 235
207config MFD_WM8350 236config MFD_WM8350
208 tristate 237 bool
209 238
210config MFD_WM8350_CONFIG_MODE_0 239config MFD_WM8350_CONFIG_MODE_0
211 bool 240 bool
@@ -256,9 +285,9 @@ config MFD_WM8352_CONFIG_MODE_3
256 depends on MFD_WM8350 285 depends on MFD_WM8350
257 286
258config MFD_WM8350_I2C 287config MFD_WM8350_I2C
259 tristate "Support Wolfson Microelectronics WM8350 with I2C" 288 bool "Support Wolfson Microelectronics WM8350 with I2C"
260 select MFD_WM8350 289 select MFD_WM8350
261 depends on I2C 290 depends on I2C=y
262 help 291 help
263 The WM8350 is an integrated audio and power management 292 The WM8350 is an integrated audio and power management
264 subsystem with watchdog and RTC functionality for embedded 293 subsystem with watchdog and RTC functionality for embedded
@@ -266,6 +295,18 @@ config MFD_WM8350_I2C
266 I2C as the control interface. Additional options must be 295 I2C as the control interface. Additional options must be
267 selected to enable support for the functionality of the chip. 296 selected to enable support for the functionality of the chip.
268 297
298config MFD_WM8994
299 tristate "Support Wolfson Microelectronics WM8994"
300 select MFD_CORE
301 depends on I2C
302 help
303 The WM8994 is a highly integrated hi-fi CODEC designed for
304 smartphone applicatiosn. As well as audio functionality it
305 has on board GPIO and regulator functionality which is
306 supported via the relevant subsystems. This driver provides
307 core support for the WM8994, in order to use the actual
308 functionaltiy of the device other drivers must be enabled.
309
269config MFD_PCF50633 310config MFD_PCF50633
270 tristate "Support for NXP PCF50633" 311 tristate "Support for NXP PCF50633"
271 depends on I2C 312 depends on I2C
@@ -300,8 +341,8 @@ config PCF50633_GPIO
300 the PCF50633 chip. 341 the PCF50633 chip.
301 342
302config AB3100_CORE 343config AB3100_CORE
303 tristate "ST-Ericsson AB3100 Mixed Signal Circuit core functions" 344 bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
304 depends on I2C 345 depends on I2C=y
305 default y if ARCH_U300 346 default y if ARCH_U300
306 help 347 help
307 Select this to enable the AB3100 Mixed Signal IC core 348 Select this to enable the AB3100 Mixed Signal IC core
@@ -329,16 +370,6 @@ config EZX_PCAP
329 This enables the PCAP ASIC present on EZX Phones. This is 370 This enables the PCAP ASIC present on EZX Phones. This is
330 needed for MMC, TouchScreen, Sound, USB, etc.. 371 needed for MMC, TouchScreen, Sound, USB, etc..
331 372
332config MFD_88PM8607
333 bool "Support Marvell 88PM8607"
334 depends on I2C=y
335 select MFD_CORE
336 help
337 This supports for Marvell 88PM8607 Power Management IC. This includes
338 the I2C driver and the core APIs _only_, you have to select
339 individual components like voltage regulators, RTC and
340 battery-charger under the corresponding menus.
341
342config AB4500_CORE 373config AB4500_CORE
343 tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip" 374 tristate "ST-Ericsson's AB4500 Mixed Signal Power management chip"
344 depends on SPI 375 depends on SPI
@@ -358,6 +389,15 @@ config MFD_TIMBERDALE
358 389
359 The timberdale FPGA can be found on the Intel Atom development board 390 The timberdale FPGA can be found on the Intel Atom development board
360 for in-vehicle infontainment, called Russellville. 391 for in-vehicle infontainment, called Russellville.
392
393config LPC_SCH
394 tristate "Intel SCH LPC"
395 depends on PCI
396 select MFD_CORE
397 help
398 LPC bridge function of the Intel SCH provides support for
399 System Management Bus and General Purpose I/O.
400
361endmenu 401endmenu
362 402
363menu "Multimedia Capabilities Port drivers" 403menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 78295d6a75f7..22715add99a7 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -2,12 +2,15 @@
2# Makefile for multifunction miscellaneous devices 2# Makefile for multifunction miscellaneous devices
3# 3#
4 4
588pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o
6obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
5obj-$(CONFIG_MFD_SM501) += sm501.o 7obj-$(CONFIG_MFD_SM501) += sm501.o
6obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o 8obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
7obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o 9obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
8 10
9obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 11obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
10obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 12obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
13obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
11 14
12obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o 15obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
13 16
@@ -22,6 +25,7 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
22wm8350-objs += wm8350-irq.o 25wm8350-objs += wm8350-irq.o
23obj-$(CONFIG_MFD_WM8350) += wm8350.o 26obj-$(CONFIG_MFD_WM8350) += wm8350.o
24obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o 27obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
28obj-$(CONFIG_MFD_WM8994) += wm8994-core.o
25 29
26obj-$(CONFIG_TPS65010) += tps65010.o 30obj-$(CONFIG_TPS65010) += tps65010.o
27obj-$(CONFIG_MENELAUS) += menelaus.o 31obj-$(CONFIG_MENELAUS) += menelaus.o
@@ -47,6 +51,8 @@ endif
47obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o 51obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
48 52
49obj-$(CONFIG_PMIC_DA903X) += da903x.o 53obj-$(CONFIG_PMIC_DA903X) += da903x.o
54max8925-objs := max8925-core.o max8925-i2c.o
55obj-$(CONFIG_MFD_MAX8925) += max8925.o
50 56
51obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o 57obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o
52obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o 58obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
@@ -55,5 +61,5 @@ obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
55obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 61obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
56obj-$(CONFIG_AB4500_CORE) += ab4500-core.o 62obj-$(CONFIG_AB4500_CORE) += ab4500-core.o
57obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 63obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
58obj-$(CONFIG_MFD_88PM8607) += 88pm8607.o
59obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 64obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
65obj-$(CONFIG_LPC_SCH) += lpc_sch.o \ No newline at end of file
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index fd42a80e7bf9..a2ce3b6af4a2 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2007-2009 ST-Ericsson 2 * Copyright (C) 2007-2010 ST-Ericsson
3 * License terms: GNU General Public License (GPL) version 2 3 * License terms: GNU General Public License (GPL) version 2
4 * Low-level core for exclusive access to the AB3100 IC on the I2C bus 4 * Low-level core for exclusive access to the AB3100 IC on the I2C bus
5 * and some basic chip-configuration. 5 * and some basic chip-configuration.
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/random.h>
17#include <linux/debugfs.h> 18#include <linux/debugfs.h>
18#include <linux/seq_file.h> 19#include <linux/seq_file.h>
19#include <linux/uaccess.h> 20#include <linux/uaccess.h>
@@ -365,18 +366,23 @@ int ab3100_event_registers_startup_state_get(struct ab3100 *ab3100,
365} 366}
366EXPORT_SYMBOL(ab3100_event_registers_startup_state_get); 367EXPORT_SYMBOL(ab3100_event_registers_startup_state_get);
367 368
368/* Interrupt handling worker */ 369/*
369static void ab3100_work(struct work_struct *work) 370 * This is a threaded interrupt handler so we can make some
371 * I2C calls etc.
372 */
373static irqreturn_t ab3100_irq_handler(int irq, void *data)
370{ 374{
371 struct ab3100 *ab3100 = container_of(work, struct ab3100, work); 375 struct ab3100 *ab3100 = data;
372 u8 event_regs[3]; 376 u8 event_regs[3];
373 u32 fatevent; 377 u32 fatevent;
374 int err; 378 int err;
375 379
380 add_interrupt_randomness(irq);
381
376 err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, 382 err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
377 event_regs, 3); 383 event_regs, 3);
378 if (err) 384 if (err)
379 goto err_event_wq; 385 goto err_event;
380 386
381 fatevent = (event_regs[0] << 16) | 387 fatevent = (event_regs[0] << 16) |
382 (event_regs[1] << 8) | 388 (event_regs[1] << 8) |
@@ -398,29 +404,11 @@ static void ab3100_work(struct work_struct *work)
398 dev_dbg(ab3100->dev, 404 dev_dbg(ab3100->dev,
399 "IRQ Event: 0x%08x\n", fatevent); 405 "IRQ Event: 0x%08x\n", fatevent);
400 406
401 /* By now the IRQ should be acked and deasserted so enable it again */ 407 return IRQ_HANDLED;
402 enable_irq(ab3100->i2c_client->irq);
403 return;
404 408
405 err_event_wq: 409 err_event:
406 dev_dbg(ab3100->dev, 410 dev_dbg(ab3100->dev,
407 "error in event workqueue\n"); 411 "error reading event status\n");
408 /* Enable the IRQ anyway, what choice do we have? */
409 enable_irq(ab3100->i2c_client->irq);
410 return;
411}
412
413static irqreturn_t ab3100_irq_handler(int irq, void *data)
414{
415 struct ab3100 *ab3100 = data;
416 /*
417 * Disable the IRQ and dispatch a worker to handle the
418 * event. Since the chip resides on I2C this is slow
419 * stuff and we will re-enable the interrupts once th
420 * worker has finished.
421 */
422 disable_irq_nosync(irq);
423 schedule_work(&ab3100->work);
424 return IRQ_HANDLED; 412 return IRQ_HANDLED;
425} 413}
426 414
@@ -735,10 +723,7 @@ static struct platform_device ab3100_##devname##_device = { \
735 .id = -1, \ 723 .id = -1, \
736} 724}
737 725
738/* 726/* This lists all the subdevices */
739 * This lists all the subdevices and corresponding register
740 * ranges.
741 */
742AB3100_DEVICE(dac, "ab3100-dac"); 727AB3100_DEVICE(dac, "ab3100-dac");
743AB3100_DEVICE(leds, "ab3100-leds"); 728AB3100_DEVICE(leds, "ab3100-leds");
744AB3100_DEVICE(power, "ab3100-power"); 729AB3100_DEVICE(power, "ab3100-power");
@@ -904,12 +889,11 @@ static int __init ab3100_probe(struct i2c_client *client,
904 if (err) 889 if (err)
905 goto exit_no_setup; 890 goto exit_no_setup;
906 891
907 INIT_WORK(&ab3100->work, ab3100_work); 892 err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
908 893 IRQF_ONESHOT, "ab3100-core", ab3100);
909 /* This real unpredictable IRQ is of course sampled for entropy */ 894 /* This real unpredictable IRQ is of course sampled for entropy */
910 err = request_irq(client->irq, ab3100_irq_handler, 895 rand_initialize_irq(client->irq);
911 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, 896
912 "AB3100 IRQ", ab3100);
913 if (err) 897 if (err)
914 goto exit_no_irq; 898 goto exit_no_irq;
915 899
diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c
index 0499b2031a2c..b603469dff69 100644
--- a/drivers/mfd/ab3100-otp.c
+++ b/drivers/mfd/ab3100-otp.c
@@ -13,6 +13,7 @@
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/mfd/ab3100.h> 14#include <linux/mfd/ab3100.h>
15#include <linux/debugfs.h> 15#include <linux/debugfs.h>
16#include <linux/seq_file.h>
16 17
17/* The OTP registers */ 18/* The OTP registers */
18#define AB3100_OTP0 0xb0 19#define AB3100_OTP0 0xb0
@@ -95,11 +96,10 @@ static int __init ab3100_otp_read(struct ab3100_otp *otp)
95 * This is a simple debugfs human-readable file that dumps out 96 * This is a simple debugfs human-readable file that dumps out
96 * the contents of the OTP. 97 * the contents of the OTP.
97 */ 98 */
98#ifdef CONFIG_DEBUGFS 99#ifdef CONFIG_DEBUG_FS
99static int show_otp(struct seq_file *s, void *v) 100static int ab3100_show_otp(struct seq_file *s, void *v)
100{ 101{
101 struct ab3100_otp *otp = s->private; 102 struct ab3100_otp *otp = s->private;
102 int err;
103 103
104 seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED"); 104 seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED");
105 seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq); 105 seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq);
@@ -113,7 +113,7 @@ static int show_otp(struct seq_file *s, void *v)
113 113
114static int ab3100_otp_open(struct inode *inode, struct file *file) 114static int ab3100_otp_open(struct inode *inode, struct file *file)
115{ 115{
116 return single_open(file, ab3100_otp_show, inode->i_private); 116 return single_open(file, ab3100_show_otp, inode->i_private);
117} 117}
118 118
119static const struct file_operations ab3100_otp_operations = { 119static const struct file_operations ab3100_otp_operations = {
@@ -131,13 +131,14 @@ static int __init ab3100_otp_init_debugfs(struct device *dev,
131 &ab3100_otp_operations); 131 &ab3100_otp_operations);
132 if (!otp->debugfs) { 132 if (!otp->debugfs) {
133 dev_err(dev, "AB3100 debugfs OTP file registration failed!\n"); 133 dev_err(dev, "AB3100 debugfs OTP file registration failed!\n");
134 return err; 134 return -ENOENT;
135 } 135 }
136 return 0;
136} 137}
137 138
138static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp) 139static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
139{ 140{
140 debugfs_remove_file(otp->debugfs); 141 debugfs_remove(otp->debugfs);
141} 142}
142#else 143#else
143/* Compile this out if debugfs not selected */ 144/* Compile this out if debugfs not selected */
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c
index aa266e1f69b2..addb846c1e34 100644
--- a/drivers/mfd/htc-egpio.c
+++ b/drivers/mfd/htc-egpio.c
@@ -108,7 +108,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc)
108 ack_irqs(ei); 108 ack_irqs(ei);
109 /* Process all set pins. */ 109 /* Process all set pins. */
110 readval &= ei->irqs_enabled; 110 readval &= ei->irqs_enabled;
111 for_each_bit(irqpin, &readval, ei->nirqs) { 111 for_each_set_bit(irqpin, &readval, ei->nirqs) {
112 /* Run irq handler */ 112 /* Run irq handler */
113 pr_debug("got IRQ %d\n", irqpin); 113 pr_debug("got IRQ %d\n", irqpin);
114 irq = ei->irq_start + irqpin; 114 irq = ei->irq_start + irqpin;
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c
new file mode 100644
index 000000000000..37b9fdab4f36
--- /dev/null
+++ b/drivers/mfd/htc-i2cpld.c
@@ -0,0 +1,710 @@
1/*
2 * htc-i2cpld.c
3 * Chip driver for an unknown CPLD chip found on omap850 HTC devices like
4 * the HTC Wizard and HTC Herald.
5 * The cpld is located on the i2c bus and acts as an input/output GPIO
6 * extender.
7 *
8 * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
9 *
10 * Based on work done in the linwizard project
11 * Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/interrupt.h>
32#include <linux/platform_device.h>
33#include <linux/i2c.h>
34#include <linux/irq.h>
35#include <linux/spinlock.h>
36#include <linux/htcpld.h>
37#include <linux/gpio.h>
38
39struct htcpld_chip {
40 spinlock_t lock;
41
42 /* chip info */
43 u8 reset;
44 u8 addr;
45 struct device *dev;
46 struct i2c_client *client;
47
48 /* Output details */
49 u8 cache_out;
50 struct gpio_chip chip_out;
51
52 /* Input details */
53 u8 cache_in;
54 struct gpio_chip chip_in;
55
56 u16 irqs_enabled;
57 uint irq_start;
58 int nirqs;
59
60 /*
61 * Work structure to allow for setting values outside of any
62 * possible interrupt context
63 */
64 struct work_struct set_val_work;
65};
66
67struct htcpld_data {
68 /* irq info */
69 u16 irqs_enabled;
70 uint irq_start;
71 int nirqs;
72 uint chained_irq;
73 unsigned int int_reset_gpio_hi;
74 unsigned int int_reset_gpio_lo;
75
76 /* htcpld info */
77 struct htcpld_chip *chip;
78 unsigned int nchips;
79};
80
81/* There does not appear to be a way to proactively mask interrupts
82 * on the htcpld chip itself. So, we simply ignore interrupts that
83 * aren't desired. */
84static void htcpld_mask(unsigned int irq)
85{
86 struct htcpld_chip *chip = get_irq_chip_data(irq);
87 chip->irqs_enabled &= ~(1 << (irq - chip->irq_start));
88 pr_debug("HTCPLD mask %d %04x\n", irq, chip->irqs_enabled);
89}
90static void htcpld_unmask(unsigned int irq)
91{
92 struct htcpld_chip *chip = get_irq_chip_data(irq);
93 chip->irqs_enabled |= 1 << (irq - chip->irq_start);
94 pr_debug("HTCPLD unmask %d %04x\n", irq, chip->irqs_enabled);
95}
96
97static int htcpld_set_type(unsigned int irq, unsigned int flags)
98{
99 struct irq_desc *d = irq_to_desc(irq);
100
101 if (!d) {
102 pr_err("HTCPLD invalid IRQ: %d\n", irq);
103 return -EINVAL;
104 }
105
106 if (flags & ~IRQ_TYPE_SENSE_MASK)
107 return -EINVAL;
108
109 /* We only allow edge triggering */
110 if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
111 return -EINVAL;
112
113 d->status &= ~IRQ_TYPE_SENSE_MASK;
114 d->status |= flags;
115
116 return 0;
117}
118
119static struct irq_chip htcpld_muxed_chip = {
120 .name = "htcpld",
121 .mask = htcpld_mask,
122 .unmask = htcpld_unmask,
123 .set_type = htcpld_set_type,
124};
125
126/* To properly dispatch IRQ events, we need to read from the
127 * chip. This is an I2C action that could possibly sleep
128 * (which is bad in interrupt context) -- so we use a threaded
129 * interrupt handler to get around that.
130 */
131static irqreturn_t htcpld_handler(int irq, void *dev)
132{
133 struct htcpld_data *htcpld = dev;
134 unsigned int i;
135 unsigned long flags;
136 int irqpin;
137 struct irq_desc *desc;
138
139 if (!htcpld) {
140 pr_debug("htcpld is null in ISR\n");
141 return IRQ_HANDLED;
142 }
143
144 /*
145 * For each chip, do a read of the chip and trigger any interrupts
146 * desired. The interrupts will be triggered from LSB to MSB (i.e.
147 * bit 0 first, then bit 1, etc.)
148 *
149 * For chips that have no interrupt range specified, just skip 'em.
150 */
151 for (i = 0; i < htcpld->nchips; i++) {
152 struct htcpld_chip *chip = &htcpld->chip[i];
153 struct i2c_client *client;
154 int val;
155 unsigned long uval, old_val;
156
157 if (!chip) {
158 pr_debug("chip %d is null in ISR\n", i);
159 continue;
160 }
161
162 if (chip->nirqs == 0)
163 continue;
164
165 client = chip->client;
166 if (!client) {
167 pr_debug("client %d is null in ISR\n", i);
168 continue;
169 }
170
171 /* Scan the chip */
172 val = i2c_smbus_read_byte_data(client, chip->cache_out);
173 if (val < 0) {
174 /* Throw a warning and skip this chip */
175 dev_warn(chip->dev, "Unable to read from chip: %d\n",
176 val);
177 continue;
178 }
179
180 uval = (unsigned long)val;
181
182 spin_lock_irqsave(&chip->lock, flags);
183
184 /* Save away the old value so we can compare it */
185 old_val = chip->cache_in;
186
187 /* Write the new value */
188 chip->cache_in = uval;
189
190 spin_unlock_irqrestore(&chip->lock, flags);
191
192 /*
193 * For each bit in the data (starting at bit 0), trigger
194 * associated interrupts.
195 */
196 for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
197 unsigned oldb, newb;
198 int flags;
199
200 irq = chip->irq_start + irqpin;
201 desc = irq_to_desc(irq);
202 flags = desc->status;
203
204 /* Run the IRQ handler, but only if the bit value
205 * changed, and the proper flags are set */
206 oldb = (old_val >> irqpin) & 1;
207 newb = (uval >> irqpin) & 1;
208
209 if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) ||
210 (oldb && !newb &&
211 (flags & IRQ_TYPE_EDGE_FALLING))) {
212 pr_debug("fire IRQ %d\n", irqpin);
213 desc->handle_irq(irq, desc);
214 }
215 }
216 }
217
218 /*
219 * In order to continue receiving interrupts, the int_reset_gpio must
220 * be asserted.
221 */
222 if (htcpld->int_reset_gpio_hi)
223 gpio_set_value(htcpld->int_reset_gpio_hi, 1);
224 if (htcpld->int_reset_gpio_lo)
225 gpio_set_value(htcpld->int_reset_gpio_lo, 0);
226
227 return IRQ_HANDLED;
228}
229
230/*
231 * The GPIO set routines can be called from interrupt context, especially if,
232 * for example they're attached to the led-gpio framework and a trigger is
233 * enabled. As such, we declared work above in the htcpld_chip structure,
234 * and that work is scheduled in the set routine. The kernel can then run
235 * the I2C functions, which will sleep, in process context.
236 */
237void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val)
238{
239 struct i2c_client *client;
240 struct htcpld_chip *chip_data;
241 unsigned long flags;
242
243 chip_data = container_of(chip, struct htcpld_chip, chip_out);
244 if (!chip_data)
245 return;
246
247 client = chip_data->client;
248 if (client == NULL)
249 return;
250
251 spin_lock_irqsave(&chip_data->lock, flags);
252 if (val)
253 chip_data->cache_out |= (1 << offset);
254 else
255 chip_data->cache_out &= ~(1 << offset);
256 spin_unlock_irqrestore(&chip_data->lock, flags);
257
258 schedule_work(&(chip_data->set_val_work));
259}
260
261void htcpld_chip_set_ni(struct work_struct *work)
262{
263 struct htcpld_chip *chip_data;
264 struct i2c_client *client;
265
266 chip_data = container_of(work, struct htcpld_chip, set_val_work);
267 client = chip_data->client;
268 i2c_smbus_read_byte_data(client, chip_data->cache_out);
269}
270
271int htcpld_chip_get(struct gpio_chip *chip, unsigned offset)
272{
273 struct htcpld_chip *chip_data;
274 int val = 0;
275 int is_input = 0;
276
277 /* Try out first */
278 chip_data = container_of(chip, struct htcpld_chip, chip_out);
279 if (!chip_data) {
280 /* Try in */
281 is_input = 1;
282 chip_data = container_of(chip, struct htcpld_chip, chip_in);
283 if (!chip_data)
284 return -EINVAL;
285 }
286
287 /* Determine if this is an input or output GPIO */
288 if (!is_input)
289 /* Use the output cache */
290 val = (chip_data->cache_out >> offset) & 1;
291 else
292 /* Use the input cache */
293 val = (chip_data->cache_in >> offset) & 1;
294
295 if (val)
296 return 1;
297 else
298 return 0;
299}
300
301static int htcpld_direction_output(struct gpio_chip *chip,
302 unsigned offset, int value)
303{
304 htcpld_chip_set(chip, offset, value);
305 return 0;
306}
307
308static int htcpld_direction_input(struct gpio_chip *chip,
309 unsigned offset)
310{
311 /*
312 * No-op: this function can only be called on the input chip.
313 * We do however make sure the offset is within range.
314 */
315 return (offset < chip->ngpio) ? 0 : -EINVAL;
316}
317
318int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset)
319{
320 struct htcpld_chip *chip_data;
321
322 chip_data = container_of(chip, struct htcpld_chip, chip_in);
323
324 if (offset < chip_data->nirqs)
325 return chip_data->irq_start + offset;
326 else
327 return -EINVAL;
328}
329
330void htcpld_chip_reset(struct i2c_client *client)
331{
332 struct htcpld_chip *chip_data = i2c_get_clientdata(client);
333 if (!chip_data)
334 return;
335
336 i2c_smbus_read_byte_data(
337 client, (chip_data->cache_out = chip_data->reset));
338}
339
340static int __devinit htcpld_setup_chip_irq(
341 struct platform_device *pdev,
342 int chip_index)
343{
344 struct htcpld_data *htcpld;
345 struct device *dev = &pdev->dev;
346 struct htcpld_core_platform_data *pdata;
347 struct htcpld_chip *chip;
348 struct htcpld_chip_platform_data *plat_chip_data;
349 unsigned int irq, irq_end;
350 int ret = 0;
351
352 /* Get the platform and driver data */
353 pdata = dev->platform_data;
354 htcpld = platform_get_drvdata(pdev);
355 chip = &htcpld->chip[chip_index];
356 plat_chip_data = &pdata->chip[chip_index];
357
358 /* Setup irq handlers */
359 irq_end = chip->irq_start + chip->nirqs;
360 for (irq = chip->irq_start; irq < irq_end; irq++) {
361 set_irq_chip(irq, &htcpld_muxed_chip);
362 set_irq_chip_data(irq, chip);
363 set_irq_handler(irq, handle_simple_irq);
364#ifdef CONFIG_ARM
365 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
366#else
367 set_irq_probe(irq);
368#endif
369 }
370
371 return ret;
372}
373
374static int __devinit htcpld_register_chip_i2c(
375 struct platform_device *pdev,
376 int chip_index)
377{
378 struct htcpld_data *htcpld;
379 struct device *dev = &pdev->dev;
380 struct htcpld_core_platform_data *pdata;
381 struct htcpld_chip *chip;
382 struct htcpld_chip_platform_data *plat_chip_data;
383 struct i2c_adapter *adapter;
384 struct i2c_client *client;
385 struct i2c_board_info info;
386
387 /* Get the platform and driver data */
388 pdata = dev->platform_data;
389 htcpld = platform_get_drvdata(pdev);
390 chip = &htcpld->chip[chip_index];
391 plat_chip_data = &pdata->chip[chip_index];
392
393 adapter = i2c_get_adapter(pdata->i2c_adapter_id);
394 if (adapter == NULL) {
395 /* Eek, no such I2C adapter! Bail out. */
396 dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n",
397 plat_chip_data->addr, pdata->i2c_adapter_id);
398 return -ENODEV;
399 }
400
401 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
402 dev_warn(dev, "i2c adapter %d non-functional\n",
403 pdata->i2c_adapter_id);
404 return -EINVAL;
405 }
406
407 memset(&info, 0, sizeof(struct i2c_board_info));
408 info.addr = plat_chip_data->addr;
409 strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE);
410 info.platform_data = chip;
411
412 /* Add the I2C device. This calls the probe() function. */
413 client = i2c_new_device(adapter, &info);
414 if (!client) {
415 /* I2C device registration failed, contineu with the next */
416 dev_warn(dev, "Unable to add I2C device for 0x%x\n",
417 plat_chip_data->addr);
418 return -ENODEV;
419 }
420
421 i2c_set_clientdata(client, chip);
422 snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%d", client->addr);
423 chip->client = client;
424
425 /* Reset the chip */
426 htcpld_chip_reset(client);
427 chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out);
428
429 return 0;
430}
431
432static void __devinit htcpld_unregister_chip_i2c(
433 struct platform_device *pdev,
434 int chip_index)
435{
436 struct htcpld_data *htcpld;
437 struct htcpld_chip *chip;
438
439 /* Get the platform and driver data */
440 htcpld = platform_get_drvdata(pdev);
441 chip = &htcpld->chip[chip_index];
442
443 if (chip->client)
444 i2c_unregister_device(chip->client);
445}
446
447static int __devinit htcpld_register_chip_gpio(
448 struct platform_device *pdev,
449 int chip_index)
450{
451 struct htcpld_data *htcpld;
452 struct device *dev = &pdev->dev;
453 struct htcpld_core_platform_data *pdata;
454 struct htcpld_chip *chip;
455 struct htcpld_chip_platform_data *plat_chip_data;
456 struct gpio_chip *gpio_chip;
457 int ret = 0;
458
459 /* Get the platform and driver data */
460 pdata = dev->platform_data;
461 htcpld = platform_get_drvdata(pdev);
462 chip = &htcpld->chip[chip_index];
463 plat_chip_data = &pdata->chip[chip_index];
464
465 /* Setup the GPIO chips */
466 gpio_chip = &(chip->chip_out);
467 gpio_chip->label = "htcpld-out";
468 gpio_chip->dev = dev;
469 gpio_chip->owner = THIS_MODULE;
470 gpio_chip->get = htcpld_chip_get;
471 gpio_chip->set = htcpld_chip_set;
472 gpio_chip->direction_input = NULL;
473 gpio_chip->direction_output = htcpld_direction_output;
474 gpio_chip->base = plat_chip_data->gpio_out_base;
475 gpio_chip->ngpio = plat_chip_data->num_gpios;
476
477 gpio_chip = &(chip->chip_in);
478 gpio_chip->label = "htcpld-in";
479 gpio_chip->dev = dev;
480 gpio_chip->owner = THIS_MODULE;
481 gpio_chip->get = htcpld_chip_get;
482 gpio_chip->set = NULL;
483 gpio_chip->direction_input = htcpld_direction_input;
484 gpio_chip->direction_output = NULL;
485 gpio_chip->to_irq = htcpld_chip_to_irq;
486 gpio_chip->base = plat_chip_data->gpio_in_base;
487 gpio_chip->ngpio = plat_chip_data->num_gpios;
488
489 /* Add the GPIO chips */
490 ret = gpiochip_add(&(chip->chip_out));
491 if (ret) {
492 dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n",
493 plat_chip_data->addr, ret);
494 return ret;
495 }
496
497 ret = gpiochip_add(&(chip->chip_in));
498 if (ret) {
499 int error;
500
501 dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n",
502 plat_chip_data->addr, ret);
503
504 error = gpiochip_remove(&(chip->chip_out));
505 if (error)
506 dev_warn(dev, "Error while trying to unregister gpio chip: %d\n", error);
507
508 return ret;
509 }
510
511 return 0;
512}
513
514static int __devinit htcpld_setup_chips(struct platform_device *pdev)
515{
516 struct htcpld_data *htcpld;
517 struct device *dev = &pdev->dev;
518 struct htcpld_core_platform_data *pdata;
519 int i;
520
521 /* Get the platform and driver data */
522 pdata = dev->platform_data;
523 htcpld = platform_get_drvdata(pdev);
524
525 /* Setup each chip's output GPIOs */
526 htcpld->nchips = pdata->num_chip;
527 htcpld->chip = kzalloc(sizeof(struct htcpld_chip) * htcpld->nchips,
528 GFP_KERNEL);
529 if (!htcpld->chip) {
530 dev_warn(dev, "Unable to allocate memory for chips\n");
531 return -ENOMEM;
532 }
533
534 /* Add the chips as best we can */
535 for (i = 0; i < htcpld->nchips; i++) {
536 int ret;
537
538 /* Setup the HTCPLD chips */
539 htcpld->chip[i].reset = pdata->chip[i].reset;
540 htcpld->chip[i].cache_out = pdata->chip[i].reset;
541 htcpld->chip[i].cache_in = 0;
542 htcpld->chip[i].dev = dev;
543 htcpld->chip[i].irq_start = pdata->chip[i].irq_base;
544 htcpld->chip[i].nirqs = pdata->chip[i].num_irqs;
545
546 INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni);
547 spin_lock_init(&(htcpld->chip[i].lock));
548
549 /* Setup the interrupts for the chip */
550 if (htcpld->chained_irq) {
551 ret = htcpld_setup_chip_irq(pdev, i);
552 if (ret)
553 continue;
554 }
555
556 /* Register the chip with I2C */
557 ret = htcpld_register_chip_i2c(pdev, i);
558 if (ret)
559 continue;
560
561
562 /* Register the chips with the GPIO subsystem */
563 ret = htcpld_register_chip_gpio(pdev, i);
564 if (ret) {
565 /* Unregister the chip from i2c and continue */
566 htcpld_unregister_chip_i2c(pdev, i);
567 continue;
568 }
569
570 dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr);
571 }
572
573 return 0;
574}
575
576static int __devinit htcpld_core_probe(struct platform_device *pdev)
577{
578 struct htcpld_data *htcpld;
579 struct device *dev = &pdev->dev;
580 struct htcpld_core_platform_data *pdata;
581 struct resource *res;
582 int ret = 0;
583
584 if (!dev)
585 return -ENODEV;
586
587 pdata = dev->platform_data;
588 if (!pdata) {
589 dev_warn(dev, "Platform data not found for htcpld core!\n");
590 return -ENXIO;
591 }
592
593 htcpld = kzalloc(sizeof(struct htcpld_data), GFP_KERNEL);
594 if (!htcpld)
595 return -ENOMEM;
596
597 /* Find chained irq */
598 ret = -EINVAL;
599 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
600 if (res) {
601 int flags;
602 htcpld->chained_irq = res->start;
603
604 /* Setup the chained interrupt handler */
605 flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
606 ret = request_threaded_irq(htcpld->chained_irq,
607 NULL, htcpld_handler,
608 flags, pdev->name, htcpld);
609 if (ret) {
610 dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret);
611 goto fail;
612 } else
613 device_init_wakeup(dev, 0);
614 }
615
616 /* Set the driver data */
617 platform_set_drvdata(pdev, htcpld);
618
619 /* Setup the htcpld chips */
620 ret = htcpld_setup_chips(pdev);
621 if (ret)
622 goto fail;
623
624 /* Request the GPIO(s) for the int reset and set them up */
625 if (pdata->int_reset_gpio_hi) {
626 ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core");
627 if (ret) {
628 /*
629 * If it failed, that sucks, but we can probably
630 * continue on without it.
631 */
632 dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n");
633 htcpld->int_reset_gpio_hi = 0;
634 } else {
635 htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi;
636 gpio_set_value(htcpld->int_reset_gpio_hi, 1);
637 }
638 }
639
640 if (pdata->int_reset_gpio_lo) {
641 ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core");
642 if (ret) {
643 /*
644 * If it failed, that sucks, but we can probably
645 * continue on without it.
646 */
647 dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n");
648 htcpld->int_reset_gpio_lo = 0;
649 } else {
650 htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo;
651 gpio_set_value(htcpld->int_reset_gpio_lo, 0);
652 }
653 }
654
655 dev_info(dev, "Initialized successfully\n");
656 return 0;
657
658fail:
659 kfree(htcpld);
660 return ret;
661}
662
663/* The I2C Driver -- used internally */
664static const struct i2c_device_id htcpld_chip_id[] = {
665 { "htcpld-chip", 0 },
666 { }
667};
668MODULE_DEVICE_TABLE(i2c, htcpld_chip_id);
669
670
671static struct i2c_driver htcpld_chip_driver = {
672 .driver = {
673 .name = "htcpld-chip",
674 },
675 .id_table = htcpld_chip_id,
676};
677
678/* The Core Driver */
679static struct platform_driver htcpld_core_driver = {
680 .driver = {
681 .name = "i2c-htcpld",
682 },
683};
684
685static int __init htcpld_core_init(void)
686{
687 int ret;
688
689 /* Register the I2C Chip driver */
690 ret = i2c_add_driver(&htcpld_chip_driver);
691 if (ret)
692 return ret;
693
694 /* Probe for our chips */
695 return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe);
696}
697
698static void __exit htcpld_core_exit(void)
699{
700 i2c_del_driver(&htcpld_chip_driver);
701 platform_driver_unregister(&htcpld_core_driver);
702}
703
704module_init(htcpld_core_init);
705module_exit(htcpld_core_exit);
706
707MODULE_AUTHOR("Cory Maccarrone <darkstar6262@gmail.com>");
708MODULE_DESCRIPTION("I2C HTC PLD Driver");
709MODULE_LICENSE("GPL");
710
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
new file mode 100644
index 000000000000..51b2f6065a0b
--- /dev/null
+++ b/drivers/mfd/lpc_sch.c
@@ -0,0 +1,133 @@
1/*
2 * lpc_sch.c - LPC interface for Intel Poulsbo SCH
3 *
4 * LPC bridge function of the Intel SCH contains many other
5 * functional units, such as Interrupt controllers, Timers,
6 * Power Management, System Management, GPIO, RTC, and LPC
7 * Configuration Registers.
8 *
9 * Copyright (c) 2010 CompuLab Ltd
10 * Author: Denis Turischev <denis@compulab.co.il>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License 2 as published
14 * by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/errno.h>
30#include <linux/acpi.h>
31#include <linux/pci.h>
32#include <linux/mfd/core.h>
33
34#define SMBASE 0x40
35#define SMBUS_IO_SIZE 64
36
37#define GPIOBASE 0x44
38#define GPIO_IO_SIZE 64
39
40static struct resource smbus_sch_resource = {
41 .flags = IORESOURCE_IO,
42};
43
44
45static struct resource gpio_sch_resource = {
46 .flags = IORESOURCE_IO,
47};
48
49static struct mfd_cell lpc_sch_cells[] = {
50 {
51 .name = "isch_smbus",
52 .num_resources = 1,
53 .resources = &smbus_sch_resource,
54 },
55 {
56 .name = "sch_gpio",
57 .num_resources = 1,
58 .resources = &gpio_sch_resource,
59 },
60};
61
62static struct pci_device_id lpc_sch_ids[] = {
63 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
64 { 0, }
65};
66MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
67
68static int __devinit lpc_sch_probe(struct pci_dev *dev,
69 const struct pci_device_id *id)
70{
71 unsigned int base_addr_cfg;
72 unsigned short base_addr;
73
74 pci_read_config_dword(dev, SMBASE, &base_addr_cfg);
75 if (!(base_addr_cfg & (1 << 31))) {
76 dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n");
77 return -ENODEV;
78 }
79 base_addr = (unsigned short)base_addr_cfg;
80 if (base_addr == 0) {
81 dev_err(&dev->dev, "I/O space for SMBus uninitialized\n");
82 return -ENODEV;
83 }
84
85 smbus_sch_resource.start = base_addr;
86 smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1;
87
88 pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg);
89 if (!(base_addr_cfg & (1 << 31))) {
90 dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n");
91 return -ENODEV;
92 }
93 base_addr = (unsigned short)base_addr_cfg;
94 if (base_addr == 0) {
95 dev_err(&dev->dev, "I/O space for GPIO uninitialized\n");
96 return -ENODEV;
97 }
98
99 gpio_sch_resource.start = base_addr;
100 gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
101
102 return mfd_add_devices(&dev->dev, -1,
103 lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0);
104}
105
106static void __devexit lpc_sch_remove(struct pci_dev *dev)
107{
108 mfd_remove_devices(&dev->dev);
109}
110
111static struct pci_driver lpc_sch_driver = {
112 .name = "lpc_sch",
113 .id_table = lpc_sch_ids,
114 .probe = lpc_sch_probe,
115 .remove = __devexit_p(lpc_sch_remove),
116};
117
118static int __init lpc_sch_init(void)
119{
120 return pci_register_driver(&lpc_sch_driver);
121}
122
123static void __exit lpc_sch_exit(void)
124{
125 pci_unregister_driver(&lpc_sch_driver);
126}
127
128module_init(lpc_sch_init);
129module_exit(lpc_sch_exit);
130
131MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
132MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH");
133MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
new file mode 100644
index 000000000000..85d63c04749b
--- /dev/null
+++ b/drivers/mfd/max8925-core.c
@@ -0,0 +1,656 @@
1/*
2 * Base driver for Maxim MAX8925
3 *
4 * Copyright (C) 2009-2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/i2c.h>
15#include <linux/irq.h>
16#include <linux/interrupt.h>
17#include <linux/platform_device.h>
18#include <linux/mfd/core.h>
19#include <linux/mfd/max8925.h>
20
21static struct resource backlight_resources[] = {
22 {
23 .name = "max8925-backlight",
24 .start = MAX8925_WLED_MODE_CNTL,
25 .end = MAX8925_WLED_CNTL,
26 .flags = IORESOURCE_IO,
27 },
28};
29
30static struct mfd_cell backlight_devs[] = {
31 {
32 .name = "max8925-backlight",
33 .num_resources = 1,
34 .resources = &backlight_resources[0],
35 .id = -1,
36 },
37};
38
39static struct resource touch_resources[] = {
40 {
41 .name = "max8925-tsc",
42 .start = MAX8925_TSC_IRQ,
43 .end = MAX8925_ADC_RES_END,
44 .flags = IORESOURCE_IO,
45 },
46};
47
48static struct mfd_cell touch_devs[] = {
49 {
50 .name = "max8925-touch",
51 .num_resources = 1,
52 .resources = &touch_resources[0],
53 .id = -1,
54 },
55};
56
57static struct resource power_supply_resources[] = {
58 {
59 .name = "max8925-power",
60 .start = MAX8925_CHG_IRQ1,
61 .end = MAX8925_CHG_IRQ1_MASK,
62 .flags = IORESOURCE_IO,
63 },
64};
65
66static struct mfd_cell power_devs[] = {
67 {
68 .name = "max8925-power",
69 .num_resources = 1,
70 .resources = &power_supply_resources[0],
71 .id = -1,
72 },
73};
74
75static struct resource rtc_resources[] = {
76 {
77 .name = "max8925-rtc",
78 .start = MAX8925_RTC_IRQ,
79 .end = MAX8925_RTC_IRQ_MASK,
80 .flags = IORESOURCE_IO,
81 },
82};
83
84static struct mfd_cell rtc_devs[] = {
85 {
86 .name = "max8925-rtc",
87 .num_resources = 1,
88 .resources = &rtc_resources[0],
89 .id = -1,
90 },
91};
92
93#define MAX8925_REG_RESOURCE(_start, _end) \
94{ \
95 .start = MAX8925_##_start, \
96 .end = MAX8925_##_end, \
97 .flags = IORESOURCE_IO, \
98}
99
100static struct resource regulator_resources[] = {
101 MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
102 MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
103 MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
104 MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
105 MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
106 MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
107 MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
108 MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
109 MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
110 MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
111 MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
112 MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
113 MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
114 MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
115 MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
116 MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
117 MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
118 MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
119 MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
120 MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
121 MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
122 MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
123 MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
124};
125
126#define MAX8925_REG_DEVS(_id) \
127{ \
128 .name = "max8925-regulator", \
129 .num_resources = 1, \
130 .resources = &regulator_resources[MAX8925_ID_##_id], \
131 .id = MAX8925_ID_##_id, \
132}
133
134static struct mfd_cell regulator_devs[] = {
135 MAX8925_REG_DEVS(SD1),
136 MAX8925_REG_DEVS(SD2),
137 MAX8925_REG_DEVS(SD3),
138 MAX8925_REG_DEVS(LDO1),
139 MAX8925_REG_DEVS(LDO2),
140 MAX8925_REG_DEVS(LDO3),
141 MAX8925_REG_DEVS(LDO4),
142 MAX8925_REG_DEVS(LDO5),
143 MAX8925_REG_DEVS(LDO6),
144 MAX8925_REG_DEVS(LDO7),
145 MAX8925_REG_DEVS(LDO8),
146 MAX8925_REG_DEVS(LDO9),
147 MAX8925_REG_DEVS(LDO10),
148 MAX8925_REG_DEVS(LDO11),
149 MAX8925_REG_DEVS(LDO12),
150 MAX8925_REG_DEVS(LDO13),
151 MAX8925_REG_DEVS(LDO14),
152 MAX8925_REG_DEVS(LDO15),
153 MAX8925_REG_DEVS(LDO16),
154 MAX8925_REG_DEVS(LDO17),
155 MAX8925_REG_DEVS(LDO18),
156 MAX8925_REG_DEVS(LDO19),
157 MAX8925_REG_DEVS(LDO20),
158};
159
160enum {
161 FLAGS_ADC = 1, /* register in ADC component */
162 FLAGS_RTC, /* register in RTC component */
163};
164
165struct max8925_irq_data {
166 int reg;
167 int mask_reg;
168 int enable; /* enable or not */
169 int offs; /* bit offset in mask register */
170 int flags;
171 int tsc_irq;
172};
173
174static struct max8925_irq_data max8925_irqs[] = {
175 [MAX8925_IRQ_VCHG_DC_OVP] = {
176 .reg = MAX8925_CHG_IRQ1,
177 .mask_reg = MAX8925_CHG_IRQ1_MASK,
178 .offs = 1 << 0,
179 },
180 [MAX8925_IRQ_VCHG_DC_F] = {
181 .reg = MAX8925_CHG_IRQ1,
182 .mask_reg = MAX8925_CHG_IRQ1_MASK,
183 .offs = 1 << 1,
184 },
185 [MAX8925_IRQ_VCHG_DC_R] = {
186 .reg = MAX8925_CHG_IRQ1,
187 .mask_reg = MAX8925_CHG_IRQ1_MASK,
188 .offs = 1 << 2,
189 },
190 [MAX8925_IRQ_VCHG_USB_OVP] = {
191 .reg = MAX8925_CHG_IRQ1,
192 .mask_reg = MAX8925_CHG_IRQ1_MASK,
193 .offs = 1 << 3,
194 },
195 [MAX8925_IRQ_VCHG_USB_F] = {
196 .reg = MAX8925_CHG_IRQ1,
197 .mask_reg = MAX8925_CHG_IRQ1_MASK,
198 .offs = 1 << 4,
199 },
200 [MAX8925_IRQ_VCHG_USB_R] = {
201 .reg = MAX8925_CHG_IRQ1,
202 .mask_reg = MAX8925_CHG_IRQ1_MASK,
203 .offs = 1 << 5,
204 },
205 [MAX8925_IRQ_VCHG_THM_OK_R] = {
206 .reg = MAX8925_CHG_IRQ2,
207 .mask_reg = MAX8925_CHG_IRQ2_MASK,
208 .offs = 1 << 0,
209 },
210 [MAX8925_IRQ_VCHG_THM_OK_F] = {
211 .reg = MAX8925_CHG_IRQ2,
212 .mask_reg = MAX8925_CHG_IRQ2_MASK,
213 .offs = 1 << 1,
214 },
215 [MAX8925_IRQ_VCHG_SYSLOW_F] = {
216 .reg = MAX8925_CHG_IRQ2,
217 .mask_reg = MAX8925_CHG_IRQ2_MASK,
218 .offs = 1 << 2,
219 },
220 [MAX8925_IRQ_VCHG_SYSLOW_R] = {
221 .reg = MAX8925_CHG_IRQ2,
222 .mask_reg = MAX8925_CHG_IRQ2_MASK,
223 .offs = 1 << 3,
224 },
225 [MAX8925_IRQ_VCHG_RST] = {
226 .reg = MAX8925_CHG_IRQ2,
227 .mask_reg = MAX8925_CHG_IRQ2_MASK,
228 .offs = 1 << 4,
229 },
230 [MAX8925_IRQ_VCHG_DONE] = {
231 .reg = MAX8925_CHG_IRQ2,
232 .mask_reg = MAX8925_CHG_IRQ2_MASK,
233 .offs = 1 << 5,
234 },
235 [MAX8925_IRQ_VCHG_TOPOFF] = {
236 .reg = MAX8925_CHG_IRQ2,
237 .mask_reg = MAX8925_CHG_IRQ2_MASK,
238 .offs = 1 << 6,
239 },
240 [MAX8925_IRQ_VCHG_TMR_FAULT] = {
241 .reg = MAX8925_CHG_IRQ2,
242 .mask_reg = MAX8925_CHG_IRQ2_MASK,
243 .offs = 1 << 7,
244 },
245 [MAX8925_IRQ_GPM_RSTIN] = {
246 .reg = MAX8925_ON_OFF_IRQ1,
247 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
248 .offs = 1 << 0,
249 },
250 [MAX8925_IRQ_GPM_MPL] = {
251 .reg = MAX8925_ON_OFF_IRQ1,
252 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
253 .offs = 1 << 1,
254 },
255 [MAX8925_IRQ_GPM_SW_3SEC] = {
256 .reg = MAX8925_ON_OFF_IRQ1,
257 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
258 .offs = 1 << 2,
259 },
260 [MAX8925_IRQ_GPM_EXTON_F] = {
261 .reg = MAX8925_ON_OFF_IRQ1,
262 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
263 .offs = 1 << 3,
264 },
265 [MAX8925_IRQ_GPM_EXTON_R] = {
266 .reg = MAX8925_ON_OFF_IRQ1,
267 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
268 .offs = 1 << 4,
269 },
270 [MAX8925_IRQ_GPM_SW_1SEC] = {
271 .reg = MAX8925_ON_OFF_IRQ1,
272 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
273 .offs = 1 << 5,
274 },
275 [MAX8925_IRQ_GPM_SW_F] = {
276 .reg = MAX8925_ON_OFF_IRQ1,
277 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
278 .offs = 1 << 6,
279 },
280 [MAX8925_IRQ_GPM_SW_R] = {
281 .reg = MAX8925_ON_OFF_IRQ1,
282 .mask_reg = MAX8925_ON_OFF_IRQ1_MASK,
283 .offs = 1 << 7,
284 },
285 [MAX8925_IRQ_GPM_SYSCKEN_F] = {
286 .reg = MAX8925_ON_OFF_IRQ2,
287 .mask_reg = MAX8925_ON_OFF_IRQ2_MASK,
288 .offs = 1 << 0,
289 },
290 [MAX8925_IRQ_GPM_SYSCKEN_R] = {
291 .reg = MAX8925_ON_OFF_IRQ2,
292 .mask_reg = MAX8925_ON_OFF_IRQ2_MASK,
293 .offs = 1 << 1,
294 },
295 [MAX8925_IRQ_RTC_ALARM1] = {
296 .reg = MAX8925_RTC_IRQ,
297 .mask_reg = MAX8925_RTC_IRQ_MASK,
298 .offs = 1 << 2,
299 .flags = FLAGS_RTC,
300 },
301 [MAX8925_IRQ_RTC_ALARM0] = {
302 .reg = MAX8925_RTC_IRQ,
303 .mask_reg = MAX8925_RTC_IRQ_MASK,
304 .offs = 1 << 3,
305 .flags = FLAGS_RTC,
306 },
307 [MAX8925_IRQ_TSC_STICK] = {
308 .reg = MAX8925_TSC_IRQ,
309 .mask_reg = MAX8925_TSC_IRQ_MASK,
310 .offs = 1 << 0,
311 .flags = FLAGS_ADC,
312 .tsc_irq = 1,
313 },
314 [MAX8925_IRQ_TSC_NSTICK] = {
315 .reg = MAX8925_TSC_IRQ,
316 .mask_reg = MAX8925_TSC_IRQ_MASK,
317 .offs = 1 << 1,
318 .flags = FLAGS_ADC,
319 .tsc_irq = 1,
320 },
321};
322
323static inline struct max8925_irq_data *irq_to_max8925(struct max8925_chip *chip,
324 int irq)
325{
326 return &max8925_irqs[irq - chip->irq_base];
327}
328
329static irqreturn_t max8925_irq(int irq, void *data)
330{
331 struct max8925_chip *chip = data;
332 struct max8925_irq_data *irq_data;
333 struct i2c_client *i2c;
334 int read_reg = -1, value = 0;
335 int i;
336
337 for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
338 irq_data = &max8925_irqs[i];
339 /* TSC IRQ should be serviced in max8925_tsc_irq() */
340 if (irq_data->tsc_irq)
341 continue;
342 if (irq_data->flags == FLAGS_RTC)
343 i2c = chip->rtc;
344 else if (irq_data->flags == FLAGS_ADC)
345 i2c = chip->adc;
346 else
347 i2c = chip->i2c;
348 if (read_reg != irq_data->reg) {
349 read_reg = irq_data->reg;
350 value = max8925_reg_read(i2c, irq_data->reg);
351 }
352 if (value & irq_data->enable)
353 handle_nested_irq(chip->irq_base + i);
354 }
355 return IRQ_HANDLED;
356}
357
358static irqreturn_t max8925_tsc_irq(int irq, void *data)
359{
360 struct max8925_chip *chip = data;
361 struct max8925_irq_data *irq_data;
362 struct i2c_client *i2c;
363 int read_reg = -1, value = 0;
364 int i;
365
366 for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
367 irq_data = &max8925_irqs[i];
368 /* non TSC IRQ should be serviced in max8925_irq() */
369 if (!irq_data->tsc_irq)
370 continue;
371 if (irq_data->flags == FLAGS_RTC)
372 i2c = chip->rtc;
373 else if (irq_data->flags == FLAGS_ADC)
374 i2c = chip->adc;
375 else
376 i2c = chip->i2c;
377 if (read_reg != irq_data->reg) {
378 read_reg = irq_data->reg;
379 value = max8925_reg_read(i2c, irq_data->reg);
380 }
381 if (value & irq_data->enable)
382 handle_nested_irq(chip->irq_base + i);
383 }
384 return IRQ_HANDLED;
385}
386
387static void max8925_irq_lock(unsigned int irq)
388{
389 struct max8925_chip *chip = get_irq_chip_data(irq);
390
391 mutex_lock(&chip->irq_lock);
392}
393
394static void max8925_irq_sync_unlock(unsigned int irq)
395{
396 struct max8925_chip *chip = get_irq_chip_data(irq);
397 struct max8925_irq_data *irq_data;
398 static unsigned char cache_chg[2] = {0xff, 0xff};
399 static unsigned char cache_on[2] = {0xff, 0xff};
400 static unsigned char cache_rtc = 0xff, cache_tsc = 0xff;
401 unsigned char irq_chg[2], irq_on[2];
402 unsigned char irq_rtc, irq_tsc;
403 int i;
404
405 /* Load cached value. In initial, all IRQs are masked */
406 irq_chg[0] = cache_chg[0];
407 irq_chg[1] = cache_chg[1];
408 irq_on[0] = cache_on[0];
409 irq_on[1] = cache_on[1];
410 irq_rtc = cache_rtc;
411 irq_tsc = cache_tsc;
412 for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
413 irq_data = &max8925_irqs[i];
414 switch (irq_data->mask_reg) {
415 case MAX8925_CHG_IRQ1_MASK:
416 irq_chg[0] &= irq_data->enable;
417 break;
418 case MAX8925_CHG_IRQ2_MASK:
419 irq_chg[1] &= irq_data->enable;
420 break;
421 case MAX8925_ON_OFF_IRQ1_MASK:
422 irq_on[0] &= irq_data->enable;
423 break;
424 case MAX8925_ON_OFF_IRQ2_MASK:
425 irq_on[1] &= irq_data->enable;
426 break;
427 case MAX8925_RTC_IRQ_MASK:
428 irq_rtc &= irq_data->enable;
429 break;
430 case MAX8925_TSC_IRQ_MASK:
431 irq_tsc &= irq_data->enable;
432 break;
433 default:
434 dev_err(chip->dev, "wrong IRQ\n");
435 break;
436 }
437 }
438 /* update mask into registers */
439 if (cache_chg[0] != irq_chg[0]) {
440 cache_chg[0] = irq_chg[0];
441 max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK,
442 irq_chg[0]);
443 }
444 if (cache_chg[1] != irq_chg[1]) {
445 cache_chg[1] = irq_chg[1];
446 max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK,
447 irq_chg[1]);
448 }
449 if (cache_on[0] != irq_on[0]) {
450 cache_on[0] = irq_on[0];
451 max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK,
452 irq_on[0]);
453 }
454 if (cache_on[1] != irq_on[1]) {
455 cache_on[1] = irq_on[1];
456 max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK,
457 irq_on[1]);
458 }
459 if (cache_rtc != irq_rtc) {
460 cache_rtc = irq_rtc;
461 max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, irq_rtc);
462 }
463 if (cache_tsc != irq_tsc) {
464 cache_tsc = irq_tsc;
465 max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, irq_tsc);
466 }
467
468 mutex_unlock(&chip->irq_lock);
469}
470
471static void max8925_irq_enable(unsigned int irq)
472{
473 struct max8925_chip *chip = get_irq_chip_data(irq);
474 max8925_irqs[irq - chip->irq_base].enable
475 = max8925_irqs[irq - chip->irq_base].offs;
476}
477
478static void max8925_irq_disable(unsigned int irq)
479{
480 struct max8925_chip *chip = get_irq_chip_data(irq);
481 max8925_irqs[irq - chip->irq_base].enable = 0;
482}
483
484static struct irq_chip max8925_irq_chip = {
485 .name = "max8925",
486 .bus_lock = max8925_irq_lock,
487 .bus_sync_unlock = max8925_irq_sync_unlock,
488 .enable = max8925_irq_enable,
489 .disable = max8925_irq_disable,
490};
491
492static int max8925_irq_init(struct max8925_chip *chip, int irq,
493 struct max8925_platform_data *pdata)
494{
495 unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
496 struct irq_desc *desc;
497 int i, ret;
498 int __irq;
499
500 if (!pdata || !pdata->irq_base) {
501 dev_warn(chip->dev, "No interrupt support on IRQ base\n");
502 return -EINVAL;
503 }
504 /* clear all interrupts */
505 max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ1);
506 max8925_reg_read(chip->i2c, MAX8925_CHG_IRQ2);
507 max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ1);
508 max8925_reg_read(chip->i2c, MAX8925_ON_OFF_IRQ2);
509 max8925_reg_read(chip->rtc, MAX8925_RTC_IRQ);
510 max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
511 /* mask all interrupts */
512 max8925_reg_write(chip->rtc, MAX8925_ALARM0_CNTL, 0);
513 max8925_reg_write(chip->rtc, MAX8925_ALARM1_CNTL, 0);
514 max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ1_MASK, 0xff);
515 max8925_reg_write(chip->i2c, MAX8925_CHG_IRQ2_MASK, 0xff);
516 max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ1_MASK, 0xff);
517 max8925_reg_write(chip->i2c, MAX8925_ON_OFF_IRQ2_MASK, 0xff);
518 max8925_reg_write(chip->rtc, MAX8925_RTC_IRQ_MASK, 0xff);
519 max8925_reg_write(chip->adc, MAX8925_TSC_IRQ_MASK, 0xff);
520
521 mutex_init(&chip->irq_lock);
522 chip->core_irq = irq;
523 chip->irq_base = pdata->irq_base;
524 desc = irq_to_desc(chip->core_irq);
525
526 /* register with genirq */
527 for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
528 __irq = i + chip->irq_base;
529 set_irq_chip_data(__irq, chip);
530 set_irq_chip_and_handler(__irq, &max8925_irq_chip,
531 handle_edge_irq);
532 set_irq_nested_thread(__irq, 1);
533#ifdef CONFIG_ARM
534 set_irq_flags(__irq, IRQF_VALID);
535#else
536 set_irq_noprobe(__irq);
537#endif
538 }
539 if (!irq) {
540 dev_warn(chip->dev, "No interrupt support on core IRQ\n");
541 goto tsc_irq;
542 }
543
544 ret = request_threaded_irq(irq, NULL, max8925_irq, flags,
545 "max8925", chip);
546 if (ret) {
547 dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
548 chip->core_irq = 0;
549 }
550tsc_irq:
551 if (!pdata->tsc_irq) {
552 dev_warn(chip->dev, "No interrupt support on TSC IRQ\n");
553 return 0;
554 }
555 chip->tsc_irq = pdata->tsc_irq;
556
557 ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
558 flags, "max8925-tsc", chip);
559 if (ret) {
560 dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
561 chip->tsc_irq = 0;
562 }
563 return 0;
564}
565
566int __devinit max8925_device_init(struct max8925_chip *chip,
567 struct max8925_platform_data *pdata)
568{
569 int ret;
570
571 max8925_irq_init(chip, chip->i2c->irq, pdata);
572
573 if (pdata && (pdata->power || pdata->touch)) {
574 /* enable ADC to control internal reference */
575 max8925_set_bits(chip->i2c, MAX8925_RESET_CNFG, 1, 1);
576 /* enable internal reference for ADC */
577 max8925_set_bits(chip->adc, MAX8925_TSC_CNFG1, 3, 2);
578 /* check for internal reference IRQ */
579 do {
580 ret = max8925_reg_read(chip->adc, MAX8925_TSC_IRQ);
581 } while (ret & MAX8925_NREF_OK);
582 /* enaable ADC scheduler, interval is 1 second */
583 max8925_set_bits(chip->adc, MAX8925_ADC_SCHED, 3, 2);
584 }
585
586 /* enable Momentary Power Loss */
587 max8925_set_bits(chip->rtc, MAX8925_MPL_CNTL, 1 << 4, 1 << 4);
588
589 ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
590 ARRAY_SIZE(rtc_devs),
591 &rtc_resources[0], 0);
592 if (ret < 0) {
593 dev_err(chip->dev, "Failed to add rtc subdev\n");
594 goto out;
595 }
596 if (pdata && pdata->regulator[0]) {
597 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
598 ARRAY_SIZE(regulator_devs),
599 &regulator_resources[0], 0);
600 if (ret < 0) {
601 dev_err(chip->dev, "Failed to add regulator subdev\n");
602 goto out_dev;
603 }
604 }
605
606 if (pdata && pdata->backlight) {
607 ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
608 ARRAY_SIZE(backlight_devs),
609 &backlight_resources[0], 0);
610 if (ret < 0) {
611 dev_err(chip->dev, "Failed to add backlight subdev\n");
612 goto out_dev;
613 }
614 }
615
616 if (pdata && pdata->power) {
617 ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
618 ARRAY_SIZE(power_devs),
619 &power_supply_resources[0], 0);
620 if (ret < 0) {
621 dev_err(chip->dev, "Failed to add power supply "
622 "subdev\n");
623 goto out_dev;
624 }
625 }
626
627 if (pdata && pdata->touch) {
628 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
629 ARRAY_SIZE(touch_devs),
630 &touch_resources[0], 0);
631 if (ret < 0) {
632 dev_err(chip->dev, "Failed to add touch subdev\n");
633 goto out_dev;
634 }
635 }
636
637 return 0;
638out_dev:
639 mfd_remove_devices(chip->dev);
640out:
641 return ret;
642}
643
644void __devexit max8925_device_exit(struct max8925_chip *chip)
645{
646 if (chip->core_irq)
647 free_irq(chip->core_irq, chip);
648 if (chip->tsc_irq)
649 free_irq(chip->tsc_irq, chip);
650 mfd_remove_devices(chip->dev);
651}
652
653
654MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925");
655MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com");
656MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
new file mode 100644
index 000000000000..c0b883c14f41
--- /dev/null
+++ b/drivers/mfd/max8925-i2c.c
@@ -0,0 +1,211 @@
1/*
2 * I2C driver for Maxim MAX8925
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/i2c.h>
15#include <linux/mfd/max8925.h>
16
17#define RTC_I2C_ADDR 0x68
18#define ADC_I2C_ADDR 0x47
19
20static inline int max8925_read_device(struct i2c_client *i2c,
21 int reg, int bytes, void *dest)
22{
23 int ret;
24
25 if (bytes > 1)
26 ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
27 else {
28 ret = i2c_smbus_read_byte_data(i2c, reg);
29 if (ret < 0)
30 return ret;
31 *(unsigned char *)dest = (unsigned char)ret;
32 }
33 return ret;
34}
35
36static inline int max8925_write_device(struct i2c_client *i2c,
37 int reg, int bytes, void *src)
38{
39 unsigned char buf[bytes + 1];
40 int ret;
41
42 buf[0] = (unsigned char)reg;
43 memcpy(&buf[1], src, bytes);
44
45 ret = i2c_master_send(i2c, buf, bytes + 1);
46 if (ret < 0)
47 return ret;
48 return 0;
49}
50
51int max8925_reg_read(struct i2c_client *i2c, int reg)
52{
53 struct max8925_chip *chip = i2c_get_clientdata(i2c);
54 unsigned char data = 0;
55 int ret;
56
57 mutex_lock(&chip->io_lock);
58 ret = max8925_read_device(i2c, reg, 1, &data);
59 mutex_unlock(&chip->io_lock);
60
61 if (ret < 0)
62 return ret;
63 else
64 return (int)data;
65}
66EXPORT_SYMBOL(max8925_reg_read);
67
68int max8925_reg_write(struct i2c_client *i2c, int reg,
69 unsigned char data)
70{
71 struct max8925_chip *chip = i2c_get_clientdata(i2c);
72 int ret;
73
74 mutex_lock(&chip->io_lock);
75 ret = max8925_write_device(i2c, reg, 1, &data);
76 mutex_unlock(&chip->io_lock);
77
78 return ret;
79}
80EXPORT_SYMBOL(max8925_reg_write);
81
82int max8925_bulk_read(struct i2c_client *i2c, int reg,
83 int count, unsigned char *buf)
84{
85 struct max8925_chip *chip = i2c_get_clientdata(i2c);
86 int ret;
87
88 mutex_lock(&chip->io_lock);
89 ret = max8925_read_device(i2c, reg, count, buf);
90 mutex_unlock(&chip->io_lock);
91
92 return ret;
93}
94EXPORT_SYMBOL(max8925_bulk_read);
95
96int max8925_bulk_write(struct i2c_client *i2c, int reg,
97 int count, unsigned char *buf)
98{
99 struct max8925_chip *chip = i2c_get_clientdata(i2c);
100 int ret;
101
102 mutex_lock(&chip->io_lock);
103 ret = max8925_write_device(i2c, reg, count, buf);
104 mutex_unlock(&chip->io_lock);
105
106 return ret;
107}
108EXPORT_SYMBOL(max8925_bulk_write);
109
110int max8925_set_bits(struct i2c_client *i2c, int reg,
111 unsigned char mask, unsigned char data)
112{
113 struct max8925_chip *chip = i2c_get_clientdata(i2c);
114 unsigned char value;
115 int ret;
116
117 mutex_lock(&chip->io_lock);
118 ret = max8925_read_device(i2c, reg, 1, &value);
119 if (ret < 0)
120 goto out;
121 value &= ~mask;
122 value |= data;
123 ret = max8925_write_device(i2c, reg, 1, &value);
124out:
125 mutex_unlock(&chip->io_lock);
126 return ret;
127}
128EXPORT_SYMBOL(max8925_set_bits);
129
130
131static const struct i2c_device_id max8925_id_table[] = {
132 { "max8925", 0 },
133 { },
134};
135MODULE_DEVICE_TABLE(i2c, max8925_id_table);
136
137static int __devinit max8925_probe(struct i2c_client *client,
138 const struct i2c_device_id *id)
139{
140 struct max8925_platform_data *pdata = client->dev.platform_data;
141 static struct max8925_chip *chip;
142
143 if (!pdata) {
144 pr_info("%s: platform data is missing\n", __func__);
145 return -EINVAL;
146 }
147
148 chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL);
149 if (chip == NULL)
150 return -ENOMEM;
151 chip->i2c = client;
152 chip->dev = &client->dev;
153 i2c_set_clientdata(client, chip);
154 dev_set_drvdata(chip->dev, chip);
155 mutex_init(&chip->io_lock);
156
157 chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
158 i2c_set_clientdata(chip->rtc, chip);
159
160 chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
161 i2c_set_clientdata(chip->adc, chip);
162
163 max8925_device_init(chip, pdata);
164
165 return 0;
166}
167
168static int __devexit max8925_remove(struct i2c_client *client)
169{
170 struct max8925_chip *chip = i2c_get_clientdata(client);
171
172 max8925_device_exit(chip);
173 i2c_unregister_device(chip->adc);
174 i2c_unregister_device(chip->rtc);
175 i2c_set_clientdata(chip->adc, NULL);
176 i2c_set_clientdata(chip->rtc, NULL);
177 i2c_set_clientdata(chip->i2c, NULL);
178 kfree(chip);
179 return 0;
180}
181
182static struct i2c_driver max8925_driver = {
183 .driver = {
184 .name = "max8925",
185 .owner = THIS_MODULE,
186 },
187 .probe = max8925_probe,
188 .remove = __devexit_p(max8925_remove),
189 .id_table = max8925_id_table,
190};
191
192static int __init max8925_i2c_init(void)
193{
194 int ret;
195
196 ret = i2c_add_driver(&max8925_driver);
197 if (ret != 0)
198 pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
199 return ret;
200}
201subsys_initcall(max8925_i2c_init);
202
203static void __exit max8925_i2c_exit(void)
204{
205 i2c_del_driver(&max8925_driver);
206}
207module_exit(max8925_i2c_exit);
208
209MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
210MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
211MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c
index 735c8a4d164f..62a847e4c2d8 100644
--- a/drivers/mfd/mc13783-core.c
+++ b/drivers/mfd/mc13783-core.c
@@ -225,7 +225,7 @@ int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
225} 225}
226EXPORT_SYMBOL(mc13783_reg_rmw); 226EXPORT_SYMBOL(mc13783_reg_rmw);
227 227
228int mc13783_mask(struct mc13783 *mc13783, int irq) 228int mc13783_irq_mask(struct mc13783 *mc13783, int irq)
229{ 229{
230 int ret; 230 int ret;
231 unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1; 231 unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
@@ -245,9 +245,9 @@ int mc13783_mask(struct mc13783 *mc13783, int irq)
245 245
246 return mc13783_reg_write(mc13783, offmask, mask | irqbit); 246 return mc13783_reg_write(mc13783, offmask, mask | irqbit);
247} 247}
248EXPORT_SYMBOL(mc13783_mask); 248EXPORT_SYMBOL(mc13783_irq_mask);
249 249
250int mc13783_unmask(struct mc13783 *mc13783, int irq) 250int mc13783_irq_unmask(struct mc13783 *mc13783, int irq)
251{ 251{
252 int ret; 252 int ret;
253 unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1; 253 unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
@@ -267,7 +267,53 @@ int mc13783_unmask(struct mc13783 *mc13783, int irq)
267 267
268 return mc13783_reg_write(mc13783, offmask, mask & ~irqbit); 268 return mc13783_reg_write(mc13783, offmask, mask & ~irqbit);
269} 269}
270EXPORT_SYMBOL(mc13783_unmask); 270EXPORT_SYMBOL(mc13783_irq_unmask);
271
272int mc13783_irq_status(struct mc13783 *mc13783, int irq,
273 int *enabled, int *pending)
274{
275 int ret;
276 unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
277 unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
278 u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
279
280 if (irq < 0 || irq >= MC13783_NUM_IRQ)
281 return -EINVAL;
282
283 if (enabled) {
284 u32 mask;
285
286 ret = mc13783_reg_read(mc13783, offmask, &mask);
287 if (ret)
288 return ret;
289
290 *enabled = mask & irqbit;
291 }
292
293 if (pending) {
294 u32 stat;
295
296 ret = mc13783_reg_read(mc13783, offstat, &stat);
297 if (ret)
298 return ret;
299
300 *pending = stat & irqbit;
301 }
302
303 return 0;
304}
305EXPORT_SYMBOL(mc13783_irq_status);
306
307int mc13783_irq_ack(struct mc13783 *mc13783, int irq)
308{
309 unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
310 unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
311
312 BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
313
314 return mc13783_reg_write(mc13783, offstat, val);
315}
316EXPORT_SYMBOL(mc13783_irq_ack);
271 317
272int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq, 318int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
273 irq_handler_t handler, const char *name, void *dev) 319 irq_handler_t handler, const char *name, void *dev)
@@ -297,7 +343,7 @@ int mc13783_irq_request(struct mc13783 *mc13783, int irq,
297 if (ret) 343 if (ret)
298 return ret; 344 return ret;
299 345
300 ret = mc13783_unmask(mc13783, irq); 346 ret = mc13783_irq_unmask(mc13783, irq);
301 if (ret) { 347 if (ret) {
302 mc13783->irqhandler[irq] = NULL; 348 mc13783->irqhandler[irq] = NULL;
303 mc13783->irqdata[irq] = NULL; 349 mc13783->irqdata[irq] = NULL;
@@ -317,7 +363,7 @@ int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
317 mc13783->irqdata[irq] != dev) 363 mc13783->irqdata[irq] != dev)
318 return -EINVAL; 364 return -EINVAL;
319 365
320 ret = mc13783_mask(mc13783, irq); 366 ret = mc13783_irq_mask(mc13783, irq);
321 if (ret) 367 if (ret)
322 return ret; 368 return ret;
323 369
@@ -333,17 +379,6 @@ static inline irqreturn_t mc13783_irqhandler(struct mc13783 *mc13783, int irq)
333 return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]); 379 return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]);
334} 380}
335 381
336int mc13783_ackirq(struct mc13783 *mc13783, int irq)
337{
338 unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
339 unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
340
341 BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
342
343 return mc13783_reg_write(mc13783, offstat, val);
344}
345EXPORT_SYMBOL(mc13783_ackirq);
346
347/* 382/*
348 * returns: number of handled irqs or negative error 383 * returns: number of handled irqs or negative error
349 * locking: holds mc13783->lock 384 * locking: holds mc13783->lock
@@ -422,7 +457,7 @@ static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
422{ 457{
423 struct mc13783_adcdone_data *adcdone_data = data; 458 struct mc13783_adcdone_data *adcdone_data = data;
424 459
425 mc13783_ackirq(adcdone_data->mc13783, irq); 460 mc13783_irq_ack(adcdone_data->mc13783, irq);
426 461
427 complete_all(&adcdone_data->done); 462 complete_all(&adcdone_data->done);
428 463
@@ -486,7 +521,7 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
486 dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__); 521 dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__);
487 mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE, 522 mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE,
488 mc13783_handler_adcdone, __func__, &adcdone_data); 523 mc13783_handler_adcdone, __func__, &adcdone_data);
489 mc13783_ackirq(mc13783, MC13783_IRQ_ADCDONE); 524 mc13783_irq_ack(mc13783, MC13783_IRQ_ADCDONE);
490 525
491 mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0); 526 mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0);
492 mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1); 527 mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1);
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index ae15e495e20e..aa17f4bddc56 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/acpi.h>
16#include <linux/mfd/core.h> 17#include <linux/mfd/core.h>
17 18
18static int mfd_add_device(struct device *parent, int id, 19static int mfd_add_device(struct device *parent, int id,
@@ -62,6 +63,10 @@ static int mfd_add_device(struct device *parent, int id,
62 res[r].start = cell->resources[r].start; 63 res[r].start = cell->resources[r].start;
63 res[r].end = cell->resources[r].end; 64 res[r].end = cell->resources[r].end;
64 } 65 }
66
67 ret = acpi_check_resource_conflict(res);
68 if (ret)
69 goto fail_res;
65 } 70 }
66 71
67 platform_device_add_resources(pdev, res, cell->num_resources); 72 platform_device_add_resources(pdev, res, cell->num_resources);
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
index 03efae8041ab..468fd366d4da 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -21,7 +21,7 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24 24#include <linux/mmc/host.h>
25#include <linux/mfd/core.h> 25#include <linux/mfd/core.h>
26#include <linux/mfd/tmio.h> 26#include <linux/mfd/tmio.h>
27#include <linux/mfd/sh_mobile_sdhi.h> 27#include <linux/mfd/sh_mobile_sdhi.h>
@@ -95,9 +95,9 @@ static int __init sh_mobile_sdhi_probe(struct platform_device *pdev)
95 95
96 clk_enable(priv->clk); 96 clk_enable(priv->clk);
97 97
98 /* FIXME: silly const unsigned int hclk */ 98 priv->mmc_data.hclk = clk_get_rate(priv->clk);
99 *(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk);
100 priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr; 99 priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr;
100 priv->mmc_data.capabilities = MMC_CAP_MMC_HIGHSPEED;
101 101
102 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); 102 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
103 priv->cell_mmc.driver_data = &priv->mmc_data; 103 priv->cell_mmc.driver_data = &priv->mmc_data;
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 0cc5eeff5ee8..dc9ea95c0561 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1430,7 +1430,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
1430 } 1430 }
1431 1431
1432 sm->regs_claim = request_mem_region(sm->io_res->start, 1432 sm->regs_claim = request_mem_region(sm->io_res->start,
1433 0x100, "sm501"); 1433 resource_size(sm->io_res), "sm501");
1434 1434
1435 if (sm->regs_claim == NULL) { 1435 if (sm->regs_claim == NULL) {
1436 dev_err(&dev->dev, "cannot claim registers\n"); 1436 dev_err(&dev->dev, "cannot claim registers\n");
@@ -1440,8 +1440,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev)
1440 1440
1441 platform_set_drvdata(dev, sm); 1441 platform_set_drvdata(dev, sm);
1442 1442
1443 sm->regs = ioremap(sm->io_res->start, 1443 sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));
1444 (sm->io_res->end - sm->io_res->start) - 1);
1445 1444
1446 if (sm->regs == NULL) { 1445 if (sm->regs == NULL) {
1447 dev_err(&dev->dev, "cannot remap registers\n"); 1446 dev_err(&dev->dev, "cannot remap registers\n");
@@ -1645,7 +1644,7 @@ static int __devinit sm501_pci_probe(struct pci_dev *dev,
1645 sm->mem_res = &dev->resource[0]; 1644 sm->mem_res = &dev->resource[0];
1646 1645
1647 sm->regs_claim = request_mem_region(sm->io_res->start, 1646 sm->regs_claim = request_mem_region(sm->io_res->start,
1648 0x100, "sm501"); 1647 resource_size(sm->io_res), "sm501");
1649 if (sm->regs_claim == NULL) { 1648 if (sm->regs_claim == NULL) {
1650 dev_err(&dev->dev, "cannot claim registers\n"); 1649 dev_err(&dev->dev, "cannot claim registers\n");
1651 err= -EBUSY; 1650 err= -EBUSY;
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index bcf4687d4af5..26d9176fca91 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -360,7 +360,7 @@ static int t7l66xb_probe(struct platform_device *dev)
360 if (ret) 360 if (ret)
361 goto err_request_scr; 361 goto err_request_scr;
362 362
363 t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); 363 t7l66xb->scr = ioremap(rscr->start, resource_size(rscr));
364 if (!t7l66xb->scr) { 364 if (!t7l66xb->scr) {
365 ret = -ENOMEM; 365 ret = -ENOMEM;
366 goto err_ioremap; 366 goto err_ioremap;
@@ -403,12 +403,12 @@ static int t7l66xb_probe(struct platform_device *dev)
403err_ioremap: 403err_ioremap:
404 release_resource(&t7l66xb->rscr); 404 release_resource(&t7l66xb->rscr);
405err_request_scr: 405err_request_scr:
406 kfree(t7l66xb);
407 clk_put(t7l66xb->clk48m); 406 clk_put(t7l66xb->clk48m);
408err_clk48m_get: 407err_clk48m_get:
409 clk_put(t7l66xb->clk32k); 408 clk_put(t7l66xb->clk32k);
410err_clk32k_get: 409err_clk32k_get:
411err_noirq: 410err_noirq:
411 kfree(t7l66xb);
412 return ret; 412 return ret;
413} 413}
414 414
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 4bc5a08a2b09..c59e5c5737d0 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -647,7 +647,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
647 if (ret) 647 if (ret)
648 goto err_request_scr; 648 goto err_request_scr;
649 649
650 tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1); 650 tc6393xb->scr = ioremap(rscr->start, resource_size(rscr));
651 if (!tc6393xb->scr) { 651 if (!tc6393xb->scr) {
652 ret = -ENOMEM; 652 ret = -ENOMEM;
653 goto err_ioremap; 653 goto err_ioremap;
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 19a930d06241..562cd4935e17 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -58,13 +58,6 @@
58 58
59#define DRIVER_NAME "twl" 59#define DRIVER_NAME "twl"
60 60
61#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
62 defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
63#define twl_has_bci() true
64#else
65#define twl_has_bci() false
66#endif
67
68#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE) 61#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
69#define twl_has_keypad() true 62#define twl_has_keypad() true
70#else 63#else
@@ -130,7 +123,7 @@
130#define TWL_NUM_SLAVES 4 123#define TWL_NUM_SLAVES 4
131 124
132#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \ 125#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
133 || defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE) 126 || defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE)
134#define twl_has_pwrbutton() true 127#define twl_has_pwrbutton() true
135#else 128#else
136#define twl_has_pwrbutton() false 129#define twl_has_pwrbutton() false
@@ -205,6 +198,7 @@
205/* subchip/slave 3 0x4B - AUDIO */ 198/* subchip/slave 3 0x4B - AUDIO */
206#define TWL6030_BASEADD_AUDIO 0x0000 199#define TWL6030_BASEADD_AUDIO 0x0000
207#define TWL6030_BASEADD_RSV 0x0000 200#define TWL6030_BASEADD_RSV 0x0000
201#define TWL6030_BASEADD_ZERO 0x0000
208 202
209/* Few power values */ 203/* Few power values */
210#define R_CFG_BOOT 0x05 204#define R_CFG_BOOT 0x05
@@ -320,9 +314,11 @@ static struct twl_mapping twl6030_map[] = {
320 { SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER }, 314 { SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER },
321 { SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE }, 315 { SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE },
322 { SUB_CHIP_ID1, TWL6030_BASEADD_PWM }, 316 { SUB_CHIP_ID1, TWL6030_BASEADD_PWM },
323 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, 317 { SUB_CHIP_ID0, TWL6030_BASEADD_ZERO },
324 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, 318 { SUB_CHIP_ID1, TWL6030_BASEADD_ZERO },
325 319
320 { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO },
321 { SUB_CHIP_ID2, TWL6030_BASEADD_ZERO },
326 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, 322 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
327 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, 323 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
328 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV }, 324 { SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
@@ -588,18 +584,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
588 struct device *child; 584 struct device *child;
589 unsigned sub_chip_id; 585 unsigned sub_chip_id;
590 586
591 if (twl_has_bci() && pdata->bci &&
592 !(features & (TPS_SUBSET | TWL5031))) {
593 child = add_child(3, "twl4030_bci",
594 pdata->bci, sizeof(*pdata->bci),
595 false,
596 /* irq0 = CHG_PRES, irq1 = BCI */
597 pdata->irq_base + BCI_PRES_INTR_OFFSET,
598 pdata->irq_base + BCI_INTR_OFFSET);
599 if (IS_ERR(child))
600 return PTR_ERR(child);
601 }
602
603 if (twl_has_gpio() && pdata->gpio) { 587 if (twl_has_gpio() && pdata->gpio) {
604 child = add_child(SUB_CHIP_ID1, "twl4030_gpio", 588 child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
605 pdata->gpio, sizeof(*pdata->gpio), 589 pdata->gpio, sizeof(*pdata->gpio),
@@ -977,6 +961,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
977 int status; 961 int status;
978 unsigned i; 962 unsigned i;
979 struct twl4030_platform_data *pdata = client->dev.platform_data; 963 struct twl4030_platform_data *pdata = client->dev.platform_data;
964 u8 temp;
980 965
981 if (!pdata) { 966 if (!pdata) {
982 dev_dbg(&client->dev, "no platform data?\n"); 967 dev_dbg(&client->dev, "no platform data?\n");
@@ -1044,6 +1029,18 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1044 goto fail; 1029 goto fail;
1045 } 1030 }
1046 1031
1032 /* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface.
1033 * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0,
1034 * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0.
1035 */
1036
1037 if (twl_class_is_4030()) {
1038 twl_i2c_read_u8(TWL4030_MODULE_INTBR, &temp, REG_GPPUPDCTR1);
1039 temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \
1040 I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
1041 twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
1042 }
1043
1047 status = add_children(pdata, id->driver_data); 1044 status = add_children(pdata, id->driver_data);
1048fail: 1045fail:
1049 if (status < 0) 1046 if (status < 0)
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 0815292fdafc..7efa8789a3a2 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -405,7 +405,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
405 405
406 if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { 406 if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
407 remap &= ~SLEEP_STATE_MASK; 407 remap &= ~SLEEP_STATE_MASK;
408 remap |= rconfig->remap_off << SLEEP_STATE_SHIFT; 408 remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
409 } 409 }
410 410
411 err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 411 err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
@@ -461,6 +461,56 @@ out:
461 return err; 461 return err;
462} 462}
463 463
464int twl4030_remove_script(u8 flags)
465{
466 int err = 0;
467
468 err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
469 R_PROTECT_KEY);
470 if (err) {
471 pr_err("twl4030: unable to unlock PROTECT_KEY\n");
472 return err;
473 }
474
475 err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
476 R_PROTECT_KEY);
477 if (err) {
478 pr_err("twl4030: unable to unlock PROTECT_KEY\n");
479 return err;
480 }
481
482 if (flags & TWL4030_WRST_SCRIPT) {
483 err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
484 R_SEQ_ADD_WARM);
485 if (err)
486 return err;
487 }
488 if (flags & TWL4030_WAKEUP12_SCRIPT) {
489 if (err)
490 err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
491 R_SEQ_ADD_S2A12);
492 return err;
493 }
494 if (flags & TWL4030_WAKEUP3_SCRIPT) {
495 err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
496 R_SEQ_ADD_S2A3);
497 if (err)
498 return err;
499 }
500 if (flags & TWL4030_SLEEP_SCRIPT) {
501 err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, END_OF_SCRIPT,
502 R_SEQ_ADD_A2S);
503 if (err)
504 return err;
505 }
506
507 err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
508 if (err)
509 pr_err("TWL4030 Unable to relock registers\n");
510
511 return err;
512}
513
464void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) 514void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
465{ 515{
466 int err = 0; 516 int err = 0;
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 252b74188ec2..b281217334eb 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -27,6 +27,7 @@
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/mfd/ucb1x00.h> 28#include <linux/mfd/ucb1x00.h>
29#include <linux/gpio.h> 29#include <linux/gpio.h>
30#include <linux/semaphore.h>
30 31
31#include <mach/dma.h> 32#include <mach/dma.h>
32#include <mach/hardware.h> 33#include <mach/hardware.h>
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 4b2021af1d96..07101e9e1cba 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -321,7 +321,6 @@ EXPORT_SYMBOL_GPL(wm831x_set_bits);
321 */ 321 */
322int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) 322int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
323{ 323{
324 int tries = 10;
325 int ret, src; 324 int ret, src;
326 325
327 mutex_lock(&wm831x->auxadc_lock); 326 mutex_lock(&wm831x->auxadc_lock);
@@ -349,13 +348,14 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
349 goto disable; 348 goto disable;
350 } 349 }
351 350
352 do { 351 /* Ignore the result to allow us to soldier on without IRQ hookup */
353 msleep(1); 352 wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5));
354 353
355 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL); 354 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
356 if (ret < 0) 355 if (ret < 0) {
357 ret = WM831X_AUX_CVT_ENA; 356 dev_err(wm831x->dev, "AUXADC status read failed: %d\n", ret);
358 } while ((ret & WM831X_AUX_CVT_ENA) && --tries); 357 goto disable;
358 }
359 359
360 if (ret & WM831X_AUX_CVT_ENA) { 360 if (ret & WM831X_AUX_CVT_ENA) {
361 dev_err(wm831x->dev, "Timed out reading AUXADC\n"); 361 dev_err(wm831x->dev, "Timed out reading AUXADC\n");
@@ -390,6 +390,15 @@ out:
390} 390}
391EXPORT_SYMBOL_GPL(wm831x_auxadc_read); 391EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
392 392
393static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
394{
395 struct wm831x *wm831x = irq_data;
396
397 complete(&wm831x->auxadc_done);
398
399 return IRQ_HANDLED;
400}
401
393/** 402/**
394 * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC 403 * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
395 * 404 *
@@ -1411,6 +1420,7 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1411 mutex_init(&wm831x->io_lock); 1420 mutex_init(&wm831x->io_lock);
1412 mutex_init(&wm831x->key_lock); 1421 mutex_init(&wm831x->key_lock);
1413 mutex_init(&wm831x->auxadc_lock); 1422 mutex_init(&wm831x->auxadc_lock);
1423 init_completion(&wm831x->auxadc_done);
1414 dev_set_drvdata(wm831x->dev, wm831x); 1424 dev_set_drvdata(wm831x->dev, wm831x);
1415 1425
1416 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); 1426 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
@@ -1449,18 +1459,33 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1449 case WM8310: 1459 case WM8310:
1450 parent = WM8310; 1460 parent = WM8310;
1451 wm831x->num_gpio = 16; 1461 wm831x->num_gpio = 16;
1462 if (rev > 0) {
1463 wm831x->has_gpio_ena = 1;
1464 wm831x->has_cs_sts = 1;
1465 }
1466
1452 dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev); 1467 dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
1453 break; 1468 break;
1454 1469
1455 case WM8311: 1470 case WM8311:
1456 parent = WM8311; 1471 parent = WM8311;
1457 wm831x->num_gpio = 16; 1472 wm831x->num_gpio = 16;
1473 if (rev > 0) {
1474 wm831x->has_gpio_ena = 1;
1475 wm831x->has_cs_sts = 1;
1476 }
1477
1458 dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev); 1478 dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
1459 break; 1479 break;
1460 1480
1461 case WM8312: 1481 case WM8312:
1462 parent = WM8312; 1482 parent = WM8312;
1463 wm831x->num_gpio = 16; 1483 wm831x->num_gpio = 16;
1484 if (rev > 0) {
1485 wm831x->has_gpio_ena = 1;
1486 wm831x->has_cs_sts = 1;
1487 }
1488
1464 dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev); 1489 dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
1465 break; 1490 break;
1466 1491
@@ -1508,6 +1533,16 @@ static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
1508 if (ret != 0) 1533 if (ret != 0)
1509 goto err; 1534 goto err;
1510 1535
1536 if (wm831x->irq_base) {
1537 ret = request_threaded_irq(wm831x->irq_base +
1538 WM831X_IRQ_AUXADC_DATA,
1539 NULL, wm831x_auxadc_irq, 0,
1540 "auxadc", wm831x);
1541 if (ret < 0)
1542 dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
1543 ret);
1544 }
1545
1511 /* The core device is up, instantiate the subdevices. */ 1546 /* The core device is up, instantiate the subdevices. */
1512 switch (parent) { 1547 switch (parent) {
1513 case WM8310: 1548 case WM8310:
@@ -1578,6 +1613,8 @@ static void wm831x_device_exit(struct wm831x *wm831x)
1578{ 1613{
1579 wm831x_otp_exit(wm831x); 1614 wm831x_otp_exit(wm831x);
1580 mfd_remove_devices(wm831x->dev); 1615 mfd_remove_devices(wm831x->dev);
1616 if (wm831x->irq_base)
1617 free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
1581 wm831x_irq_exit(wm831x); 1618 wm831x_irq_exit(wm831x);
1582 kfree(wm831x); 1619 kfree(wm831x);
1583} 1620}
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index 9a970bd68775..bd75807d5302 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -339,7 +339,6 @@ EXPORT_SYMBOL_GPL(wm8350_reg_unlock);
339int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) 339int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
340{ 340{
341 u16 reg, result = 0; 341 u16 reg, result = 0;
342 int tries = 5;
343 342
344 if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP) 343 if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
345 return -EINVAL; 344 return -EINVAL;
@@ -363,12 +362,13 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
363 reg |= 1 << channel | WM8350_AUXADC_POLL; 362 reg |= 1 << channel | WM8350_AUXADC_POLL;
364 wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); 363 wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
365 364
366 do { 365 /* We ignore the result of the completion and just check for a
367 schedule_timeout_interruptible(1); 366 * conversion result, allowing us to soldier on if the IRQ
368 reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1); 367 * infrastructure is not set up for the chip. */
369 } while ((reg & WM8350_AUXADC_POLL) && --tries); 368 wait_for_completion_timeout(&wm8350->auxadc_done, msecs_to_jiffies(5));
370 369
371 if (!tries) 370 reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
371 if (reg & WM8350_AUXADC_POLL)
372 dev_err(wm8350->dev, "adc chn %d read timeout\n", channel); 372 dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
373 else 373 else
374 result = wm8350_reg_read(wm8350, 374 result = wm8350_reg_read(wm8350,
@@ -385,6 +385,15 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
385} 385}
386EXPORT_SYMBOL_GPL(wm8350_read_auxadc); 386EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
387 387
388static irqreturn_t wm8350_auxadc_irq(int irq, void *irq_data)
389{
390 struct wm8350 *wm8350 = irq_data;
391
392 complete(&wm8350->auxadc_done);
393
394 return IRQ_HANDLED;
395}
396
388/* 397/*
389 * Cache is always host endian. 398 * Cache is always host endian.
390 */ 399 */
@@ -682,11 +691,22 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
682 } 691 }
683 692
684 mutex_init(&wm8350->auxadc_mutex); 693 mutex_init(&wm8350->auxadc_mutex);
694 init_completion(&wm8350->auxadc_done);
685 695
686 ret = wm8350_irq_init(wm8350, irq, pdata); 696 ret = wm8350_irq_init(wm8350, irq, pdata);
687 if (ret < 0) 697 if (ret < 0)
688 goto err; 698 goto err;
689 699
700 if (wm8350->irq_base) {
701 ret = request_threaded_irq(wm8350->irq_base +
702 WM8350_IRQ_AUXADC_DATARDY,
703 NULL, wm8350_auxadc_irq, 0,
704 "auxadc", wm8350);
705 if (ret < 0)
706 dev_warn(wm8350->dev,
707 "Failed to request AUXADC IRQ: %d\n", ret);
708 }
709
690 if (pdata && pdata->init) { 710 if (pdata && pdata->init) {
691 ret = pdata->init(wm8350); 711 ret = pdata->init(wm8350);
692 if (ret != 0) { 712 if (ret != 0) {
@@ -736,6 +756,9 @@ void wm8350_device_exit(struct wm8350 *wm8350)
736 platform_device_unregister(wm8350->gpio.pdev); 756 platform_device_unregister(wm8350->gpio.pdev);
737 platform_device_unregister(wm8350->codec.pdev); 757 platform_device_unregister(wm8350->codec.pdev);
738 758
759 if (wm8350->irq_base)
760 free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350);
761
739 wm8350_irq_exit(wm8350); 762 wm8350_irq_exit(wm8350);
740 763
741 kfree(wm8350->reg_cache); 764 kfree(wm8350->reg_cache);
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index 9025f29e2707..f56c9adf9493 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -18,7 +18,7 @@
18#include <linux/bug.h> 18#include <linux/bug.h>
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/workqueue.h> 21#include <linux/irq.h>
22 22
23#include <linux/mfd/wm8350/core.h> 23#include <linux/mfd/wm8350/core.h>
24#include <linux/mfd/wm8350/audio.h> 24#include <linux/mfd/wm8350/audio.h>
@@ -29,8 +29,6 @@
29#include <linux/mfd/wm8350/supply.h> 29#include <linux/mfd/wm8350/supply.h>
30#include <linux/mfd/wm8350/wdt.h> 30#include <linux/mfd/wm8350/wdt.h>
31 31
32#define WM8350_NUM_IRQ_REGS 7
33
34#define WM8350_INT_OFFSET_1 0 32#define WM8350_INT_OFFSET_1 0
35#define WM8350_INT_OFFSET_2 1 33#define WM8350_INT_OFFSET_2 1
36#define WM8350_POWER_UP_INT_OFFSET 2 34#define WM8350_POWER_UP_INT_OFFSET 2
@@ -366,19 +364,10 @@ static struct wm8350_irq_data wm8350_irqs[] = {
366 }, 364 },
367}; 365};
368 366
369static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq) 367static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
368 int irq)
370{ 369{
371 mutex_lock(&wm8350->irq_mutex); 370 return &wm8350_irqs[irq - wm8350->irq_base];
372
373 if (wm8350->irq[irq].handler)
374 wm8350->irq[irq].handler(irq, wm8350->irq[irq].data);
375 else {
376 dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
377 irq);
378 wm8350_mask_irq(wm8350, irq);
379 }
380
381 mutex_unlock(&wm8350->irq_mutex);
382} 371}
383 372
384/* 373/*
@@ -386,7 +375,9 @@ static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
386 * interrupts are clear on read the IRQ line will be reasserted and 375 * interrupts are clear on read the IRQ line will be reasserted and
387 * the physical IRQ will be handled again if another interrupt is 376 * the physical IRQ will be handled again if another interrupt is
388 * asserted while we run - in the normal course of events this is a 377 * asserted while we run - in the normal course of events this is a
389 * rare occurrence so we save I2C/SPI reads. 378 * rare occurrence so we save I2C/SPI reads. We're also assuming that
379 * it's rare to get lots of interrupts firing simultaneously so try to
380 * minimise I/O.
390 */ 381 */
391static irqreturn_t wm8350_irq(int irq, void *irq_data) 382static irqreturn_t wm8350_irq(int irq, void *irq_data)
392{ 383{
@@ -397,7 +388,6 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data)
397 struct wm8350_irq_data *data; 388 struct wm8350_irq_data *data;
398 int i; 389 int i;
399 390
400 /* TODO: Use block reads to improve performance? */
401 level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS) 391 level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
402 & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK); 392 & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
403 393
@@ -416,93 +406,101 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data)
416 sub_reg[data->reg] = 406 sub_reg[data->reg] =
417 wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 + 407 wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
418 data->reg); 408 data->reg);
419 sub_reg[data->reg] &= 409 sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
420 ~wm8350_reg_read(wm8350,
421 WM8350_INT_STATUS_1_MASK +
422 data->reg);
423 read_done[data->reg] = 1; 410 read_done[data->reg] = 1;
424 } 411 }
425 412
426 if (sub_reg[data->reg] & data->mask) 413 if (sub_reg[data->reg] & data->mask)
427 wm8350_irq_call_handler(wm8350, i); 414 handle_nested_irq(wm8350->irq_base + i);
428 } 415 }
429 416
430 return IRQ_HANDLED; 417 return IRQ_HANDLED;
431} 418}
432 419
433int wm8350_register_irq(struct wm8350 *wm8350, int irq, 420static void wm8350_irq_lock(unsigned int irq)
434 irq_handler_t handler, unsigned long flags,
435 const char *name, void *data)
436{ 421{
437 if (irq < 0 || irq >= WM8350_NUM_IRQ || !handler) 422 struct wm8350 *wm8350 = get_irq_chip_data(irq);
438 return -EINVAL;
439
440 if (wm8350->irq[irq].handler)
441 return -EBUSY;
442
443 mutex_lock(&wm8350->irq_mutex);
444 wm8350->irq[irq].handler = handler;
445 wm8350->irq[irq].data = data;
446 mutex_unlock(&wm8350->irq_mutex);
447
448 wm8350_unmask_irq(wm8350, irq);
449 423
450 return 0; 424 mutex_lock(&wm8350->irq_lock);
451} 425}
452EXPORT_SYMBOL_GPL(wm8350_register_irq);
453 426
454int wm8350_free_irq(struct wm8350 *wm8350, int irq) 427static void wm8350_irq_sync_unlock(unsigned int irq)
455{ 428{
456 if (irq < 0 || irq >= WM8350_NUM_IRQ) 429 struct wm8350 *wm8350 = get_irq_chip_data(irq);
457 return -EINVAL; 430 int i;
458 431
459 wm8350_mask_irq(wm8350, irq); 432 for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
433 /* If there's been a change in the mask write it back
434 * to the hardware. */
435 if (wm8350->irq_masks[i] !=
436 wm8350->reg_cache[WM8350_INT_STATUS_1_MASK + i])
437 WARN_ON(wm8350_reg_write(wm8350,
438 WM8350_INT_STATUS_1_MASK + i,
439 wm8350->irq_masks[i]));
440 }
460 441
461 mutex_lock(&wm8350->irq_mutex); 442 mutex_unlock(&wm8350->irq_lock);
462 wm8350->irq[irq].handler = NULL;
463 mutex_unlock(&wm8350->irq_mutex);
464 return 0;
465} 443}
466EXPORT_SYMBOL_GPL(wm8350_free_irq);
467 444
468int wm8350_mask_irq(struct wm8350 *wm8350, int irq) 445static void wm8350_irq_enable(unsigned int irq)
469{ 446{
470 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK + 447 struct wm8350 *wm8350 = get_irq_chip_data(irq);
471 wm8350_irqs[irq].reg, 448 struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
472 wm8350_irqs[irq].mask); 449
450 wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
473} 451}
474EXPORT_SYMBOL_GPL(wm8350_mask_irq);
475 452
476int wm8350_unmask_irq(struct wm8350 *wm8350, int irq) 453static void wm8350_irq_disable(unsigned int irq)
477{ 454{
478 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK + 455 struct wm8350 *wm8350 = get_irq_chip_data(irq);
479 wm8350_irqs[irq].reg, 456 struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
480 wm8350_irqs[irq].mask); 457
458 wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
481} 459}
482EXPORT_SYMBOL_GPL(wm8350_unmask_irq); 460
461static struct irq_chip wm8350_irq_chip = {
462 .name = "wm8350",
463 .bus_lock = wm8350_irq_lock,
464 .bus_sync_unlock = wm8350_irq_sync_unlock,
465 .disable = wm8350_irq_disable,
466 .enable = wm8350_irq_enable,
467};
483 468
484int wm8350_irq_init(struct wm8350 *wm8350, int irq, 469int wm8350_irq_init(struct wm8350 *wm8350, int irq,
485 struct wm8350_platform_data *pdata) 470 struct wm8350_platform_data *pdata)
486{ 471{
487 int ret; 472 int ret, cur_irq, i;
488 int flags = IRQF_ONESHOT; 473 int flags = IRQF_ONESHOT;
489 474
490 if (!irq) { 475 if (!irq) {
491 dev_err(wm8350->dev, "No IRQ configured\n"); 476 dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
492 return -EINVAL; 477 return 0;
478 }
479
480 if (!pdata || !pdata->irq_base) {
481 dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
482 return 0;
493 } 483 }
494 484
485 /* Mask top level interrupts */
495 wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF); 486 wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
496 wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
497 wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
498 wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
499 wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
500 wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
501 487
502 mutex_init(&wm8350->irq_mutex); 488 /* Mask all individual interrupts by default and cache the
489 * masks. We read the masks back since there are unwritable
490 * bits in the mask registers. */
491 for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
492 wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i,
493 0xFFFF);
494 wm8350->irq_masks[i] =
495 wm8350_reg_read(wm8350,
496 WM8350_INT_STATUS_1_MASK + i);
497 }
498
499 mutex_init(&wm8350->irq_lock);
503 wm8350->chip_irq = irq; 500 wm8350->chip_irq = irq;
501 wm8350->irq_base = pdata->irq_base;
504 502
505 if (pdata && pdata->irq_high) { 503 if (pdata->irq_high) {
506 flags |= IRQF_TRIGGER_HIGH; 504 flags |= IRQF_TRIGGER_HIGH;
507 505
508 wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, 506 wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
@@ -514,11 +512,32 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
514 WM8350_IRQ_POL); 512 WM8350_IRQ_POL);
515 } 513 }
516 514
515 /* Register with genirq */
516 for (cur_irq = wm8350->irq_base;
517 cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
518 cur_irq++) {
519 set_irq_chip_data(cur_irq, wm8350);
520 set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip,
521 handle_edge_irq);
522 set_irq_nested_thread(cur_irq, 1);
523
524 /* ARM needs us to explicitly flag the IRQ as valid
525 * and will set them noprobe when we do so. */
526#ifdef CONFIG_ARM
527 set_irq_flags(cur_irq, IRQF_VALID);
528#else
529 set_irq_noprobe(cur_irq);
530#endif
531 }
532
517 ret = request_threaded_irq(irq, NULL, wm8350_irq, flags, 533 ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
518 "wm8350", wm8350); 534 "wm8350", wm8350);
519 if (ret != 0) 535 if (ret != 0)
520 dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret); 536 dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
521 537
538 /* Allow interrupts to fire */
539 wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0);
540
522 return ret; 541 return ret;
523} 542}
524 543
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
new file mode 100644
index 000000000000..844e1c1b7d90
--- /dev/null
+++ b/drivers/mfd/wm8994-core.c
@@ -0,0 +1,537 @@
1/*
2 * wm8994-core.c -- Device access for Wolfson WM8994
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/i2c.h>
18#include <linux/delay.h>
19#include <linux/mfd/core.h>
20#include <linux/regulator/consumer.h>
21#include <linux/regulator/machine.h>
22
23#include <linux/mfd/wm8994/core.h>
24#include <linux/mfd/wm8994/pdata.h>
25#include <linux/mfd/wm8994/registers.h>
26
27static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
28 int bytes, void *dest)
29{
30 int ret, i;
31 u16 *buf = dest;
32
33 BUG_ON(bytes % 2);
34 BUG_ON(bytes <= 0);
35
36 ret = wm8994->read_dev(wm8994, reg, bytes, dest);
37 if (ret < 0)
38 return ret;
39
40 for (i = 0; i < bytes / 2; i++) {
41 buf[i] = be16_to_cpu(buf[i]);
42
43 dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
44 buf[i], reg + i, reg + i);
45 }
46
47 return 0;
48}
49
50/**
51 * wm8994_reg_read: Read a single WM8994 register.
52 *
53 * @wm8994: Device to read from.
54 * @reg: Register to read.
55 */
56int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
57{
58 unsigned short val;
59 int ret;
60
61 mutex_lock(&wm8994->io_lock);
62
63 ret = wm8994_read(wm8994, reg, 2, &val);
64
65 mutex_unlock(&wm8994->io_lock);
66
67 if (ret < 0)
68 return ret;
69 else
70 return val;
71}
72EXPORT_SYMBOL_GPL(wm8994_reg_read);
73
74/**
75 * wm8994_bulk_read: Read multiple WM8994 registers
76 *
77 * @wm8994: Device to read from
78 * @reg: First register
79 * @count: Number of registers
80 * @buf: Buffer to fill.
81 */
82int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
83 int count, u16 *buf)
84{
85 int ret;
86
87 mutex_lock(&wm8994->io_lock);
88
89 ret = wm8994_read(wm8994, reg, count * 2, buf);
90
91 mutex_unlock(&wm8994->io_lock);
92
93 return ret;
94}
95EXPORT_SYMBOL_GPL(wm8994_bulk_read);
96
97static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
98 int bytes, void *src)
99{
100 u16 *buf = src;
101 int i;
102
103 BUG_ON(bytes % 2);
104 BUG_ON(bytes <= 0);
105
106 for (i = 0; i < bytes / 2; i++) {
107 dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
108 buf[i], reg + i, reg + i);
109
110 buf[i] = cpu_to_be16(buf[i]);
111 }
112
113 return wm8994->write_dev(wm8994, reg, bytes, src);
114}
115
116/**
117 * wm8994_reg_write: Write a single WM8994 register.
118 *
119 * @wm8994: Device to write to.
120 * @reg: Register to write to.
121 * @val: Value to write.
122 */
123int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
124 unsigned short val)
125{
126 int ret;
127
128 mutex_lock(&wm8994->io_lock);
129
130 ret = wm8994_write(wm8994, reg, 2, &val);
131
132 mutex_unlock(&wm8994->io_lock);
133
134 return ret;
135}
136EXPORT_SYMBOL_GPL(wm8994_reg_write);
137
138/**
139 * wm8994_set_bits: Set the value of a bitfield in a WM8994 register
140 *
141 * @wm8994: Device to write to.
142 * @reg: Register to write to.
143 * @mask: Mask of bits to set.
144 * @val: Value to set (unshifted)
145 */
146int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
147 unsigned short mask, unsigned short val)
148{
149 int ret;
150 u16 r;
151
152 mutex_lock(&wm8994->io_lock);
153
154 ret = wm8994_read(wm8994, reg, 2, &r);
155 if (ret < 0)
156 goto out;
157
158 r &= ~mask;
159 r |= val;
160
161 ret = wm8994_write(wm8994, reg, 2, &r);
162
163out:
164 mutex_unlock(&wm8994->io_lock);
165
166 return ret;
167}
168EXPORT_SYMBOL_GPL(wm8994_set_bits);
169
170static struct mfd_cell wm8994_regulator_devs[] = {
171 { .name = "wm8994-ldo", .id = 1 },
172 { .name = "wm8994-ldo", .id = 2 },
173};
174
175static struct mfd_cell wm8994_devs[] = {
176 { .name = "wm8994-codec" },
177 { .name = "wm8994-gpio" },
178};
179
180/*
181 * Supplies for the main bulk of CODEC; the LDO supplies are ignored
182 * and should be handled via the standard regulator API supply
183 * management.
184 */
185static const char *wm8994_main_supplies[] = {
186 "DBVDD",
187 "DCVDD",
188 "AVDD1",
189 "AVDD2",
190 "CPVDD",
191 "SPKVDD1",
192 "SPKVDD2",
193};
194
195#ifdef CONFIG_PM
196static int wm8994_device_suspend(struct device *dev)
197{
198 struct wm8994 *wm8994 = dev_get_drvdata(dev);
199 int ret;
200
201 /* GPIO configuration state is saved here since we may be configuring
202 * the GPIO alternate functions even if we're not using the gpiolib
203 * driver for them.
204 */
205 ret = wm8994_read(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
206 &wm8994->gpio_regs);
207 if (ret < 0)
208 dev_err(dev, "Failed to save GPIO registers: %d\n", ret);
209
210 /* For similar reasons we also stash the regulator states */
211 ret = wm8994_read(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
212 &wm8994->ldo_regs);
213 if (ret < 0)
214 dev_err(dev, "Failed to save LDO registers: %d\n", ret);
215
216 ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
217 wm8994->supplies);
218 if (ret != 0) {
219 dev_err(dev, "Failed to disable supplies: %d\n", ret);
220 return ret;
221 }
222
223 return 0;
224}
225
226static int wm8994_device_resume(struct device *dev)
227{
228 struct wm8994 *wm8994 = dev_get_drvdata(dev);
229 int ret;
230
231 ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
232 wm8994->supplies);
233 if (ret != 0) {
234 dev_err(dev, "Failed to enable supplies: %d\n", ret);
235 return ret;
236 }
237
238 ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
239 &wm8994->ldo_regs);
240 if (ret < 0)
241 dev_err(dev, "Failed to restore LDO registers: %d\n", ret);
242
243 ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
244 &wm8994->gpio_regs);
245 if (ret < 0)
246 dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
247
248 return 0;
249}
250#endif
251
252#ifdef CONFIG_REGULATOR
253static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
254{
255 struct wm8994_ldo_pdata *ldo_pdata;
256
257 if (!pdata)
258 return 0;
259
260 ldo_pdata = &pdata->ldo[ldo];
261
262 if (!ldo_pdata->init_data)
263 return 0;
264
265 return ldo_pdata->init_data->num_consumer_supplies != 0;
266}
267#else
268static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
269{
270 return 0;
271}
272#endif
273
274/*
275 * Instantiate the generic non-control parts of the device.
276 */
277static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq)
278{
279 struct wm8994_pdata *pdata = wm8994->dev->platform_data;
280 int ret, i;
281
282 mutex_init(&wm8994->io_lock);
283 dev_set_drvdata(wm8994->dev, wm8994);
284
285 /* Add the on-chip regulators first for bootstrapping */
286 ret = mfd_add_devices(wm8994->dev, -1,
287 wm8994_regulator_devs,
288 ARRAY_SIZE(wm8994_regulator_devs),
289 NULL, 0);
290 if (ret != 0) {
291 dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
292 goto err;
293 }
294
295 wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
296 ARRAY_SIZE(wm8994_main_supplies),
297 GFP_KERNEL);
298 if (!wm8994->supplies)
299 goto err;
300
301 for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
302 wm8994->supplies[i].supply = wm8994_main_supplies[i];
303
304 ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies),
305 wm8994->supplies);
306 if (ret != 0) {
307 dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
308 goto err_supplies;
309 }
310
311 ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies),
312 wm8994->supplies);
313 if (ret != 0) {
314 dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
315 goto err_get;
316 }
317
318 ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET);
319 if (ret < 0) {
320 dev_err(wm8994->dev, "Failed to read ID register\n");
321 goto err_enable;
322 }
323 if (ret != 0x8994) {
324 dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
325 ret);
326 ret = -EINVAL;
327 goto err_enable;
328 }
329
330 ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION);
331 if (ret < 0) {
332 dev_err(wm8994->dev, "Failed to read revision register: %d\n",
333 ret);
334 goto err_enable;
335 }
336
337 switch (ret) {
338 case 0:
339 case 1:
340 dev_warn(wm8994->dev, "revision %c not fully supported\n",
341 'A' + ret);
342 break;
343 default:
344 dev_info(wm8994->dev, "revision %c\n", 'A' + ret);
345 break;
346 }
347
348
349 if (pdata) {
350 wm8994->gpio_base = pdata->gpio_base;
351
352 /* GPIO configuration is only applied if it's non-zero */
353 for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
354 if (pdata->gpio_defaults[i]) {
355 wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
356 0xffff,
357 pdata->gpio_defaults[i]);
358 }
359 }
360 }
361
362 /* In some system designs where the regulators are not in use,
363 * we can achieve a small reduction in leakage currents by
364 * floating LDO outputs. This bit makes no difference if the
365 * LDOs are enabled, it only affects cases where the LDOs were
366 * in operation and are then disabled.
367 */
368 for (i = 0; i < WM8994_NUM_LDO_REGS; i++) {
369 if (wm8994_ldo_in_use(pdata, i))
370 wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
371 WM8994_LDO1_DISCH, WM8994_LDO1_DISCH);
372 else
373 wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
374 WM8994_LDO1_DISCH, 0);
375 }
376
377 ret = mfd_add_devices(wm8994->dev, -1,
378 wm8994_devs, ARRAY_SIZE(wm8994_devs),
379 NULL, 0);
380 if (ret != 0) {
381 dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
382 goto err_enable;
383 }
384
385 return 0;
386
387err_enable:
388 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
389 wm8994->supplies);
390err_get:
391 regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
392err_supplies:
393 kfree(wm8994->supplies);
394err:
395 mfd_remove_devices(wm8994->dev);
396 kfree(wm8994);
397 return ret;
398}
399
400static void wm8994_device_exit(struct wm8994 *wm8994)
401{
402 mfd_remove_devices(wm8994->dev);
403 regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies),
404 wm8994->supplies);
405 regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies);
406 kfree(wm8994->supplies);
407 kfree(wm8994);
408}
409
410static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
411 int bytes, void *dest)
412{
413 struct i2c_client *i2c = wm8994->control_data;
414 int ret;
415 u16 r = cpu_to_be16(reg);
416
417 ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
418 if (ret < 0)
419 return ret;
420 if (ret != 2)
421 return -EIO;
422
423 ret = i2c_master_recv(i2c, dest, bytes);
424 if (ret < 0)
425 return ret;
426 if (ret != bytes)
427 return -EIO;
428 return 0;
429}
430
431/* Currently we allocate the write buffer on the stack; this is OK for
432 * small writes - if we need to do large writes this will need to be
433 * revised.
434 */
435static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
436 int bytes, void *src)
437{
438 struct i2c_client *i2c = wm8994->control_data;
439 unsigned char msg[bytes + 2];
440 int ret;
441
442 reg = cpu_to_be16(reg);
443 memcpy(&msg[0], &reg, 2);
444 memcpy(&msg[2], src, bytes);
445
446 ret = i2c_master_send(i2c, msg, bytes + 2);
447 if (ret < 0)
448 return ret;
449 if (ret < bytes + 2)
450 return -EIO;
451
452 return 0;
453}
454
455static int wm8994_i2c_probe(struct i2c_client *i2c,
456 const struct i2c_device_id *id)
457{
458 struct wm8994 *wm8994;
459
460 wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL);
461 if (wm8994 == NULL) {
462 kfree(i2c);
463 return -ENOMEM;
464 }
465
466 i2c_set_clientdata(i2c, wm8994);
467 wm8994->dev = &i2c->dev;
468 wm8994->control_data = i2c;
469 wm8994->read_dev = wm8994_i2c_read_device;
470 wm8994->write_dev = wm8994_i2c_write_device;
471
472 return wm8994_device_init(wm8994, id->driver_data, i2c->irq);
473}
474
475static int wm8994_i2c_remove(struct i2c_client *i2c)
476{
477 struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
478
479 wm8994_device_exit(wm8994);
480
481 return 0;
482}
483
484#ifdef CONFIG_PM
485static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state)
486{
487 return wm8994_device_suspend(&i2c->dev);
488}
489
490static int wm8994_i2c_resume(struct i2c_client *i2c)
491{
492 return wm8994_device_resume(&i2c->dev);
493}
494#else
495#define wm8994_i2c_suspend NULL
496#define wm8994_i2c_resume NULL
497#endif
498
499static const struct i2c_device_id wm8994_i2c_id[] = {
500 { "wm8994", 0 },
501 { }
502};
503MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
504
505static struct i2c_driver wm8994_i2c_driver = {
506 .driver = {
507 .name = "wm8994",
508 .owner = THIS_MODULE,
509 },
510 .probe = wm8994_i2c_probe,
511 .remove = wm8994_i2c_remove,
512 .suspend = wm8994_i2c_suspend,
513 .resume = wm8994_i2c_resume,
514 .id_table = wm8994_i2c_id,
515};
516
517static int __init wm8994_i2c_init(void)
518{
519 int ret;
520
521 ret = i2c_add_driver(&wm8994_i2c_driver);
522 if (ret != 0)
523 pr_err("Failed to register wm8994 I2C driver: %d\n", ret);
524
525 return ret;
526}
527module_init(wm8994_i2c_init);
528
529static void __exit wm8994_i2c_exit(void)
530{
531 i2c_del_driver(&wm8994_i2c_driver);
532}
533module_exit(wm8994_i2c_exit);
534
535MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC");
536MODULE_LICENSE("GPL");
537MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e3551d20464f..d16af6a423fb 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -212,6 +212,15 @@ config CS5535_MFGPT_DEFAULT_IRQ
212 want to use a different IRQ by default. This is here for 212 want to use a different IRQ by default. This is here for
213 architectures to set as necessary. 213 architectures to set as necessary.
214 214
215config CS5535_CLOCK_EVENT_SRC
216 tristate "CS5535/CS5536 high-res timer (MFGPT) events"
217 depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
218 help
219 This driver provides a clock event source based on the MFGPT
220 timer(s) in the CS5535 and CS5536 companion chips.
221 MFGPTs have a better resolution and max interval than the
222 generic PIT, and are suitable for use as high-res timers.
223
215config HP_ILO 224config HP_ILO
216 tristate "Channel interface driver for HP iLO/iLO2 processor" 225 tristate "Channel interface driver for HP iLO/iLO2 processor"
217 depends on PCI 226 depends on PCI
diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c
index dd0a3913bf6d..3b7292a5cea9 100644
--- a/drivers/misc/iwmc3200top/main.c
+++ b/drivers/misc/iwmc3200top/main.c
@@ -597,8 +597,6 @@ static void iwmct_remove(struct sdio_func *func)
597 struct iwmct_work_struct *read_req; 597 struct iwmct_work_struct *read_req;
598 struct iwmct_priv *priv = sdio_get_drvdata(func); 598 struct iwmct_priv *priv = sdio_get_drvdata(func);
599 599
600 priv = sdio_get_drvdata(func);
601
602 LOG_INFO(priv, INIT, "enter\n"); 600 LOG_INFO(priv, INIT, "enter\n");
603 601
604 sdio_claim_host(func); 602 sdio_claim_host(func);
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index 3648b23d5c92..4a0648301fdf 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -26,21 +26,9 @@
26 * It is adapted from the Linux Kernel Dump Test Tool by 26 * It is adapted from the Linux Kernel Dump Test Tool by
27 * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net> 27 * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
28 * 28 *
29 * Usage : insmod lkdtm.ko [recur_count={>0}] cpoint_name=<> cpoint_type=<> 29 * Debugfs support added by Simon Kagstrom <simon.kagstrom@netinsight.net>
30 * [cpoint_count={>0}]
31 * 30 *
32 * recur_count : Recursion level for the stack overflow test. Default is 10. 31 * See Documentation/fault-injection/provoke-crashes.txt for instructions
33 *
34 * cpoint_name : Crash point where the kernel is to be crashed. It can be
35 * one of INT_HARDWARE_ENTRY, INT_HW_IRQ_EN, INT_TASKLET_ENTRY,
36 * FS_DEVRW, MEM_SWAPOUT, TIMERADD, SCSI_DISPATCH_CMD,
37 * IDE_CORE_CP
38 *
39 * cpoint_type : Indicates the action to be taken on hitting the crash point.
40 * It can be one of PANIC, BUG, EXCEPTION, LOOP, OVERFLOW
41 *
42 * cpoint_count : Indicates the number of times the crash point is to be hit
43 * to trigger an action. The default is 10.
44 */ 32 */
45 33
46#include <linux/kernel.h> 34#include <linux/kernel.h>
@@ -53,13 +41,12 @@
53#include <linux/interrupt.h> 41#include <linux/interrupt.h>
54#include <linux/hrtimer.h> 42#include <linux/hrtimer.h>
55#include <scsi/scsi_cmnd.h> 43#include <scsi/scsi_cmnd.h>
44#include <linux/debugfs.h>
56 45
57#ifdef CONFIG_IDE 46#ifdef CONFIG_IDE
58#include <linux/ide.h> 47#include <linux/ide.h>
59#endif 48#endif
60 49
61#define NUM_CPOINTS 8
62#define NUM_CPOINT_TYPES 5
63#define DEFAULT_COUNT 10 50#define DEFAULT_COUNT 10
64#define REC_NUM_DEFAULT 10 51#define REC_NUM_DEFAULT 10
65 52
@@ -72,7 +59,8 @@ enum cname {
72 MEM_SWAPOUT, 59 MEM_SWAPOUT,
73 TIMERADD, 60 TIMERADD,
74 SCSI_DISPATCH_CMD, 61 SCSI_DISPATCH_CMD,
75 IDE_CORE_CP 62 IDE_CORE_CP,
63 DIRECT,
76}; 64};
77 65
78enum ctype { 66enum ctype {
@@ -81,7 +69,11 @@ enum ctype {
81 BUG, 69 BUG,
82 EXCEPTION, 70 EXCEPTION,
83 LOOP, 71 LOOP,
84 OVERFLOW 72 OVERFLOW,
73 CORRUPT_STACK,
74 UNALIGNED_LOAD_STORE_WRITE,
75 OVERWRITE_ALLOCATION,
76 WRITE_AFTER_FREE,
85}; 77};
86 78
87static char* cp_name[] = { 79static char* cp_name[] = {
@@ -92,7 +84,8 @@ static char* cp_name[] = {
92 "MEM_SWAPOUT", 84 "MEM_SWAPOUT",
93 "TIMERADD", 85 "TIMERADD",
94 "SCSI_DISPATCH_CMD", 86 "SCSI_DISPATCH_CMD",
95 "IDE_CORE_CP" 87 "IDE_CORE_CP",
88 "DIRECT",
96}; 89};
97 90
98static char* cp_type[] = { 91static char* cp_type[] = {
@@ -100,7 +93,11 @@ static char* cp_type[] = {
100 "BUG", 93 "BUG",
101 "EXCEPTION", 94 "EXCEPTION",
102 "LOOP", 95 "LOOP",
103 "OVERFLOW" 96 "OVERFLOW",
97 "CORRUPT_STACK",
98 "UNALIGNED_LOAD_STORE_WRITE",
99 "OVERWRITE_ALLOCATION",
100 "WRITE_AFTER_FREE",
104}; 101};
105 102
106static struct jprobe lkdtm; 103static struct jprobe lkdtm;
@@ -193,34 +190,66 @@ int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
193} 190}
194#endif 191#endif
195 192
193/* Return the crashpoint number or NONE if the name is invalid */
194static enum ctype parse_cp_type(const char *what, size_t count)
195{
196 int i;
197
198 for (i = 0; i < ARRAY_SIZE(cp_type); i++) {
199 if (!strcmp(what, cp_type[i]))
200 return i + 1;
201 }
202
203 return NONE;
204}
205
206static const char *cp_type_to_str(enum ctype type)
207{
208 if (type == NONE || type < 0 || type > ARRAY_SIZE(cp_type))
209 return "None";
210
211 return cp_type[type - 1];
212}
213
214static const char *cp_name_to_str(enum cname name)
215{
216 if (name == INVALID || name < 0 || name > ARRAY_SIZE(cp_name))
217 return "INVALID";
218
219 return cp_name[name - 1];
220}
221
222
196static int lkdtm_parse_commandline(void) 223static int lkdtm_parse_commandline(void)
197{ 224{
198 int i; 225 int i;
199 226
200 if (cpoint_name == NULL || cpoint_type == NULL || 227 if (cpoint_count < 1 || recur_count < 1)
201 cpoint_count < 1 || recur_count < 1)
202 return -EINVAL; 228 return -EINVAL;
203 229
204 for (i = 0; i < NUM_CPOINTS; ++i) { 230 count = cpoint_count;
231
232 /* No special parameters */
233 if (!cpoint_type && !cpoint_name)
234 return 0;
235
236 /* Neither or both of these need to be set */
237 if (!cpoint_type || !cpoint_name)
238 return -EINVAL;
239
240 cptype = parse_cp_type(cpoint_type, strlen(cpoint_type));
241 if (cptype == NONE)
242 return -EINVAL;
243
244 for (i = 0; i < ARRAY_SIZE(cp_name); i++) {
205 if (!strcmp(cpoint_name, cp_name[i])) { 245 if (!strcmp(cpoint_name, cp_name[i])) {
206 cpoint = i + 1; 246 cpoint = i + 1;
207 break; 247 return 0;
208 }
209 }
210
211 for (i = 0; i < NUM_CPOINT_TYPES; ++i) {
212 if (!strcmp(cpoint_type, cp_type[i])) {
213 cptype = i + 1;
214 break;
215 } 248 }
216 } 249 }
217 250
218 if (cpoint == INVALID || cptype == NONE) 251 /* Could not find a valid crash point */
219 return -EINVAL; 252 return -EINVAL;
220
221 count = cpoint_count;
222
223 return 0;
224} 253}
225 254
226static int recursive_loop(int a) 255static int recursive_loop(int a)
@@ -235,53 +264,92 @@ static int recursive_loop(int a)
235 return recursive_loop(a); 264 return recursive_loop(a);
236} 265}
237 266
238void lkdtm_handler(void) 267static void lkdtm_do_action(enum ctype which)
239{ 268{
240 printk(KERN_INFO "lkdtm : Crash point %s of type %s hit\n", 269 switch (which) {
241 cpoint_name, cpoint_type); 270 case PANIC:
242 --count; 271 panic("dumptest");
272 break;
273 case BUG:
274 BUG();
275 break;
276 case EXCEPTION:
277 *((int *) 0) = 0;
278 break;
279 case LOOP:
280 for (;;)
281 ;
282 break;
283 case OVERFLOW:
284 (void) recursive_loop(0);
285 break;
286 case CORRUPT_STACK: {
287 volatile u32 data[8];
288 volatile u32 *p = data;
289
290 p[12] = 0x12345678;
291 break;
292 }
293 case UNALIGNED_LOAD_STORE_WRITE: {
294 static u8 data[5] __attribute__((aligned(4))) = {1, 2,
295 3, 4, 5};
296 u32 *p;
297 u32 val = 0x12345678;
298
299 p = (u32 *)(data + 1);
300 if (*p == 0)
301 val = 0x87654321;
302 *p = val;
303 break;
304 }
305 case OVERWRITE_ALLOCATION: {
306 size_t len = 1020;
307 u32 *data = kmalloc(len, GFP_KERNEL);
308
309 data[1024 / sizeof(u32)] = 0x12345678;
310 kfree(data);
311 break;
312 }
313 case WRITE_AFTER_FREE: {
314 size_t len = 1024;
315 u32 *data = kmalloc(len, GFP_KERNEL);
316
317 kfree(data);
318 schedule();
319 memset(data, 0x78, len);
320 break;
321 }
322 case NONE:
323 default:
324 break;
325 }
326
327}
328
329static void lkdtm_handler(void)
330{
331 count--;
332 printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n",
333 cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
243 334
244 if (count == 0) { 335 if (count == 0) {
245 switch (cptype) { 336 lkdtm_do_action(cptype);
246 case NONE:
247 break;
248 case PANIC:
249 printk(KERN_INFO "lkdtm : PANIC\n");
250 panic("dumptest");
251 break;
252 case BUG:
253 printk(KERN_INFO "lkdtm : BUG\n");
254 BUG();
255 break;
256 case EXCEPTION:
257 printk(KERN_INFO "lkdtm : EXCEPTION\n");
258 *((int *) 0) = 0;
259 break;
260 case LOOP:
261 printk(KERN_INFO "lkdtm : LOOP\n");
262 for (;;);
263 break;
264 case OVERFLOW:
265 printk(KERN_INFO "lkdtm : OVERFLOW\n");
266 (void) recursive_loop(0);
267 break;
268 default:
269 break;
270 }
271 count = cpoint_count; 337 count = cpoint_count;
272 } 338 }
273} 339}
274 340
275static int __init lkdtm_module_init(void) 341static int lkdtm_register_cpoint(enum cname which)
276{ 342{
277 int ret; 343 int ret;
278 344
279 if (lkdtm_parse_commandline() == -EINVAL) { 345 cpoint = INVALID;
280 printk(KERN_INFO "lkdtm : Invalid command\n"); 346 if (lkdtm.entry != NULL)
281 return -EINVAL; 347 unregister_jprobe(&lkdtm);
282 }
283 348
284 switch (cpoint) { 349 switch (which) {
350 case DIRECT:
351 lkdtm_do_action(cptype);
352 return 0;
285 case INT_HARDWARE_ENTRY: 353 case INT_HARDWARE_ENTRY:
286 lkdtm.kp.symbol_name = "do_IRQ"; 354 lkdtm.kp.symbol_name = "do_IRQ";
287 lkdtm.entry = (kprobe_opcode_t*) jp_do_irq; 355 lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
@@ -315,28 +383,268 @@ static int __init lkdtm_module_init(void)
315 lkdtm.kp.symbol_name = "generic_ide_ioctl"; 383 lkdtm.kp.symbol_name = "generic_ide_ioctl";
316 lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl; 384 lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
317#else 385#else
318 printk(KERN_INFO "lkdtm : Crash point not available\n"); 386 printk(KERN_INFO "lkdtm: Crash point not available\n");
387 return -EINVAL;
319#endif 388#endif
320 break; 389 break;
321 default: 390 default:
322 printk(KERN_INFO "lkdtm : Invalid Crash Point\n"); 391 printk(KERN_INFO "lkdtm: Invalid Crash Point\n");
323 break; 392 return -EINVAL;
324 } 393 }
325 394
395 cpoint = which;
326 if ((ret = register_jprobe(&lkdtm)) < 0) { 396 if ((ret = register_jprobe(&lkdtm)) < 0) {
327 printk(KERN_INFO "lkdtm : Couldn't register jprobe\n"); 397 printk(KERN_INFO "lkdtm: Couldn't register jprobe\n");
328 return ret; 398 cpoint = INVALID;
399 }
400
401 return ret;
402}
403
404static ssize_t do_register_entry(enum cname which, struct file *f,
405 const char __user *user_buf, size_t count, loff_t *off)
406{
407 char *buf;
408 int err;
409
410 if (count >= PAGE_SIZE)
411 return -EINVAL;
412
413 buf = (char *)__get_free_page(GFP_KERNEL);
414 if (!buf)
415 return -ENOMEM;
416 if (copy_from_user(buf, user_buf, count)) {
417 free_page((unsigned long) buf);
418 return -EFAULT;
419 }
420 /* NULL-terminate and remove enter */
421 buf[count] = '\0';
422 strim(buf);
423
424 cptype = parse_cp_type(buf, count);
425 free_page((unsigned long) buf);
426
427 if (cptype == NONE)
428 return -EINVAL;
429
430 err = lkdtm_register_cpoint(which);
431 if (err < 0)
432 return err;
433
434 *off += count;
435
436 return count;
437}
438
439/* Generic read callback that just prints out the available crash types */
440static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
441 size_t count, loff_t *off)
442{
443 char *buf;
444 int i, n, out;
445
446 buf = (char *)__get_free_page(GFP_KERNEL);
447
448 n = snprintf(buf, PAGE_SIZE, "Available crash types:\n");
449 for (i = 0; i < ARRAY_SIZE(cp_type); i++)
450 n += snprintf(buf + n, PAGE_SIZE - n, "%s\n", cp_type[i]);
451 buf[n] = '\0';
452
453 out = simple_read_from_buffer(user_buf, count, off,
454 buf, n);
455 free_page((unsigned long) buf);
456
457 return out;
458}
459
460static int lkdtm_debugfs_open(struct inode *inode, struct file *file)
461{
462 return 0;
463}
464
465
466static ssize_t int_hardware_entry(struct file *f, const char __user *buf,
467 size_t count, loff_t *off)
468{
469 return do_register_entry(INT_HARDWARE_ENTRY, f, buf, count, off);
470}
471
472static ssize_t int_hw_irq_en(struct file *f, const char __user *buf,
473 size_t count, loff_t *off)
474{
475 return do_register_entry(INT_HW_IRQ_EN, f, buf, count, off);
476}
477
478static ssize_t int_tasklet_entry(struct file *f, const char __user *buf,
479 size_t count, loff_t *off)
480{
481 return do_register_entry(INT_TASKLET_ENTRY, f, buf, count, off);
482}
483
484static ssize_t fs_devrw_entry(struct file *f, const char __user *buf,
485 size_t count, loff_t *off)
486{
487 return do_register_entry(FS_DEVRW, f, buf, count, off);
488}
489
490static ssize_t mem_swapout_entry(struct file *f, const char __user *buf,
491 size_t count, loff_t *off)
492{
493 return do_register_entry(MEM_SWAPOUT, f, buf, count, off);
494}
495
496static ssize_t timeradd_entry(struct file *f, const char __user *buf,
497 size_t count, loff_t *off)
498{
499 return do_register_entry(TIMERADD, f, buf, count, off);
500}
501
502static ssize_t scsi_dispatch_cmd_entry(struct file *f,
503 const char __user *buf, size_t count, loff_t *off)
504{
505 return do_register_entry(SCSI_DISPATCH_CMD, f, buf, count, off);
506}
507
508static ssize_t ide_core_cp_entry(struct file *f, const char __user *buf,
509 size_t count, loff_t *off)
510{
511 return do_register_entry(IDE_CORE_CP, f, buf, count, off);
512}
513
514/* Special entry to just crash directly. Available without KPROBEs */
515static ssize_t direct_entry(struct file *f, const char __user *user_buf,
516 size_t count, loff_t *off)
517{
518 enum ctype type;
519 char *buf;
520
521 if (count >= PAGE_SIZE)
522 return -EINVAL;
523 if (count < 1)
524 return -EINVAL;
525
526 buf = (char *)__get_free_page(GFP_KERNEL);
527 if (!buf)
528 return -ENOMEM;
529 if (copy_from_user(buf, user_buf, count)) {
530 free_page((unsigned long) buf);
531 return -EFAULT;
532 }
533 /* NULL-terminate and remove enter */
534 buf[count] = '\0';
535 strim(buf);
536
537 type = parse_cp_type(buf, count);
538 free_page((unsigned long) buf);
539 if (type == NONE)
540 return -EINVAL;
541
542 printk(KERN_INFO "lkdtm: Performing direct entry %s\n",
543 cp_type_to_str(type));
544 lkdtm_do_action(type);
545 *off += count;
546
547 return count;
548}
549
550struct crash_entry {
551 const char *name;
552 const struct file_operations fops;
553};
554
555static const struct crash_entry crash_entries[] = {
556 {"DIRECT", {.read = lkdtm_debugfs_read,
557 .open = lkdtm_debugfs_open,
558 .write = direct_entry} },
559 {"INT_HARDWARE_ENTRY", {.read = lkdtm_debugfs_read,
560 .open = lkdtm_debugfs_open,
561 .write = int_hardware_entry} },
562 {"INT_HW_IRQ_EN", {.read = lkdtm_debugfs_read,
563 .open = lkdtm_debugfs_open,
564 .write = int_hw_irq_en} },
565 {"INT_TASKLET_ENTRY", {.read = lkdtm_debugfs_read,
566 .open = lkdtm_debugfs_open,
567 .write = int_tasklet_entry} },
568 {"FS_DEVRW", {.read = lkdtm_debugfs_read,
569 .open = lkdtm_debugfs_open,
570 .write = fs_devrw_entry} },
571 {"MEM_SWAPOUT", {.read = lkdtm_debugfs_read,
572 .open = lkdtm_debugfs_open,
573 .write = mem_swapout_entry} },
574 {"TIMERADD", {.read = lkdtm_debugfs_read,
575 .open = lkdtm_debugfs_open,
576 .write = timeradd_entry} },
577 {"SCSI_DISPATCH_CMD", {.read = lkdtm_debugfs_read,
578 .open = lkdtm_debugfs_open,
579 .write = scsi_dispatch_cmd_entry} },
580 {"IDE_CORE_CP", {.read = lkdtm_debugfs_read,
581 .open = lkdtm_debugfs_open,
582 .write = ide_core_cp_entry} },
583};
584
585static struct dentry *lkdtm_debugfs_root;
586
587static int __init lkdtm_module_init(void)
588{
589 int ret = -EINVAL;
590 int n_debugfs_entries = 1; /* Assume only the direct entry */
591 int i;
592
593 /* Register debugfs interface */
594 lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
595 if (!lkdtm_debugfs_root) {
596 printk(KERN_ERR "lkdtm: creating root dir failed\n");
597 return -ENODEV;
598 }
599
600#ifdef CONFIG_KPROBES
601 n_debugfs_entries = ARRAY_SIZE(crash_entries);
602#endif
603
604 for (i = 0; i < n_debugfs_entries; i++) {
605 const struct crash_entry *cur = &crash_entries[i];
606 struct dentry *de;
607
608 de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root,
609 NULL, &cur->fops);
610 if (de == NULL) {
611 printk(KERN_ERR "lkdtm: could not create %s\n",
612 cur->name);
613 goto out_err;
614 }
615 }
616
617 if (lkdtm_parse_commandline() == -EINVAL) {
618 printk(KERN_INFO "lkdtm: Invalid command\n");
619 goto out_err;
620 }
621
622 if (cpoint != INVALID && cptype != NONE) {
623 ret = lkdtm_register_cpoint(cpoint);
624 if (ret < 0) {
625 printk(KERN_INFO "lkdtm: Invalid crash point %d\n",
626 cpoint);
627 goto out_err;
628 }
629 printk(KERN_INFO "lkdtm: Crash point %s of type %s registered\n",
630 cpoint_name, cpoint_type);
631 } else {
632 printk(KERN_INFO "lkdtm: No crash points registered, enable through debugfs\n");
329 } 633 }
330 634
331 printk(KERN_INFO "lkdtm : Crash point %s of type %s registered\n",
332 cpoint_name, cpoint_type);
333 return 0; 635 return 0;
636
637out_err:
638 debugfs_remove_recursive(lkdtm_debugfs_root);
639 return ret;
334} 640}
335 641
336static void __exit lkdtm_module_exit(void) 642static void __exit lkdtm_module_exit(void)
337{ 643{
338 unregister_jprobe(&lkdtm); 644 debugfs_remove_recursive(lkdtm_debugfs_root);
339 printk(KERN_INFO "lkdtm : Crash point unregistered\n"); 645
646 unregister_jprobe(&lkdtm);
647 printk(KERN_INFO "lkdtm: Crash point unregistered\n");
340} 648}
341 649
342module_init(lkdtm_module_init); 650module_init(lkdtm_module_init);
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 16f0abda1423..57b152f8d1b9 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -475,7 +475,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
475 475
476 if (skb->data[0] == 0xff) { 476 if (skb->data[0] == 0xff) {
477 /* we are being asked to broadcast to all partitions */ 477 /* we are being asked to broadcast to all partitions */
478 for_each_bit(dest_partid, xpnet_broadcast_partitions, 478 for_each_set_bit(dest_partid, xpnet_broadcast_partitions,
479 xp_max_npartitions) { 479 xp_max_npartitions) {
480 480
481 xpnet_send(skb, queued_msg, start_addr, end_addr, 481 xpnet_send(skb, queued_msg, start_addr, end_addr,
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 30acd5265821..f4b97d3c3d0f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1151,6 +1151,9 @@ void mmc_stop_host(struct mmc_host *host)
1151 cancel_delayed_work(&host->detect); 1151 cancel_delayed_work(&host->detect);
1152 mmc_flush_scheduled_work(); 1152 mmc_flush_scheduled_work();
1153 1153
1154 /* clear pm flags now and let card drivers set them as needed */
1155 host->pm_flags = 0;
1156
1154 mmc_bus_get(host); 1157 mmc_bus_get(host);
1155 if (host->bus_ops && !host->bus_dead) { 1158 if (host->bus_ops && !host->bus_dead) {
1156 if (host->bus_ops->remove) 1159 if (host->bus_ops->remove)
@@ -1273,12 +1276,13 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
1273 mmc_claim_host(host); 1276 mmc_claim_host(host);
1274 mmc_detach_bus(host); 1277 mmc_detach_bus(host);
1275 mmc_release_host(host); 1278 mmc_release_host(host);
1279 host->pm_flags = 0;
1276 err = 0; 1280 err = 0;
1277 } 1281 }
1278 } 1282 }
1279 mmc_bus_put(host); 1283 mmc_bus_put(host);
1280 1284
1281 if (!err) 1285 if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
1282 mmc_power_off(host); 1286 mmc_power_off(host);
1283 1287
1284 return err; 1288 return err;
@@ -1296,8 +1300,10 @@ int mmc_resume_host(struct mmc_host *host)
1296 1300
1297 mmc_bus_get(host); 1301 mmc_bus_get(host);
1298 if (host->bus_ops && !host->bus_dead) { 1302 if (host->bus_ops && !host->bus_dead) {
1299 mmc_power_up(host); 1303 if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
1300 mmc_select_voltage(host, host->ocr); 1304 mmc_power_up(host);
1305 mmc_select_voltage(host, host->ocr);
1306 }
1301 BUG_ON(!host->bus_ops->resume); 1307 BUG_ON(!host->bus_ops->resume);
1302 err = host->bus_ops->resume(host); 1308 err = host->bus_ops->resume(host);
1303 if (err) { 1309 if (err) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 06b64085a355..2dd4cfe7ca17 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -188,6 +188,40 @@ static int sdio_disable_cd(struct mmc_card *card)
188} 188}
189 189
190/* 190/*
191 * Devices that remain active during a system suspend are
192 * put back into 1-bit mode.
193 */
194static int sdio_disable_wide(struct mmc_card *card)
195{
196 int ret;
197 u8 ctrl;
198
199 if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
200 return 0;
201
202 if (card->cccr.low_speed && !card->cccr.wide_bus)
203 return 0;
204
205 ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
206 if (ret)
207 return ret;
208
209 if (!(ctrl & SDIO_BUS_WIDTH_4BIT))
210 return 0;
211
212 ctrl &= ~SDIO_BUS_WIDTH_4BIT;
213 ctrl |= SDIO_BUS_ASYNC_INT;
214
215 ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
216 if (ret)
217 return ret;
218
219 mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1);
220
221 return 0;
222}
223
224/*
191 * Test if the card supports high-speed mode and, if so, switch to it. 225 * Test if the card supports high-speed mode and, if so, switch to it.
192 */ 226 */
193static int sdio_enable_hs(struct mmc_card *card) 227static int sdio_enable_hs(struct mmc_card *card)
@@ -224,7 +258,7 @@ static int sdio_enable_hs(struct mmc_card *card)
224 * we're trying to reinitialise. 258 * we're trying to reinitialise.
225 */ 259 */
226static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, 260static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
227 struct mmc_card *oldcard) 261 struct mmc_card *oldcard, int powered_resume)
228{ 262{
229 struct mmc_card *card; 263 struct mmc_card *card;
230 int err; 264 int err;
@@ -235,9 +269,11 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
235 /* 269 /*
236 * Inform the card of the voltage 270 * Inform the card of the voltage
237 */ 271 */
238 err = mmc_send_io_op_cond(host, host->ocr, &ocr); 272 if (!powered_resume) {
239 if (err) 273 err = mmc_send_io_op_cond(host, host->ocr, &ocr);
240 goto err; 274 if (err)
275 goto err;
276 }
241 277
242 /* 278 /*
243 * For SPI, enable CRC as appropriate. 279 * For SPI, enable CRC as appropriate.
@@ -262,7 +298,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
262 /* 298 /*
263 * For native busses: set card RCA and quit open drain mode. 299 * For native busses: set card RCA and quit open drain mode.
264 */ 300 */
265 if (!mmc_host_is_spi(host)) { 301 if (!powered_resume && !mmc_host_is_spi(host)) {
266 err = mmc_send_relative_addr(host, &card->rca); 302 err = mmc_send_relative_addr(host, &card->rca);
267 if (err) 303 if (err)
268 goto remove; 304 goto remove;
@@ -273,7 +309,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
273 /* 309 /*
274 * Select card, as all following commands rely on that. 310 * Select card, as all following commands rely on that.
275 */ 311 */
276 if (!mmc_host_is_spi(host)) { 312 if (!powered_resume && !mmc_host_is_spi(host)) {
277 err = mmc_select_card(card); 313 err = mmc_select_card(card);
278 if (err) 314 if (err)
279 goto remove; 315 goto remove;
@@ -425,6 +461,12 @@ static int mmc_sdio_suspend(struct mmc_host *host)
425 } 461 }
426 } 462 }
427 463
464 if (!err && host->pm_flags & MMC_PM_KEEP_POWER) {
465 mmc_claim_host(host);
466 sdio_disable_wide(host->card);
467 mmc_release_host(host);
468 }
469
428 return err; 470 return err;
429} 471}
430 472
@@ -437,7 +479,13 @@ static int mmc_sdio_resume(struct mmc_host *host)
437 479
438 /* Basic card reinitialization. */ 480 /* Basic card reinitialization. */
439 mmc_claim_host(host); 481 mmc_claim_host(host);
440 err = mmc_sdio_init_card(host, host->ocr, host->card); 482 err = mmc_sdio_init_card(host, host->ocr, host->card,
483 (host->pm_flags & MMC_PM_KEEP_POWER));
484 if (!err)
485 /* We may have switched to 1-bit mode during suspend. */
486 err = sdio_enable_wide(host->card);
487 if (!err && host->sdio_irqs)
488 mmc_signal_sdio_irq(host);
441 mmc_release_host(host); 489 mmc_release_host(host);
442 490
443 /* 491 /*
@@ -507,7 +555,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
507 /* 555 /*
508 * Detect and init the card. 556 * Detect and init the card.
509 */ 557 */
510 err = mmc_sdio_init_card(host, host->ocr, NULL); 558 err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
511 if (err) 559 if (err)
512 goto err; 560 goto err;
513 card = host->card; 561 card = host->card;
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index f9aa8a7deffa..ff27c8c71355 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
189{ 189{
190 unsigned mval = min(func->card->host->max_seg_size, 190 unsigned mval = min(func->card->host->max_seg_size,
191 func->card->host->max_blk_size); 191 func->card->host->max_blk_size);
192 mval = min(mval, func->max_blksize); 192
193 if (mmc_blksz_for_byte_mode(func->card))
194 mval = min(mval, func->cur_blksize);
195 else
196 mval = min(mval, func->max_blksize);
197
193 return min(mval, 512u); /* maximum size for byte mode */ 198 return min(mval, 512u); /* maximum size for byte mode */
194} 199}
195 200
@@ -635,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
635 *err_ret = ret; 640 *err_ret = ret;
636} 641}
637EXPORT_SYMBOL_GPL(sdio_f0_writeb); 642EXPORT_SYMBOL_GPL(sdio_f0_writeb);
643
644/**
645 * sdio_get_host_pm_caps - get host power management capabilities
646 * @func: SDIO function attached to host
647 *
648 * Returns a capability bitmask corresponding to power management
649 * features supported by the host controller that the card function
650 * might rely upon during a system suspend. The host doesn't need
651 * to be claimed, nor the function active, for this information to be
652 * obtained.
653 */
654mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func)
655{
656 BUG_ON(!func);
657 BUG_ON(!func->card);
658
659 return func->card->host->pm_caps;
660}
661EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps);
662
663/**
664 * sdio_set_host_pm_flags - set wanted host power management capabilities
665 * @func: SDIO function attached to host
666 *
667 * Set a capability bitmask corresponding to wanted host controller
668 * power management features for the upcoming suspend state.
669 * This must be called, if needed, each time the suspend method of
670 * the function driver is called, and must contain only bits that
671 * were returned by sdio_get_host_pm_caps().
672 * The host doesn't need to be claimed, nor the function active,
673 * for this information to be set.
674 */
675int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
676{
677 struct mmc_host *host;
678
679 BUG_ON(!func);
680 BUG_ON(!func->card);
681
682 host = func->card->host;
683
684 if (flags & ~host->pm_caps)
685 return -EINVAL;
686
687 /* function suspend methods are serialized, hence no lock needed */
688 host->pm_flags |= flags;
689 return 0;
690}
691EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index ce1d28884e29..2e13b94769fd 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -69,20 +69,16 @@ config MMC_SDHCI_PCI
69 If unsure, say N. 69 If unsure, say N.
70 70
71config MMC_RICOH_MMC 71config MMC_RICOH_MMC
72 tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" 72 bool "Ricoh MMC Controller Disabler (EXPERIMENTAL)"
73 depends on MMC_SDHCI_PCI 73 depends on MMC_SDHCI_PCI
74 help 74 help
75 This selects the disabler for the Ricoh MMC Controller. This 75 This adds a pci quirk to disable Ricoh MMC Controller. This
76 proprietary controller is unnecessary because the SDHCI driver 76 proprietary controller is unnecessary because the SDHCI driver
77 supports MMC cards on the SD controller, but if it is not 77 supports MMC cards on the SD controller, but if it is not
78 disabled, it will steal the MMC cards away - rendering them 78 disabled, it will steal the MMC cards away - rendering them
79 useless. It is safe to select this driver even if you don't 79 useless. It is safe to select this even if you don't
80 have a Ricoh based card reader. 80 have a Ricoh based card reader.
81 81
82
83 To compile this driver as a module, choose M here:
84 the module will be called ricoh_mmc.
85
86 If unsure, say Y. 82 If unsure, say Y.
87 83
88config MMC_SDHCI_OF 84config MMC_SDHCI_OF
@@ -193,6 +189,7 @@ config MMC_AU1X
193 189
194choice 190choice
195 prompt "Atmel SD/MMC Driver" 191 prompt "Atmel SD/MMC Driver"
192 depends on AVR32 || ARCH_AT91
196 default MMC_ATMELMCI if AVR32 193 default MMC_ATMELMCI if AVR32
197 help 194 help
198 Choose which driver to use for the Atmel MCI Silicon 195 Choose which driver to use for the Atmel MCI Silicon
@@ -368,7 +365,7 @@ config MMC_SDRICOH_CS
368 365
369config MMC_TMIO 366config MMC_TMIO
370 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" 367 tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
371 depends on MFD_TMIO || MFD_ASIC3 || SUPERH 368 depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI
372 help 369 help
373 This provides support for the SD/MMC cell found in TC6393XB, 370 This provides support for the SD/MMC cell found in TC6393XB,
374 T7L66XB and also HTC ASIC3 371 T7L66XB and also HTC ASIC3
@@ -399,7 +396,7 @@ config MMC_VIA_SDMMC
399 396
400config SDH_BFIN 397config SDH_BFIN
401 tristate "Blackfin Secure Digital Host support" 398 tristate "Blackfin Secure Digital Host support"
402 depends on MMC && ((BF54x && !BF544) || (BF51x && !BF512)) 399 depends on (BF54x && !BF544) || (BF51x && !BF512)
403 help 400 help
404 If you say yes here you will get support for the Blackfin on-chip 401 If you say yes here you will get support for the Blackfin on-chip
405 Secure Digital Host interface. This includes support for MMC and 402 Secure Digital Host interface. This includes support for MMC and
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 3d253dd4240f..f4803977dfce 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_MMC_IMX) += imxmmc.o
12obj-$(CONFIG_MMC_MXC) += mxcmmc.o 12obj-$(CONFIG_MMC_MXC) += mxcmmc.o
13obj-$(CONFIG_MMC_SDHCI) += sdhci.o 13obj-$(CONFIG_MMC_SDHCI) += sdhci.o
14obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o 14obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
15obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
16obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o 15obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
17obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o 16obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
18obj-$(CONFIG_MMC_WBSD) += wbsd.o 17obj-$(CONFIG_MMC_WBSD) += wbsd.o
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 63924e0c7ea9..91dc60cd032b 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -78,6 +78,17 @@
78 78
79#define DRIVER_NAME "at91_mci" 79#define DRIVER_NAME "at91_mci"
80 80
81static inline int at91mci_is_mci1rev2xx(void)
82{
83 return ( cpu_is_at91sam9260()
84 || cpu_is_at91sam9263()
85 || cpu_is_at91cap9()
86 || cpu_is_at91sam9rl()
87 || cpu_is_at91sam9g10()
88 || cpu_is_at91sam9g20()
89 );
90}
91
81#define FL_SENT_COMMAND (1 << 0) 92#define FL_SENT_COMMAND (1 << 0)
82#define FL_SENT_STOP (1 << 1) 93#define FL_SENT_STOP (1 << 1)
83 94
@@ -88,6 +99,10 @@
88#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) 99#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg))
89#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) 100#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg))
90 101
102#define MCI_BLKSIZE 512
103#define MCI_MAXBLKSIZE 4095
104#define MCI_BLKATONCE 256
105#define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE)
91 106
92/* 107/*
93 * Low level type for this driver 108 * Low level type for this driver
@@ -200,8 +215,8 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
200 size = data->blksz * data->blocks; 215 size = data->blksz * data->blocks;
201 len = data->sg_len; 216 len = data->sg_len;
202 217
203 /* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */ 218 /* MCI1 rev2xx Data Write Operation and number of bytes erratum */
204 if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) 219 if (at91mci_is_mci1rev2xx())
205 if (host->total_length == 12) 220 if (host->total_length == 12)
206 memset(dmabuf, 0, 12); 221 memset(dmabuf, 0, 12);
207 222
@@ -227,8 +242,10 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
227 for (index = 0; index < (amount / 4); index++) 242 for (index = 0; index < (amount / 4); index++)
228 *dmabuf++ = swab32(sgbuffer[index]); 243 *dmabuf++ = swab32(sgbuffer[index]);
229 } else { 244 } else {
230 memcpy(dmabuf, sgbuffer, amount); 245 char *tmpv = (char *)dmabuf;
231 dmabuf += amount; 246 memcpy(tmpv, sgbuffer, amount);
247 tmpv += amount;
248 dmabuf = (unsigned *)tmpv;
232 } 249 }
233 250
234 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); 251 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
@@ -245,80 +262,14 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
245} 262}
246 263
247/* 264/*
248 * Prepare a dma read
249 */
250static void at91_mci_pre_dma_read(struct at91mci_host *host)
251{
252 int i;
253 struct scatterlist *sg;
254 struct mmc_command *cmd;
255 struct mmc_data *data;
256
257 pr_debug("pre dma read\n");
258
259 cmd = host->cmd;
260 if (!cmd) {
261 pr_debug("no command\n");
262 return;
263 }
264
265 data = cmd->data;
266 if (!data) {
267 pr_debug("no data\n");
268 return;
269 }
270
271 for (i = 0; i < 2; i++) {
272 /* nothing left to transfer */
273 if (host->transfer_index >= data->sg_len) {
274 pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index);
275 break;
276 }
277
278 /* Check to see if this needs filling */
279 if (i == 0) {
280 if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) {
281 pr_debug("Transfer active in current\n");
282 continue;
283 }
284 }
285 else {
286 if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) {
287 pr_debug("Transfer active in next\n");
288 continue;
289 }
290 }
291
292 /* Setup the next transfer */
293 pr_debug("Using transfer index %d\n", host->transfer_index);
294
295 sg = &data->sg[host->transfer_index++];
296 pr_debug("sg = %p\n", sg);
297
298 sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
299
300 pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
301
302 if (i == 0) {
303 at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
304 at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
305 }
306 else {
307 at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
308 at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4);
309 }
310 }
311
312 pr_debug("pre dma read done\n");
313}
314
315/*
316 * Handle after a dma read 265 * Handle after a dma read
317 */ 266 */
318static void at91_mci_post_dma_read(struct at91mci_host *host) 267static void at91_mci_post_dma_read(struct at91mci_host *host)
319{ 268{
320 struct mmc_command *cmd; 269 struct mmc_command *cmd;
321 struct mmc_data *data; 270 struct mmc_data *data;
271 unsigned int len, i, size;
272 unsigned *dmabuf = host->buffer;
322 273
323 pr_debug("post dma read\n"); 274 pr_debug("post dma read\n");
324 275
@@ -334,42 +285,39 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
334 return; 285 return;
335 } 286 }
336 287
337 while (host->in_use_index < host->transfer_index) { 288 size = data->blksz * data->blocks;
338 struct scatterlist *sg; 289 len = data->sg_len;
339 290
340 pr_debug("finishing index %d\n", host->in_use_index); 291 at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
292 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
341 293
342 sg = &data->sg[host->in_use_index++]; 294 for (i = 0; i < len; i++) {
295 struct scatterlist *sg;
296 int amount;
297 unsigned int *sgbuffer;
343 298
344 pr_debug("Unmapping page %08X\n", sg->dma_address); 299 sg = &data->sg[i];
345 300
346 dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); 301 sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
302 amount = min(size, sg->length);
303 size -= amount;
347 304
348 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ 305 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
349 unsigned int *buffer;
350 int index; 306 int index;
351 307 for (index = 0; index < (amount / 4); index++)
352 /* Swap the contents of the buffer */ 308 sgbuffer[index] = swab32(*dmabuf++);
353 buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; 309 } else {
354 pr_debug("buffer = %p, length = %d\n", buffer, sg->length); 310 char *tmpv = (char *)dmabuf;
355 311 memcpy(sgbuffer, tmpv, amount);
356 for (index = 0; index < (sg->length / 4); index++) 312 tmpv += amount;
357 buffer[index] = swab32(buffer[index]); 313 dmabuf = (unsigned *)tmpv;
358
359 kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
360 } 314 }
361 315
362 flush_dcache_page(sg_page(sg)); 316 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
363 317 dmac_flush_range((void *)sgbuffer, ((void *)sgbuffer) + amount);
364 data->bytes_xfered += sg->length; 318 data->bytes_xfered += amount;
365 } 319 if (size == 0)
366 320 break;
367 /* Is there another transfer to trigger? */
368 if (host->transfer_index < data->sg_len)
369 at91_mci_pre_dma_read(host);
370 else {
371 at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
372 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
373 } 321 }
374 322
375 pr_debug("post dma read done\n"); 323 pr_debug("post dma read done\n");
@@ -461,7 +409,7 @@ static void at91_mci_enable(struct at91mci_host *host)
461 at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); 409 at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
462 mr = AT91_MCI_PDCMODE | 0x34a; 410 mr = AT91_MCI_PDCMODE | 0x34a;
463 411
464 if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) 412 if (at91mci_is_mci1rev2xx())
465 mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; 413 mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
466 414
467 at91_mci_write(host, AT91_MCI_MR, mr); 415 at91_mci_write(host, AT91_MCI_MR, mr);
@@ -602,10 +550,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
602 /* 550 /*
603 * Handle a read 551 * Handle a read
604 */ 552 */
605 host->buffer = NULL;
606 host->total_length = 0; 553 host->total_length = 0;
607 554
608 at91_mci_pre_dma_read(host); 555 at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address);
556 at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ?
557 (blocks * block_length) : (blocks * block_length) / 4);
558 at91_mci_write(host, ATMEL_PDC_RNPR, 0);
559 at91_mci_write(host, ATMEL_PDC_RNCR, 0);
560
609 ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; 561 ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
610 } 562 }
611 else { 563 else {
@@ -614,27 +566,15 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
614 */ 566 */
615 host->total_length = block_length * blocks; 567 host->total_length = block_length * blocks;
616 /* 568 /*
617 * AT91SAM926[0/3] Data Write Operation and 569 * MCI1 rev2xx Data Write Operation and
618 * number of bytes erratum 570 * number of bytes erratum
619 */ 571 */
620 if (cpu_is_at91sam9260 () || cpu_is_at91sam9263()) 572 if (at91mci_is_mci1rev2xx())
621 if (host->total_length < 12) 573 if (host->total_length < 12)
622 host->total_length = 12; 574 host->total_length = 12;
623 575
624 host->buffer = kmalloc(host->total_length, GFP_KERNEL);
625 if (!host->buffer) {
626 pr_debug("Can't alloc tx buffer\n");
627 cmd->error = -ENOMEM;
628 mmc_request_done(host->mmc, host->request);
629 return;
630 }
631
632 at91_mci_sg_to_dma(host, data); 576 at91_mci_sg_to_dma(host, data);
633 577
634 host->physical_address = dma_map_single(NULL,
635 host->buffer, host->total_length,
636 DMA_TO_DEVICE);
637
638 pr_debug("Transmitting %d bytes\n", host->total_length); 578 pr_debug("Transmitting %d bytes\n", host->total_length);
639 579
640 at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); 580 at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
@@ -701,14 +641,6 @@ static void at91_mci_completed_command(struct at91mci_host *host, unsigned int s
701 cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); 641 cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
702 cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); 642 cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));
703 643
704 if (host->buffer) {
705 dma_unmap_single(NULL,
706 host->physical_address, host->total_length,
707 DMA_TO_DEVICE);
708 kfree(host->buffer);
709 host->buffer = NULL;
710 }
711
712 pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", 644 pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
713 status, at91_mci_read(host, AT91_MCI_SR), 645 status, at91_mci_read(host, AT91_MCI_SR),
714 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); 646 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
@@ -754,7 +686,8 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
754 host->request = mrq; 686 host->request = mrq;
755 host->flags = 0; 687 host->flags = 0;
756 688
757 mod_timer(&host->timer, jiffies + HZ); 689 /* more than 1s timeout needed with slow SD cards */
690 mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000));
758 691
759 at91_mci_process_next(host); 692 at91_mci_process_next(host);
760} 693}
@@ -942,7 +875,8 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
942 pr_debug("****** Resetting SD-card bus width ******\n"); 875 pr_debug("****** Resetting SD-card bus width ******\n");
943 at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); 876 at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
944 } 877 }
945 mmc_detect_change(host->mmc, msecs_to_jiffies(100)); 878 /* 0.5s needed because of early card detect switch firing */
879 mmc_detect_change(host->mmc, msecs_to_jiffies(500));
946 } 880 }
947 return IRQ_HANDLED; 881 return IRQ_HANDLED;
948} 882}
@@ -1006,24 +940,42 @@ static int __init at91_mci_probe(struct platform_device *pdev)
1006 mmc->f_min = 375000; 940 mmc->f_min = 375000;
1007 mmc->f_max = 25000000; 941 mmc->f_max = 25000000;
1008 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 942 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1009 mmc->caps = MMC_CAP_SDIO_IRQ; 943 mmc->caps = 0;
1010 944
1011 mmc->max_blk_size = 4095; 945 mmc->max_blk_size = MCI_MAXBLKSIZE;
1012 mmc->max_blk_count = mmc->max_req_size; 946 mmc->max_blk_count = MCI_BLKATONCE;
947 mmc->max_req_size = MCI_BUFSIZE;
948 mmc->max_phys_segs = MCI_BLKATONCE;
949 mmc->max_hw_segs = MCI_BLKATONCE;
950 mmc->max_seg_size = MCI_BUFSIZE;
1013 951
1014 host = mmc_priv(mmc); 952 host = mmc_priv(mmc);
1015 host->mmc = mmc; 953 host->mmc = mmc;
1016 host->buffer = NULL;
1017 host->bus_mode = 0; 954 host->bus_mode = 0;
1018 host->board = pdev->dev.platform_data; 955 host->board = pdev->dev.platform_data;
1019 if (host->board->wire4) { 956 if (host->board->wire4) {
1020 if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) 957 if (at91mci_is_mci1rev2xx())
1021 mmc->caps |= MMC_CAP_4_BIT_DATA; 958 mmc->caps |= MMC_CAP_4_BIT_DATA;
1022 else 959 else
1023 dev_warn(&pdev->dev, "4 wire bus mode not supported" 960 dev_warn(&pdev->dev, "4 wire bus mode not supported"
1024 " - using 1 wire\n"); 961 " - using 1 wire\n");
1025 } 962 }
1026 963
964 host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE,
965 &host->physical_address, GFP_KERNEL);
966 if (!host->buffer) {
967 ret = -ENOMEM;
968 dev_err(&pdev->dev, "Can't allocate transmit buffer\n");
969 goto fail5;
970 }
971
972 /* Add SDIO capability when available */
973 if (at91mci_is_mci1rev2xx()) {
974 /* at91mci MCI1 rev2xx sdio interrupt erratum */
975 if (host->board->wire4 || !host->board->slot_b)
976 mmc->caps |= MMC_CAP_SDIO_IRQ;
977 }
978
1027 /* 979 /*
1028 * Reserve GPIOs ... board init code makes sure these pins are set 980 * Reserve GPIOs ... board init code makes sure these pins are set
1029 * up as GPIOs with the right direction (input, except for vcc) 981 * up as GPIOs with the right direction (input, except for vcc)
@@ -1032,7 +984,7 @@ static int __init at91_mci_probe(struct platform_device *pdev)
1032 ret = gpio_request(host->board->det_pin, "mmc_detect"); 984 ret = gpio_request(host->board->det_pin, "mmc_detect");
1033 if (ret < 0) { 985 if (ret < 0) {
1034 dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); 986 dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
1035 goto fail5; 987 goto fail4b;
1036 } 988 }
1037 } 989 }
1038 if (host->board->wp_pin) { 990 if (host->board->wp_pin) {
@@ -1132,6 +1084,10 @@ fail3:
1132fail4: 1084fail4:
1133 if (host->board->det_pin) 1085 if (host->board->det_pin)
1134 gpio_free(host->board->det_pin); 1086 gpio_free(host->board->det_pin);
1087fail4b:
1088 if (host->buffer)
1089 dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
1090 host->buffer, host->physical_address);
1135fail5: 1091fail5:
1136 mmc_free_host(mmc); 1092 mmc_free_host(mmc);
1137fail6: 1093fail6:
@@ -1154,6 +1110,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
1154 1110
1155 host = mmc_priv(mmc); 1111 host = mmc_priv(mmc);
1156 1112
1113 if (host->buffer)
1114 dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
1115 host->buffer, host->physical_address);
1116
1157 if (host->board->det_pin) { 1117 if (host->board->det_pin) {
1158 if (device_can_wakeup(&pdev->dev)) 1118 if (device_can_wakeup(&pdev->dev))
1159 free_irq(gpio_to_irq(host->board->det_pin), host); 1119 free_irq(gpio_to_irq(host->board->det_pin), host);
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index 3343a57355cc..56f7b448b911 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -115,7 +115,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
115 unsigned int length; 115 unsigned int length;
116 unsigned int data_ctl; 116 unsigned int data_ctl;
117 unsigned int dma_cfg; 117 unsigned int dma_cfg;
118 struct scatterlist *sg; 118 unsigned int cycle_ns, timeout;
119 119
120 dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags); 120 dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags);
121 host->data = data; 121 host->data = data;
@@ -136,8 +136,11 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
136 data_ctl |= ((ffs(data->blksz) - 1) << 4); 136 data_ctl |= ((ffs(data->blksz) - 1) << 4);
137 137
138 bfin_write_SDH_DATA_CTL(data_ctl); 138 bfin_write_SDH_DATA_CTL(data_ctl);
139 139 /* the time of a host clock period in ns */
140 bfin_write_SDH_DATA_TIMER(0xFFFF); 140 cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1)));
141 timeout = data->timeout_ns / cycle_ns;
142 timeout += data->timeout_clks;
143 bfin_write_SDH_DATA_TIMER(timeout);
141 SSYNC(); 144 SSYNC();
142 145
143 if (data->flags & MMC_DATA_READ) { 146 if (data->flags & MMC_DATA_READ) {
@@ -151,6 +154,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data)
151#if defined(CONFIG_BF54x) 154#if defined(CONFIG_BF54x)
152 dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN; 155 dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN;
153 { 156 {
157 struct scatterlist *sg;
154 int i; 158 int i;
155 for_each_sg(data->sg, sg, host->dma_len, i) { 159 for_each_sg(data->sg, sg, host->dma_len, i) {
156 host->sg_cpu[i].start_addr = sg_dma_address(sg); 160 host->sg_cpu[i].start_addr = sg_dma_address(sg);
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index dd45e7c3517e..3bd0ba294e9d 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -73,6 +73,7 @@
73/* DAVINCI_MMCCTL definitions */ 73/* DAVINCI_MMCCTL definitions */
74#define MMCCTL_DATRST (1 << 0) 74#define MMCCTL_DATRST (1 << 0)
75#define MMCCTL_CMDRST (1 << 1) 75#define MMCCTL_CMDRST (1 << 1)
76#define MMCCTL_WIDTH_8_BIT (1 << 8)
76#define MMCCTL_WIDTH_4_BIT (1 << 2) 77#define MMCCTL_WIDTH_4_BIT (1 << 2)
77#define MMCCTL_DATEG_DISABLED (0 << 6) 78#define MMCCTL_DATEG_DISABLED (0 << 6)
78#define MMCCTL_DATEG_RISING (1 << 6) 79#define MMCCTL_DATEG_RISING (1 << 6)
@@ -791,22 +792,42 @@ static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios)
791 792
792static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 793static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
793{ 794{
794 unsigned int mmc_pclk = 0;
795 struct mmc_davinci_host *host = mmc_priv(mmc); 795 struct mmc_davinci_host *host = mmc_priv(mmc);
796 796
797 mmc_pclk = host->mmc_input_clk;
798 dev_dbg(mmc_dev(host->mmc), 797 dev_dbg(mmc_dev(host->mmc),
799 "clock %dHz busmode %d powermode %d Vdd %04x\n", 798 "clock %dHz busmode %d powermode %d Vdd %04x\n",
800 ios->clock, ios->bus_mode, ios->power_mode, 799 ios->clock, ios->bus_mode, ios->power_mode,
801 ios->vdd); 800 ios->vdd);
802 if (ios->bus_width == MMC_BUS_WIDTH_4) { 801
803 dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n"); 802 switch (ios->bus_width) {
804 writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT, 803 case MMC_BUS_WIDTH_8:
805 host->base + DAVINCI_MMCCTL); 804 dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n");
806 } else { 805 writel((readl(host->base + DAVINCI_MMCCTL) &
807 dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n"); 806 ~MMCCTL_WIDTH_4_BIT) | MMCCTL_WIDTH_8_BIT,
808 writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT,
809 host->base + DAVINCI_MMCCTL); 807 host->base + DAVINCI_MMCCTL);
808 break;
809 case MMC_BUS_WIDTH_4:
810 dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n");
811 if (host->version == MMC_CTLR_VERSION_2)
812 writel((readl(host->base + DAVINCI_MMCCTL) &
813 ~MMCCTL_WIDTH_8_BIT) | MMCCTL_WIDTH_4_BIT,
814 host->base + DAVINCI_MMCCTL);
815 else
816 writel(readl(host->base + DAVINCI_MMCCTL) |
817 MMCCTL_WIDTH_4_BIT,
818 host->base + DAVINCI_MMCCTL);
819 break;
820 case MMC_BUS_WIDTH_1:
821 dev_dbg(mmc_dev(host->mmc), "Enabling 1 bit mode\n");
822 if (host->version == MMC_CTLR_VERSION_2)
823 writel(readl(host->base + DAVINCI_MMCCTL) &
824 ~(MMCCTL_WIDTH_8_BIT | MMCCTL_WIDTH_4_BIT),
825 host->base + DAVINCI_MMCCTL);
826 else
827 writel(readl(host->base + DAVINCI_MMCCTL) &
828 ~MMCCTL_WIDTH_4_BIT,
829 host->base + DAVINCI_MMCCTL);
830 break;
810 } 831 }
811 832
812 calculate_clk_divider(mmc, ios); 833 calculate_clk_divider(mmc, ios);
@@ -1189,10 +1210,14 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
1189 1210
1190 /* REVISIT: someday, support IRQ-driven card detection. */ 1211 /* REVISIT: someday, support IRQ-driven card detection. */
1191 mmc->caps |= MMC_CAP_NEEDS_POLL; 1212 mmc->caps |= MMC_CAP_NEEDS_POLL;
1213 mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
1192 1214
1193 if (!pdata || pdata->wires == 4 || pdata->wires == 0) 1215 if (pdata && (pdata->wires == 4 || pdata->wires == 0))
1194 mmc->caps |= MMC_CAP_4_BIT_DATA; 1216 mmc->caps |= MMC_CAP_4_BIT_DATA;
1195 1217
1218 if (pdata && (pdata->wires == 8))
1219 mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
1220
1196 host->version = pdata->version; 1221 host->version = pdata->version;
1197 1222
1198 mmc->ops = &mmc_davinci_ops; 1223 mmc->ops = &mmc_davinci_ops;
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
deleted file mode 100644
index f62790513322..000000000000
--- a/drivers/mmc/host/ricoh_mmc.c
+++ /dev/null
@@ -1,262 +0,0 @@
1/*
2 * ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller.
3 *
4 * Copyright (C) 2007 Philip Langdale, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
10 */
11
12/*
13 * This is a conceptually ridiculous driver, but it is required by the way
14 * the Ricoh multi-function chips (R5CXXX) work. These chips implement
15 * the four main memory card controllers (SD, MMC, MS, xD) and one or both
16 * of cardbus or firewire. It happens that they implement SD and MMC
17 * support as separate controllers (and PCI functions). The linux SDHCI
18 * driver supports MMC cards but the chip detects MMC cards in hardware
19 * and directs them to the MMC controller - so the SDHCI driver never sees
20 * them. To get around this, we must disable the useless MMC controller.
21 * At that point, the SDHCI controller will start seeing them. As a bonus,
22 * a detection event occurs immediately, even if the MMC card is already
23 * in the reader.
24 *
25 * It seems to be the case that the relevant PCI registers to deactivate the
26 * MMC controller live on PCI function 0, which might be the cardbus controller
27 * or the firewire controller, depending on the particular chip in question. As
28 * such, it makes what this driver has to do unavoidably ugly. Such is life.
29 */
30
31#include <linux/pci.h>
32
33#define DRIVER_NAME "ricoh-mmc"
34
35static const struct pci_device_id pci_ids[] __devinitdata = {
36 {
37 .vendor = PCI_VENDOR_ID_RICOH,
38 .device = PCI_DEVICE_ID_RICOH_R5C843,
39 .subvendor = PCI_ANY_ID,
40 .subdevice = PCI_ANY_ID,
41 },
42 { /* end: all zeroes */ },
43};
44
45MODULE_DEVICE_TABLE(pci, pci_ids);
46
47static int ricoh_mmc_disable(struct pci_dev *fw_dev)
48{
49 u8 write_enable;
50 u8 write_target;
51 u8 disable;
52
53 if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
54 /* via RL5C476 */
55
56 pci_read_config_byte(fw_dev, 0xB7, &disable);
57 if (disable & 0x02) {
58 printk(KERN_INFO DRIVER_NAME
59 ": Controller already disabled. " \
60 "Nothing to do.\n");
61 return -ENODEV;
62 }
63
64 pci_read_config_byte(fw_dev, 0x8E, &write_enable);
65 pci_write_config_byte(fw_dev, 0x8E, 0xAA);
66 pci_read_config_byte(fw_dev, 0x8D, &write_target);
67 pci_write_config_byte(fw_dev, 0x8D, 0xB7);
68 pci_write_config_byte(fw_dev, 0xB7, disable | 0x02);
69 pci_write_config_byte(fw_dev, 0x8E, write_enable);
70 pci_write_config_byte(fw_dev, 0x8D, write_target);
71 } else {
72 /* via R5C832 */
73
74 pci_read_config_byte(fw_dev, 0xCB, &disable);
75 if (disable & 0x02) {
76 printk(KERN_INFO DRIVER_NAME
77 ": Controller already disabled. " \
78 "Nothing to do.\n");
79 return -ENODEV;
80 }
81
82 pci_read_config_byte(fw_dev, 0xCA, &write_enable);
83 pci_write_config_byte(fw_dev, 0xCA, 0x57);
84 pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
85 pci_write_config_byte(fw_dev, 0xCA, write_enable);
86 }
87
88 printk(KERN_INFO DRIVER_NAME
89 ": Controller is now disabled.\n");
90
91 return 0;
92}
93
94static int ricoh_mmc_enable(struct pci_dev *fw_dev)
95{
96 u8 write_enable;
97 u8 write_target;
98 u8 disable;
99
100 if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
101 /* via RL5C476 */
102
103 pci_read_config_byte(fw_dev, 0x8E, &write_enable);
104 pci_write_config_byte(fw_dev, 0x8E, 0xAA);
105 pci_read_config_byte(fw_dev, 0x8D, &write_target);
106 pci_write_config_byte(fw_dev, 0x8D, 0xB7);
107 pci_read_config_byte(fw_dev, 0xB7, &disable);
108 pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02);
109 pci_write_config_byte(fw_dev, 0x8E, write_enable);
110 pci_write_config_byte(fw_dev, 0x8D, write_target);
111 } else {
112 /* via R5C832 */
113
114 pci_read_config_byte(fw_dev, 0xCA, &write_enable);
115 pci_read_config_byte(fw_dev, 0xCB, &disable);
116 pci_write_config_byte(fw_dev, 0xCA, 0x57);
117 pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
118 pci_write_config_byte(fw_dev, 0xCA, write_enable);
119 }
120
121 printk(KERN_INFO DRIVER_NAME
122 ": Controller is now re-enabled.\n");
123
124 return 0;
125}
126
127static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
128 const struct pci_device_id *ent)
129{
130 u8 rev;
131 u8 ctrlfound = 0;
132
133 struct pci_dev *fw_dev = NULL;
134
135 BUG_ON(pdev == NULL);
136 BUG_ON(ent == NULL);
137
138 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
139
140 printk(KERN_INFO DRIVER_NAME
141 ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n",
142 pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
143 (int)rev);
144
145 while ((fw_dev =
146 pci_get_device(PCI_VENDOR_ID_RICOH,
147 PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {
148 if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
149 PCI_FUNC(fw_dev->devfn) == 0 &&
150 pdev->bus == fw_dev->bus) {
151 if (ricoh_mmc_disable(fw_dev) != 0)
152 return -ENODEV;
153
154 pci_set_drvdata(pdev, fw_dev);
155
156 ++ctrlfound;
157 break;
158 }
159 }
160
161 fw_dev = NULL;
162
163 while (!ctrlfound &&
164 (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH,
165 PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
166 if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
167 PCI_FUNC(fw_dev->devfn) == 0 &&
168 pdev->bus == fw_dev->bus) {
169 if (ricoh_mmc_disable(fw_dev) != 0)
170 return -ENODEV;
171
172 pci_set_drvdata(pdev, fw_dev);
173
174 ++ctrlfound;
175 }
176 }
177
178 if (!ctrlfound) {
179 printk(KERN_WARNING DRIVER_NAME
180 ": Main Ricoh function not found. Cannot disable controller.\n");
181 return -ENODEV;
182 }
183
184 return 0;
185}
186
187static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
188{
189 struct pci_dev *fw_dev = NULL;
190
191 fw_dev = pci_get_drvdata(pdev);
192 BUG_ON(fw_dev == NULL);
193
194 ricoh_mmc_enable(fw_dev);
195
196 pci_set_drvdata(pdev, NULL);
197}
198
199static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state)
200{
201 struct pci_dev *fw_dev = NULL;
202
203 fw_dev = pci_get_drvdata(pdev);
204 BUG_ON(fw_dev == NULL);
205
206 printk(KERN_INFO DRIVER_NAME ": Suspending.\n");
207
208 ricoh_mmc_enable(fw_dev);
209
210 return 0;
211}
212
213static int ricoh_mmc_resume_early(struct pci_dev *pdev)
214{
215 struct pci_dev *fw_dev = NULL;
216
217 fw_dev = pci_get_drvdata(pdev);
218 BUG_ON(fw_dev == NULL);
219
220 printk(KERN_INFO DRIVER_NAME ": Resuming.\n");
221
222 ricoh_mmc_disable(fw_dev);
223
224 return 0;
225}
226
227static struct pci_driver ricoh_mmc_driver = {
228 .name = DRIVER_NAME,
229 .id_table = pci_ids,
230 .probe = ricoh_mmc_probe,
231 .remove = __devexit_p(ricoh_mmc_remove),
232 .suspend_late = ricoh_mmc_suspend_late,
233 .resume_early = ricoh_mmc_resume_early,
234};
235
236/*****************************************************************************\
237 * *
238 * Driver init/exit *
239 * *
240\*****************************************************************************/
241
242static int __init ricoh_mmc_drv_init(void)
243{
244 printk(KERN_INFO DRIVER_NAME
245 ": Ricoh MMC Controller disabling driver\n");
246 printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n");
247
248 return pci_register_driver(&ricoh_mmc_driver);
249}
250
251static void __exit ricoh_mmc_drv_exit(void)
252{
253 pci_unregister_driver(&ricoh_mmc_driver);
254}
255
256module_init(ricoh_mmc_drv_init);
257module_exit(ricoh_mmc_drv_exit);
258
259MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>");
260MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver");
261MODULE_LICENSE("GPL");
262
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index d96e1abf2d64..2fdf7689ae6c 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1179,7 +1179,7 @@ static int s3cmci_card_present(struct mmc_host *mmc)
1179 struct s3c24xx_mci_pdata *pdata = host->pdata; 1179 struct s3c24xx_mci_pdata *pdata = host->pdata;
1180 int ret; 1180 int ret;
1181 1181
1182 if (pdata->gpio_detect == 0) 1182 if (pdata->no_detect)
1183 return -ENOSYS; 1183 return -ENOSYS;
1184 1184
1185 ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; 1185 ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
@@ -1360,6 +1360,8 @@ static struct mmc_host_ops s3cmci_ops = {
1360static struct s3c24xx_mci_pdata s3cmci_def_pdata = { 1360static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
1361 /* This is currently here to avoid a number of if (host->pdata) 1361 /* This is currently here to avoid a number of if (host->pdata)
1362 * checks. Any zero fields to ensure reasonable defaults are picked. */ 1362 * checks. Any zero fields to ensure reasonable defaults are picked. */
1363 .no_wprotect = 1,
1364 .no_detect = 1,
1363}; 1365};
1364 1366
1365#ifdef CONFIG_CPU_FREQ 1367#ifdef CONFIG_CPU_FREQ
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 5c3a1767770a..8e1020cf73f4 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -80,9 +80,6 @@ struct sdhci_pci_chip {
80 80
81static int ricoh_probe(struct sdhci_pci_chip *chip) 81static int ricoh_probe(struct sdhci_pci_chip *chip)
82{ 82{
83 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
84 chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET;
85
86 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || 83 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
87 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) 84 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
88 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; 85 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
@@ -92,7 +89,9 @@ static int ricoh_probe(struct sdhci_pci_chip *chip)
92 89
93static const struct sdhci_pci_fixes sdhci_ricoh = { 90static const struct sdhci_pci_fixes sdhci_ricoh = {
94 .probe = ricoh_probe, 91 .probe = ricoh_probe,
95 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, 92 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
93 SDHCI_QUIRK_FORCE_DMA |
94 SDHCI_QUIRK_CLOCK_BEFORE_RESET,
96}; 95};
97 96
98static const struct sdhci_pci_fixes sdhci_ene_712 = { 97static const struct sdhci_pci_fixes sdhci_ene_712 = {
@@ -501,6 +500,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
501{ 500{
502 struct sdhci_pci_chip *chip; 501 struct sdhci_pci_chip *chip;
503 struct sdhci_pci_slot *slot; 502 struct sdhci_pci_slot *slot;
503 mmc_pm_flag_t pm_flags = 0;
504 int i, ret; 504 int i, ret;
505 505
506 chip = pci_get_drvdata(pdev); 506 chip = pci_get_drvdata(pdev);
@@ -519,6 +519,8 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
519 sdhci_resume_host(chip->slots[i]->host); 519 sdhci_resume_host(chip->slots[i]->host);
520 return ret; 520 return ret;
521 } 521 }
522
523 pm_flags |= slot->host->mmc->pm_flags;
522 } 524 }
523 525
524 if (chip->fixes && chip->fixes->suspend) { 526 if (chip->fixes && chip->fixes->suspend) {
@@ -531,9 +533,15 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
531 } 533 }
532 534
533 pci_save_state(pdev); 535 pci_save_state(pdev);
534 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); 536 if (pm_flags & MMC_PM_KEEP_POWER) {
535 pci_disable_device(pdev); 537 if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
536 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 538 pci_enable_wake(pdev, PCI_D3hot, 1);
539 pci_set_power_state(pdev, PCI_D3hot);
540 } else {
541 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
542 pci_disable_device(pdev);
543 pci_set_power_state(pdev, pci_choose_state(pdev, state));
544 }
537 545
538 return 0; 546 return 0;
539} 547}
@@ -653,6 +661,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
653 goto unmap; 661 goto unmap;
654 } 662 }
655 663
664 host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
665
656 ret = sdhci_add_host(host); 666 ret = sdhci_add_host(host);
657 if (ret) 667 if (ret)
658 goto remove; 668 goto remove;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c279fbc4c2e5..d6ab62d539fb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -174,20 +174,31 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
174 sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); 174 sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
175} 175}
176 176
177static void sdhci_init(struct sdhci_host *host) 177static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
178
179static void sdhci_init(struct sdhci_host *host, int soft)
178{ 180{
179 sdhci_reset(host, SDHCI_RESET_ALL); 181 if (soft)
182 sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
183 else
184 sdhci_reset(host, SDHCI_RESET_ALL);
180 185
181 sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, 186 sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
182 SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | 187 SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
183 SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | 188 SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
184 SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | 189 SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
185 SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); 190 SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
191
192 if (soft) {
193 /* force clock reconfiguration */
194 host->clock = 0;
195 sdhci_set_ios(host->mmc, &host->mmc->ios);
196 }
186} 197}
187 198
188static void sdhci_reinit(struct sdhci_host *host) 199static void sdhci_reinit(struct sdhci_host *host)
189{ 200{
190 sdhci_init(host); 201 sdhci_init(host, 0);
191 sdhci_enable_card_detection(host); 202 sdhci_enable_card_detection(host);
192} 203}
193 204
@@ -376,6 +387,20 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
376 local_irq_restore(*flags); 387 local_irq_restore(*flags);
377} 388}
378 389
390static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd)
391{
392 __le32 *dataddr = (__le32 __force *)(desc + 4);
393 __le16 *cmdlen = (__le16 __force *)desc;
394
395 /* SDHCI specification says ADMA descriptors should be 4 byte
396 * aligned, so using 16 or 32bit operations should be safe. */
397
398 cmdlen[0] = cpu_to_le16(cmd);
399 cmdlen[1] = cpu_to_le16(len);
400
401 dataddr[0] = cpu_to_le32(addr);
402}
403
379static int sdhci_adma_table_pre(struct sdhci_host *host, 404static int sdhci_adma_table_pre(struct sdhci_host *host,
380 struct mmc_data *data) 405 struct mmc_data *data)
381{ 406{
@@ -443,19 +468,11 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
443 sdhci_kunmap_atomic(buffer, &flags); 468 sdhci_kunmap_atomic(buffer, &flags);
444 } 469 }
445 470
446 desc[7] = (align_addr >> 24) & 0xff; 471 /* tran, valid */
447 desc[6] = (align_addr >> 16) & 0xff; 472 sdhci_set_adma_desc(desc, align_addr, offset, 0x21);
448 desc[5] = (align_addr >> 8) & 0xff;
449 desc[4] = (align_addr >> 0) & 0xff;
450 473
451 BUG_ON(offset > 65536); 474 BUG_ON(offset > 65536);
452 475
453 desc[3] = (offset >> 8) & 0xff;
454 desc[2] = (offset >> 0) & 0xff;
455
456 desc[1] = 0x00;
457 desc[0] = 0x21; /* tran, valid */
458
459 align += 4; 476 align += 4;
460 align_addr += 4; 477 align_addr += 4;
461 478
@@ -465,19 +482,10 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
465 len -= offset; 482 len -= offset;
466 } 483 }
467 484
468 desc[7] = (addr >> 24) & 0xff;
469 desc[6] = (addr >> 16) & 0xff;
470 desc[5] = (addr >> 8) & 0xff;
471 desc[4] = (addr >> 0) & 0xff;
472
473 BUG_ON(len > 65536); 485 BUG_ON(len > 65536);
474 486
475 desc[3] = (len >> 8) & 0xff; 487 /* tran, valid */
476 desc[2] = (len >> 0) & 0xff; 488 sdhci_set_adma_desc(desc, addr, len, 0x21);
477
478 desc[1] = 0x00;
479 desc[0] = 0x21; /* tran, valid */
480
481 desc += 8; 489 desc += 8;
482 490
483 /* 491 /*
@@ -490,16 +498,9 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
490 /* 498 /*
491 * Add a terminating entry. 499 * Add a terminating entry.
492 */ 500 */
493 desc[7] = 0;
494 desc[6] = 0;
495 desc[5] = 0;
496 desc[4] = 0;
497 501
498 desc[3] = 0; 502 /* nop, end, valid */
499 desc[2] = 0; 503 sdhci_set_adma_desc(desc, 0, 0, 0x3);
500
501 desc[1] = 0x00;
502 desc[0] = 0x03; /* nop, end, valid */
503 504
504 /* 505 /*
505 * Resync align buffer as we might have changed it. 506 * Resync align buffer as we might have changed it.
@@ -1610,16 +1611,13 @@ int sdhci_resume_host(struct sdhci_host *host)
1610 if (ret) 1611 if (ret)
1611 return ret; 1612 return ret;
1612 1613
1613 sdhci_init(host); 1614 sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER));
1614 mmiowb(); 1615 mmiowb();
1615 1616
1616 ret = mmc_resume_host(host->mmc); 1617 ret = mmc_resume_host(host->mmc);
1617 if (ret)
1618 return ret;
1619
1620 sdhci_enable_card_detection(host); 1618 sdhci_enable_card_detection(host);
1621 1619
1622 return 0; 1620 return ret;
1623} 1621}
1624 1622
1625EXPORT_SYMBOL_GPL(sdhci_resume_host); 1623EXPORT_SYMBOL_GPL(sdhci_resume_host);
@@ -1874,7 +1872,7 @@ int sdhci_add_host(struct sdhci_host *host)
1874 if (ret) 1872 if (ret)
1875 goto untasklet; 1873 goto untasklet;
1876 1874
1877 sdhci_init(host); 1875 sdhci_init(host, 0);
1878 1876
1879#ifdef CONFIG_MMC_DEBUG 1877#ifdef CONFIG_MMC_DEBUG
1880 sdhci_dumpregs(host); 1878 sdhci_dumpregs(host);
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index e22c3fa3516a..b2b577f6afd4 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -323,7 +323,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid)
323 if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { 323 if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
324 ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | 324 ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
325 TMIO_STAT_CARD_REMOVE); 325 TMIO_STAT_CARD_REMOVE);
326 mmc_detect_change(host->mmc, 0); 326 mmc_detect_change(host->mmc, msecs_to_jiffies(100));
327 } 327 }
328 328
329 /* CRC and other errors */ 329 /* CRC and other errors */
@@ -550,6 +550,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
550 550
551 mmc->ops = &tmio_mmc_ops; 551 mmc->ops = &tmio_mmc_ops;
552 mmc->caps = MMC_CAP_4_BIT_DATA; 552 mmc->caps = MMC_CAP_4_BIT_DATA;
553 mmc->caps |= pdata->capabilities;
553 mmc->f_max = pdata->hclk; 554 mmc->f_max = pdata->hclk;
554 mmc->f_min = mmc->f_max / 512; 555 mmc->f_min = mmc->f_max / 512;
555 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 556 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
@@ -568,14 +569,14 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
568 if (ret >= 0) 569 if (ret >= 0)
569 host->irq = ret; 570 host->irq = ret;
570 else 571 else
571 goto unmap_ctl; 572 goto cell_disable;
572 573
573 disable_mmc_irqs(host, TMIO_MASK_ALL); 574 disable_mmc_irqs(host, TMIO_MASK_ALL);
574 575
575 ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | 576 ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED |
576 IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); 577 IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host);
577 if (ret) 578 if (ret)
578 goto unmap_ctl; 579 goto cell_disable;
579 580
580 mmc_add_host(mmc); 581 mmc_add_host(mmc);
581 582
@@ -587,6 +588,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
587 588
588 return 0; 589 return 0;
589 590
591cell_disable:
592 if (cell->disable)
593 cell->disable(dev);
590unmap_ctl: 594unmap_ctl:
591 iounmap(host->ctl); 595 iounmap(host->ctl);
592host_free: 596host_free:
@@ -597,6 +601,7 @@ out:
597 601
598static int __devexit tmio_mmc_remove(struct platform_device *dev) 602static int __devexit tmio_mmc_remove(struct platform_device *dev)
599{ 603{
604 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data;
600 struct mmc_host *mmc = platform_get_drvdata(dev); 605 struct mmc_host *mmc = platform_get_drvdata(dev);
601 606
602 platform_set_drvdata(dev, NULL); 607 platform_set_drvdata(dev, NULL);
@@ -605,6 +610,8 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev)
605 struct tmio_mmc_host *host = mmc_priv(mmc); 610 struct tmio_mmc_host *host = mmc_priv(mmc);
606 mmc_remove_host(mmc); 611 mmc_remove_host(mmc);
607 free_irq(host->irq, host); 612 free_irq(host->irq, host);
613 if (cell->disable)
614 cell->disable(dev);
608 iounmap(host->ctl); 615 iounmap(host->ctl);
609 mmc_free_host(mmc); 616 mmc_free_host(mmc);
610 } 617 }
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 692dc23363b9..dafecfbcd91a 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -55,10 +55,8 @@
55/* Define some IRQ masks */ 55/* Define some IRQ masks */
56/* This is the mask used at reset by the chip */ 56/* This is the mask used at reset by the chip */
57#define TMIO_MASK_ALL 0x837f031d 57#define TMIO_MASK_ALL 0x837f031d
58#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \ 58#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND)
59 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) 59#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND)
60#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \
61 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
62#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ 60#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
63 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) 61 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
64#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) 62#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 14cec04c34f9..bc45ef9af17d 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -37,6 +37,7 @@
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
39#include <linux/stringify.h> 39#include <linux/stringify.h>
40#include <linux/namei.h>
40#include <linux/stat.h> 41#include <linux/stat.h>
41#include <linux/miscdevice.h> 42#include <linux/miscdevice.h>
42#include <linux/log2.h> 43#include <linux/log2.h>
@@ -50,7 +51,8 @@
50 51
51/** 52/**
52 * struct mtd_dev_param - MTD device parameter description data structure. 53 * struct mtd_dev_param - MTD device parameter description data structure.
53 * @name: MTD device name or number string 54 * @name: MTD character device node path, MTD device name, or MTD device number
55 * string
54 * @vid_hdr_offs: VID header offset 56 * @vid_hdr_offs: VID header offset
55 */ 57 */
56struct mtd_dev_param { 58struct mtd_dev_param {
@@ -59,10 +61,10 @@ struct mtd_dev_param {
59}; 61};
60 62
61/* Numbers of elements set in the @mtd_dev_param array */ 63/* Numbers of elements set in the @mtd_dev_param array */
62static int mtd_devs; 64static int __initdata mtd_devs;
63 65
64/* MTD devices specification parameters */ 66/* MTD devices specification parameters */
65static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; 67static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
66 68
67/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ 69/* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
68struct class *ubi_class; 70struct class *ubi_class;
@@ -363,11 +365,13 @@ static void dev_release(struct device *dev)
363/** 365/**
364 * ubi_sysfs_init - initialize sysfs for an UBI device. 366 * ubi_sysfs_init - initialize sysfs for an UBI device.
365 * @ubi: UBI device description object 367 * @ubi: UBI device description object
368 * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
369 * taken
366 * 370 *
367 * This function returns zero in case of success and a negative error code in 371 * This function returns zero in case of success and a negative error code in
368 * case of failure. 372 * case of failure.
369 */ 373 */
370static int ubi_sysfs_init(struct ubi_device *ubi) 374static int ubi_sysfs_init(struct ubi_device *ubi, int *ref)
371{ 375{
372 int err; 376 int err;
373 377
@@ -379,6 +383,7 @@ static int ubi_sysfs_init(struct ubi_device *ubi)
379 if (err) 383 if (err)
380 return err; 384 return err;
381 385
386 *ref = 1;
382 err = device_create_file(&ubi->dev, &dev_eraseblock_size); 387 err = device_create_file(&ubi->dev, &dev_eraseblock_size);
383 if (err) 388 if (err)
384 return err; 389 return err;
@@ -434,7 +439,7 @@ static void ubi_sysfs_close(struct ubi_device *ubi)
434} 439}
435 440
436/** 441/**
437 * kill_volumes - destroy all volumes. 442 * kill_volumes - destroy all user volumes.
438 * @ubi: UBI device description object 443 * @ubi: UBI device description object
439 */ 444 */
440static void kill_volumes(struct ubi_device *ubi) 445static void kill_volumes(struct ubi_device *ubi)
@@ -447,36 +452,29 @@ static void kill_volumes(struct ubi_device *ubi)
447} 452}
448 453
449/** 454/**
450 * free_user_volumes - free all user volumes.
451 * @ubi: UBI device description object
452 *
453 * Normally the volumes are freed at the release function of the volume device
454 * objects. However, on error paths the volumes have to be freed before the
455 * device objects have been initialized.
456 */
457static void free_user_volumes(struct ubi_device *ubi)
458{
459 int i;
460
461 for (i = 0; i < ubi->vtbl_slots; i++)
462 if (ubi->volumes[i]) {
463 kfree(ubi->volumes[i]->eba_tbl);
464 kfree(ubi->volumes[i]);
465 }
466}
467
468/**
469 * uif_init - initialize user interfaces for an UBI device. 455 * uif_init - initialize user interfaces for an UBI device.
470 * @ubi: UBI device description object 456 * @ubi: UBI device description object
457 * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was
458 * taken, otherwise set to %0
459 *
460 * This function initializes various user interfaces for an UBI device. If the
461 * initialization fails at an early stage, this function frees all the
462 * resources it allocated, returns an error, and @ref is set to %0. However,
463 * if the initialization fails after the UBI device was registered in the
464 * driver core subsystem, this function takes a reference to @ubi->dev, because
465 * otherwise the release function ('dev_release()') would free whole @ubi
466 * object. The @ref argument is set to %1 in this case. The caller has to put
467 * this reference.
471 * 468 *
472 * This function returns zero in case of success and a negative error code in 469 * This function returns zero in case of success and a negative error code in
473 * case of failure. Note, this function destroys all volumes if it fails. 470 * case of failure.
474 */ 471 */
475static int uif_init(struct ubi_device *ubi) 472static int uif_init(struct ubi_device *ubi, int *ref)
476{ 473{
477 int i, err; 474 int i, err;
478 dev_t dev; 475 dev_t dev;
479 476
477 *ref = 0;
480 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); 478 sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
481 479
482 /* 480 /*
@@ -504,7 +502,7 @@ static int uif_init(struct ubi_device *ubi)
504 goto out_unreg; 502 goto out_unreg;
505 } 503 }
506 504
507 err = ubi_sysfs_init(ubi); 505 err = ubi_sysfs_init(ubi, ref);
508 if (err) 506 if (err)
509 goto out_sysfs; 507 goto out_sysfs;
510 508
@@ -522,6 +520,8 @@ static int uif_init(struct ubi_device *ubi)
522out_volumes: 520out_volumes:
523 kill_volumes(ubi); 521 kill_volumes(ubi);
524out_sysfs: 522out_sysfs:
523 if (*ref)
524 get_device(&ubi->dev);
525 ubi_sysfs_close(ubi); 525 ubi_sysfs_close(ubi);
526 cdev_del(&ubi->cdev); 526 cdev_del(&ubi->cdev);
527out_unreg: 527out_unreg:
@@ -875,7 +875,7 @@ static int ubi_reboot_notifier(struct notifier_block *n, unsigned long state,
875int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) 875int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
876{ 876{
877 struct ubi_device *ubi; 877 struct ubi_device *ubi;
878 int i, err, do_free = 1; 878 int i, err, ref = 0;
879 879
880 /* 880 /*
881 * Check if we already have the same MTD device attached. 881 * Check if we already have the same MTD device attached.
@@ -975,9 +975,9 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
975 goto out_detach; 975 goto out_detach;
976 } 976 }
977 977
978 err = uif_init(ubi); 978 err = uif_init(ubi, &ref);
979 if (err) 979 if (err)
980 goto out_nofree; 980 goto out_detach;
981 981
982 ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); 982 ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name);
983 if (IS_ERR(ubi->bgt_thread)) { 983 if (IS_ERR(ubi->bgt_thread)) {
@@ -1025,12 +1025,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
1025 1025
1026out_uif: 1026out_uif:
1027 uif_close(ubi); 1027 uif_close(ubi);
1028out_nofree:
1029 do_free = 0;
1030out_detach: 1028out_detach:
1031 ubi_wl_close(ubi); 1029 ubi_wl_close(ubi);
1032 if (do_free)
1033 free_user_volumes(ubi);
1034 free_internal_volumes(ubi); 1030 free_internal_volumes(ubi);
1035 vfree(ubi->vtbl); 1031 vfree(ubi->vtbl);
1036out_free: 1032out_free:
@@ -1039,7 +1035,10 @@ out_free:
1039#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 1035#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
1040 vfree(ubi->dbg_peb_buf); 1036 vfree(ubi->dbg_peb_buf);
1041#endif 1037#endif
1042 kfree(ubi); 1038 if (ref)
1039 put_device(&ubi->dev);
1040 else
1041 kfree(ubi);
1043 return err; 1042 return err;
1044} 1043}
1045 1044
@@ -1096,7 +1095,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
1096 1095
1097 /* 1096 /*
1098 * Get a reference to the device in order to prevent 'dev_release()' 1097 * Get a reference to the device in order to prevent 'dev_release()'
1099 * from freeing @ubi object. 1098 * from freeing the @ubi object.
1100 */ 1099 */
1101 get_device(&ubi->dev); 1100 get_device(&ubi->dev);
1102 1101
@@ -1116,13 +1115,50 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway)
1116} 1115}
1117 1116
1118/** 1117/**
1119 * find_mtd_device - open an MTD device by its name or number. 1118 * open_mtd_by_chdev - open an MTD device by its character device node path.
1120 * @mtd_dev: name or number of the device 1119 * @mtd_dev: MTD character device node path
1120 *
1121 * This helper function opens an MTD device by its character node device path.
1122 * Returns MTD device description object in case of success and a negative
1123 * error code in case of failure.
1124 */
1125static struct mtd_info * __init open_mtd_by_chdev(const char *mtd_dev)
1126{
1127 int err, major, minor, mode;
1128 struct path path;
1129
1130 /* Probably this is an MTD character device node path */
1131 err = kern_path(mtd_dev, LOOKUP_FOLLOW, &path);
1132 if (err)
1133 return ERR_PTR(err);
1134
1135 /* MTD device number is defined by the major / minor numbers */
1136 major = imajor(path.dentry->d_inode);
1137 minor = iminor(path.dentry->d_inode);
1138 mode = path.dentry->d_inode->i_mode;
1139 path_put(&path);
1140 if (major != MTD_CHAR_MAJOR || !S_ISCHR(mode))
1141 return ERR_PTR(-EINVAL);
1142
1143 if (minor & 1)
1144 /*
1145 * Just do not think the "/dev/mtdrX" devices support is need,
1146 * so do not support them to avoid doing extra work.
1147 */
1148 return ERR_PTR(-EINVAL);
1149
1150 return get_mtd_device(NULL, minor / 2);
1151}
1152
1153/**
1154 * open_mtd_device - open MTD device by name, character device path, or number.
1155 * @mtd_dev: name, character device node path, or MTD device device number
1121 * 1156 *
1122 * This function tries to open and MTD device described by @mtd_dev string, 1157 * This function tries to open and MTD device described by @mtd_dev string,
1123 * which is first treated as an ASCII number, and if it is not true, it is 1158 * which is first treated as ASCII MTD device number, and if it is not true, it
1124 * treated as MTD device name. Returns MTD device description object in case of 1159 * is treated as MTD device name, and if that is also not true, it is treated
1125 * success and a negative error code in case of failure. 1160 * as MTD character device node path. Returns MTD device description object in
1161 * case of success and a negative error code in case of failure.
1126 */ 1162 */
1127static struct mtd_info * __init open_mtd_device(const char *mtd_dev) 1163static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
1128{ 1164{
@@ -1137,6 +1173,9 @@ static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
1137 * MTD device name. 1173 * MTD device name.
1138 */ 1174 */
1139 mtd = get_mtd_device_nm(mtd_dev); 1175 mtd = get_mtd_device_nm(mtd_dev);
1176 if (IS_ERR(mtd) && PTR_ERR(mtd) == -ENODEV)
1177 /* Probably this is an MTD character device node path */
1178 mtd = open_mtd_by_chdev(mtd_dev);
1140 } else 1179 } else
1141 mtd = get_mtd_device(NULL, mtd_num); 1180 mtd = get_mtd_device(NULL, mtd_num);
1142 1181
@@ -1352,13 +1391,15 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp)
1352 1391
1353module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); 1392module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000);
1354MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: " 1393MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: "
1355 "mtd=<name|num>[,<vid_hdr_offs>].\n" 1394 "mtd=<name|num|path>[,<vid_hdr_offs>].\n"
1356 "Multiple \"mtd\" parameters may be specified.\n" 1395 "Multiple \"mtd\" parameters may be specified.\n"
1357 "MTD devices may be specified by their number or name.\n" 1396 "MTD devices may be specified by their number, name, or "
1397 "path to the MTD character device node.\n"
1358 "Optional \"vid_hdr_offs\" parameter specifies UBI VID " 1398 "Optional \"vid_hdr_offs\" parameter specifies UBI VID "
1359 "header position and data starting position to be used " 1399 "header position to be used by UBI.\n"
1360 "by UBI.\n" 1400 "Example 1: mtd=/dev/mtd0 - attach MTD device "
1361 "Example: mtd=content,1984 mtd=4 - attach MTD device" 1401 "/dev/mtd0.\n"
1402 "Example 2: mtd=content,1984 mtd=4 - attach MTD device "
1362 "with name \"content\" using VID header offset 1984, and " 1403 "with name \"content\" using VID header offset 1984, and "
1363 "MTD device number 4 with default VID header offset."); 1404 "MTD device number 4 with default VID header offset.");
1364 1405
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index f30bcb372c05..17a107129726 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -96,8 +96,11 @@ void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
96 96
97#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID 97#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
98int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); 98int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len);
99int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
100 int offset, int len);
99#else 101#else
100#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 102#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
103#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
101#endif 104#endif
102 105
103#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT 106#ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT
@@ -176,6 +179,7 @@ static inline int ubi_dbg_is_erase_failure(void)
176#define ubi_dbg_is_write_failure() 0 179#define ubi_dbg_is_write_failure() 0
177#define ubi_dbg_is_erase_failure() 0 180#define ubi_dbg_is_erase_failure() 0
178#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 181#define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0
182#define ubi_dbg_check_write(ubi, buf, pnum, offset, len) 0
179 183
180#endif /* !CONFIG_MTD_UBI_DEBUG */ 184#endif /* !CONFIG_MTD_UBI_DEBUG */
181#endif /* !__UBI_DEBUG_H__ */ 185#endif /* !__UBI_DEBUG_H__ */
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 8aa51e7a6a7d..b4ecc84c7549 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -143,7 +143,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
143 143
144 err = paranoid_check_not_bad(ubi, pnum); 144 err = paranoid_check_not_bad(ubi, pnum);
145 if (err) 145 if (err)
146 return err > 0 ? -EINVAL : err; 146 return err;
147 147
148 addr = (loff_t)pnum * ubi->peb_size + offset; 148 addr = (loff_t)pnum * ubi->peb_size + offset;
149retry: 149retry:
@@ -236,12 +236,12 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
236 236
237 err = paranoid_check_not_bad(ubi, pnum); 237 err = paranoid_check_not_bad(ubi, pnum);
238 if (err) 238 if (err)
239 return err > 0 ? -EINVAL : err; 239 return err;
240 240
241 /* The area we are writing to has to contain all 0xFF bytes */ 241 /* The area we are writing to has to contain all 0xFF bytes */
242 err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); 242 err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
243 if (err) 243 if (err)
244 return err > 0 ? -EINVAL : err; 244 return err;
245 245
246 if (offset >= ubi->leb_start) { 246 if (offset >= ubi->leb_start) {
247 /* 247 /*
@@ -250,10 +250,10 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
250 */ 250 */
251 err = paranoid_check_peb_ec_hdr(ubi, pnum); 251 err = paranoid_check_peb_ec_hdr(ubi, pnum);
252 if (err) 252 if (err)
253 return err > 0 ? -EINVAL : err; 253 return err;
254 err = paranoid_check_peb_vid_hdr(ubi, pnum); 254 err = paranoid_check_peb_vid_hdr(ubi, pnum);
255 if (err) 255 if (err)
256 return err > 0 ? -EINVAL : err; 256 return err;
257 } 257 }
258 258
259 if (ubi_dbg_is_write_failure()) { 259 if (ubi_dbg_is_write_failure()) {
@@ -273,6 +273,21 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
273 } else 273 } else
274 ubi_assert(written == len); 274 ubi_assert(written == len);
275 275
276 if (!err) {
277 err = ubi_dbg_check_write(ubi, buf, pnum, offset, len);
278 if (err)
279 return err;
280
281 /*
282 * Since we always write sequentially, the rest of the PEB has
283 * to contain only 0xFF bytes.
284 */
285 offset += len;
286 len = ubi->peb_size - offset;
287 if (len)
288 err = ubi_dbg_check_all_ff(ubi, pnum, offset, len);
289 }
290
276 return err; 291 return err;
277} 292}
278 293
@@ -348,7 +363,7 @@ retry:
348 363
349 err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); 364 err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size);
350 if (err) 365 if (err)
351 return err > 0 ? -EINVAL : err; 366 return err;
352 367
353 if (ubi_dbg_is_erase_failure() && !err) { 368 if (ubi_dbg_is_erase_failure() && !err) {
354 dbg_err("cannot erase PEB %d (emulated)", pnum); 369 dbg_err("cannot erase PEB %d (emulated)", pnum);
@@ -542,7 +557,7 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture)
542 557
543 err = paranoid_check_not_bad(ubi, pnum); 558 err = paranoid_check_not_bad(ubi, pnum);
544 if (err != 0) 559 if (err != 0)
545 return err > 0 ? -EINVAL : err; 560 return err;
546 561
547 if (ubi->ro_mode) { 562 if (ubi->ro_mode) {
548 ubi_err("read-only mode"); 563 ubi_err("read-only mode");
@@ -819,7 +834,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
819 834
820 err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); 835 err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr);
821 if (err) 836 if (err)
822 return -EINVAL; 837 return err;
823 838
824 err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize); 839 err = ubi_io_write(ubi, ec_hdr, pnum, 0, ubi->ec_hdr_alsize);
825 return err; 840 return err;
@@ -1083,7 +1098,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
1083 1098
1084 err = paranoid_check_peb_ec_hdr(ubi, pnum); 1099 err = paranoid_check_peb_ec_hdr(ubi, pnum);
1085 if (err) 1100 if (err)
1086 return err > 0 ? -EINVAL : err; 1101 return err;
1087 1102
1088 vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); 1103 vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC);
1089 vid_hdr->version = UBI_VERSION; 1104 vid_hdr->version = UBI_VERSION;
@@ -1092,7 +1107,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
1092 1107
1093 err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); 1108 err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr);
1094 if (err) 1109 if (err)
1095 return -EINVAL; 1110 return err;
1096 1111
1097 p = (char *)vid_hdr - ubi->vid_hdr_shift; 1112 p = (char *)vid_hdr - ubi->vid_hdr_shift;
1098 err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset, 1113 err = ubi_io_write(ubi, p, pnum, ubi->vid_hdr_aloffset,
@@ -1107,8 +1122,8 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
1107 * @ubi: UBI device description object 1122 * @ubi: UBI device description object
1108 * @pnum: physical eraseblock number to check 1123 * @pnum: physical eraseblock number to check
1109 * 1124 *
1110 * This function returns zero if the physical eraseblock is good, a positive 1125 * This function returns zero if the physical eraseblock is good, %-EINVAL if
1111 * number if it is bad and a negative error code if an error occurred. 1126 * it is bad and a negative error code if an error occurred.
1112 */ 1127 */
1113static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) 1128static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
1114{ 1129{
@@ -1120,7 +1135,7 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
1120 1135
1121 ubi_err("paranoid check failed for PEB %d", pnum); 1136 ubi_err("paranoid check failed for PEB %d", pnum);
1122 ubi_dbg_dump_stack(); 1137 ubi_dbg_dump_stack();
1123 return err; 1138 return err > 0 ? -EINVAL : err;
1124} 1139}
1125 1140
1126/** 1141/**
@@ -1130,7 +1145,7 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum)
1130 * @ec_hdr: the erase counter header to check 1145 * @ec_hdr: the erase counter header to check
1131 * 1146 *
1132 * This function returns zero if the erase counter header contains valid 1147 * This function returns zero if the erase counter header contains valid
1133 * values, and %1 if not. 1148 * values, and %-EINVAL if not.
1134 */ 1149 */
1135static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, 1150static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
1136 const struct ubi_ec_hdr *ec_hdr) 1151 const struct ubi_ec_hdr *ec_hdr)
@@ -1156,7 +1171,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
1156fail: 1171fail:
1157 ubi_dbg_dump_ec_hdr(ec_hdr); 1172 ubi_dbg_dump_ec_hdr(ec_hdr);
1158 ubi_dbg_dump_stack(); 1173 ubi_dbg_dump_stack();
1159 return 1; 1174 return -EINVAL;
1160} 1175}
1161 1176
1162/** 1177/**
@@ -1164,8 +1179,8 @@ fail:
1164 * @ubi: UBI device description object 1179 * @ubi: UBI device description object
1165 * @pnum: the physical eraseblock number to check 1180 * @pnum: the physical eraseblock number to check
1166 * 1181 *
1167 * This function returns zero if the erase counter header is all right, %1 if 1182 * This function returns zero if the erase counter header is all right and and
1168 * not, and a negative error code if an error occurred. 1183 * a negative error code if not or if an error occurred.
1169 */ 1184 */
1170static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) 1185static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
1171{ 1186{
@@ -1188,7 +1203,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum)
1188 ubi_err("paranoid check failed for PEB %d", pnum); 1203 ubi_err("paranoid check failed for PEB %d", pnum);
1189 ubi_dbg_dump_ec_hdr(ec_hdr); 1204 ubi_dbg_dump_ec_hdr(ec_hdr);
1190 ubi_dbg_dump_stack(); 1205 ubi_dbg_dump_stack();
1191 err = 1; 1206 err = -EINVAL;
1192 goto exit; 1207 goto exit;
1193 } 1208 }
1194 1209
@@ -1206,7 +1221,7 @@ exit:
1206 * @vid_hdr: the volume identifier header to check 1221 * @vid_hdr: the volume identifier header to check
1207 * 1222 *
1208 * This function returns zero if the volume identifier header is all right, and 1223 * This function returns zero if the volume identifier header is all right, and
1209 * %1 if not. 1224 * %-EINVAL if not.
1210 */ 1225 */
1211static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, 1226static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
1212 const struct ubi_vid_hdr *vid_hdr) 1227 const struct ubi_vid_hdr *vid_hdr)
@@ -1233,7 +1248,7 @@ fail:
1233 ubi_err("paranoid check failed for PEB %d", pnum); 1248 ubi_err("paranoid check failed for PEB %d", pnum);
1234 ubi_dbg_dump_vid_hdr(vid_hdr); 1249 ubi_dbg_dump_vid_hdr(vid_hdr);
1235 ubi_dbg_dump_stack(); 1250 ubi_dbg_dump_stack();
1236 return 1; 1251 return -EINVAL;
1237 1252
1238} 1253}
1239 1254
@@ -1243,7 +1258,7 @@ fail:
1243 * @pnum: the physical eraseblock number to check 1258 * @pnum: the physical eraseblock number to check
1244 * 1259 *
1245 * This function returns zero if the volume identifier header is all right, 1260 * This function returns zero if the volume identifier header is all right,
1246 * %1 if not, and a negative error code if an error occurred. 1261 * and a negative error code if not or if an error occurred.
1247 */ 1262 */
1248static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) 1263static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
1249{ 1264{
@@ -1270,7 +1285,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum)
1270 ubi_err("paranoid check failed for PEB %d", pnum); 1285 ubi_err("paranoid check failed for PEB %d", pnum);
1271 ubi_dbg_dump_vid_hdr(vid_hdr); 1286 ubi_dbg_dump_vid_hdr(vid_hdr);
1272 ubi_dbg_dump_stack(); 1287 ubi_dbg_dump_stack();
1273 err = 1; 1288 err = -EINVAL;
1274 goto exit; 1289 goto exit;
1275 } 1290 }
1276 1291
@@ -1282,6 +1297,61 @@ exit:
1282} 1297}
1283 1298
1284/** 1299/**
1300 * ubi_dbg_check_write - make sure write succeeded.
1301 * @ubi: UBI device description object
1302 * @buf: buffer with data which were written
1303 * @pnum: physical eraseblock number the data were written to
1304 * @offset: offset within the physical eraseblock the data were written to
1305 * @len: how many bytes were written
1306 *
1307 * This functions reads data which were recently written and compares it with
1308 * the original data buffer - the data have to match. Returns zero if the data
1309 * match and a negative error code if not or in case of failure.
1310 */
1311int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum,
1312 int offset, int len)
1313{
1314 int err, i;
1315
1316 mutex_lock(&ubi->dbg_buf_mutex);
1317 err = ubi_io_read(ubi, ubi->dbg_peb_buf, pnum, offset, len);
1318 if (err)
1319 goto out_unlock;
1320
1321 for (i = 0; i < len; i++) {
1322 uint8_t c = ((uint8_t *)buf)[i];
1323 uint8_t c1 = ((uint8_t *)ubi->dbg_peb_buf)[i];
1324 int dump_len;
1325
1326 if (c == c1)
1327 continue;
1328
1329 ubi_err("paranoid check failed for PEB %d:%d, len %d",
1330 pnum, offset, len);
1331 ubi_msg("data differ at position %d", i);
1332 dump_len = max_t(int, 128, len - i);
1333 ubi_msg("hex dump of the original buffer from %d to %d",
1334 i, i + dump_len);
1335 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
1336 buf + i, dump_len, 1);
1337 ubi_msg("hex dump of the read buffer from %d to %d",
1338 i, i + dump_len);
1339 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
1340 ubi->dbg_peb_buf + i, dump_len, 1);
1341 ubi_dbg_dump_stack();
1342 err = -EINVAL;
1343 goto out_unlock;
1344 }
1345 mutex_unlock(&ubi->dbg_buf_mutex);
1346
1347 return 0;
1348
1349out_unlock:
1350 mutex_unlock(&ubi->dbg_buf_mutex);
1351 return err;
1352}
1353
1354/**
1285 * ubi_dbg_check_all_ff - check that a region of flash is empty. 1355 * ubi_dbg_check_all_ff - check that a region of flash is empty.
1286 * @ubi: UBI device description object 1356 * @ubi: UBI device description object
1287 * @pnum: the physical eraseblock number to check 1357 * @pnum: the physical eraseblock number to check
@@ -1289,8 +1359,8 @@ exit:
1289 * @len: the length of the region to check 1359 * @len: the length of the region to check
1290 * 1360 *
1291 * This function returns zero if only 0xFF bytes are present at offset 1361 * This function returns zero if only 0xFF bytes are present at offset
1292 * @offset of the physical eraseblock @pnum, %1 if not, and a negative error 1362 * @offset of the physical eraseblock @pnum, and a negative error code if not
1293 * code if an error occurred. 1363 * or if an error occurred.
1294 */ 1364 */
1295int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) 1365int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len)
1296{ 1366{
@@ -1321,7 +1391,7 @@ fail:
1321 ubi_msg("hex dump of the %d-%d region", offset, offset + len); 1391 ubi_msg("hex dump of the %d-%d region", offset, offset + len);
1322 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, 1392 print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
1323 ubi->dbg_peb_buf, len, 1); 1393 ubi->dbg_peb_buf, len, 1);
1324 err = 1; 1394 err = -EINVAL;
1325error: 1395error:
1326 ubi_dbg_dump_stack(); 1396 ubi_dbg_dump_stack();
1327 mutex_unlock(&ubi->dbg_buf_mutex); 1397 mutex_unlock(&ubi->dbg_buf_mutex);
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 90af61a2c3e4..594184bbd56a 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -974,11 +974,8 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
974 seb->ec = si->mean_ec; 974 seb->ec = si->mean_ec;
975 975
976 err = paranoid_check_si(ubi, si); 976 err = paranoid_check_si(ubi, si);
977 if (err) { 977 if (err)
978 if (err > 0)
979 err = -EINVAL;
980 goto out_vidh; 978 goto out_vidh;
981 }
982 979
983 ubi_free_vid_hdr(ubi, vidh); 980 ubi_free_vid_hdr(ubi, vidh);
984 kfree(ech); 981 kfree(ech);
@@ -1086,8 +1083,8 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
1086 * @ubi: UBI device description object 1083 * @ubi: UBI device description object
1087 * @si: scanning information 1084 * @si: scanning information
1088 * 1085 *
1089 * This function returns zero if the scanning information is all right, %1 if 1086 * This function returns zero if the scanning information is all right, and a
1090 * not and a negative error code if an error occurred. 1087 * negative error code if not or if an error occurred.
1091 */ 1088 */
1092static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si) 1089static int paranoid_check_si(struct ubi_device *ubi, struct ubi_scan_info *si)
1093{ 1090{
@@ -1346,7 +1343,7 @@ bad_vid_hdr:
1346 1343
1347out: 1344out:
1348 ubi_dbg_dump_stack(); 1345 ubi_dbg_dump_stack();
1349 return 1; 1346 return -EINVAL;
1350} 1347}
1351 1348
1352#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ 1349#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 600c7229d5cf..f64ddabd4ac8 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -464,7 +464,7 @@ retry:
464 ubi->peb_size - ubi->vid_hdr_aloffset); 464 ubi->peb_size - ubi->vid_hdr_aloffset);
465 if (err) { 465 if (err) {
466 ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); 466 ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum);
467 return err > 0 ? -EINVAL : err; 467 return err;
468 } 468 }
469 469
470 return e->pnum; 470 return e->pnum;
@@ -513,7 +513,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
513 dbg_wl("erase PEB %d, old EC %llu", e->pnum, ec); 513 dbg_wl("erase PEB %d, old EC %llu", e->pnum, ec);
514 514
515 err = paranoid_check_ec(ubi, e->pnum, e->ec); 515 err = paranoid_check_ec(ubi, e->pnum, e->ec);
516 if (err > 0) 516 if (err)
517 return -EINVAL; 517 return -EINVAL;
518 518
519 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); 519 ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS);
@@ -1572,8 +1572,7 @@ void ubi_wl_close(struct ubi_device *ubi)
1572 * @ec: the erase counter to check 1572 * @ec: the erase counter to check
1573 * 1573 *
1574 * This function returns zero if the erase counter of physical eraseblock @pnum 1574 * This function returns zero if the erase counter of physical eraseblock @pnum
1575 * is equivalent to @ec, %1 if not, and a negative error code if an error 1575 * is equivalent to @ec, and a negative error code if not or if an error occurred.
1576 * occurred.
1577 */ 1576 */
1578static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec) 1577static int paranoid_check_ec(struct ubi_device *ubi, int pnum, int ec)
1579{ 1578{
@@ -1611,8 +1610,8 @@ out_free:
1611 * @e: the wear-leveling entry to check 1610 * @e: the wear-leveling entry to check
1612 * @root: the root of the tree 1611 * @root: the root of the tree
1613 * 1612 *
1614 * This function returns zero if @e is in the @root RB-tree and %1 if it is 1613 * This function returns zero if @e is in the @root RB-tree and %-EINVAL if it
1615 * not. 1614 * is not.
1616 */ 1615 */
1617static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e, 1616static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
1618 struct rb_root *root) 1617 struct rb_root *root)
@@ -1623,7 +1622,7 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
1623 ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ", 1622 ubi_err("paranoid check failed for PEB %d, EC %d, RB-tree %p ",
1624 e->pnum, e->ec, root); 1623 e->pnum, e->ec, root);
1625 ubi_dbg_dump_stack(); 1624 ubi_dbg_dump_stack();
1626 return 1; 1625 return -EINVAL;
1627} 1626}
1628 1627
1629/** 1628/**
@@ -1632,7 +1631,7 @@ static int paranoid_check_in_wl_tree(struct ubi_wl_entry *e,
1632 * @ubi: UBI device description object 1631 * @ubi: UBI device description object
1633 * @e: the wear-leveling entry to check 1632 * @e: the wear-leveling entry to check
1634 * 1633 *
1635 * This function returns zero if @e is in @ubi->pq and %1 if it is not. 1634 * This function returns zero if @e is in @ubi->pq and %-EINVAL if it is not.
1636 */ 1635 */
1637static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e) 1636static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e)
1638{ 1637{
@@ -1647,6 +1646,6 @@ static int paranoid_check_in_pq(struct ubi_device *ubi, struct ubi_wl_entry *e)
1647 ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue", 1646 ubi_err("paranoid check failed for PEB %d, EC %d, Protect queue",
1648 e->pnum, e->ec); 1647 e->pnum, e->ec);
1649 ubi_dbg_dump_stack(); 1648 ubi_dbg_dump_stack();
1650 return 1; 1649 return -EINVAL;
1651} 1650}
1652#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ 1651#endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6aa526ee9096..61a7b4351e78 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -998,7 +998,7 @@ static int gfar_probe(struct of_device *ofdev,
998 } 998 }
999 999
1000 /* Need to reverse the bit maps as bit_map's MSB is q0 1000 /* Need to reverse the bit maps as bit_map's MSB is q0
1001 * but, for_each_bit parses from right to left, which 1001 * but, for_each_set_bit parses from right to left, which
1002 * basically reverses the queue numbers */ 1002 * basically reverses the queue numbers */
1003 for (i = 0; i< priv->num_grps; i++) { 1003 for (i = 0; i< priv->num_grps; i++) {
1004 priv->gfargrp[i].tx_bit_map = reverse_bitmap( 1004 priv->gfargrp[i].tx_bit_map = reverse_bitmap(
@@ -1011,7 +1011,7 @@ static int gfar_probe(struct of_device *ofdev,
1011 * also assign queues to groups */ 1011 * also assign queues to groups */
1012 for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) { 1012 for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
1013 priv->gfargrp[grp_idx].num_rx_queues = 0x0; 1013 priv->gfargrp[grp_idx].num_rx_queues = 0x0;
1014 for_each_bit(i, &priv->gfargrp[grp_idx].rx_bit_map, 1014 for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
1015 priv->num_rx_queues) { 1015 priv->num_rx_queues) {
1016 priv->gfargrp[grp_idx].num_rx_queues++; 1016 priv->gfargrp[grp_idx].num_rx_queues++;
1017 priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx]; 1017 priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
@@ -1019,7 +1019,7 @@ static int gfar_probe(struct of_device *ofdev,
1019 rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i); 1019 rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
1020 } 1020 }
1021 priv->gfargrp[grp_idx].num_tx_queues = 0x0; 1021 priv->gfargrp[grp_idx].num_tx_queues = 0x0;
1022 for_each_bit (i, &priv->gfargrp[grp_idx].tx_bit_map, 1022 for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map,
1023 priv->num_tx_queues) { 1023 priv->num_tx_queues) {
1024 priv->gfargrp[grp_idx].num_tx_queues++; 1024 priv->gfargrp[grp_idx].num_tx_queues++;
1025 priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx]; 1025 priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
@@ -1709,7 +1709,7 @@ void gfar_configure_coalescing(struct gfar_private *priv,
1709 1709
1710 if (priv->mode == MQ_MG_MODE) { 1710 if (priv->mode == MQ_MG_MODE) {
1711 baddr = &regs->txic0; 1711 baddr = &regs->txic0;
1712 for_each_bit (i, &tx_mask, priv->num_tx_queues) { 1712 for_each_set_bit(i, &tx_mask, priv->num_tx_queues) {
1713 if (likely(priv->tx_queue[i]->txcoalescing)) { 1713 if (likely(priv->tx_queue[i]->txcoalescing)) {
1714 gfar_write(baddr + i, 0); 1714 gfar_write(baddr + i, 0);
1715 gfar_write(baddr + i, priv->tx_queue[i]->txic); 1715 gfar_write(baddr + i, priv->tx_queue[i]->txic);
@@ -1717,7 +1717,7 @@ void gfar_configure_coalescing(struct gfar_private *priv,
1717 } 1717 }
1718 1718
1719 baddr = &regs->rxic0; 1719 baddr = &regs->rxic0;
1720 for_each_bit (i, &rx_mask, priv->num_rx_queues) { 1720 for_each_set_bit(i, &rx_mask, priv->num_rx_queues) {
1721 if (likely(priv->rx_queue[i]->rxcoalescing)) { 1721 if (likely(priv->rx_queue[i]->rxcoalescing)) {
1722 gfar_write(baddr + i, 0); 1722 gfar_write(baddr + i, 0);
1723 gfar_write(baddr + i, priv->rx_queue[i]->rxic); 1723 gfar_write(baddr + i, priv->rx_queue[i]->rxic);
@@ -2607,7 +2607,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
2607 budget_per_queue = left_over_budget/num_queues; 2607 budget_per_queue = left_over_budget/num_queues;
2608 left_over_budget = 0; 2608 left_over_budget = 0;
2609 2609
2610 for_each_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { 2610 for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
2611 if (test_bit(i, &serviced_queues)) 2611 if (test_bit(i, &serviced_queues))
2612 continue; 2612 continue;
2613 rx_queue = priv->rx_queue[i]; 2613 rx_queue = priv->rx_queue[i];
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 45e3532b166f..684af371462d 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1050,7 +1050,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
1050 */ 1050 */
1051 for (v_idx = 0; v_idx < q_vectors; v_idx++) { 1051 for (v_idx = 0; v_idx < q_vectors; v_idx++) {
1052 q_vector = adapter->q_vector[v_idx]; 1052 q_vector = adapter->q_vector[v_idx];
1053 /* XXX for_each_bit(...) */ 1053 /* XXX for_each_set_bit(...) */
1054 r_idx = find_first_bit(q_vector->rxr_idx, 1054 r_idx = find_first_bit(q_vector->rxr_idx,
1055 adapter->num_rx_queues); 1055 adapter->num_rx_queues);
1056 1056
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 235b5fd4b8d4..ca653c49b765 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -751,7 +751,7 @@ static void ixgbevf_configure_msix(struct ixgbevf_adapter *adapter)
751 */ 751 */
752 for (v_idx = 0; v_idx < q_vectors; v_idx++) { 752 for (v_idx = 0; v_idx < q_vectors; v_idx++) {
753 q_vector = adapter->q_vector[v_idx]; 753 q_vector = adapter->q_vector[v_idx];
754 /* XXX for_each_bit(...) */ 754 /* XXX for_each_set_bit(...) */
755 r_idx = find_first_bit(q_vector->rxr_idx, 755 r_idx = find_first_bit(q_vector->rxr_idx,
756 adapter->num_rx_queues); 756 adapter->num_rx_queues);
757 757
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 8a964f130367..a6452af9c6c5 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -394,7 +394,7 @@ static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar)
394 ieee80211_tx_status_irqsafe(ar->hw, skb); 394 ieee80211_tx_status_irqsafe(ar->hw, skb);
395 } 395 }
396 396
397 for_each_bit(i, &queue_bitmap, BITS_PER_BYTE) { 397 for_each_set_bit(i, &queue_bitmap, BITS_PER_BYTE) {
398#ifdef AR9170_QUEUE_STOP_DEBUG 398#ifdef AR9170_QUEUE_STOP_DEBUG
399 printk(KERN_DEBUG "%s: wake queue %d\n", 399 printk(KERN_DEBUG "%s: wake queue %d\n",
400 wiphy_name(ar->hw->wiphy), i); 400 wiphy_name(ar->hw->wiphy), i);
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index be992ca41cf1..c29c994de0e2 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -89,7 +89,7 @@ static int iwm_debugfs_dbg_modules_write(void *data, u64 val)
89 for (i = 0; i < __IWM_DM_NR; i++) 89 for (i = 0; i < __IWM_DM_NR; i++)
90 iwm->dbg.dbg_module[i] = 0; 90 iwm->dbg.dbg_module[i] = 0;
91 91
92 for_each_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR) 92 for_each_set_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR)
93 iwm->dbg.dbg_module[bit] = iwm->dbg.dbg_level; 93 iwm->dbg.dbg_module[bit] = iwm->dbg.dbg_level;
94 94
95 return 0; 95 return 0;
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index ad8f7eabb5aa..8456b4dbd146 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1116,7 +1116,7 @@ static int iwm_ntf_stop_resume_tx(struct iwm_priv *iwm, u8 *buf,
1116 return -EINVAL; 1116 return -EINVAL;
1117 } 1117 }
1118 1118
1119 for_each_bit(bit, (unsigned long *)&tid_msk, IWM_UMAC_TID_NR) { 1119 for_each_set_bit(bit, (unsigned long *)&tid_msk, IWM_UMAC_TID_NR) {
1120 tid_info = &sta_info->tid_info[bit]; 1120 tid_info = &sta_info->tid_info[bit];
1121 1121
1122 mutex_lock(&tid_info->mutex); 1122 mutex_lock(&tid_info->mutex);
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index 0be1d50645ab..caa153133754 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -460,7 +460,7 @@ static int init_slot(int slot, struct eeprom_eisa_slot_info *es)
460 slot, id_string); 460 slot, id_string);
461 461
462 print_eisa_id(id_string, es->eisa_slot_id); 462 print_eisa_id(id_string, es->eisa_slot_id);
463 printk(" expected %s \n", id_string); 463 printk(" expected %s\n", id_string);
464 464
465 return -1; 465 return -1;
466 466
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index a35c9c5b89e8..f7806d81f1e0 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -169,7 +169,7 @@ superio_init(struct pci_dev *pcidev)
169 /* ...then properly fixup the USB to point at suckyio PIC */ 169 /* ...then properly fixup the USB to point at suckyio PIC */
170 sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); 170 sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
171 171
172 printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", 172 printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i)\n",
173 pci_name(pdev), pdev->irq); 173 pci_name(pdev), pdev->irq);
174 174
175 pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); 175 pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5b548aee9cbc..77b493b3d97b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -303,6 +303,49 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
303} 303}
304EXPORT_SYMBOL_GPL(pci_find_ext_capability); 304EXPORT_SYMBOL_GPL(pci_find_ext_capability);
305 305
306/**
307 * pci_bus_find_ext_capability - find an extended capability
308 * @bus: the PCI bus to query
309 * @devfn: PCI device to query
310 * @cap: capability code
311 *
312 * Like pci_find_ext_capability() but works for pci devices that do not have a
313 * pci_dev structure set up yet.
314 *
315 * Returns the address of the requested capability structure within the
316 * device's PCI configuration space or 0 in case the device does not
317 * support it.
318 */
319int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
320 int cap)
321{
322 u32 header;
323 int ttl;
324 int pos = PCI_CFG_SPACE_SIZE;
325
326 /* minimum 8 bytes per capability */
327 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
328
329 if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
330 return 0;
331 if (header == 0xffffffff || header == 0)
332 return 0;
333
334 while (ttl-- > 0) {
335 if (PCI_EXT_CAP_ID(header) == cap)
336 return pos;
337
338 pos = PCI_EXT_CAP_NEXT(header);
339 if (pos < PCI_CFG_SPACE_SIZE)
340 break;
341
342 if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
343 break;
344 }
345
346 return 0;
347}
348
306static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) 349static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
307{ 350{
308 int rc, ttl = PCI_FIND_CAP_TTL; 351 int rc, ttl = PCI_FIND_CAP_TTL;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 039e87b71442..81d19d5683ac 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2533,6 +2533,91 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov);
2533 2533
2534#endif /* CONFIG_PCI_IOV */ 2534#endif /* CONFIG_PCI_IOV */
2535 2535
2536/*
2537 * This is a quirk for the Ricoh MMC controller found as a part of
2538 * some mulifunction chips.
2539
2540 * This is very similiar and based on the ricoh_mmc driver written by
2541 * Philip Langdale. Thank you for these magic sequences.
2542 *
2543 * These chips implement the four main memory card controllers (SD, MMC, MS, xD)
2544 * and one or both of cardbus or firewire.
2545 *
2546 * It happens that they implement SD and MMC
2547 * support as separate controllers (and PCI functions). The linux SDHCI
2548 * driver supports MMC cards but the chip detects MMC cards in hardware
2549 * and directs them to the MMC controller - so the SDHCI driver never sees
2550 * them.
2551 *
2552 * To get around this, we must disable the useless MMC controller.
2553 * At that point, the SDHCI controller will start seeing them
2554 * It seems to be the case that the relevant PCI registers to deactivate the
2555 * MMC controller live on PCI function 0, which might be the cardbus controller
2556 * or the firewire controller, depending on the particular chip in question
2557 *
2558 * This has to be done early, because as soon as we disable the MMC controller
2559 * other pci functions shift up one level, e.g. function #2 becomes function
2560 * #1, and this will confuse the pci core.
2561 */
2562
2563#ifdef CONFIG_MMC_RICOH_MMC
2564static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev)
2565{
2566 /* disable via cardbus interface */
2567 u8 write_enable;
2568 u8 write_target;
2569 u8 disable;
2570
2571 /* disable must be done via function #0 */
2572 if (PCI_FUNC(dev->devfn))
2573 return;
2574
2575 pci_read_config_byte(dev, 0xB7, &disable);
2576 if (disable & 0x02)
2577 return;
2578
2579 pci_read_config_byte(dev, 0x8E, &write_enable);
2580 pci_write_config_byte(dev, 0x8E, 0xAA);
2581 pci_read_config_byte(dev, 0x8D, &write_target);
2582 pci_write_config_byte(dev, 0x8D, 0xB7);
2583 pci_write_config_byte(dev, 0xB7, disable | 0x02);
2584 pci_write_config_byte(dev, 0x8E, write_enable);
2585 pci_write_config_byte(dev, 0x8D, write_target);
2586
2587 dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n");
2588 dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
2589}
2590DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
2591DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
2592
2593static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
2594{
2595 /* disable via firewire interface */
2596 u8 write_enable;
2597 u8 disable;
2598
2599 /* disable must be done via function #0 */
2600 if (PCI_FUNC(dev->devfn))
2601 return;
2602
2603 pci_read_config_byte(dev, 0xCB, &disable);
2604
2605 if (disable & 0x02)
2606 return;
2607
2608 pci_read_config_byte(dev, 0xCA, &write_enable);
2609 pci_write_config_byte(dev, 0xCA, 0x57);
2610 pci_write_config_byte(dev, 0xCB, disable | 0x02);
2611 pci_write_config_byte(dev, 0xCA, write_enable);
2612
2613 dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
2614 dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
2615}
2616DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
2617DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
2618#endif /*CONFIG_MMC_RICOH_MMC*/
2619
2620
2536static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, 2621static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
2537 struct pci_fixup *end) 2622 struct pci_fixup *end)
2538{ 2623{
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index bf1467213954..faaa9b4d0d07 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -29,6 +29,13 @@ config APM_POWER
29 Say Y here to enable support APM status emulation using 29 Say Y here to enable support APM status emulation using
30 battery class devices. 30 battery class devices.
31 31
32config MAX8925_POWER
33 tristate "MAX8925 battery charger support"
34 depends on MFD_MAX8925
35 help
36 Say Y here to enable support for the battery charger in the Maxim
37 MAX8925 PMIC.
38
32config WM831X_BACKUP 39config WM831X_BACKUP
33 tristate "WM831X backup battery charger support" 40 tristate "WM831X backup battery charger support"
34 depends on MFD_WM831X 41 depends on MFD_WM831X
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 573597c683b4..a2ba7c85c97a 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
16 16
17obj-$(CONFIG_PDA_POWER) += pda_power.o 17obj-$(CONFIG_PDA_POWER) += pda_power.o
18obj-$(CONFIG_APM_POWER) += apm_power.o 18obj-$(CONFIG_APM_POWER) += apm_power.o
19obj-$(CONFIG_MAX8925_POWER) += max8925_power.o
19obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o 20obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o
20obj-$(CONFIG_WM831X_POWER) += wm831x_power.o 21obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
21obj-$(CONFIG_WM8350_POWER) += wm8350_power.o 22obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c
new file mode 100644
index 000000000000..a1b4410544d7
--- /dev/null
+++ b/drivers/power/max8925_power.c
@@ -0,0 +1,534 @@
1/*
2 * Battery driver for Maxim MAX8925
3 *
4 * Copyright (c) 2009-2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/err.h>
14#include <linux/i2c.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/power_supply.h>
18#include <linux/mfd/max8925.h>
19
20/* registers in GPM */
21#define MAX8925_OUT5VEN 0x54
22#define MAX8925_OUT3VEN 0x58
23#define MAX8925_CHG_CNTL1 0x7c
24
25/* bits definition */
26#define MAX8925_CHG_STAT_VSYSLOW (1 << 0)
27#define MAX8925_CHG_STAT_MODE_MASK (3 << 2)
28#define MAX8925_CHG_STAT_EN_MASK (1 << 4)
29#define MAX8925_CHG_MBDET (1 << 1)
30#define MAX8925_CHG_AC_RANGE_MASK (3 << 6)
31
32/* registers in ADC */
33#define MAX8925_ADC_RES_CNFG1 0x06
34#define MAX8925_ADC_AVG_CNFG1 0x07
35#define MAX8925_ADC_ACQ_CNFG1 0x08
36#define MAX8925_ADC_ACQ_CNFG2 0x09
37/* 2 bytes registers in below. MSB is 1st, LSB is 2nd. */
38#define MAX8925_ADC_AUX2 0x62
39#define MAX8925_ADC_VCHG 0x64
40#define MAX8925_ADC_VBBATT 0x66
41#define MAX8925_ADC_VMBATT 0x68
42#define MAX8925_ADC_ISNS 0x6a
43#define MAX8925_ADC_THM 0x6c
44#define MAX8925_ADC_TDIE 0x6e
45#define MAX8925_CMD_AUX2 0xc8
46#define MAX8925_CMD_VCHG 0xd0
47#define MAX8925_CMD_VBBATT 0xd8
48#define MAX8925_CMD_VMBATT 0xe0
49#define MAX8925_CMD_ISNS 0xe8
50#define MAX8925_CMD_THM 0xf0
51#define MAX8925_CMD_TDIE 0xf8
52
53enum {
54 MEASURE_AUX2,
55 MEASURE_VCHG,
56 MEASURE_VBBATT,
57 MEASURE_VMBATT,
58 MEASURE_ISNS,
59 MEASURE_THM,
60 MEASURE_TDIE,
61 MEASURE_MAX,
62};
63
64struct max8925_power_info {
65 struct max8925_chip *chip;
66 struct i2c_client *gpm;
67 struct i2c_client *adc;
68
69 struct power_supply ac;
70 struct power_supply usb;
71 struct power_supply battery;
72 int irq_base;
73 unsigned ac_online:1;
74 unsigned usb_online:1;
75 unsigned bat_online:1;
76 unsigned chg_mode:2;
77 unsigned batt_detect:1; /* detecing MB by ID pin */
78 unsigned topoff_threshold:2;
79 unsigned fast_charge:3;
80
81 int (*set_charger) (int);
82};
83
84static int __set_charger(struct max8925_power_info *info, int enable)
85{
86 struct max8925_chip *chip = info->chip;
87 if (enable) {
88 /* enable charger in platform */
89 if (info->set_charger)
90 info->set_charger(1);
91 /* enable charger */
92 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 0);
93 } else {
94 /* disable charge */
95 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
96 if (info->set_charger)
97 info->set_charger(0);
98 }
99 dev_dbg(chip->dev, "%s\n", (enable) ? "Enable charger"
100 : "Disable charger");
101 return 0;
102}
103
104static irqreturn_t max8925_charger_handler(int irq, void *data)
105{
106 struct max8925_power_info *info = (struct max8925_power_info *)data;
107 struct max8925_chip *chip = info->chip;
108
109 switch (irq - chip->irq_base) {
110 case MAX8925_IRQ_VCHG_DC_R:
111 info->ac_online = 1;
112 __set_charger(info, 1);
113 dev_dbg(chip->dev, "Adapter inserted\n");
114 break;
115 case MAX8925_IRQ_VCHG_DC_F:
116 info->ac_online = 0;
117 __set_charger(info, 0);
118 dev_dbg(chip->dev, "Adapter is removal\n");
119 break;
120 case MAX8925_IRQ_VCHG_USB_R:
121 info->usb_online = 1;
122 __set_charger(info, 1);
123 dev_dbg(chip->dev, "USB inserted\n");
124 break;
125 case MAX8925_IRQ_VCHG_USB_F:
126 info->usb_online = 0;
127 __set_charger(info, 0);
128 dev_dbg(chip->dev, "USB is removal\n");
129 break;
130 case MAX8925_IRQ_VCHG_THM_OK_F:
131 /* Battery is not ready yet */
132 dev_dbg(chip->dev, "Battery temperature is out of range\n");
133 case MAX8925_IRQ_VCHG_DC_OVP:
134 dev_dbg(chip->dev, "Error detection\n");
135 __set_charger(info, 0);
136 break;
137 case MAX8925_IRQ_VCHG_THM_OK_R:
138 /* Battery is ready now */
139 dev_dbg(chip->dev, "Battery temperature is in range\n");
140 break;
141 case MAX8925_IRQ_VCHG_SYSLOW_R:
142 /* VSYS is low */
143 dev_info(chip->dev, "Sys power is too low\n");
144 break;
145 case MAX8925_IRQ_VCHG_SYSLOW_F:
146 dev_dbg(chip->dev, "Sys power is above low threshold\n");
147 break;
148 case MAX8925_IRQ_VCHG_DONE:
149 __set_charger(info, 0);
150 dev_dbg(chip->dev, "Charging is done\n");
151 break;
152 case MAX8925_IRQ_VCHG_TOPOFF:
153 dev_dbg(chip->dev, "Charging in top-off mode\n");
154 break;
155 case MAX8925_IRQ_VCHG_TMR_FAULT:
156 __set_charger(info, 0);
157 dev_dbg(chip->dev, "Safe timer is expired\n");
158 break;
159 case MAX8925_IRQ_VCHG_RST:
160 __set_charger(info, 0);
161 dev_dbg(chip->dev, "Charger is reset\n");
162 break;
163 }
164 return IRQ_HANDLED;
165}
166
167static int start_measure(struct max8925_power_info *info, int type)
168{
169 unsigned char buf[2] = {0, 0};
170 int meas_reg = 0, ret;
171
172 switch (type) {
173 case MEASURE_VCHG:
174 meas_reg = MAX8925_ADC_VCHG;
175 break;
176 case MEASURE_VBBATT:
177 meas_reg = MAX8925_ADC_VBBATT;
178 break;
179 case MEASURE_VMBATT:
180 meas_reg = MAX8925_ADC_VMBATT;
181 break;
182 case MEASURE_ISNS:
183 meas_reg = MAX8925_ADC_ISNS;
184 break;
185 default:
186 return -EINVAL;
187 }
188
189 max8925_bulk_read(info->adc, meas_reg, 2, buf);
190 ret = (buf[0] << 4) | (buf[1] >> 4);
191
192 return ret;
193}
194
195static int max8925_ac_get_prop(struct power_supply *psy,
196 enum power_supply_property psp,
197 union power_supply_propval *val)
198{
199 struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
200 int ret = 0;
201
202 switch (psp) {
203 case POWER_SUPPLY_PROP_ONLINE:
204 val->intval = info->ac_online;
205 break;
206 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
207 if (info->ac_online) {
208 ret = start_measure(info, MEASURE_VCHG);
209 if (ret >= 0) {
210 val->intval = ret << 1; /* unit is mV */
211 goto out;
212 }
213 }
214 ret = -ENODATA;
215 break;
216 default:
217 ret = -ENODEV;
218 break;
219 }
220out:
221 return ret;
222}
223
224static enum power_supply_property max8925_ac_props[] = {
225 POWER_SUPPLY_PROP_ONLINE,
226 POWER_SUPPLY_PROP_VOLTAGE_NOW,
227};
228
229static int max8925_usb_get_prop(struct power_supply *psy,
230 enum power_supply_property psp,
231 union power_supply_propval *val)
232{
233 struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
234 int ret = 0;
235
236 switch (psp) {
237 case POWER_SUPPLY_PROP_ONLINE:
238 val->intval = info->usb_online;
239 break;
240 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
241 if (info->usb_online) {
242 ret = start_measure(info, MEASURE_VCHG);
243 if (ret >= 0) {
244 val->intval = ret << 1; /* unit is mV */
245 goto out;
246 }
247 }
248 ret = -ENODATA;
249 break;
250 default:
251 ret = -ENODEV;
252 break;
253 }
254out:
255 return ret;
256}
257
258static enum power_supply_property max8925_usb_props[] = {
259 POWER_SUPPLY_PROP_ONLINE,
260 POWER_SUPPLY_PROP_VOLTAGE_NOW,
261};
262
263static int max8925_bat_get_prop(struct power_supply *psy,
264 enum power_supply_property psp,
265 union power_supply_propval *val)
266{
267 struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
268 long long int tmp = 0;
269 int ret = 0;
270
271 switch (psp) {
272 case POWER_SUPPLY_PROP_ONLINE:
273 val->intval = info->bat_online;
274 break;
275 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
276 if (info->bat_online) {
277 ret = start_measure(info, MEASURE_VMBATT);
278 if (ret >= 0) {
279 val->intval = ret << 1; /* unit is mV */
280 ret = 0;
281 break;
282 }
283 }
284 ret = -ENODATA;
285 break;
286 case POWER_SUPPLY_PROP_CURRENT_NOW:
287 if (info->bat_online) {
288 ret = start_measure(info, MEASURE_ISNS);
289 if (ret >= 0) {
290 tmp = (long long int)ret * 6250 / 4096 - 3125;
291 ret = (int)tmp;
292 val->intval = 0;
293 if (ret > 0)
294 val->intval = ret; /* unit is mA */
295 ret = 0;
296 break;
297 }
298 }
299 ret = -ENODATA;
300 break;
301 case POWER_SUPPLY_PROP_CHARGE_TYPE:
302 if (!info->bat_online) {
303 ret = -ENODATA;
304 break;
305 }
306 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
307 ret = (ret & MAX8925_CHG_STAT_MODE_MASK) >> 2;
308 switch (ret) {
309 case 1:
310 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
311 break;
312 case 0:
313 case 2:
314 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
315 break;
316 case 3:
317 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
318 break;
319 }
320 ret = 0;
321 break;
322 case POWER_SUPPLY_PROP_STATUS:
323 if (!info->bat_online) {
324 ret = -ENODATA;
325 break;
326 }
327 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
328 if (info->usb_online || info->ac_online) {
329 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
330 if (ret & MAX8925_CHG_STAT_EN_MASK)
331 val->intval = POWER_SUPPLY_STATUS_CHARGING;
332 } else
333 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
334 ret = 0;
335 break;
336 default:
337 ret = -ENODEV;
338 break;
339 }
340 return ret;
341}
342
343static enum power_supply_property max8925_battery_props[] = {
344 POWER_SUPPLY_PROP_ONLINE,
345 POWER_SUPPLY_PROP_VOLTAGE_NOW,
346 POWER_SUPPLY_PROP_CURRENT_NOW,
347 POWER_SUPPLY_PROP_CHARGE_TYPE,
348 POWER_SUPPLY_PROP_STATUS,
349};
350
351#define REQUEST_IRQ(_irq, _name) \
352do { \
353 ret = request_threaded_irq(chip->irq_base + _irq, NULL, \
354 max8925_charger_handler, \
355 IRQF_ONESHOT, _name, info); \
356 if (ret) \
357 dev_err(chip->dev, "Failed to request IRQ #%d: %d\n", \
358 _irq, ret); \
359} while (0)
360
361static __devinit int max8925_init_charger(struct max8925_chip *chip,
362 struct max8925_power_info *info)
363{
364 int ret;
365
366 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
367 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
368 REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
369 REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp");
370 REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove");
371 REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert");
372 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
373 REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
374 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
375 REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
376 REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
377 REQUEST_IRQ(MAX8925_IRQ_VCHG_DONE, "charger-done");
378 REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
379 REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
380
381 info->ac_online = 0;
382 info->usb_online = 0;
383 info->bat_online = 0;
384 ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
385 if (ret >= 0) {
386 /*
387 * If battery detection is enabled, ID pin of battery is
388 * connected to MBDET pin of MAX8925. It could be used to
389 * detect battery presence.
390 * Otherwise, we have to assume that battery is always on.
391 */
392 if (info->batt_detect)
393 info->bat_online = (ret & MAX8925_CHG_MBDET) ? 0 : 1;
394 else
395 info->bat_online = 1;
396 if (ret & MAX8925_CHG_AC_RANGE_MASK)
397 info->ac_online = 1;
398 else
399 info->ac_online = 0;
400 }
401 /* disable charge */
402 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
403 /* set charging current in charge topoff mode */
404 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 3 << 5,
405 info->topoff_threshold << 5);
406 /* set charing current in fast charge mode */
407 max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 7, info->fast_charge);
408
409 return 0;
410}
411
412static __devexit int max8925_deinit_charger(struct max8925_power_info *info)
413{
414 struct max8925_chip *chip = info->chip;
415 int irq;
416
417 irq = chip->irq_base + MAX8925_IRQ_VCHG_DC_OVP;
418 for (; irq <= chip->irq_base + MAX8925_IRQ_VCHG_TMR_FAULT; irq++)
419 free_irq(irq, info);
420
421 return 0;
422}
423
424static __devinit int max8925_power_probe(struct platform_device *pdev)
425{
426 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
427 struct max8925_platform_data *max8925_pdata;
428 struct max8925_power_pdata *pdata = NULL;
429 struct max8925_power_info *info;
430 int ret;
431
432 if (pdev->dev.parent->platform_data) {
433 max8925_pdata = pdev->dev.parent->platform_data;
434 pdata = max8925_pdata->power;
435 }
436
437 if (!pdata) {
438 dev_err(&pdev->dev, "platform data isn't assigned to "
439 "power supply\n");
440 return -EINVAL;
441 }
442
443 info = kzalloc(sizeof(struct max8925_power_info), GFP_KERNEL);
444 if (!info)
445 return -ENOMEM;
446 info->chip = chip;
447 info->gpm = chip->i2c;
448 info->adc = chip->adc;
449
450 info->ac.name = "max8925-ac";
451 info->ac.type = POWER_SUPPLY_TYPE_MAINS;
452 info->ac.properties = max8925_ac_props;
453 info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
454 info->ac.get_property = max8925_ac_get_prop;
455 ret = power_supply_register(&pdev->dev, &info->ac);
456 if (ret)
457 goto out;
458 info->ac.dev->parent = &pdev->dev;
459
460 info->usb.name = "max8925-usb";
461 info->usb.type = POWER_SUPPLY_TYPE_USB;
462 info->usb.properties = max8925_usb_props;
463 info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
464 info->usb.get_property = max8925_usb_get_prop;
465 ret = power_supply_register(&pdev->dev, &info->usb);
466 if (ret)
467 goto out_usb;
468 info->usb.dev->parent = &pdev->dev;
469
470 info->battery.name = "max8925-battery";
471 info->battery.type = POWER_SUPPLY_TYPE_BATTERY;
472 info->battery.properties = max8925_battery_props;
473 info->battery.num_properties = ARRAY_SIZE(max8925_battery_props);
474 info->battery.get_property = max8925_bat_get_prop;
475 ret = power_supply_register(&pdev->dev, &info->battery);
476 if (ret)
477 goto out_battery;
478 info->battery.dev->parent = &pdev->dev;
479
480 info->batt_detect = pdata->batt_detect;
481 info->topoff_threshold = pdata->topoff_threshold;
482 info->fast_charge = pdata->fast_charge;
483 info->set_charger = pdata->set_charger;
484 dev_set_drvdata(&pdev->dev, info);
485 platform_set_drvdata(pdev, info);
486
487 max8925_init_charger(chip, info);
488 return 0;
489out_battery:
490 power_supply_unregister(&info->battery);
491out_usb:
492 power_supply_unregister(&info->ac);
493out:
494 kfree(info);
495 return ret;
496}
497
498static __devexit int max8925_power_remove(struct platform_device *pdev)
499{
500 struct max8925_power_info *info = platform_get_drvdata(pdev);
501
502 if (info) {
503 power_supply_unregister(&info->ac);
504 power_supply_unregister(&info->usb);
505 power_supply_unregister(&info->battery);
506 max8925_deinit_charger(info);
507 kfree(info);
508 }
509 return 0;
510}
511
512static struct platform_driver max8925_power_driver = {
513 .probe = max8925_power_probe,
514 .remove = __devexit_p(max8925_power_remove),
515 .driver = {
516 .name = "max8925-power",
517 },
518};
519
520static int __init max8925_power_init(void)
521{
522 return platform_driver_register(&max8925_power_driver);
523}
524module_init(max8925_power_init);
525
526static void __exit max8925_power_exit(void)
527{
528 platform_driver_unregister(&max8925_power_driver);
529}
530module_exit(max8925_power_exit);
531
532MODULE_LICENSE("GPL");
533MODULE_DESCRIPTION("Power supply driver for MAX8925");
534MODULE_ALIAS("platform:max8925-power");
diff --git a/drivers/power/wm8350_power.c b/drivers/power/wm8350_power.c
index ad4f071e1287..0693902d6151 100644
--- a/drivers/power/wm8350_power.c
+++ b/drivers/power/wm8350_power.c
@@ -190,7 +190,7 @@ static irqreturn_t wm8350_charger_handler(int irq, void *data)
190 struct wm8350_power *power = &wm8350->power; 190 struct wm8350_power *power = &wm8350->power;
191 struct wm8350_charger_policy *policy = power->policy; 191 struct wm8350_charger_policy *policy = power->policy;
192 192
193 switch (irq) { 193 switch (irq - wm8350->irq_base) {
194 case WM8350_IRQ_CHG_BAT_FAIL: 194 case WM8350_IRQ_CHG_BAT_FAIL:
195 dev_err(wm8350->dev, "battery failed\n"); 195 dev_err(wm8350->dev, "battery failed\n");
196 break; 196 break;
@@ -428,18 +428,18 @@ static void wm8350_init_charger(struct wm8350 *wm8350)
428 428
429static void free_charger_irq(struct wm8350 *wm8350) 429static void free_charger_irq(struct wm8350 *wm8350)
430{ 430{
431 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT); 431 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350);
432 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD); 432 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350);
433 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL); 433 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350);
434 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO); 434 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350);
435 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END); 435 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350);
436 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START); 436 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350);
437 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9); 437 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350);
438 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1); 438 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350);
439 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85); 439 wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350);
440 wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB); 440 wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350);
441 wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB); 441 wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350);
442 wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB); 442 wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350);
443} 443}
444 444
445static __devinit int wm8350_power_probe(struct platform_device *pdev) 445static __devinit int wm8350_power_probe(struct platform_device *pdev)
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 04719551381b..5fb83e2ced25 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -11,15 +11,17 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/i2c.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <linux/regulator/driver.h> 16#include <linux/regulator/driver.h>
16#include <linux/regulator/machine.h> 17#include <linux/regulator/machine.h>
17#include <linux/mfd/88pm8607.h> 18#include <linux/mfd/88pm860x.h>
18 19
19struct pm8607_regulator_info { 20struct pm8607_regulator_info {
20 struct regulator_desc desc; 21 struct regulator_desc desc;
21 struct pm8607_chip *chip; 22 struct pm860x_chip *chip;
22 struct regulator_dev *regulator; 23 struct regulator_dev *regulator;
24 struct i2c_client *i2c;
23 25
24 int min_uV; 26 int min_uV;
25 int max_uV; 27 int max_uV;
@@ -46,7 +48,6 @@ static inline int check_range(struct pm8607_regulator_info *info,
46static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) 48static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
47{ 49{
48 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 50 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
49 uint8_t chip_id = info->chip->chip_id;
50 int ret = -EINVAL; 51 int ret = -EINVAL;
51 52
52 switch (info->desc.id) { 53 switch (info->desc.id) {
@@ -88,79 +89,29 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
88 case PM8607_ID_LDO2: 89 case PM8607_ID_LDO2:
89 case PM8607_ID_LDO3: 90 case PM8607_ID_LDO3:
90 case PM8607_ID_LDO9: 91 case PM8607_ID_LDO9:
91 switch (chip_id) { 92 ret = (index < 3) ? (index * 50000 + 1800000) :
92 case PM8607_CHIP_A0: 93 ((index < 7) ? (index * 50000 + 2550000) :
93 case PM8607_CHIP_A1: 94 3300000);
94 ret = (index < 3) ? (index * 50000 + 1800000) :
95 ((index < 8) ? (index * 50000 + 2550000) :
96 -EINVAL);
97 break;
98 case PM8607_CHIP_B0:
99 ret = (index < 3) ? (index * 50000 + 1800000) :
100 ((index < 7) ? (index * 50000 + 2550000) :
101 3300000);
102 break;
103 }
104 break; 95 break;
105 case PM8607_ID_LDO4: 96 case PM8607_ID_LDO4:
106 switch (chip_id) { 97 ret = (index < 3) ? (index * 50000 + 1800000) :
107 case PM8607_CHIP_A0: 98 ((index < 6) ? (index * 50000 + 2550000) :
108 case PM8607_CHIP_A1: 99 ((index == 6) ? 2900000 : 3300000));
109 ret = (index < 3) ? (index * 50000 + 1800000) :
110 ((index < 8) ? (index * 50000 + 2550000) :
111 -EINVAL);
112 break;
113 case PM8607_CHIP_B0:
114 ret = (index < 3) ? (index * 50000 + 1800000) :
115 ((index < 6) ? (index * 50000 + 2550000) :
116 ((index == 6) ? 2900000 : 3300000));
117 break;
118 }
119 break; 100 break;
120 case PM8607_ID_LDO6: 101 case PM8607_ID_LDO6:
121 switch (chip_id) { 102 ret = (index < 2) ? (index * 50000 + 1800000) :
122 case PM8607_CHIP_A0: 103 ((index < 7) ? (index * 50000 + 2500000) :
123 case PM8607_CHIP_A1: 104 3300000);
124 ret = (index < 3) ? (index * 50000 + 1800000) :
125 ((index < 8) ? (index * 50000 + 2450000) :
126 -EINVAL);
127 break;
128 case PM8607_CHIP_B0:
129 ret = (index < 2) ? (index * 50000 + 1800000) :
130 ((index < 7) ? (index * 50000 + 2500000) :
131 3300000);
132 break;
133 }
134 break; 105 break;
135 case PM8607_ID_LDO10: 106 case PM8607_ID_LDO10:
136 switch (chip_id) { 107 ret = (index < 3) ? (index * 50000 + 1800000) :
137 case PM8607_CHIP_A0: 108 ((index < 7) ? (index * 50000 + 2550000) :
138 case PM8607_CHIP_A1: 109 ((index == 7) ? 3300000 : 1200000));
139 ret = (index < 3) ? (index * 50000 + 1800000) :
140 ((index < 8) ? (index * 50000 + 2550000) :
141 1200000);
142 break;
143 case PM8607_CHIP_B0:
144 ret = (index < 3) ? (index * 50000 + 1800000) :
145 ((index < 7) ? (index * 50000 + 2550000) :
146 ((index == 7) ? 3300000 : 1200000));
147 break;
148 }
149 break; 110 break;
150 case PM8607_ID_LDO14: 111 case PM8607_ID_LDO14:
151 switch (chip_id) { 112 ret = (index < 2) ? (index * 50000 + 1800000) :
152 case PM8607_CHIP_A0: 113 ((index < 7) ? (index * 50000 + 2600000) :
153 case PM8607_CHIP_A1: 114 3300000);
154 ret = (index < 3) ? (index * 50000 + 1800000) :
155 ((index < 8) ? (index * 50000 + 2550000) :
156 -EINVAL);
157 break;
158 case PM8607_CHIP_B0:
159 ret = (index < 2) ? (index * 50000 + 1800000) :
160 ((index < 7) ? (index * 50000 + 2600000) :
161 3300000);
162 break;
163 }
164 break; 115 break;
165 } 116 }
166 return ret; 117 return ret;
@@ -169,7 +120,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
169static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) 120static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
170{ 121{
171 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 122 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
172 uint8_t chip_id = info->chip->chip_id;
173 int val = -ENOENT; 123 int val = -ENOENT;
174 int ret; 124 int ret;
175 125
@@ -254,161 +204,77 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
254 case PM8607_ID_LDO2: 204 case PM8607_ID_LDO2:
255 case PM8607_ID_LDO3: 205 case PM8607_ID_LDO3:
256 case PM8607_ID_LDO9: 206 case PM8607_ID_LDO9:
257 switch (chip_id) { 207 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
258 case PM8607_CHIP_A0: 208 if (min_uV <= 1800000)
259 case PM8607_CHIP_A1: 209 val = 0;
260 if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ 210 else if (min_uV <= 1900000)
261 if (min_uV <= 1800000) 211 val = (min_uV - 1750001) / 50000;
262 val = 0; 212 else
263 else if (min_uV <= 1900000) 213 val = 3; /* 2700mV */
264 val = (min_uV - 1750001) / 50000; 214 } else { /* 2700mV ~ 2850mV / 50mV */
265 else 215 if (min_uV <= 2850000) {
266 val = 3; /* 2700mV */ 216 val = (min_uV - 2650001) / 50000;
267 else { /* 2700mV ~ 2900mV / 50mV */ 217 val += 3;
268 if (min_uV <= 2900000) { 218 } else if (min_uV <= 3300000)
269 val = (min_uV - 2650001) / 50000; 219 val = 7;
270 val += 3; 220 else
271 } else 221 val = -EINVAL;
272 val = -EINVAL;
273 }
274 break;
275 case PM8607_CHIP_B0:
276 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
277 if (min_uV <= 1800000)
278 val = 0;
279 else if (min_uV <= 1900000)
280 val = (min_uV - 1750001) / 50000;
281 else
282 val = 3; /* 2700mV */
283 } else { /* 2700mV ~ 2850mV / 50mV */
284 if (min_uV <= 2850000) {
285 val = (min_uV - 2650001) / 50000;
286 val += 3;
287 } else if (min_uV <= 3300000)
288 val = 7;
289 else
290 val = -EINVAL;
291 }
292 break;
293 } 222 }
294 break; 223 break;
295 case PM8607_ID_LDO4: 224 case PM8607_ID_LDO4:
296 switch (chip_id) { 225 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
297 case PM8607_CHIP_A0: 226 if (min_uV <= 1800000)
298 case PM8607_CHIP_A1: 227 val = 0;
299 if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ 228 else if (min_uV <= 1900000)
300 if (min_uV <= 1800000) 229 val = (min_uV - 1750001) / 50000;
301 val = 0; 230 else
302 else if (min_uV <= 1900000) 231 val = 3; /* 2700mV */
303 val = (min_uV - 1750001) / 50000; 232 } else { /* 2700mV ~ 2800mV / 50mV */
304 else 233 if (min_uV <= 2850000) {
305 val = 3; /* 2700mV */ 234 val = (min_uV - 2650001) / 50000;
306 else { /* 2700mV ~ 2900mV / 50mV */ 235 val += 3;
307 if (min_uV <= 2900000) { 236 } else if (min_uV <= 2900000)
308 val = (min_uV - 2650001) / 50000; 237 val = 6;
309 val += 3; 238 else if (min_uV <= 3300000)
310 } else 239 val = 7;
311 val = -EINVAL; 240 else
312 } 241 val = -EINVAL;
313 break;
314 case PM8607_CHIP_B0:
315 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
316 if (min_uV <= 1800000)
317 val = 0;
318 else if (min_uV <= 1900000)
319 val = (min_uV - 1750001) / 50000;
320 else
321 val = 3; /* 2700mV */
322 } else { /* 2700mV ~ 2800mV / 50mV */
323 if (min_uV <= 2850000) {
324 val = (min_uV - 2650001) / 50000;
325 val += 3;
326 } else if (min_uV <= 2900000)
327 val = 6;
328 else if (min_uV <= 3300000)
329 val = 7;
330 else
331 val = -EINVAL;
332 }
333 break;
334 } 242 }
335 break; 243 break;
336 case PM8607_ID_LDO6: 244 case PM8607_ID_LDO6:
337 switch (chip_id) { 245 if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
338 case PM8607_CHIP_A0: 246 if (min_uV <= 1800000)
339 case PM8607_CHIP_A1: 247 val = 0;
340 if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */ 248 else if (min_uV <= 1850000)
341 if (min_uV <= 1800000) 249 val = (min_uV - 1750001) / 50000;
342 val = 0; 250 else
343 else if (min_uV <= 1900000) 251 val = 2; /* 2600mV */
344 val = (min_uV - 1750001) / 50000; 252 } else { /* 2600mV ~ 2800mV / 50mV */
345 else 253 if (min_uV <= 2800000) {
346 val = 3; /* 2600mV */ 254 val = (min_uV - 2550001) / 50000;
347 } else { /* 2600mV ~ 2800mV / 50mV */ 255 val += 2;
348 if (min_uV <= 2800000) { 256 } else if (min_uV <= 3300000)
349 val = (min_uV - 2550001) / 50000; 257 val = 7;
350 val += 3; 258 else
351 } else 259 val = -EINVAL;
352 val = -EINVAL;
353 }
354 break;
355 case PM8607_CHIP_B0:
356 if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
357 if (min_uV <= 1800000)
358 val = 0;
359 else if (min_uV <= 1850000)
360 val = (min_uV - 1750001) / 50000;
361 else
362 val = 2; /* 2600mV */
363 } else { /* 2600mV ~ 2800mV / 50mV */
364 if (min_uV <= 2800000) {
365 val = (min_uV - 2550001) / 50000;
366 val += 2;
367 } else if (min_uV <= 3300000)
368 val = 7;
369 else
370 val = -EINVAL;
371 }
372 break;
373 } 260 }
374 break; 261 break;
375 case PM8607_ID_LDO14: 262 case PM8607_ID_LDO14:
376 switch (chip_id) { 263 if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
377 case PM8607_CHIP_A0: 264 if (min_uV <= 1800000)
378 case PM8607_CHIP_A1: 265 val = 0;
379 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ 266 else if (min_uV <= 1850000)
380 if (min_uV <= 1800000) 267 val = (min_uV - 1750001) / 50000;
381 val = 0; 268 else
382 else if (min_uV <= 1900000) 269 val = 2; /* 2700mV */
383 val = (min_uV - 1750001) / 50000; 270 } else { /* 2700mV ~ 2900mV / 50mV */
384 else 271 if (min_uV <= 2900000) {
385 val = 3; /* 2700mV */ 272 val = (min_uV - 2650001) / 50000;
386 } else { /* 2700mV ~ 2900mV / 50mV */ 273 val += 2;
387 if (min_uV <= 2900000) { 274 } else if (min_uV <= 3300000)
388 val = (min_uV - 2650001) / 50000; 275 val = 7;
389 val += 3; 276 else
390 } else 277 val = -EINVAL;
391 val = -EINVAL;
392 }
393 break;
394 case PM8607_CHIP_B0:
395 if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
396 if (min_uV <= 1800000)
397 val = 0;
398 else if (min_uV <= 1850000)
399 val = (min_uV - 1750001) / 50000;
400 else
401 val = 2; /* 2700mV */
402 } else { /* 2700mV ~ 2900mV / 50mV */
403 if (min_uV <= 2900000) {
404 val = (min_uV - 2650001) / 50000;
405 val += 2;
406 } else if (min_uV <= 3300000)
407 val = 7;
408 else
409 val = -EINVAL;
410 }
411 break;
412 } 278 }
413 break; 279 break;
414 } 280 }
@@ -428,7 +294,6 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
428 int min_uV, int max_uV) 294 int min_uV, int max_uV)
429{ 295{
430 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 296 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
431 struct pm8607_chip *chip = info->chip;
432 uint8_t val, mask; 297 uint8_t val, mask;
433 int ret; 298 int ret;
434 299
@@ -443,13 +308,13 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
443 val = (uint8_t)(ret << info->vol_shift); 308 val = (uint8_t)(ret << info->vol_shift);
444 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; 309 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
445 310
446 ret = pm8607_set_bits(chip, info->vol_reg, mask, val); 311 ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
447 if (ret) 312 if (ret)
448 return ret; 313 return ret;
449 switch (info->desc.id) { 314 switch (info->desc.id) {
450 case PM8607_ID_BUCK1: 315 case PM8607_ID_BUCK1:
451 case PM8607_ID_BUCK3: 316 case PM8607_ID_BUCK3:
452 ret = pm8607_set_bits(chip, info->update_reg, 317 ret = pm860x_set_bits(info->i2c, info->update_reg,
453 1 << info->update_bit, 318 1 << info->update_bit,
454 1 << info->update_bit); 319 1 << info->update_bit);
455 break; 320 break;
@@ -460,11 +325,10 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
460static int pm8607_get_voltage(struct regulator_dev *rdev) 325static int pm8607_get_voltage(struct regulator_dev *rdev)
461{ 326{
462 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 327 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
463 struct pm8607_chip *chip = info->chip;
464 uint8_t val, mask; 328 uint8_t val, mask;
465 int ret; 329 int ret;
466 330
467 ret = pm8607_reg_read(chip, info->vol_reg); 331 ret = pm860x_reg_read(info->i2c, info->vol_reg);
468 if (ret < 0) 332 if (ret < 0)
469 return ret; 333 return ret;
470 334
@@ -477,9 +341,8 @@ static int pm8607_get_voltage(struct regulator_dev *rdev)
477static int pm8607_enable(struct regulator_dev *rdev) 341static int pm8607_enable(struct regulator_dev *rdev)
478{ 342{
479 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 343 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
480 struct pm8607_chip *chip = info->chip;
481 344
482 return pm8607_set_bits(chip, info->enable_reg, 345 return pm860x_set_bits(info->i2c, info->enable_reg,
483 1 << info->enable_bit, 346 1 << info->enable_bit,
484 1 << info->enable_bit); 347 1 << info->enable_bit);
485} 348}
@@ -487,19 +350,17 @@ static int pm8607_enable(struct regulator_dev *rdev)
487static int pm8607_disable(struct regulator_dev *rdev) 350static int pm8607_disable(struct regulator_dev *rdev)
488{ 351{
489 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 352 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
490 struct pm8607_chip *chip = info->chip;
491 353
492 return pm8607_set_bits(chip, info->enable_reg, 354 return pm860x_set_bits(info->i2c, info->enable_reg,
493 1 << info->enable_bit, 0); 355 1 << info->enable_bit, 0);
494} 356}
495 357
496static int pm8607_is_enabled(struct regulator_dev *rdev) 358static int pm8607_is_enabled(struct regulator_dev *rdev)
497{ 359{
498 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 360 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
499 struct pm8607_chip *chip = info->chip;
500 int ret; 361 int ret;
501 362
502 ret = pm8607_reg_read(chip, info->enable_reg); 363 ret = pm860x_reg_read(info->i2c, info->enable_reg);
503 if (ret < 0) 364 if (ret < 0)
504 return ret; 365 return ret;
505 366
@@ -589,8 +450,8 @@ static inline struct pm8607_regulator_info *find_regulator_info(int id)
589 450
590static int __devinit pm8607_regulator_probe(struct platform_device *pdev) 451static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
591{ 452{
592 struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent); 453 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
593 struct pm8607_platform_data *pdata = chip->dev->platform_data; 454 struct pm860x_platform_data *pdata = chip->dev->platform_data;
594 struct pm8607_regulator_info *info = NULL; 455 struct pm8607_regulator_info *info = NULL;
595 456
596 info = find_regulator_info(pdev->id); 457 info = find_regulator_info(pdev->id);
@@ -599,6 +460,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
599 return -EINVAL; 460 return -EINVAL;
600 } 461 }
601 462
463 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
602 info->chip = chip; 464 info->chip = chip;
603 465
604 info->regulator = regulator_register(&info->desc, &pdev->dev, 466 info->regulator = regulator_register(&info->desc, &pdev->dev,
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 834b48441829..04f2e085116a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -94,6 +94,12 @@ config REGULATOR_MAX8660
94 This driver controls a Maxim 8660/8661 voltage output 94 This driver controls a Maxim 8660/8661 voltage output
95 regulator via I2C bus. 95 regulator via I2C bus.
96 96
97config REGULATOR_MAX8925
98 tristate "Maxim MAX8925 Power Management IC"
99 depends on MFD_MAX8925
100 help
101 Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC.
102
97config REGULATOR_TWL4030 103config REGULATOR_TWL4030
98 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" 104 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
99 depends on TWL4030_CORE 105 depends on TWL4030_CORE
@@ -191,7 +197,7 @@ config REGULATOR_TPS6507X
191 197
192config REGULATOR_88PM8607 198config REGULATOR_88PM8607
193 bool "Marvell 88PM8607 Power regulators" 199 bool "Marvell 88PM8607 Power regulators"
194 depends on MFD_88PM8607=y 200 depends on MFD_88PM860X=y
195 help 201 help
196 This driver supports 88PM8607 voltage regulator chips. 202 This driver supports 88PM8607 voltage regulator chips.
197 203
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index e845b66ad59c..4e7feece22d5 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
15obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o 15obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
16obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o 16obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
17obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 17obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
18obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
18obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 19obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
19obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o 20obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
20obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o 21obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
new file mode 100644
index 000000000000..67873f08ed40
--- /dev/null
+++ b/drivers/regulator/max8925-regulator.c
@@ -0,0 +1,306 @@
1/*
2 * Regulators driver for Maxim max8925
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/err.h>
14#include <linux/i2c.h>
15#include <linux/platform_device.h>
16#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h>
18#include <linux/mfd/max8925.h>
19
20#define SD1_DVM_VMIN 850000
21#define SD1_DVM_VMAX 1000000
22#define SD1_DVM_STEP 50000
23#define SD1_DVM_SHIFT 5 /* SDCTL1 bit5 */
24#define SD1_DVM_EN 6 /* SDV1 bit 6 */
25
26struct max8925_regulator_info {
27 struct regulator_desc desc;
28 struct regulator_dev *regulator;
29 struct i2c_client *i2c;
30 struct max8925_chip *chip;
31
32 int min_uV;
33 int max_uV;
34 int step_uV;
35 int vol_reg;
36 int vol_shift;
37 int vol_nbits;
38 int enable_bit;
39 int enable_reg;
40};
41
42static inline int check_range(struct max8925_regulator_info *info,
43 int min_uV, int max_uV)
44{
45 if (min_uV < info->min_uV || min_uV > info->max_uV)
46 return -EINVAL;
47
48 return 0;
49}
50
51static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index)
52{
53 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
54 return info->min_uV + index * info->step_uV;
55}
56
57static int max8925_set_voltage(struct regulator_dev *rdev,
58 int min_uV, int max_uV)
59{
60 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
61 unsigned char data, mask;
62
63 if (check_range(info, min_uV, max_uV)) {
64 dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
65 min_uV, max_uV);
66 return -EINVAL;
67 }
68 data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
69 data <<= info->vol_shift;
70 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
71
72 return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
73}
74
75static int max8925_get_voltage(struct regulator_dev *rdev)
76{
77 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
78 unsigned char data, mask;
79 int ret;
80
81 ret = max8925_reg_read(info->i2c, info->vol_reg);
82 if (ret < 0)
83 return ret;
84 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
85 data = (ret & mask) >> info->vol_shift;
86
87 return max8925_list_voltage(rdev, data);
88}
89
90static int max8925_enable(struct regulator_dev *rdev)
91{
92 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
93
94 return max8925_set_bits(info->i2c, info->enable_reg,
95 1 << info->enable_bit,
96 1 << info->enable_bit);
97}
98
99static int max8925_disable(struct regulator_dev *rdev)
100{
101 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
102
103 return max8925_set_bits(info->i2c, info->enable_reg,
104 1 << info->enable_bit, 0);
105}
106
107static int max8925_is_enabled(struct regulator_dev *rdev)
108{
109 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
110 int ret;
111
112 ret = max8925_reg_read(info->i2c, info->vol_reg);
113 if (ret < 0)
114 return ret;
115
116 return ret & (1 << info->enable_bit);
117}
118
119static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
120{
121 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
122 unsigned char data, mask;
123
124 if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX)
125 return -EINVAL;
126
127 data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP;
128 data <<= SD1_DVM_SHIFT;
129 mask = 3 << SD1_DVM_SHIFT;
130
131 return max8925_set_bits(info->i2c, info->enable_reg, mask, data);
132}
133
134static int max8925_set_dvm_enable(struct regulator_dev *rdev)
135{
136 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
137
138 return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN,
139 1 << SD1_DVM_EN);
140}
141
142static int max8925_set_dvm_disable(struct regulator_dev *rdev)
143{
144 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
145
146 return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0);
147}
148
149static struct regulator_ops max8925_regulator_sdv_ops = {
150 .set_voltage = max8925_set_voltage,
151 .get_voltage = max8925_get_voltage,
152 .enable = max8925_enable,
153 .disable = max8925_disable,
154 .is_enabled = max8925_is_enabled,
155 .set_suspend_voltage = max8925_set_dvm_voltage,
156 .set_suspend_enable = max8925_set_dvm_enable,
157 .set_suspend_disable = max8925_set_dvm_disable,
158};
159
160static struct regulator_ops max8925_regulator_ldo_ops = {
161 .set_voltage = max8925_set_voltage,
162 .get_voltage = max8925_get_voltage,
163 .enable = max8925_enable,
164 .disable = max8925_disable,
165 .is_enabled = max8925_is_enabled,
166};
167
168#define MAX8925_SDV(_id, min, max, step) \
169{ \
170 .desc = { \
171 .name = "SDV" #_id, \
172 .ops = &max8925_regulator_sdv_ops, \
173 .type = REGULATOR_VOLTAGE, \
174 .id = MAX8925_ID_SD##_id, \
175 .owner = THIS_MODULE, \
176 }, \
177 .min_uV = min * 1000, \
178 .max_uV = max * 1000, \
179 .step_uV = step * 1000, \
180 .vol_reg = MAX8925_SDV##_id, \
181 .vol_shift = 0, \
182 .vol_nbits = 6, \
183 .enable_reg = MAX8925_SDCTL##_id, \
184 .enable_bit = 0, \
185}
186
187#define MAX8925_LDO(_id, min, max, step) \
188{ \
189 .desc = { \
190 .name = "LDO" #_id, \
191 .ops = &max8925_regulator_ldo_ops, \
192 .type = REGULATOR_VOLTAGE, \
193 .id = MAX8925_ID_LDO##_id, \
194 .owner = THIS_MODULE, \
195 }, \
196 .min_uV = min * 1000, \
197 .max_uV = max * 1000, \
198 .step_uV = step * 1000, \
199 .vol_reg = MAX8925_LDOVOUT##_id, \
200 .vol_shift = 0, \
201 .vol_nbits = 6, \
202 .enable_reg = MAX8925_LDOCTL##_id, \
203 .enable_bit = 0, \
204}
205
206static struct max8925_regulator_info max8925_regulator_info[] = {
207 MAX8925_SDV(1, 637.5, 1425, 12.5),
208 MAX8925_SDV(2, 650, 2225, 25),
209 MAX8925_SDV(3, 750, 3900, 50),
210
211 MAX8925_LDO(1, 750, 3900, 50),
212 MAX8925_LDO(2, 650, 2250, 25),
213 MAX8925_LDO(3, 650, 2250, 25),
214 MAX8925_LDO(4, 750, 3900, 50),
215 MAX8925_LDO(5, 750, 3900, 50),
216 MAX8925_LDO(6, 750, 3900, 50),
217 MAX8925_LDO(7, 750, 3900, 50),
218 MAX8925_LDO(8, 750, 3900, 50),
219 MAX8925_LDO(9, 750, 3900, 50),
220 MAX8925_LDO(10, 750, 3900, 50),
221 MAX8925_LDO(11, 750, 3900, 50),
222 MAX8925_LDO(12, 750, 3900, 50),
223 MAX8925_LDO(13, 750, 3900, 50),
224 MAX8925_LDO(14, 750, 3900, 50),
225 MAX8925_LDO(15, 750, 3900, 50),
226 MAX8925_LDO(16, 750, 3900, 50),
227 MAX8925_LDO(17, 650, 2250, 25),
228 MAX8925_LDO(18, 650, 2250, 25),
229 MAX8925_LDO(19, 750, 3900, 50),
230 MAX8925_LDO(20, 750, 3900, 50),
231};
232
233static inline struct max8925_regulator_info *find_regulator_info(int id)
234{
235 struct max8925_regulator_info *ri;
236 int i;
237
238 for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
239 ri = &max8925_regulator_info[i];
240 if (ri->desc.id == id)
241 return ri;
242 }
243 return NULL;
244}
245
246static int __devinit max8925_regulator_probe(struct platform_device *pdev)
247{
248 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
249 struct max8925_platform_data *pdata = chip->dev->platform_data;
250 struct max8925_regulator_info *ri = NULL;
251 struct regulator_dev *rdev;
252
253 ri = find_regulator_info(pdev->id);
254 if (ri == NULL) {
255 dev_err(&pdev->dev, "invalid regulator ID specified\n");
256 return -EINVAL;
257 }
258 ri->i2c = chip->i2c;
259 ri->chip = chip;
260
261 rdev = regulator_register(&ri->desc, &pdev->dev,
262 pdata->regulator[pdev->id], ri);
263 if (IS_ERR(rdev)) {
264 dev_err(&pdev->dev, "failed to register regulator %s\n",
265 ri->desc.name);
266 return PTR_ERR(rdev);
267 }
268
269 platform_set_drvdata(pdev, rdev);
270 return 0;
271}
272
273static int __devexit max8925_regulator_remove(struct platform_device *pdev)
274{
275 struct regulator_dev *rdev = platform_get_drvdata(pdev);
276
277 regulator_unregister(rdev);
278 return 0;
279}
280
281static struct platform_driver max8925_regulator_driver = {
282 .driver = {
283 .name = "max8925-regulator",
284 .owner = THIS_MODULE,
285 },
286 .probe = max8925_regulator_probe,
287 .remove = __devexit_p(max8925_regulator_remove),
288};
289
290static int __init max8925_regulator_init(void)
291{
292 return platform_driver_register(&max8925_regulator_driver);
293}
294subsys_initcall(max8925_regulator_init);
295
296static void __exit max8925_regulator_exit(void)
297{
298 platform_driver_unregister(&max8925_regulator_driver);
299}
300module_exit(max8925_regulator_exit);
301
302MODULE_LICENSE("GPL");
303MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
304MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC");
305MODULE_ALIAS("platform:max8925-regulator");
306
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 94227dd6ba7b..723cd1fb4867 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1453,7 +1453,7 @@ static int wm8350_regulator_remove(struct platform_device *pdev)
1453 struct regulator_dev *rdev = platform_get_drvdata(pdev); 1453 struct regulator_dev *rdev = platform_get_drvdata(pdev);
1454 struct wm8350 *wm8350 = rdev_get_drvdata(rdev); 1454 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
1455 1455
1456 wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq); 1456 wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
1457 1457
1458 regulator_unregister(rdev); 1458 regulator_unregister(rdev);
1459 1459
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 2bb8a8b7ffaf..6a1303759432 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -175,6 +175,16 @@ config RTC_DRV_MAX6900
175 This driver can also be built as a module. If so, the module 175 This driver can also be built as a module. If so, the module
176 will be called rtc-max6900. 176 will be called rtc-max6900.
177 177
178config RTC_DRV_MAX8925
179 tristate "Maxim MAX8925"
180 depends on MFD_MAX8925
181 help
182 If you say yes here you will get support for the
183 RTC of Maxim MAX8925 PMIC.
184
185 This driver can also be built as a module. If so, the module
186 will be called rtc-max8925.
187
178config RTC_DRV_RS5C372 188config RTC_DRV_RS5C372
179 tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" 189 tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A"
180 help 190 help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index b7148afb8f55..44ef194a9573 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o
52obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o 52obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
53obj-$(CONFIG_RTC_MXC) += rtc-mxc.o 53obj-$(CONFIG_RTC_MXC) += rtc-mxc.o
54obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o 54obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
55obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o
55obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o 56obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
56obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o 57obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o
57obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o 58obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index be5a6b73e601..40845c7e9322 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -226,6 +226,7 @@ static void __exit rtc_exit(void)
226{ 226{
227 rtc_dev_exit(); 227 rtc_dev_exit();
228 class_destroy(rtc_class); 228 class_destroy(rtc_class);
229 idr_destroy(&rtc_idr);
229} 230}
230 231
231subsys_initcall(rtc_init); 232subsys_initcall(rtc_init);
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 86c61f143515..78a018b5c941 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -161,7 +161,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
161 if (offset == 0) 161 if (offset == 0)
162 return -EILSEQ; 162 return -EILSEQ;
163 163
164 memset(alrm, 0, sizeof(alrm)); 164 memset(alrm, 0, sizeof(*alrm));
165 if (alarm != ALARM_DISABLED && offset != 0) { 165 if (alarm != ALARM_DISABLED && offset != 0) {
166 rtc_time_to_tm(offset + alarm, tm); 166 rtc_time_to_tm(offset + alarm, tm);
167 167
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 03ea530981d1..44c4399ee714 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -271,12 +271,13 @@ static int coh901331_resume(struct platform_device *pdev)
271{ 271{
272 struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev); 272 struct coh901331_port *rtap = dev_get_drvdata(&pdev->dev);
273 273
274 if (device_may_wakeup(&pdev->dev)) 274 if (device_may_wakeup(&pdev->dev)) {
275 disable_irq_wake(rtap->irq); 275 disable_irq_wake(rtap->irq);
276 else 276 } else {
277 clk_enable(rtap->clk); 277 clk_enable(rtap->clk);
278 writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK); 278 writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK);
279 clk_disable(rtap->clk); 279 clk_disable(rtap->clk);
280 }
280 return 0; 281 return 0;
281} 282}
282#else 283#else
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c
index 9da02d108b73..91bde976bc0f 100644
--- a/drivers/rtc/rtc-ep93xx.c
+++ b/drivers/rtc/rtc-ep93xx.c
@@ -115,6 +115,15 @@ static ssize_t ep93xx_rtc_show_comp_delete(struct device *dev,
115} 115}
116static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL); 116static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL);
117 117
118static struct attribute *ep93xx_rtc_attrs[] = {
119 &dev_attr_comp_preload.attr,
120 &dev_attr_comp_delete.attr,
121 NULL
122};
123
124static const struct attribute_group ep93xx_rtc_sysfs_files = {
125 .attrs = ep93xx_rtc_attrs,
126};
118 127
119static int __init ep93xx_rtc_probe(struct platform_device *pdev) 128static int __init ep93xx_rtc_probe(struct platform_device *pdev)
120{ 129{
@@ -123,27 +132,22 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
123 struct rtc_device *rtc; 132 struct rtc_device *rtc;
124 int err; 133 int err;
125 134
126 ep93xx_rtc = kzalloc(sizeof(struct ep93xx_rtc), GFP_KERNEL); 135 ep93xx_rtc = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_rtc), GFP_KERNEL);
127 if (ep93xx_rtc == NULL) 136 if (!ep93xx_rtc)
128 return -ENOMEM; 137 return -ENOMEM;
129 138
130 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 139 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
131 if (res == NULL) { 140 if (!res)
132 err = -ENXIO; 141 return -ENXIO;
133 goto fail_free;
134 }
135 142
136 res = request_mem_region(res->start, resource_size(res), pdev->name); 143 if (!devm_request_mem_region(&pdev->dev, res->start,
137 if (res == NULL) { 144 resource_size(res), pdev->name))
138 err = -EBUSY; 145 return -EBUSY;
139 goto fail_free;
140 }
141 146
142 ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res)); 147 ep93xx_rtc->mmio_base = devm_ioremap(&pdev->dev, res->start,
143 if (ep93xx_rtc->mmio_base == NULL) { 148 resource_size(res));
144 err = -ENXIO; 149 if (!ep93xx_rtc->mmio_base)
145 goto fail; 150 return -ENXIO;
146 }
147 151
148 pdev->dev.platform_data = ep93xx_rtc; 152 pdev->dev.platform_data = ep93xx_rtc;
149 153
@@ -151,53 +155,34 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev)
151 &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); 155 &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE);
152 if (IS_ERR(rtc)) { 156 if (IS_ERR(rtc)) {
153 err = PTR_ERR(rtc); 157 err = PTR_ERR(rtc);
154 goto fail; 158 goto exit;
155 } 159 }
156 160
157 platform_set_drvdata(pdev, rtc); 161 platform_set_drvdata(pdev, rtc);
158 162
159 err = device_create_file(&pdev->dev, &dev_attr_comp_preload); 163 err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
160 if (err) 164 if (err)
161 goto fail; 165 goto fail;
162 err = device_create_file(&pdev->dev, &dev_attr_comp_delete);
163 if (err) {
164 device_remove_file(&pdev->dev, &dev_attr_comp_preload);
165 goto fail;
166 }
167 166
168 return 0; 167 return 0;
169 168
170fail: 169fail:
171 if (ep93xx_rtc->mmio_base) { 170 platform_set_drvdata(pdev, NULL);
172 iounmap(ep93xx_rtc->mmio_base); 171 rtc_device_unregister(rtc);
173 pdev->dev.platform_data = NULL; 172exit:
174 } 173 pdev->dev.platform_data = NULL;
175 release_mem_region(res->start, resource_size(res));
176fail_free:
177 kfree(ep93xx_rtc);
178 return err; 174 return err;
179} 175}
180 176
181static int __exit ep93xx_rtc_remove(struct platform_device *pdev) 177static int __exit ep93xx_rtc_remove(struct platform_device *pdev)
182{ 178{
183 struct rtc_device *rtc = platform_get_drvdata(pdev); 179 struct rtc_device *rtc = platform_get_drvdata(pdev);
184 struct ep93xx_rtc *ep93xx_rtc = pdev->dev.platform_data;
185 struct resource *res;
186
187 /* cleanup sysfs */
188 device_remove_file(&pdev->dev, &dev_attr_comp_delete);
189 device_remove_file(&pdev->dev, &dev_attr_comp_preload);
190 180
181 sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files);
182 platform_set_drvdata(pdev, NULL);
191 rtc_device_unregister(rtc); 183 rtc_device_unregister(rtc);
192
193 iounmap(ep93xx_rtc->mmio_base);
194 pdev->dev.platform_data = NULL; 184 pdev->dev.platform_data = NULL;
195 185
196 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
197 release_mem_region(res->start, resource_size(res));
198
199 platform_set_drvdata(pdev, NULL);
200
201 return 0; 186 return 0;
202} 187}
203 188
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c
new file mode 100644
index 000000000000..acdbb1760187
--- /dev/null
+++ b/drivers/rtc/rtc-max8925.c
@@ -0,0 +1,314 @@
1/*
2 * RTC driver for Maxim MAX8925
3 *
4 * Copyright (C) 2009-2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/i2c.h>
14#include <linux/rtc.h>
15#include <linux/platform_device.h>
16#include <linux/mfd/max8925.h>
17
18enum {
19 RTC_SEC = 0,
20 RTC_MIN,
21 RTC_HOUR,
22 RTC_WEEKDAY,
23 RTC_DATE,
24 RTC_MONTH,
25 RTC_YEAR1,
26 RTC_YEAR2,
27};
28
29#define MAX8925_RTC_SEC 0x00
30#define MAX8925_RTC_MIN 0x01
31#define MAX8925_RTC_HOUR 0x02
32#define MAX8925_RTC_WEEKDAY 0x03
33#define MAX8925_RTC_DATE 0x04
34#define MAX8925_RTC_MONTH 0x05
35#define MAX8925_RTC_YEAR1 0x06
36#define MAX8925_RTC_YEAR2 0x07
37#define MAX8925_ALARM0_SEC 0x08
38#define MAX8925_ALARM0_MIN 0x09
39#define MAX8925_ALARM0_HOUR 0x0a
40#define MAX8925_ALARM0_WEEKDAY 0x0b
41#define MAX8925_ALARM0_DATE 0x0c
42#define MAX8925_ALARM0_MON 0x0d
43#define MAX8925_ALARM0_YEAR1 0x0e
44#define MAX8925_ALARM0_YEAR2 0x0f
45#define MAX8925_ALARM1_SEC 0x10
46#define MAX8925_ALARM1_MIN 0x11
47#define MAX8925_ALARM1_HOUR 0x12
48#define MAX8925_ALARM1_WEEKDAY 0x13
49#define MAX8925_ALARM1_DATE 0x14
50#define MAX8925_ALARM1_MON 0x15
51#define MAX8925_ALARM1_YEAR1 0x16
52#define MAX8925_ALARM1_YEAR2 0x17
53#define MAX8925_RTC_CNTL 0x1b
54#define MAX8925_RTC_STATUS 0x20
55
56#define TIME_NUM 8
57#define ALARM_1SEC (1 << 7)
58#define HOUR_12 (1 << 7)
59#define HOUR_AM_PM (1 << 5)
60#define ALARM0_IRQ (1 << 3)
61#define ALARM1_IRQ (1 << 2)
62#define ALARM0_STATUS (1 << 2)
63#define ALARM1_STATUS (1 << 1)
64
65
66struct max8925_rtc_info {
67 struct rtc_device *rtc_dev;
68 struct max8925_chip *chip;
69 struct i2c_client *rtc;
70 struct device *dev;
71};
72
73static irqreturn_t rtc_update_handler(int irq, void *data)
74{
75 struct max8925_rtc_info *info = (struct max8925_rtc_info *)data;
76
77 /* disable ALARM0 except for 1SEC alarm */
78 max8925_set_bits(info->rtc, MAX8925_ALARM0_CNTL, 0x7f, 0);
79 rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
80 return IRQ_HANDLED;
81}
82
83static int tm_calc(struct rtc_time *tm, unsigned char *buf, int len)
84{
85 if (len < TIME_NUM)
86 return -EINVAL;
87 tm->tm_year = (buf[RTC_YEAR2] >> 4) * 1000
88 + (buf[RTC_YEAR2] & 0xf) * 100
89 + (buf[RTC_YEAR1] >> 4) * 10
90 + (buf[RTC_YEAR1] & 0xf);
91 tm->tm_year -= 1900;
92 tm->tm_mon = ((buf[RTC_MONTH] >> 4) & 0x01) * 10
93 + (buf[RTC_MONTH] & 0x0f);
94 tm->tm_mday = ((buf[RTC_DATE] >> 4) & 0x03) * 10
95 + (buf[RTC_DATE] & 0x0f);
96 tm->tm_wday = buf[RTC_WEEKDAY] & 0x07;
97 if (buf[RTC_HOUR] & HOUR_12) {
98 tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x1) * 10
99 + (buf[RTC_HOUR] & 0x0f);
100 if (buf[RTC_HOUR] & HOUR_AM_PM)
101 tm->tm_hour += 12;
102 } else
103 tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x03) * 10
104 + (buf[RTC_HOUR] & 0x0f);
105 tm->tm_min = ((buf[RTC_MIN] >> 4) & 0x7) * 10
106 + (buf[RTC_MIN] & 0x0f);
107 tm->tm_sec = ((buf[RTC_SEC] >> 4) & 0x7) * 10
108 + (buf[RTC_SEC] & 0x0f);
109 return 0;
110}
111
112static int data_calc(unsigned char *buf, struct rtc_time *tm, int len)
113{
114 unsigned char high, low;
115
116 if (len < TIME_NUM)
117 return -EINVAL;
118
119 high = (tm->tm_year + 1900) / 1000;
120 low = (tm->tm_year + 1900) / 100;
121 low = low - high * 10;
122 buf[RTC_YEAR2] = (high << 4) + low;
123 high = (tm->tm_year + 1900) / 10;
124 low = tm->tm_year + 1900;
125 low = low - high * 10;
126 high = high - (high / 10) * 10;
127 buf[RTC_YEAR1] = (high << 4) + low;
128 high = tm->tm_mon / 10;
129 low = tm->tm_mon;
130 low = low - high * 10;
131 buf[RTC_MONTH] = (high << 4) + low;
132 high = tm->tm_mday / 10;
133 low = tm->tm_mday;
134 low = low - high * 10;
135 buf[RTC_DATE] = (high << 4) + low;
136 buf[RTC_WEEKDAY] = tm->tm_wday;
137 high = tm->tm_hour / 10;
138 low = tm->tm_hour;
139 low = low - high * 10;
140 buf[RTC_HOUR] = (high << 4) + low;
141 high = tm->tm_min / 10;
142 low = tm->tm_min;
143 low = low - high * 10;
144 buf[RTC_MIN] = (high << 4) + low;
145 high = tm->tm_sec / 10;
146 low = tm->tm_sec;
147 low = low - high * 10;
148 buf[RTC_SEC] = (high << 4) + low;
149 return 0;
150}
151
152static int max8925_rtc_read_time(struct device *dev, struct rtc_time *tm)
153{
154 struct max8925_rtc_info *info = dev_get_drvdata(dev);
155 unsigned char buf[TIME_NUM];
156 int ret;
157
158 ret = max8925_bulk_read(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf);
159 if (ret < 0)
160 goto out;
161 ret = tm_calc(tm, buf, TIME_NUM);
162out:
163 return ret;
164}
165
166static int max8925_rtc_set_time(struct device *dev, struct rtc_time *tm)
167{
168 struct max8925_rtc_info *info = dev_get_drvdata(dev);
169 unsigned char buf[TIME_NUM];
170 int ret;
171
172 ret = data_calc(buf, tm, TIME_NUM);
173 if (ret < 0)
174 goto out;
175 ret = max8925_bulk_write(info->rtc, MAX8925_RTC_SEC, TIME_NUM, buf);
176out:
177 return ret;
178}
179
180static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
181{
182 struct max8925_rtc_info *info = dev_get_drvdata(dev);
183 unsigned char buf[TIME_NUM];
184 int ret;
185
186 ret = max8925_bulk_read(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
187 if (ret < 0)
188 goto out;
189 ret = tm_calc(&alrm->time, buf, TIME_NUM);
190 if (ret < 0)
191 goto out;
192 ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK);
193 if (ret < 0)
194 goto out;
195 if ((ret & ALARM0_IRQ) == 0)
196 alrm->enabled = 1;
197 else
198 alrm->enabled = 0;
199 ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS);
200 if (ret < 0)
201 goto out;
202 if (ret & ALARM0_STATUS)
203 alrm->pending = 1;
204 else
205 alrm->pending = 0;
206out:
207 return ret;
208}
209
210static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
211{
212 struct max8925_rtc_info *info = dev_get_drvdata(dev);
213 unsigned char buf[TIME_NUM];
214 int ret;
215
216 ret = data_calc(buf, &alrm->time, TIME_NUM);
217 if (ret < 0)
218 goto out;
219 ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
220 if (ret < 0)
221 goto out;
222 /* only enable alarm on year/month/day/hour/min/sec */
223 ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
224 if (ret < 0)
225 goto out;
226out:
227 return ret;
228}
229
230static const struct rtc_class_ops max8925_rtc_ops = {
231 .read_time = max8925_rtc_read_time,
232 .set_time = max8925_rtc_set_time,
233 .read_alarm = max8925_rtc_read_alarm,
234 .set_alarm = max8925_rtc_set_alarm,
235};
236
237static int __devinit max8925_rtc_probe(struct platform_device *pdev)
238{
239 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
240 struct max8925_rtc_info *info;
241 int irq, ret;
242
243 info = kzalloc(sizeof(struct max8925_rtc_info), GFP_KERNEL);
244 if (!info)
245 return -ENOMEM;
246 info->chip = chip;
247 info->rtc = chip->rtc;
248 info->dev = &pdev->dev;
249 irq = chip->irq_base + MAX8925_IRQ_RTC_ALARM0;
250
251 ret = request_threaded_irq(irq, NULL, rtc_update_handler,
252 IRQF_ONESHOT, "rtc-alarm0", info);
253 if (ret < 0) {
254 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
255 irq, ret);
256 goto out_irq;
257 }
258
259 info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev,
260 &max8925_rtc_ops, THIS_MODULE);
261 ret = PTR_ERR(info->rtc_dev);
262 if (IS_ERR(info->rtc_dev)) {
263 dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
264 goto out_rtc;
265 }
266
267 dev_set_drvdata(&pdev->dev, info);
268 platform_set_drvdata(pdev, info);
269
270 return 0;
271out_rtc:
272 free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info);
273out_irq:
274 kfree(info);
275 return ret;
276}
277
278static int __devexit max8925_rtc_remove(struct platform_device *pdev)
279{
280 struct max8925_rtc_info *info = platform_get_drvdata(pdev);
281
282 if (info) {
283 free_irq(info->chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info);
284 rtc_device_unregister(info->rtc_dev);
285 kfree(info);
286 }
287 return 0;
288}
289
290static struct platform_driver max8925_rtc_driver = {
291 .driver = {
292 .name = "max8925-rtc",
293 .owner = THIS_MODULE,
294 },
295 .probe = max8925_rtc_probe,
296 .remove = __devexit_p(max8925_rtc_remove),
297};
298
299static int __init max8925_rtc_init(void)
300{
301 return platform_driver_register(&max8925_rtc_driver);
302}
303module_init(max8925_rtc_init);
304
305static void __exit max8925_rtc_exit(void)
306{
307 platform_driver_unregister(&max8925_rtc_driver);
308}
309module_exit(max8925_rtc_exit);
310
311MODULE_DESCRIPTION("Maxim MAX8925 RTC driver");
312MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
313MODULE_LICENSE("GPL");
314
diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c
index 850f983c039c..d60c81b7b693 100644
--- a/drivers/rtc/rtc-mc13783.c
+++ b/drivers/rtc/rtc-mc13783.c
@@ -28,6 +28,34 @@ struct mc13783_rtc {
28 int valid; 28 int valid;
29}; 29};
30 30
31static int mc13783_rtc_irq_enable_unlocked(struct device *dev,
32 unsigned int enabled, int irq)
33{
34 struct mc13783_rtc *priv = dev_get_drvdata(dev);
35 int (*func)(struct mc13783 *mc13783, int irq);
36
37 if (!priv->valid)
38 return -ENODATA;
39
40 func = enabled ? mc13783_irq_unmask : mc13783_irq_mask;
41 return func(priv->mc13783, irq);
42}
43
44static int mc13783_rtc_irq_enable(struct device *dev,
45 unsigned int enabled, int irq)
46{
47 struct mc13783_rtc *priv = dev_get_drvdata(dev);
48 int ret;
49
50 mc13783_lock(priv->mc13783);
51
52 ret = mc13783_rtc_irq_enable_unlocked(dev, enabled, irq);
53
54 mc13783_unlock(priv->mc13783);
55
56 return ret;
57}
58
31static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm) 59static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm)
32{ 60{
33 struct mc13783_rtc *priv = dev_get_drvdata(dev); 61 struct mc13783_rtc *priv = dev_get_drvdata(dev);
@@ -78,6 +106,7 @@ static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
78{ 106{
79 struct mc13783_rtc *priv = dev_get_drvdata(dev); 107 struct mc13783_rtc *priv = dev_get_drvdata(dev);
80 unsigned int seconds, days; 108 unsigned int seconds, days;
109 unsigned int alarmseconds;
81 int ret; 110 int ret;
82 111
83 seconds = secs % 86400; 112 seconds = secs % 86400;
@@ -86,7 +115,22 @@ static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
86 mc13783_lock(priv->mc13783); 115 mc13783_lock(priv->mc13783);
87 116
88 /* 117 /*
89 * first write seconds=0 to prevent a day switch between writing days 118 * temporarily invalidate alarm to prevent triggering it when the day is
119 * already updated while the time isn't yet.
120 */
121 ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &alarmseconds);
122 if (unlikely(ret))
123 goto out;
124
125 if (alarmseconds < 86400) {
126 ret = mc13783_reg_write(priv->mc13783,
127 MC13783_RTCTODA, 0x1ffff);
128 if (unlikely(ret))
129 goto out;
130 }
131
132 /*
133 * write seconds=0 to prevent a day switch between writing days
90 * and seconds below 134 * and seconds below
91 */ 135 */
92 ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, 0); 136 ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTOD, 0);
@@ -101,11 +145,19 @@ static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
101 if (unlikely(ret)) 145 if (unlikely(ret))
102 goto out; 146 goto out;
103 147
104 ret = mc13783_ackirq(priv->mc13783, MC13783_IRQ_RTCRST); 148 /* restore alarm */
149 if (alarmseconds < 86400) {
150 ret = mc13783_reg_write(priv->mc13783,
151 MC13783_RTCTODA, alarmseconds);
152 if (unlikely(ret))
153 goto out;
154 }
155
156 ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_RTCRST);
105 if (unlikely(ret)) 157 if (unlikely(ret))
106 goto out; 158 goto out;
107 159
108 ret = mc13783_unmask(priv->mc13783, MC13783_IRQ_RTCRST); 160 ret = mc13783_irq_unmask(priv->mc13783, MC13783_IRQ_RTCRST);
109out: 161out:
110 priv->valid = !ret; 162 priv->valid = !ret;
111 163
@@ -114,41 +166,139 @@ out:
114 return ret; 166 return ret;
115} 167}
116 168
117static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev) 169static int mc13783_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
118{ 170{
119 struct mc13783_rtc *priv = dev; 171 struct mc13783_rtc *priv = dev_get_drvdata(dev);
120 struct mc13783 *mc13783 = priv->mc13783; 172 unsigned seconds, days;
173 unsigned long s1970;
174 int enabled, pending;
175 int ret;
121 176
122 dev_dbg(&priv->rtc->dev, "1HZ\n"); 177 mc13783_lock(priv->mc13783);
123 178
124 rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF); 179 ret = mc13783_reg_read(priv->mc13783, MC13783_RTCTODA, &seconds);
180 if (unlikely(ret))
181 goto out;
182 if (seconds >= 86400) {
183 ret = -ENODATA;
184 goto out;
185 }
186
187 ret = mc13783_reg_read(priv->mc13783, MC13783_RTCDAY, &days);
188 if (unlikely(ret))
189 goto out;
125 190
126 mc13783_ackirq(mc13783, irq); 191 ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_TODA,
192 &enabled, &pending);
127 193
128 return IRQ_HANDLED; 194out:
195 mc13783_unlock(priv->mc13783);
196
197 if (ret)
198 return ret;
199
200 alarm->enabled = enabled;
201 alarm->pending = pending;
202
203 s1970 = days * 86400 + seconds;
204
205 rtc_time_to_tm(s1970, &alarm->time);
206 dev_dbg(dev, "%s: %lu\n", __func__, s1970);
207
208 return 0;
129} 209}
130 210
131static int mc13783_rtc_update_irq_enable(struct device *dev, 211static int mc13783_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
132 unsigned int enabled)
133{ 212{
134 struct mc13783_rtc *priv = dev_get_drvdata(dev); 213 struct mc13783_rtc *priv = dev_get_drvdata(dev);
135 int ret = -ENODATA; 214 unsigned long s1970;
215 unsigned seconds, days;
216 int ret;
136 217
137 mc13783_lock(priv->mc13783); 218 mc13783_lock(priv->mc13783);
138 if (!priv->valid) 219
220 /* disable alarm to prevent false triggering */
221 ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, 0x1ffff);
222 if (unlikely(ret))
139 goto out; 223 goto out;
140 224
141 ret = (enabled ? mc13783_unmask : mc13783_mask)(priv->mc13783, 225 ret = mc13783_irq_ack(priv->mc13783, MC13783_IRQ_TODA);
142 MC13783_IRQ_1HZ); 226 if (unlikely(ret))
227 goto out;
228
229 ret = rtc_tm_to_time(&alarm->time, &s1970);
230 if (unlikely(ret))
231 goto out;
232
233 dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
234 s1970);
235
236 ret = mc13783_rtc_irq_enable_unlocked(dev, alarm->enabled,
237 MC13783_IRQ_TODA);
238 if (unlikely(ret))
239 goto out;
240
241 seconds = s1970 % 86400;
242 days = s1970 / 86400;
243
244 ret = mc13783_reg_write(priv->mc13783, MC13783_RTCDAYA, days);
245 if (unlikely(ret))
246 goto out;
247
248 ret = mc13783_reg_write(priv->mc13783, MC13783_RTCTODA, seconds);
249
143out: 250out:
144 mc13783_unlock(priv->mc13783); 251 mc13783_unlock(priv->mc13783);
145 252
146 return ret; 253 return ret;
147} 254}
148 255
256static irqreturn_t mc13783_rtc_alarm_handler(int irq, void *dev)
257{
258 struct mc13783_rtc *priv = dev;
259 struct mc13783 *mc13783 = priv->mc13783;
260
261 dev_dbg(&priv->rtc->dev, "Alarm\n");
262
263 rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF);
264
265 mc13783_irq_ack(mc13783, irq);
266
267 return IRQ_HANDLED;
268}
269
270static irqreturn_t mc13783_rtc_update_handler(int irq, void *dev)
271{
272 struct mc13783_rtc *priv = dev;
273 struct mc13783 *mc13783 = priv->mc13783;
274
275 dev_dbg(&priv->rtc->dev, "1HZ\n");
276
277 rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
278
279 mc13783_irq_ack(mc13783, irq);
280
281 return IRQ_HANDLED;
282}
283
284static int mc13783_rtc_update_irq_enable(struct device *dev,
285 unsigned int enabled)
286{
287 return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_1HZ);
288}
289
290static int mc13783_rtc_alarm_irq_enable(struct device *dev,
291 unsigned int enabled)
292{
293 return mc13783_rtc_irq_enable(dev, enabled, MC13783_IRQ_TODA);
294}
295
149static const struct rtc_class_ops mc13783_rtc_ops = { 296static const struct rtc_class_ops mc13783_rtc_ops = {
150 .read_time = mc13783_rtc_read_time, 297 .read_time = mc13783_rtc_read_time,
151 .set_mmss = mc13783_rtc_set_mmss, 298 .set_mmss = mc13783_rtc_set_mmss,
299 .read_alarm = mc13783_rtc_read_alarm,
300 .set_alarm = mc13783_rtc_set_alarm,
301 .alarm_irq_enable = mc13783_rtc_alarm_irq_enable,
152 .update_irq_enable = mc13783_rtc_update_irq_enable, 302 .update_irq_enable = mc13783_rtc_update_irq_enable,
153}; 303};
154 304
@@ -160,7 +310,7 @@ static irqreturn_t mc13783_rtc_reset_handler(int irq, void *dev)
160 dev_dbg(&priv->rtc->dev, "RTCRST\n"); 310 dev_dbg(&priv->rtc->dev, "RTCRST\n");
161 priv->valid = 0; 311 priv->valid = 0;
162 312
163 mc13783_mask(mc13783, irq); 313 mc13783_irq_mask(mc13783, irq);
164 314
165 return IRQ_HANDLED; 315 return IRQ_HANDLED;
166} 316}
@@ -169,6 +319,7 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
169{ 319{
170 int ret; 320 int ret;
171 struct mc13783_rtc *priv; 321 struct mc13783_rtc *priv;
322 int rtcrst_pending;
172 323
173 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 324 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
174 if (!priv) 325 if (!priv)
@@ -177,8 +328,6 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
177 priv->mc13783 = dev_get_drvdata(pdev->dev.parent); 328 priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
178 platform_set_drvdata(pdev, priv); 329 platform_set_drvdata(pdev, priv);
179 330
180 priv->valid = 1;
181
182 mc13783_lock(priv->mc13783); 331 mc13783_lock(priv->mc13783);
183 332
184 ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST, 333 ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST,
@@ -186,33 +335,45 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev)
186 if (ret) 335 if (ret)
187 goto err_reset_irq_request; 336 goto err_reset_irq_request;
188 337
338 ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_RTCRST,
339 NULL, &rtcrst_pending);
340 if (ret)
341 goto err_reset_irq_status;
342
343 priv->valid = !rtcrst_pending;
344
189 ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ, 345 ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ,
190 mc13783_rtc_update_handler, DRIVER_NAME, priv); 346 mc13783_rtc_update_handler, DRIVER_NAME, priv);
191 if (ret) 347 if (ret)
192 goto err_update_irq_request; 348 goto err_update_irq_request;
193 349
194 mc13783_unlock(priv->mc13783); 350 ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_TODA,
351 mc13783_rtc_alarm_handler, DRIVER_NAME, priv);
352 if (ret)
353 goto err_alarm_irq_request;
195 354
196 priv->rtc = rtc_device_register(pdev->name, 355 priv->rtc = rtc_device_register(pdev->name,
197 &pdev->dev, &mc13783_rtc_ops, THIS_MODULE); 356 &pdev->dev, &mc13783_rtc_ops, THIS_MODULE);
198
199 if (IS_ERR(priv->rtc)) { 357 if (IS_ERR(priv->rtc)) {
200 ret = PTR_ERR(priv->rtc); 358 ret = PTR_ERR(priv->rtc);
201 359
202 mc13783_lock(priv->mc13783); 360 mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv);
361err_alarm_irq_request:
203 362
204 mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv); 363 mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
205err_update_irq_request: 364err_update_irq_request:
206 365
366err_reset_irq_status:
367
207 mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv); 368 mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
208err_reset_irq_request: 369err_reset_irq_request:
209 370
210 mc13783_unlock(priv->mc13783);
211
212 platform_set_drvdata(pdev, NULL); 371 platform_set_drvdata(pdev, NULL);
213 kfree(priv); 372 kfree(priv);
214 } 373 }
215 374
375 mc13783_unlock(priv->mc13783);
376
216 return ret; 377 return ret;
217} 378}
218 379
@@ -220,10 +381,11 @@ static int __devexit mc13783_rtc_remove(struct platform_device *pdev)
220{ 381{
221 struct mc13783_rtc *priv = platform_get_drvdata(pdev); 382 struct mc13783_rtc *priv = platform_get_drvdata(pdev);
222 383
223 rtc_device_unregister(priv->rtc);
224
225 mc13783_lock(priv->mc13783); 384 mc13783_lock(priv->mc13783);
226 385
386 rtc_device_unregister(priv->rtc);
387
388 mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv);
227 mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv); 389 mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv);
228 mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv); 390 mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv);
229 391
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 6bd5072d4eb7..8710f9415d98 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -396,8 +396,11 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
396 pdata->ioaddr = ioremap(res->start, resource_size(res)); 396 pdata->ioaddr = ioremap(res->start, resource_size(res));
397 397
398 clk = clk_get(&pdev->dev, "ckil"); 398 clk = clk_get(&pdev->dev, "ckil");
399 if (IS_ERR(clk)) 399 if (IS_ERR(clk)) {
400 return PTR_ERR(clk); 400 iounmap(pdata->ioaddr);
401 ret = PTR_ERR(clk);
402 goto exit_free_pdata;
403 }
401 404
402 rate = clk_get_rate(clk); 405 rate = clk_get_rate(clk);
403 clk_put(clk); 406 clk_put(clk);
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index e75df9d50e27..2ceb365533b2 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -315,7 +315,7 @@ kfree_exit:
315 return ret; 315 return ret;
316} 316}
317 317
318static int pcf2123_remove(struct spi_device *spi) 318static int __devexit pcf2123_remove(struct spi_device *spi)
319{ 319{
320 struct pcf2123_plat_data *pdata = spi->dev.platform_data; 320 struct pcf2123_plat_data *pdata = spi->dev.platform_data;
321 int i; 321 int i;
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index c6a83a2a722c..ed1b86828124 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -57,7 +57,7 @@ enum {
57 REG_RTC_COMP_LSB_REG, 57 REG_RTC_COMP_LSB_REG,
58 REG_RTC_COMP_MSB_REG, 58 REG_RTC_COMP_MSB_REG,
59}; 59};
60const static u8 twl4030_rtc_reg_map[] = { 60static const u8 twl4030_rtc_reg_map[] = {
61 [REG_SECONDS_REG] = 0x00, 61 [REG_SECONDS_REG] = 0x00,
62 [REG_MINUTES_REG] = 0x01, 62 [REG_MINUTES_REG] = 0x01,
63 [REG_HOURS_REG] = 0x02, 63 [REG_HOURS_REG] = 0x02,
@@ -80,7 +80,7 @@ const static u8 twl4030_rtc_reg_map[] = {
80 [REG_RTC_COMP_LSB_REG] = 0x10, 80 [REG_RTC_COMP_LSB_REG] = 0x10,
81 [REG_RTC_COMP_MSB_REG] = 0x11, 81 [REG_RTC_COMP_MSB_REG] = 0x11,
82}; 82};
83const static u8 twl6030_rtc_reg_map[] = { 83static const u8 twl6030_rtc_reg_map[] = {
84 [REG_SECONDS_REG] = 0x00, 84 [REG_SECONDS_REG] = 0x00,
85 [REG_MINUTES_REG] = 0x01, 85 [REG_MINUTES_REG] = 0x01,
86 [REG_HOURS_REG] = 0x02, 86 [REG_HOURS_REG] = 0x02,
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index f1e440521c54..3d0dc76b38af 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -307,11 +307,18 @@ static int wm8350_rtc_update_irq_enable(struct device *dev,
307{ 307{
308 struct wm8350 *wm8350 = dev_get_drvdata(dev); 308 struct wm8350 *wm8350 = dev_get_drvdata(dev);
309 309
310 /* Suppress duplicate changes since genirq nests enable and
311 * disable calls. */
312 if (enabled == wm8350->rtc.update_enabled)
313 return 0;
314
310 if (enabled) 315 if (enabled)
311 wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); 316 wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
312 else 317 else
313 wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); 318 wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
314 319
320 wm8350->rtc.update_enabled = enabled;
321
315 return 0; 322 return 0;
316} 323}
317 324
@@ -478,8 +485,8 @@ static int __devexit wm8350_rtc_remove(struct platform_device *pdev)
478 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 485 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
479 struct wm8350_rtc *wm_rtc = &wm8350->rtc; 486 struct wm8350_rtc *wm_rtc = &wm8350->rtc;
480 487
481 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC); 488 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350);
482 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM); 489 wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350);
483 490
484 rtc_device_unregister(wm_rtc->rtc); 491 rtc_device_unregister(wm_rtc->rtc);
485 492
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 4951aa82e9f5..bbea90baf98f 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -26,6 +26,7 @@
26#include <asm/ebcdic.h> 26#include <asm/ebcdic.h>
27#include <asm/idals.h> 27#include <asm/idals.h>
28#include <asm/itcw.h> 28#include <asm/itcw.h>
29#include <asm/diag.h>
29 30
30/* This is ugly... */ 31/* This is ugly... */
31#define PRINTK_HEADER "dasd:" 32#define PRINTK_HEADER "dasd:"
@@ -2212,6 +2213,13 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
2212 goto out; 2213 goto out;
2213 } 2214 }
2214 2215
2216 if ((mode & FMODE_WRITE) &&
2217 (test_bit(DASD_FLAG_DEVICE_RO, &base->flags) ||
2218 (base->features & DASD_FEATURE_READONLY))) {
2219 rc = -EROFS;
2220 goto out;
2221 }
2222
2215 return 0; 2223 return 0;
2216 2224
2217out: 2225out:
@@ -2289,6 +2297,34 @@ dasd_exit(void)
2289 * SECTION: common functions for ccw_driver use 2297 * SECTION: common functions for ccw_driver use
2290 */ 2298 */
2291 2299
2300/*
2301 * Is the device read-only?
2302 * Note that this function does not report the setting of the
2303 * readonly device attribute, but how it is configured in z/VM.
2304 */
2305int dasd_device_is_ro(struct dasd_device *device)
2306{
2307 struct ccw_dev_id dev_id;
2308 struct diag210 diag_data;
2309 int rc;
2310
2311 if (!MACHINE_IS_VM)
2312 return 0;
2313 ccw_device_get_id(device->cdev, &dev_id);
2314 memset(&diag_data, 0, sizeof(diag_data));
2315 diag_data.vrdcdvno = dev_id.devno;
2316 diag_data.vrdclen = sizeof(diag_data);
2317 rc = diag210(&diag_data);
2318 if (rc == 0 || rc == 2) {
2319 return diag_data.vrdcvfla & 0x80;
2320 } else {
2321 DBF_EVENT(DBF_WARNING, "diag210 failed for dev=%04x with rc=%d",
2322 dev_id.devno, rc);
2323 return 0;
2324 }
2325}
2326EXPORT_SYMBOL_GPL(dasd_device_is_ro);
2327
2292static void dasd_generic_auto_online(void *data, async_cookie_t cookie) 2328static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
2293{ 2329{
2294 struct ccw_device *cdev = data; 2330 struct ccw_device *cdev = data;
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 44796ba4eb9b..51224f76b980 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -1045,6 +1045,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
1045 1045
1046 erp->retries = 5; 1046 erp->retries = 5;
1047 1047
1048 } else if (sense[1] & SNS1_WRITE_INHIBITED) {
1049 dev_err(&device->cdev->dev, "An I/O request was rejected"
1050 " because writing is inhibited\n");
1051 erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
1048 } else { 1052 } else {
1049 /* fatal error - set status to FAILED 1053 /* fatal error - set status to FAILED
1050 internal error 09 - Command Reject */ 1054 internal error 09 - Command Reject */
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index d49766f3b940..8e23919c8704 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -742,6 +742,7 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
742 const char *buf, size_t count) 742 const char *buf, size_t count)
743{ 743{
744 struct dasd_devmap *devmap; 744 struct dasd_devmap *devmap;
745 struct dasd_device *device;
745 int val; 746 int val;
746 char *endp; 747 char *endp;
747 748
@@ -758,12 +759,14 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
758 devmap->features |= DASD_FEATURE_READONLY; 759 devmap->features |= DASD_FEATURE_READONLY;
759 else 760 else
760 devmap->features &= ~DASD_FEATURE_READONLY; 761 devmap->features &= ~DASD_FEATURE_READONLY;
761 if (devmap->device) 762 device = devmap->device;
762 devmap->device->features = devmap->features; 763 if (device) {
763 if (devmap->device && devmap->device->block 764 device->features = devmap->features;
764 && devmap->device->block->gdp) 765 val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
765 set_disk_ro(devmap->device->block->gdp, val); 766 }
766 spin_unlock(&dasd_devmap_lock); 767 spin_unlock(&dasd_devmap_lock);
768 if (device && device->block && device->block->gdp)
769 set_disk_ro(device->block->gdp, val);
767 return count; 770 return count;
768} 771}
769 772
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 6e14863f5c70..687f323cdc38 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -145,12 +145,10 @@ dasd_diag_erp(struct dasd_device *device)
145 mdsk_term_io(device); 145 mdsk_term_io(device);
146 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); 146 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
147 if (rc == 4) { 147 if (rc == 4) {
148 if (!(device->features & DASD_FEATURE_READONLY)) { 148 if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags)))
149 pr_warning("%s: The access mode of a DIAG device " 149 pr_warning("%s: The access mode of a DIAG device "
150 "changed to read-only\n", 150 "changed to read-only\n",
151 dev_name(&device->cdev->dev)); 151 dev_name(&device->cdev->dev));
152 device->features |= DASD_FEATURE_READONLY;
153 }
154 rc = 0; 152 rc = 0;
155 } 153 }
156 if (rc) 154 if (rc)
@@ -449,7 +447,7 @@ dasd_diag_check_device(struct dasd_device *device)
449 rc = -EIO; 447 rc = -EIO;
450 } else { 448 } else {
451 if (rc == 4) 449 if (rc == 4)
452 device->features |= DASD_FEATURE_READONLY; 450 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
453 pr_info("%s: New DASD with %ld byte/block, total size %ld " 451 pr_info("%s: New DASD with %ld byte/block, total size %ld "
454 "KB%s\n", dev_name(&device->cdev->dev), 452 "KB%s\n", dev_name(&device->cdev->dev),
455 (unsigned long) block->bp_block, 453 (unsigned long) block->bp_block,
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 1cca21aafaba..01f4e7a34aa8 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1089,6 +1089,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1089 struct dasd_eckd_private *private; 1089 struct dasd_eckd_private *private;
1090 struct dasd_block *block; 1090 struct dasd_block *block;
1091 int is_known, rc; 1091 int is_known, rc;
1092 int readonly;
1092 1093
1093 if (!ccw_device_is_pathgroup(device->cdev)) { 1094 if (!ccw_device_is_pathgroup(device->cdev)) {
1094 dev_warn(&device->cdev->dev, 1095 dev_warn(&device->cdev->dev,
@@ -1182,15 +1183,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1182 else 1183 else
1183 private->real_cyl = private->rdc_data.no_cyl; 1184 private->real_cyl = private->rdc_data.no_cyl;
1184 1185
1186 readonly = dasd_device_is_ro(device);
1187 if (readonly)
1188 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
1189
1185 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) " 1190 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
1186 "with %d cylinders, %d heads, %d sectors\n", 1191 "with %d cylinders, %d heads, %d sectors%s\n",
1187 private->rdc_data.dev_type, 1192 private->rdc_data.dev_type,
1188 private->rdc_data.dev_model, 1193 private->rdc_data.dev_model,
1189 private->rdc_data.cu_type, 1194 private->rdc_data.cu_type,
1190 private->rdc_data.cu_model.model, 1195 private->rdc_data.cu_model.model,
1191 private->real_cyl, 1196 private->real_cyl,
1192 private->rdc_data.trk_per_cyl, 1197 private->rdc_data.trk_per_cyl,
1193 private->rdc_data.sec_per_trk); 1198 private->rdc_data.sec_per_trk,
1199 readonly ? ", read-only device" : "");
1194 return 0; 1200 return 0;
1195 1201
1196out_err3: 1202out_err3:
@@ -2839,8 +2845,13 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
2839 char *psf_data, *rssd_result; 2845 char *psf_data, *rssd_result;
2840 struct dasd_ccw_req *cqr; 2846 struct dasd_ccw_req *cqr;
2841 struct ccw1 *ccw; 2847 struct ccw1 *ccw;
2848 char psf0, psf1;
2842 int rc; 2849 int rc;
2843 2850
2851 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
2852 return -EACCES;
2853 psf0 = psf1 = 0;
2854
2844 /* Copy parms from caller */ 2855 /* Copy parms from caller */
2845 rc = -EFAULT; 2856 rc = -EFAULT;
2846 if (copy_from_user(&usrparm, argp, sizeof(usrparm))) 2857 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
@@ -2869,12 +2880,8 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
2869 (void __user *)(unsigned long) usrparm.psf_data, 2880 (void __user *)(unsigned long) usrparm.psf_data,
2870 usrparm.psf_data_len)) 2881 usrparm.psf_data_len))
2871 goto out_free; 2882 goto out_free;
2872 2883 psf0 = psf_data[0];
2873 /* sanity check on syscall header */ 2884 psf1 = psf_data[1];
2874 if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
2875 rc = -EINVAL;
2876 goto out_free;
2877 }
2878 2885
2879 /* setup CCWs for PSF + RSSD */ 2886 /* setup CCWs for PSF + RSSD */
2880 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device); 2887 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device);
@@ -2925,7 +2932,9 @@ out_free:
2925 kfree(rssd_result); 2932 kfree(rssd_result);
2926 kfree(psf_data); 2933 kfree(psf_data);
2927out: 2934out:
2928 DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc); 2935 DBF_DEV_EVENT(DBF_WARNING, device,
2936 "Symmetrix ioctl (0x%02x 0x%02x): rc=%d",
2937 (int) psf0, (int) psf1, rc);
2929 return rc; 2938 return rc;
2930} 2939}
2931 2940
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 0f152444ac77..37282b90eecc 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -124,6 +124,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
124 struct dasd_fba_private *private; 124 struct dasd_fba_private *private;
125 struct ccw_device *cdev = device->cdev; 125 struct ccw_device *cdev = device->cdev;
126 int rc; 126 int rc;
127 int readonly;
127 128
128 private = (struct dasd_fba_private *) device->private; 129 private = (struct dasd_fba_private *) device->private;
129 if (!private) { 130 if (!private) {
@@ -162,16 +163,21 @@ dasd_fba_check_characteristics(struct dasd_device *device)
162 return rc; 163 return rc;
163 } 164 }
164 165
166 readonly = dasd_device_is_ro(device);
167 if (readonly)
168 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
169
165 dev_info(&device->cdev->dev, 170 dev_info(&device->cdev->dev,
166 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB " 171 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
167 "and %d B/blk\n", 172 "and %d B/blk%s\n",
168 cdev->id.dev_type, 173 cdev->id.dev_type,
169 cdev->id.dev_model, 174 cdev->id.dev_model,
170 cdev->id.cu_type, 175 cdev->id.cu_type,
171 cdev->id.cu_model, 176 cdev->id.cu_model,
172 ((private->rdc_data.blk_bdsa * 177 ((private->rdc_data.blk_bdsa *
173 (private->rdc_data.blk_size >> 9)) >> 11), 178 (private->rdc_data.blk_size >> 9)) >> 11),
174 private->rdc_data.blk_size); 179 private->rdc_data.blk_size,
180 readonly ? ", read-only device" : "");
175 return 0; 181 return 0;
176} 182}
177 183
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 94f92a1247f2..30a1ca3d08b7 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -70,7 +70,8 @@ int dasd_gendisk_alloc(struct dasd_block *block)
70 } 70 }
71 len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); 71 len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26));
72 72
73 if (block->base->features & DASD_FEATURE_READONLY) 73 if (base->features & DASD_FEATURE_READONLY ||
74 test_bit(DASD_FLAG_DEVICE_RO, &base->flags))
74 set_disk_ro(gdp, 1); 75 set_disk_ro(gdp, 1);
75 gdp->private_data = block; 76 gdp->private_data = block;
76 gdp->queue = block->request_queue; 77 gdp->queue = block->request_queue;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index ed73ce550822..a91d4a97d4f2 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -436,6 +436,10 @@ struct dasd_block {
436#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 436#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
437#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ 437#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */
438#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ 438#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */
439#define DASD_FLAG_DEVICE_RO 6 /* The device itself is read-only. Don't
440 * confuse this with the user specified
441 * read-only feature.
442 */
439 443
440void dasd_put_device_wake(struct dasd_device *); 444void dasd_put_device_wake(struct dasd_device *);
441 445
@@ -609,6 +613,9 @@ char *dasd_get_sense(struct irb *);
609void dasd_device_set_stop_bits(struct dasd_device *, int); 613void dasd_device_set_stop_bits(struct dasd_device *, int);
610void dasd_device_remove_stop_bits(struct dasd_device *, int); 614void dasd_device_remove_stop_bits(struct dasd_device *, int);
611 615
616int dasd_device_is_ro(struct dasd_device *);
617
618
612/* externals in dasd_devmap.c */ 619/* externals in dasd_devmap.c */
613extern int dasd_max_devindex; 620extern int dasd_max_devindex;
614extern int dasd_probeonly; 621extern int dasd_probeonly;
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 7039d9cf0fb4..3479f8158a1b 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -199,7 +199,8 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
199 if (!argp) 199 if (!argp)
200 return -EINVAL; 200 return -EINVAL;
201 201
202 if (block->base->features & DASD_FEATURE_READONLY) 202 if (block->base->features & DASD_FEATURE_READONLY ||
203 test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
203 return -EROFS; 204 return -EROFS;
204 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) 205 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
205 return -EFAULT; 206 return -EFAULT;
@@ -349,7 +350,8 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp)
349 return -EINVAL; 350 return -EINVAL;
350 if (get_user(intval, (int __user *)argp)) 351 if (get_user(intval, (int __user *)argp))
351 return -EFAULT; 352 return -EFAULT;
352 353 if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
354 return -EROFS;
353 set_disk_ro(bdev->bd_disk, intval); 355 set_disk_ro(bdev->bd_disk, intval);
354 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); 356 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval);
355} 357}
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index c6abb75c4615..6d229f3523a0 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -764,7 +764,7 @@ static void sch_create_and_recog_new_device(struct subchannel *sch)
764static void io_subchannel_register(struct ccw_device *cdev) 764static void io_subchannel_register(struct ccw_device *cdev)
765{ 765{
766 struct subchannel *sch; 766 struct subchannel *sch;
767 int ret; 767 int ret, adjust_init_count = 1;
768 unsigned long flags; 768 unsigned long flags;
769 769
770 sch = to_subchannel(cdev->dev.parent); 770 sch = to_subchannel(cdev->dev.parent);
@@ -793,6 +793,7 @@ static void io_subchannel_register(struct ccw_device *cdev)
793 cdev->private->dev_id.ssid, 793 cdev->private->dev_id.ssid,
794 cdev->private->dev_id.devno); 794 cdev->private->dev_id.devno);
795 } 795 }
796 adjust_init_count = 0;
796 goto out; 797 goto out;
797 } 798 }
798 /* 799 /*
@@ -818,7 +819,7 @@ out:
818 cdev->private->flags.recog_done = 1; 819 cdev->private->flags.recog_done = 1;
819 wake_up(&cdev->private->wait_q); 820 wake_up(&cdev->private->wait_q);
820out_err: 821out_err:
821 if (atomic_dec_and_test(&ccw_device_init_count)) 822 if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count))
822 wake_up(&ccw_device_init_wq); 823 wake_up(&ccw_device_init_wq);
823} 824}
824 825
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index c94eb2a0fa2e..6ce83f56d537 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -33,7 +33,6 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data,
33 DBF_HEX(&init_data->input_handler, sizeof(void *)); 33 DBF_HEX(&init_data->input_handler, sizeof(void *));
34 DBF_HEX(&init_data->output_handler, sizeof(void *)); 34 DBF_HEX(&init_data->output_handler, sizeof(void *));
35 DBF_HEX(&init_data->int_parm, sizeof(long)); 35 DBF_HEX(&init_data->int_parm, sizeof(long));
36 DBF_HEX(&init_data->flags, sizeof(long));
37 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *)); 36 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
38 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *)); 37 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
39 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); 38 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 232ef047ba34..4f8f74311778 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -588,10 +588,11 @@ static void qdio_kick_handler(struct qdio_q *q)
588 if (q->is_input_q) { 588 if (q->is_input_q) {
589 qperf_inc(q, inbound_handler); 589 qperf_inc(q, inbound_handler);
590 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 590 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
591 } else 591 } else {
592 qperf_inc(q, outbound_handler); 592 qperf_inc(q, outbound_handler);
593 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", 593 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
594 start, count); 594 start, count);
595 }
595 596
596 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, 597 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
597 q->irq_ptr->int_parm); 598 q->irq_ptr->int_parm);
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index cb909a5b5047..977bb4d4ed15 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -43,6 +43,16 @@ config SMSGIUCV
43 Select this option if you want to be able to receive SMSG messages 43 Select this option if you want to be able to receive SMSG messages
44 from other VM guest systems. 44 from other VM guest systems.
45 45
46config SMSGIUCV_EVENT
47 tristate "Deliver IUCV special messages as uevents (VM only)"
48 depends on SMSGIUCV
49 help
50 Select this option to deliver CP special messages (SMSGs) as
51 uevents. The driver handles only those special messages that
52 start with "APP".
53
54 To compile as a module, choose M. The module name is "smsgiucv_app".
55
46config CLAW 56config CLAW
47 tristate "CLAW device support" 57 tristate "CLAW device support"
48 depends on CCW && NETDEVICES 58 depends on CCW && NETDEVICES
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 6cab5a62f99e..4dfe8c1092da 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -6,6 +6,7 @@ ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o
6obj-$(CONFIG_CTCM) += ctcm.o fsm.o 6obj-$(CONFIG_CTCM) += ctcm.o fsm.o
7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
9obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o
9obj-$(CONFIG_LCS) += lcs.o 10obj-$(CONFIG_LCS) += lcs.o
10obj-$(CONFIG_CLAW) += claw.o 11obj-$(CONFIG_CLAW) += claw.o
11qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o 12qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index fa8a519218ac..7d25bdd443cd 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3805,9 +3805,6 @@ static int qeth_qdio_establish(struct qeth_card *card)
3805 init_data.input_handler = card->discipline.input_handler; 3805 init_data.input_handler = card->discipline.input_handler;
3806 init_data.output_handler = card->discipline.output_handler; 3806 init_data.output_handler = card->discipline.output_handler;
3807 init_data.int_parm = (unsigned long) card; 3807 init_data.int_parm = (unsigned long) card;
3808 init_data.flags = QDIO_INBOUND_0COPY_SBALS |
3809 QDIO_OUTBOUND_0COPY_SBALS |
3810 QDIO_USE_OUTBOUND_PCIS;
3811 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 3808 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3812 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 3809 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
3813 3810
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 67f2485d2372..ecef1edee701 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -31,9 +31,9 @@
31 31
32struct smsg_callback { 32struct smsg_callback {
33 struct list_head list; 33 struct list_head list;
34 char *prefix; 34 const char *prefix;
35 int len; 35 int len;
36 void (*callback)(char *from, char *str); 36 void (*callback)(const char *from, char *str);
37}; 37};
38 38
39MODULE_AUTHOR 39MODULE_AUTHOR
@@ -100,8 +100,8 @@ static void smsg_message_pending(struct iucv_path *path,
100 kfree(buffer); 100 kfree(buffer);
101} 101}
102 102
103int smsg_register_callback(char *prefix, 103int smsg_register_callback(const char *prefix,
104 void (*callback)(char *from, char *str)) 104 void (*callback)(const char *from, char *str))
105{ 105{
106 struct smsg_callback *cb; 106 struct smsg_callback *cb;
107 107
@@ -117,8 +117,9 @@ int smsg_register_callback(char *prefix,
117 return 0; 117 return 0;
118} 118}
119 119
120void smsg_unregister_callback(char *prefix, 120void smsg_unregister_callback(const char *prefix,
121 void (*callback)(char *from, char *str)) 121 void (*callback)(const char *from,
122 char *str))
122{ 123{
123 struct smsg_callback *cb, *tmp; 124 struct smsg_callback *cb, *tmp;
124 125
@@ -176,7 +177,7 @@ static const struct dev_pm_ops smsg_pm_ops = {
176 177
177static struct device_driver smsg_driver = { 178static struct device_driver smsg_driver = {
178 .owner = THIS_MODULE, 179 .owner = THIS_MODULE,
179 .name = "SMSGIUCV", 180 .name = SMSGIUCV_DRV_NAME,
180 .bus = &iucv_bus, 181 .bus = &iucv_bus,
181 .pm = &smsg_pm_ops, 182 .pm = &smsg_pm_ops,
182}; 183};
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h
index 67f5d4f8378d..149a1151608d 100644
--- a/drivers/s390/net/smsgiucv.h
+++ b/drivers/s390/net/smsgiucv.h
@@ -5,6 +5,10 @@
5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6 */ 6 */
7 7
8int smsg_register_callback(char *, void (*)(char *, char *)); 8#define SMSGIUCV_DRV_NAME "SMSGIUCV"
9void smsg_unregister_callback(char *, void (*)(char *, char *)); 9
10int smsg_register_callback(const char *,
11 void (*)(const char *, char *));
12void smsg_unregister_callback(const char *,
13 void (*)(const char *, char *));
10 14
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c
new file mode 100644
index 000000000000..91579dc6a2b0
--- /dev/null
+++ b/drivers/s390/net/smsgiucv_app.c
@@ -0,0 +1,211 @@
1/*
2 * Deliver z/VM CP special messages (SMSG) as uevents.
3 *
4 * The driver registers for z/VM CP special messages with the
5 * "APP" prefix. Incoming messages are delivered to user space
6 * as uevents.
7 *
8 * Copyright IBM Corp. 2010
9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
10 *
11 */
12#define KMSG_COMPONENT "smsgiucv_app"
13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14
15#include <linux/ctype.h>
16#include <linux/err.h>
17#include <linux/device.h>
18#include <linux/list.h>
19#include <linux/kobject.h>
20#include <linux/module.h>
21#include <linux/spinlock.h>
22#include <linux/workqueue.h>
23#include <net/iucv/iucv.h>
24#include "smsgiucv.h"
25
26/* prefix used for SMSG registration */
27#define SMSG_PREFIX "APP"
28
29/* SMSG related uevent environment variables */
30#define ENV_SENDER_STR "SMSG_SENDER="
31#define ENV_SENDER_LEN (strlen(ENV_SENDER_STR) + 8 + 1)
32#define ENV_PREFIX_STR "SMSG_ID="
33#define ENV_PREFIX_LEN (strlen(ENV_PREFIX_STR) + \
34 strlen(SMSG_PREFIX) + 1)
35#define ENV_TEXT_STR "SMSG_TEXT="
36#define ENV_TEXT_LEN(msg) (strlen(ENV_TEXT_STR) + strlen((msg)) + 1)
37
38/* z/VM user ID which is permitted to send SMSGs
39 * If the value is undefined or empty (""), special messages are
40 * accepted from any z/VM user ID. */
41static char *sender;
42module_param(sender, charp, 0400);
43MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted");
44
45/* SMSG device representation */
46static struct device *smsg_app_dev;
47
48/* list element for queuing received messages for delivery */
49struct smsg_app_event {
50 struct list_head list;
51 char *buf;
52 char *envp[4];
53};
54
55/* queue for outgoing uevents */
56static LIST_HEAD(smsg_event_queue);
57static DEFINE_SPINLOCK(smsg_event_queue_lock);
58
59static void smsg_app_event_free(struct smsg_app_event *ev)
60{
61 kfree(ev->buf);
62 kfree(ev);
63}
64
65static struct smsg_app_event *smsg_app_event_alloc(const char *from,
66 const char *msg)
67{
68 struct smsg_app_event *ev;
69
70 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
71 if (!ev)
72 return NULL;
73
74 ev->buf = kzalloc(ENV_SENDER_LEN + ENV_PREFIX_LEN +
75 ENV_TEXT_LEN(msg), GFP_ATOMIC);
76 if (!ev->buf) {
77 kfree(ev);
78 return NULL;
79 }
80
81 /* setting up environment pointers into buf */
82 ev->envp[0] = ev->buf;
83 ev->envp[1] = ev->envp[0] + ENV_SENDER_LEN;
84 ev->envp[2] = ev->envp[1] + ENV_PREFIX_LEN;
85 ev->envp[3] = NULL;
86
87 /* setting up environment: sender, prefix name, and message text */
88 snprintf(ev->envp[0], ENV_SENDER_LEN, ENV_SENDER_STR "%s", from);
89 snprintf(ev->envp[1], ENV_PREFIX_LEN, ENV_PREFIX_STR "%s", SMSG_PREFIX);
90 snprintf(ev->envp[2], ENV_TEXT_LEN(msg), ENV_TEXT_STR "%s", msg);
91
92 return ev;
93}
94
95static void smsg_event_work_fn(struct work_struct *work)
96{
97 LIST_HEAD(event_queue);
98 struct smsg_app_event *p, *n;
99 struct device *dev;
100
101 dev = get_device(smsg_app_dev);
102 if (!dev)
103 return;
104
105 spin_lock_bh(&smsg_event_queue_lock);
106 list_splice_init(&smsg_event_queue, &event_queue);
107 spin_unlock_bh(&smsg_event_queue_lock);
108
109 list_for_each_entry_safe(p, n, &event_queue, list) {
110 list_del(&p->list);
111 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, p->envp);
112 smsg_app_event_free(p);
113 }
114
115 put_device(dev);
116}
117static DECLARE_WORK(smsg_event_work, smsg_event_work_fn);
118
119static void smsg_app_callback(const char *from, char *msg)
120{
121 struct smsg_app_event *se;
122
123 /* check if the originating z/VM user ID matches
124 * the configured sender. */
125 if (sender && strlen(sender) > 0 && strcmp(from, sender) != 0)
126 return;
127
128 /* get start of message text (skip prefix and leading blanks) */
129 msg += strlen(SMSG_PREFIX);
130 while (*msg && isspace(*msg))
131 msg++;
132 if (*msg == '\0')
133 return;
134
135 /* allocate event list element and its environment */
136 se = smsg_app_event_alloc(from, msg);
137 if (!se)
138 return;
139
140 /* queue event and schedule work function */
141 spin_lock(&smsg_event_queue_lock);
142 list_add_tail(&se->list, &smsg_event_queue);
143 spin_unlock(&smsg_event_queue_lock);
144
145 schedule_work(&smsg_event_work);
146 return;
147}
148
149static int __init smsgiucv_app_init(void)
150{
151 struct device_driver *smsgiucv_drv;
152 int rc;
153
154 if (!MACHINE_IS_VM)
155 return -ENODEV;
156
157 smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL);
158 if (!smsg_app_dev)
159 return -ENOMEM;
160
161 smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus);
162 if (!smsgiucv_drv) {
163 kfree(smsg_app_dev);
164 return -ENODEV;
165 }
166
167 rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT);
168 if (rc) {
169 kfree(smsg_app_dev);
170 goto fail_put_driver;
171 }
172 smsg_app_dev->bus = &iucv_bus;
173 smsg_app_dev->parent = iucv_root;
174 smsg_app_dev->release = (void (*)(struct device *)) kfree;
175 smsg_app_dev->driver = smsgiucv_drv;
176 rc = device_register(smsg_app_dev);
177 if (rc) {
178 put_device(smsg_app_dev);
179 goto fail_put_driver;
180 }
181
182 /* register with the smsgiucv device driver */
183 rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback);
184 if (rc) {
185 device_unregister(smsg_app_dev);
186 goto fail_put_driver;
187 }
188
189 rc = 0;
190fail_put_driver:
191 put_driver(smsgiucv_drv);
192 return rc;
193}
194module_init(smsgiucv_app_init);
195
196static void __exit smsgiucv_app_exit(void)
197{
198 /* unregister callback */
199 smsg_unregister_callback(SMSG_PREFIX, smsg_app_callback);
200
201 /* cancel pending work and flush any queued event work */
202 cancel_work_sync(&smsg_event_work);
203 smsg_event_work_fn(&smsg_event_work);
204
205 device_unregister(smsg_app_dev);
206}
207module_exit(smsgiucv_app_exit);
208
209MODULE_LICENSE("GPL v2");
210MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents");
211MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 71b97ff77cf0..6479273a3094 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -319,8 +319,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
319 id->input_handler = zfcp_qdio_int_resp; 319 id->input_handler = zfcp_qdio_int_resp;
320 id->output_handler = zfcp_qdio_int_req; 320 id->output_handler = zfcp_qdio_int_req;
321 id->int_parm = (unsigned long) qdio; 321 id->int_parm = (unsigned long) qdio;
322 id->flags = QDIO_INBOUND_0COPY_SBALS |
323 QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
324 id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); 322 id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal);
325 id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); 323 id->output_sbal_addr_array = (void **) (qdio->req_q.sbal);
326 324
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 746e07033dce..d6ff73395623 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1009,6 +1009,10 @@ config SERIAL_SH_SCI_CONSOLE
1009 depends on SERIAL_SH_SCI=y 1009 depends on SERIAL_SH_SCI=y
1010 select SERIAL_CORE_CONSOLE 1010 select SERIAL_CORE_CONSOLE
1011 1011
1012config SERIAL_SH_SCI_DMA
1013 bool "DMA support"
1014 depends on SERIAL_SH_SCI && SH_DMAE && EXPERIMENTAL
1015
1012config SERIAL_PNX8XXX 1016config SERIAL_PNX8XXX
1013 bool "Enable PNX8XXX SoCs' UART Support" 1017 bool "Enable PNX8XXX SoCs' UART Support"
1014 depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) 1018 depends on MIPS && (SOC_PNX8550 || SOC_PNX833X)
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 42f3333c4ad0..980f39449ee5 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -48,6 +48,9 @@
48#include <linux/ctype.h> 48#include <linux/ctype.h>
49#include <linux/err.h> 49#include <linux/err.h>
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/dmaengine.h>
52#include <linux/scatterlist.h>
53#include <linux/timer.h>
51 54
52#ifdef CONFIG_SUPERH 55#ifdef CONFIG_SUPERH
53#include <asm/sh_bios.h> 56#include <asm/sh_bios.h>
@@ -84,6 +87,27 @@ struct sci_port {
84 struct clk *dclk; 87 struct clk *dclk;
85 88
86 struct list_head node; 89 struct list_head node;
90 struct dma_chan *chan_tx;
91 struct dma_chan *chan_rx;
92#ifdef CONFIG_SERIAL_SH_SCI_DMA
93 struct device *dma_dev;
94 enum sh_dmae_slave_chan_id slave_tx;
95 enum sh_dmae_slave_chan_id slave_rx;
96 struct dma_async_tx_descriptor *desc_tx;
97 struct dma_async_tx_descriptor *desc_rx[2];
98 dma_cookie_t cookie_tx;
99 dma_cookie_t cookie_rx[2];
100 dma_cookie_t active_rx;
101 struct scatterlist sg_tx;
102 unsigned int sg_len_tx;
103 struct scatterlist sg_rx[2];
104 size_t buf_len_rx;
105 struct sh_dmae_slave param_tx;
106 struct sh_dmae_slave param_rx;
107 struct work_struct work_tx;
108 struct work_struct work_rx;
109 struct timer_list rx_timer;
110#endif
87}; 111};
88 112
89struct sh_sci_priv { 113struct sh_sci_priv {
@@ -269,29 +293,44 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
269 defined(CONFIG_CPU_SUBTYPE_SH7780) || \ 293 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
270 defined(CONFIG_CPU_SUBTYPE_SH7785) || \ 294 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
271 defined(CONFIG_CPU_SUBTYPE_SH7786) 295 defined(CONFIG_CPU_SUBTYPE_SH7786)
272static inline int scif_txroom(struct uart_port *port) 296static int scif_txfill(struct uart_port *port)
273{ 297{
274 return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); 298 return sci_in(port, SCTFDR) & 0xff;
275} 299}
276 300
277static inline int scif_rxroom(struct uart_port *port) 301static int scif_txroom(struct uart_port *port)
302{
303 return SCIF_TXROOM_MAX - scif_txfill(port);
304}
305
306static int scif_rxfill(struct uart_port *port)
278{ 307{
279 return sci_in(port, SCRFDR) & 0xff; 308 return sci_in(port, SCRFDR) & 0xff;
280} 309}
281#elif defined(CONFIG_CPU_SUBTYPE_SH7763) 310#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
282static inline int scif_txroom(struct uart_port *port) 311static int scif_txfill(struct uart_port *port)
283{ 312{
284 if ((port->mapbase == 0xffe00000) || 313 if (port->mapbase == 0xffe00000 ||
285 (port->mapbase == 0xffe08000)) { 314 port->mapbase == 0xffe08000)
286 /* SCIF0/1*/ 315 /* SCIF0/1*/
287 return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); 316 return sci_in(port, SCTFDR) & 0xff;
288 } else { 317 else
289 /* SCIF2 */ 318 /* SCIF2 */
290 return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); 319 return sci_in(port, SCFDR) >> 8;
291 }
292} 320}
293 321
294static inline int scif_rxroom(struct uart_port *port) 322static int scif_txroom(struct uart_port *port)
323{
324 if (port->mapbase == 0xffe00000 ||
325 port->mapbase == 0xffe08000)
326 /* SCIF0/1*/
327 return SCIF_TXROOM_MAX - scif_txfill(port);
328 else
329 /* SCIF2 */
330 return SCIF2_TXROOM_MAX - scif_txfill(port);
331}
332
333static int scif_rxfill(struct uart_port *port)
295{ 334{
296 if ((port->mapbase == 0xffe00000) || 335 if ((port->mapbase == 0xffe00000) ||
297 (port->mapbase == 0xffe08000)) { 336 (port->mapbase == 0xffe08000)) {
@@ -303,23 +342,33 @@ static inline int scif_rxroom(struct uart_port *port)
303 } 342 }
304} 343}
305#else 344#else
306static inline int scif_txroom(struct uart_port *port) 345static int scif_txfill(struct uart_port *port)
346{
347 return sci_in(port, SCFDR) >> 8;
348}
349
350static int scif_txroom(struct uart_port *port)
307{ 351{
308 return SCIF_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); 352 return SCIF_TXROOM_MAX - scif_txfill(port);
309} 353}
310 354
311static inline int scif_rxroom(struct uart_port *port) 355static int scif_rxfill(struct uart_port *port)
312{ 356{
313 return sci_in(port, SCFDR) & SCIF_RFDC_MASK; 357 return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
314} 358}
315#endif 359#endif
316 360
317static inline int sci_txroom(struct uart_port *port) 361static int sci_txfill(struct uart_port *port)
318{ 362{
319 return (sci_in(port, SCxSR) & SCI_TDRE) != 0; 363 return !(sci_in(port, SCxSR) & SCI_TDRE);
320} 364}
321 365
322static inline int sci_rxroom(struct uart_port *port) 366static int sci_txroom(struct uart_port *port)
367{
368 return !sci_txfill(port);
369}
370
371static int sci_rxfill(struct uart_port *port)
323{ 372{
324 return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; 373 return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
325} 374}
@@ -406,9 +455,9 @@ static inline void sci_receive_chars(struct uart_port *port)
406 455
407 while (1) { 456 while (1) {
408 if (port->type == PORT_SCI) 457 if (port->type == PORT_SCI)
409 count = sci_rxroom(port); 458 count = sci_rxfill(port);
410 else 459 else
411 count = scif_rxroom(port); 460 count = scif_rxfill(port);
412 461
413 /* Don't copy more bytes than there is room for in the buffer */ 462 /* Don't copy more bytes than there is room for in the buffer */
414 count = tty_buffer_request_room(tty, count); 463 count = tty_buffer_request_room(tty, count);
@@ -453,10 +502,10 @@ static inline void sci_receive_chars(struct uart_port *port)
453 } 502 }
454 503
455 /* Store data and status */ 504 /* Store data and status */
456 if (status&SCxSR_FER(port)) { 505 if (status & SCxSR_FER(port)) {
457 flag = TTY_FRAME; 506 flag = TTY_FRAME;
458 dev_notice(port->dev, "frame error\n"); 507 dev_notice(port->dev, "frame error\n");
459 } else if (status&SCxSR_PER(port)) { 508 } else if (status & SCxSR_PER(port)) {
460 flag = TTY_PARITY; 509 flag = TTY_PARITY;
461 dev_notice(port->dev, "parity error\n"); 510 dev_notice(port->dev, "parity error\n");
462 } else 511 } else
@@ -618,13 +667,39 @@ static inline int sci_handle_breaks(struct uart_port *port)
618 return copied; 667 return copied;
619} 668}
620 669
621static irqreturn_t sci_rx_interrupt(int irq, void *port) 670static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
622{ 671{
672#ifdef CONFIG_SERIAL_SH_SCI_DMA
673 struct uart_port *port = ptr;
674 struct sci_port *s = to_sci_port(port);
675
676 if (s->chan_rx) {
677 unsigned long tout;
678 u16 scr = sci_in(port, SCSCR);
679 u16 ssr = sci_in(port, SCxSR);
680
681 /* Disable future Rx interrupts */
682 sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE);
683 /* Clear current interrupt */
684 sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
685 /* Calculate delay for 1.5 DMA buffers */
686 tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 /
687 port->fifosize / 2;
688 dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n",
689 tout * 1000 / HZ);
690 if (tout < 2)
691 tout = 2;
692 mod_timer(&s->rx_timer, jiffies + tout);
693
694 return IRQ_HANDLED;
695 }
696#endif
697
623 /* I think sci_receive_chars has to be called irrespective 698 /* I think sci_receive_chars has to be called irrespective
624 * of whether the I_IXOFF is set, otherwise, how is the interrupt 699 * of whether the I_IXOFF is set, otherwise, how is the interrupt
625 * to be disabled? 700 * to be disabled?
626 */ 701 */
627 sci_receive_chars(port); 702 sci_receive_chars(ptr);
628 703
629 return IRQ_HANDLED; 704 return IRQ_HANDLED;
630} 705}
@@ -680,6 +755,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
680{ 755{
681 unsigned short ssr_status, scr_status, err_enabled; 756 unsigned short ssr_status, scr_status, err_enabled;
682 struct uart_port *port = ptr; 757 struct uart_port *port = ptr;
758 struct sci_port *s = to_sci_port(port);
683 irqreturn_t ret = IRQ_NONE; 759 irqreturn_t ret = IRQ_NONE;
684 760
685 ssr_status = sci_in(port, SCxSR); 761 ssr_status = sci_in(port, SCxSR);
@@ -687,10 +763,15 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
687 err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE); 763 err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE);
688 764
689 /* Tx Interrupt */ 765 /* Tx Interrupt */
690 if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE)) 766 if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE) &&
767 !s->chan_tx)
691 ret = sci_tx_interrupt(irq, ptr); 768 ret = sci_tx_interrupt(irq, ptr);
692 /* Rx Interrupt */ 769 /*
693 if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE)) 770 * Rx Interrupt: if we're using DMA, the DMA controller clears RDF /
771 * DR flags
772 */
773 if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) &&
774 (scr_status & SCI_CTRL_FLAGS_RIE))
694 ret = sci_rx_interrupt(irq, ptr); 775 ret = sci_rx_interrupt(irq, ptr);
695 /* Error Interrupt */ 776 /* Error Interrupt */
696 if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) 777 if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
@@ -699,6 +780,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
699 if ((ssr_status & SCxSR_BRK(port)) && err_enabled) 780 if ((ssr_status & SCxSR_BRK(port)) && err_enabled)
700 ret = sci_br_interrupt(irq, ptr); 781 ret = sci_br_interrupt(irq, ptr);
701 782
783 WARN_ONCE(ret == IRQ_NONE,
784 "%s: %d IRQ %d, status %x, control %x\n", __func__,
785 irq, port->line, ssr_status, scr_status);
786
702 return ret; 787 return ret;
703} 788}
704 789
@@ -800,7 +885,9 @@ static void sci_free_irq(struct sci_port *port)
800static unsigned int sci_tx_empty(struct uart_port *port) 885static unsigned int sci_tx_empty(struct uart_port *port)
801{ 886{
802 unsigned short status = sci_in(port, SCxSR); 887 unsigned short status = sci_in(port, SCxSR);
803 return status & SCxSR_TEND(port) ? TIOCSER_TEMT : 0; 888 unsigned short in_tx_fifo = scif_txfill(port);
889
890 return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
804} 891}
805 892
806static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) 893static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
@@ -812,16 +899,297 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
812 899
813static unsigned int sci_get_mctrl(struct uart_port *port) 900static unsigned int sci_get_mctrl(struct uart_port *port)
814{ 901{
815 /* This routine is used for geting signals of: DTR, DCD, DSR, RI, 902 /* This routine is used for getting signals of: DTR, DCD, DSR, RI,
816 and CTS/RTS */ 903 and CTS/RTS */
817 904
818 return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; 905 return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR;
819} 906}
820 907
908#ifdef CONFIG_SERIAL_SH_SCI_DMA
909static void sci_dma_tx_complete(void *arg)
910{
911 struct sci_port *s = arg;
912 struct uart_port *port = &s->port;
913 struct circ_buf *xmit = &port->state->xmit;
914 unsigned long flags;
915
916 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
917
918 spin_lock_irqsave(&port->lock, flags);
919
920 xmit->tail += s->sg_tx.length;
921 xmit->tail &= UART_XMIT_SIZE - 1;
922
923 port->icount.tx += s->sg_tx.length;
924
925 async_tx_ack(s->desc_tx);
926 s->cookie_tx = -EINVAL;
927 s->desc_tx = NULL;
928
929 spin_unlock_irqrestore(&port->lock, flags);
930
931 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
932 uart_write_wakeup(port);
933
934 if (uart_circ_chars_pending(xmit))
935 schedule_work(&s->work_tx);
936}
937
938/* Locking: called with port lock held */
939static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty,
940 size_t count)
941{
942 struct uart_port *port = &s->port;
943 int i, active, room;
944
945 room = tty_buffer_request_room(tty, count);
946
947 if (s->active_rx == s->cookie_rx[0]) {
948 active = 0;
949 } else if (s->active_rx == s->cookie_rx[1]) {
950 active = 1;
951 } else {
952 dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
953 return 0;
954 }
955
956 if (room < count)
957 dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
958 count - room);
959 if (!room)
960 return room;
961
962 for (i = 0; i < room; i++)
963 tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i],
964 TTY_NORMAL);
965
966 port->icount.rx += room;
967
968 return room;
969}
970
971static void sci_dma_rx_complete(void *arg)
972{
973 struct sci_port *s = arg;
974 struct uart_port *port = &s->port;
975 struct tty_struct *tty = port->state->port.tty;
976 unsigned long flags;
977 int count;
978
979 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
980
981 spin_lock_irqsave(&port->lock, flags);
982
983 count = sci_dma_rx_push(s, tty, s->buf_len_rx);
984
985 mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5));
986
987 spin_unlock_irqrestore(&port->lock, flags);
988
989 if (count)
990 tty_flip_buffer_push(tty);
991
992 schedule_work(&s->work_rx);
993}
994
995static void sci_start_rx(struct uart_port *port);
996static void sci_start_tx(struct uart_port *port);
997
998static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
999{
1000 struct dma_chan *chan = s->chan_rx;
1001 struct uart_port *port = &s->port;
1002
1003 s->chan_rx = NULL;
1004 s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
1005 dma_release_channel(chan);
1006 dma_free_coherent(port->dev, s->buf_len_rx * 2,
1007 sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
1008 if (enable_pio)
1009 sci_start_rx(port);
1010}
1011
1012static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
1013{
1014 struct dma_chan *chan = s->chan_tx;
1015 struct uart_port *port = &s->port;
1016
1017 s->chan_tx = NULL;
1018 s->cookie_tx = -EINVAL;
1019 dma_release_channel(chan);
1020 if (enable_pio)
1021 sci_start_tx(port);
1022}
1023
1024static void sci_submit_rx(struct sci_port *s)
1025{
1026 struct dma_chan *chan = s->chan_rx;
1027 int i;
1028
1029 for (i = 0; i < 2; i++) {
1030 struct scatterlist *sg = &s->sg_rx[i];
1031 struct dma_async_tx_descriptor *desc;
1032
1033 desc = chan->device->device_prep_slave_sg(chan,
1034 sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT);
1035
1036 if (desc) {
1037 s->desc_rx[i] = desc;
1038 desc->callback = sci_dma_rx_complete;
1039 desc->callback_param = s;
1040 s->cookie_rx[i] = desc->tx_submit(desc);
1041 }
1042
1043 if (!desc || s->cookie_rx[i] < 0) {
1044 if (i) {
1045 async_tx_ack(s->desc_rx[0]);
1046 s->cookie_rx[0] = -EINVAL;
1047 }
1048 if (desc) {
1049 async_tx_ack(desc);
1050 s->cookie_rx[i] = -EINVAL;
1051 }
1052 dev_warn(s->port.dev,
1053 "failed to re-start DMA, using PIO\n");
1054 sci_rx_dma_release(s, true);
1055 return;
1056 }
1057 }
1058
1059 s->active_rx = s->cookie_rx[0];
1060
1061 dma_async_issue_pending(chan);
1062}
1063
1064static void work_fn_rx(struct work_struct *work)
1065{
1066 struct sci_port *s = container_of(work, struct sci_port, work_rx);
1067 struct uart_port *port = &s->port;
1068 struct dma_async_tx_descriptor *desc;
1069 int new;
1070
1071 if (s->active_rx == s->cookie_rx[0]) {
1072 new = 0;
1073 } else if (s->active_rx == s->cookie_rx[1]) {
1074 new = 1;
1075 } else {
1076 dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
1077 return;
1078 }
1079 desc = s->desc_rx[new];
1080
1081 if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) !=
1082 DMA_SUCCESS) {
1083 /* Handle incomplete DMA receive */
1084 struct tty_struct *tty = port->state->port.tty;
1085 struct dma_chan *chan = s->chan_rx;
1086 struct sh_desc *sh_desc = container_of(desc, struct sh_desc,
1087 async_tx);
1088 unsigned long flags;
1089 int count;
1090
1091 chan->device->device_terminate_all(chan);
1092 dev_dbg(port->dev, "Read %u bytes with cookie %d\n",
1093 sh_desc->partial, sh_desc->cookie);
1094
1095 spin_lock_irqsave(&port->lock, flags);
1096 count = sci_dma_rx_push(s, tty, sh_desc->partial);
1097 spin_unlock_irqrestore(&port->lock, flags);
1098
1099 if (count)
1100 tty_flip_buffer_push(tty);
1101
1102 sci_submit_rx(s);
1103
1104 return;
1105 }
1106
1107 s->cookie_rx[new] = desc->tx_submit(desc);
1108 if (s->cookie_rx[new] < 0) {
1109 dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
1110 sci_rx_dma_release(s, true);
1111 return;
1112 }
1113
1114 dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__,
1115 s->cookie_rx[new], new);
1116
1117 s->active_rx = s->cookie_rx[!new];
1118}
1119
1120static void work_fn_tx(struct work_struct *work)
1121{
1122 struct sci_port *s = container_of(work, struct sci_port, work_tx);
1123 struct dma_async_tx_descriptor *desc;
1124 struct dma_chan *chan = s->chan_tx;
1125 struct uart_port *port = &s->port;
1126 struct circ_buf *xmit = &port->state->xmit;
1127 struct scatterlist *sg = &s->sg_tx;
1128
1129 /*
1130 * DMA is idle now.
1131 * Port xmit buffer is already mapped, and it is one page... Just adjust
1132 * offsets and lengths. Since it is a circular buffer, we have to
1133 * transmit till the end, and then the rest. Take the port lock to get a
1134 * consistent xmit buffer state.
1135 */
1136 spin_lock_irq(&port->lock);
1137 sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
1138 sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
1139 sg->offset;
1140 sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
1141 CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
1142 sg->dma_length = sg->length;
1143 spin_unlock_irq(&port->lock);
1144
1145 BUG_ON(!sg->length);
1146
1147 desc = chan->device->device_prep_slave_sg(chan,
1148 sg, s->sg_len_tx, DMA_TO_DEVICE,
1149 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1150 if (!desc) {
1151 /* switch to PIO */
1152 sci_tx_dma_release(s, true);
1153 return;
1154 }
1155
1156 dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE);
1157
1158 spin_lock_irq(&port->lock);
1159 s->desc_tx = desc;
1160 desc->callback = sci_dma_tx_complete;
1161 desc->callback_param = s;
1162 spin_unlock_irq(&port->lock);
1163 s->cookie_tx = desc->tx_submit(desc);
1164 if (s->cookie_tx < 0) {
1165 dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n");
1166 /* switch to PIO */
1167 sci_tx_dma_release(s, true);
1168 return;
1169 }
1170
1171 dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__,
1172 xmit->buf, xmit->tail, xmit->head, s->cookie_tx);
1173
1174 dma_async_issue_pending(chan);
1175}
1176#endif
1177
821static void sci_start_tx(struct uart_port *port) 1178static void sci_start_tx(struct uart_port *port)
822{ 1179{
823 unsigned short ctrl; 1180 unsigned short ctrl;
824 1181
1182#ifdef CONFIG_SERIAL_SH_SCI_DMA
1183 struct sci_port *s = to_sci_port(port);
1184
1185 if (s->chan_tx) {
1186 if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0)
1187 schedule_work(&s->work_tx);
1188
1189 return;
1190 }
1191#endif
1192
825 /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ 1193 /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
826 ctrl = sci_in(port, SCSCR); 1194 ctrl = sci_in(port, SCSCR);
827 ctrl |= SCI_CTRL_FLAGS_TIE; 1195 ctrl |= SCI_CTRL_FLAGS_TIE;
@@ -838,13 +1206,12 @@ static void sci_stop_tx(struct uart_port *port)
838 sci_out(port, SCSCR, ctrl); 1206 sci_out(port, SCSCR, ctrl);
839} 1207}
840 1208
841static void sci_start_rx(struct uart_port *port, unsigned int tty_start) 1209static void sci_start_rx(struct uart_port *port)
842{ 1210{
843 unsigned short ctrl; 1211 unsigned short ctrl = SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE;
844 1212
845 /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ 1213 /* Set RIE (Receive Interrupt Enable) bit in SCSCR */
846 ctrl = sci_in(port, SCSCR); 1214 ctrl |= sci_in(port, SCSCR);
847 ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE;
848 sci_out(port, SCSCR, ctrl); 1215 sci_out(port, SCSCR, ctrl);
849} 1216}
850 1217
@@ -868,16 +1235,154 @@ static void sci_break_ctl(struct uart_port *port, int break_state)
868 /* Nothing here yet .. */ 1235 /* Nothing here yet .. */
869} 1236}
870 1237
1238#ifdef CONFIG_SERIAL_SH_SCI_DMA
1239static bool filter(struct dma_chan *chan, void *slave)
1240{
1241 struct sh_dmae_slave *param = slave;
1242
1243 dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__,
1244 param->slave_id);
1245
1246 if (param->dma_dev == chan->device->dev) {
1247 chan->private = param;
1248 return true;
1249 } else {
1250 return false;
1251 }
1252}
1253
1254static void rx_timer_fn(unsigned long arg)
1255{
1256 struct sci_port *s = (struct sci_port *)arg;
1257 struct uart_port *port = &s->port;
1258
1259 u16 scr = sci_in(port, SCSCR);
1260 sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE);
1261 dev_dbg(port->dev, "DMA Rx timed out\n");
1262 schedule_work(&s->work_rx);
1263}
1264
1265static void sci_request_dma(struct uart_port *port)
1266{
1267 struct sci_port *s = to_sci_port(port);
1268 struct sh_dmae_slave *param;
1269 struct dma_chan *chan;
1270 dma_cap_mask_t mask;
1271 int nent;
1272
1273 dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__,
1274 port->line, s->dma_dev);
1275
1276 if (!s->dma_dev)
1277 return;
1278
1279 dma_cap_zero(mask);
1280 dma_cap_set(DMA_SLAVE, mask);
1281
1282 param = &s->param_tx;
1283
1284 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
1285 param->slave_id = s->slave_tx;
1286 param->dma_dev = s->dma_dev;
1287
1288 s->cookie_tx = -EINVAL;
1289 chan = dma_request_channel(mask, filter, param);
1290 dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan);
1291 if (chan) {
1292 s->chan_tx = chan;
1293 sg_init_table(&s->sg_tx, 1);
1294 /* UART circular tx buffer is an aligned page. */
1295 BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
1296 sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
1297 UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK);
1298 nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
1299 if (!nent)
1300 sci_tx_dma_release(s, false);
1301 else
1302 dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__,
1303 sg_dma_len(&s->sg_tx),
1304 port->state->xmit.buf, sg_dma_address(&s->sg_tx));
1305
1306 s->sg_len_tx = nent;
1307
1308 INIT_WORK(&s->work_tx, work_fn_tx);
1309 }
1310
1311 param = &s->param_rx;
1312
1313 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
1314 param->slave_id = s->slave_rx;
1315 param->dma_dev = s->dma_dev;
1316
1317 chan = dma_request_channel(mask, filter, param);
1318 dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
1319 if (chan) {
1320 dma_addr_t dma[2];
1321 void *buf[2];
1322 int i;
1323
1324 s->chan_rx = chan;
1325
1326 s->buf_len_rx = 2 * max(16, (int)port->fifosize);
1327 buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2,
1328 &dma[0], GFP_KERNEL);
1329
1330 if (!buf[0]) {
1331 dev_warn(port->dev,
1332 "failed to allocate dma buffer, using PIO\n");
1333 sci_rx_dma_release(s, true);
1334 return;
1335 }
1336
1337 buf[1] = buf[0] + s->buf_len_rx;
1338 dma[1] = dma[0] + s->buf_len_rx;
1339
1340 for (i = 0; i < 2; i++) {
1341 struct scatterlist *sg = &s->sg_rx[i];
1342
1343 sg_init_table(sg, 1);
1344 sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
1345 (int)buf[i] & ~PAGE_MASK);
1346 sg->dma_address = dma[i];
1347 sg->dma_length = sg->length;
1348 }
1349
1350 INIT_WORK(&s->work_rx, work_fn_rx);
1351 setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s);
1352
1353 sci_submit_rx(s);
1354 }
1355}
1356
1357static void sci_free_dma(struct uart_port *port)
1358{
1359 struct sci_port *s = to_sci_port(port);
1360
1361 if (!s->dma_dev)
1362 return;
1363
1364 if (s->chan_tx)
1365 sci_tx_dma_release(s, false);
1366 if (s->chan_rx)
1367 sci_rx_dma_release(s, false);
1368}
1369#endif
1370
871static int sci_startup(struct uart_port *port) 1371static int sci_startup(struct uart_port *port)
872{ 1372{
873 struct sci_port *s = to_sci_port(port); 1373 struct sci_port *s = to_sci_port(port);
874 1374
1375 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
1376
875 if (s->enable) 1377 if (s->enable)
876 s->enable(port); 1378 s->enable(port);
877 1379
878 sci_request_irq(s); 1380 sci_request_irq(s);
1381#ifdef CONFIG_SERIAL_SH_SCI_DMA
1382 sci_request_dma(port);
1383#endif
879 sci_start_tx(port); 1384 sci_start_tx(port);
880 sci_start_rx(port, 1); 1385 sci_start_rx(port);
881 1386
882 return 0; 1387 return 0;
883} 1388}
@@ -886,8 +1391,13 @@ static void sci_shutdown(struct uart_port *port)
886{ 1391{
887 struct sci_port *s = to_sci_port(port); 1392 struct sci_port *s = to_sci_port(port);
888 1393
1394 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
1395
889 sci_stop_rx(port); 1396 sci_stop_rx(port);
890 sci_stop_tx(port); 1397 sci_stop_tx(port);
1398#ifdef CONFIG_SERIAL_SH_SCI_DMA
1399 sci_free_dma(port);
1400#endif
891 sci_free_irq(s); 1401 sci_free_irq(s);
892 1402
893 if (s->disable) 1403 if (s->disable)
@@ -937,6 +1447,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
937 1447
938 sci_out(port, SCSMR, smr_val); 1448 sci_out(port, SCSMR, smr_val);
939 1449
1450 dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
1451 SCSCR_INIT(port));
1452
940 if (t > 0) { 1453 if (t > 0) {
941 if (t >= 256) { 1454 if (t >= 256) {
942 sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); 1455 sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
@@ -954,7 +1467,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
954 sci_out(port, SCSCR, SCSCR_INIT(port)); 1467 sci_out(port, SCSCR, SCSCR_INIT(port));
955 1468
956 if ((termios->c_cflag & CREAD) != 0) 1469 if ((termios->c_cflag & CREAD) != 0)
957 sci_start_rx(port, 0); 1470 sci_start_rx(port);
958} 1471}
959 1472
960static const char *sci_type(struct uart_port *port) 1473static const char *sci_type(struct uart_port *port)
@@ -1049,19 +1562,21 @@ static void __devinit sci_init_single(struct platform_device *dev,
1049 unsigned int index, 1562 unsigned int index,
1050 struct plat_sci_port *p) 1563 struct plat_sci_port *p)
1051{ 1564{
1052 sci_port->port.ops = &sci_uart_ops; 1565 struct uart_port *port = &sci_port->port;
1053 sci_port->port.iotype = UPIO_MEM; 1566
1054 sci_port->port.line = index; 1567 port->ops = &sci_uart_ops;
1568 port->iotype = UPIO_MEM;
1569 port->line = index;
1055 1570
1056 switch (p->type) { 1571 switch (p->type) {
1057 case PORT_SCIFA: 1572 case PORT_SCIFA:
1058 sci_port->port.fifosize = 64; 1573 port->fifosize = 64;
1059 break; 1574 break;
1060 case PORT_SCIF: 1575 case PORT_SCIF:
1061 sci_port->port.fifosize = 16; 1576 port->fifosize = 16;
1062 break; 1577 break;
1063 default: 1578 default:
1064 sci_port->port.fifosize = 1; 1579 port->fifosize = 1;
1065 break; 1580 break;
1066 } 1581 }
1067 1582
@@ -1070,19 +1585,28 @@ static void __devinit sci_init_single(struct platform_device *dev,
1070 sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); 1585 sci_port->dclk = clk_get(&dev->dev, "peripheral_clk");
1071 sci_port->enable = sci_clk_enable; 1586 sci_port->enable = sci_clk_enable;
1072 sci_port->disable = sci_clk_disable; 1587 sci_port->disable = sci_clk_disable;
1073 sci_port->port.dev = &dev->dev; 1588 port->dev = &dev->dev;
1074 } 1589 }
1075 1590
1076 sci_port->break_timer.data = (unsigned long)sci_port; 1591 sci_port->break_timer.data = (unsigned long)sci_port;
1077 sci_port->break_timer.function = sci_break_timer; 1592 sci_port->break_timer.function = sci_break_timer;
1078 init_timer(&sci_port->break_timer); 1593 init_timer(&sci_port->break_timer);
1079 1594
1080 sci_port->port.mapbase = p->mapbase; 1595 port->mapbase = p->mapbase;
1081 sci_port->port.membase = p->membase; 1596 port->membase = p->membase;
1082 1597
1083 sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; 1598 port->irq = p->irqs[SCIx_TXI_IRQ];
1084 sci_port->port.flags = p->flags; 1599 port->flags = p->flags;
1085 sci_port->type = sci_port->port.type = p->type; 1600 sci_port->type = port->type = p->type;
1601
1602#ifdef CONFIG_SERIAL_SH_SCI_DMA
1603 sci_port->dma_dev = p->dma_dev;
1604 sci_port->slave_tx = p->dma_slave_tx;
1605 sci_port->slave_rx = p->dma_slave_rx;
1606
1607 dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__,
1608 p->dma_dev, p->dma_slave_tx, p->dma_slave_rx);
1609#endif
1086 1610
1087 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); 1611 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
1088} 1612}
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index fc2e963e65e9..7696a664f8a5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -71,8 +71,6 @@ source "drivers/staging/asus_oled/Kconfig"
71 71
72source "drivers/staging/panel/Kconfig" 72source "drivers/staging/panel/Kconfig"
73 73
74source "drivers/staging/altpciechdma/Kconfig"
75
76source "drivers/staging/rtl8187se/Kconfig" 74source "drivers/staging/rtl8187se/Kconfig"
77 75
78source "drivers/staging/rtl8192su/Kconfig" 76source "drivers/staging/rtl8192su/Kconfig"
@@ -81,20 +79,14 @@ source "drivers/staging/rtl8192u/Kconfig"
81 79
82source "drivers/staging/rtl8192e/Kconfig" 80source "drivers/staging/rtl8192e/Kconfig"
83 81
84source "drivers/staging/mimio/Kconfig"
85
86source "drivers/staging/frontier/Kconfig" 82source "drivers/staging/frontier/Kconfig"
87 83
88source "drivers/staging/dream/Kconfig" 84source "drivers/staging/dream/Kconfig"
89 85
90source "drivers/staging/pohmelfs/Kconfig" 86source "drivers/staging/pohmelfs/Kconfig"
91 87
92source "drivers/staging/b3dfg/Kconfig"
93
94source "drivers/staging/phison/Kconfig" 88source "drivers/staging/phison/Kconfig"
95 89
96source "drivers/staging/p9auth/Kconfig"
97
98source "drivers/staging/line6/Kconfig" 90source "drivers/staging/line6/Kconfig"
99 91
100source "drivers/gpu/drm/vmwgfx/Kconfig" 92source "drivers/gpu/drm/vmwgfx/Kconfig"
@@ -117,7 +109,7 @@ source "drivers/staging/hv/Kconfig"
117 109
118source "drivers/staging/vme/Kconfig" 110source "drivers/staging/vme/Kconfig"
119 111
120source "drivers/staging/rar/Kconfig" 112source "drivers/staging/rar_register/Kconfig"
121 113
122source "drivers/staging/sep/Kconfig" 114source "drivers/staging/sep/Kconfig"
123 115
@@ -143,5 +135,9 @@ source "drivers/staging/netwave/Kconfig"
143 135
144source "drivers/staging/sm7xx/Kconfig" 136source "drivers/staging/sm7xx/Kconfig"
145 137
138source "drivers/staging/dt3155/Kconfig"
139
140source "drivers/staging/crystalhd/Kconfig"
141
146endif # !STAGING_EXCLUDE_BUILD 142endif # !STAGING_EXCLUDE_BUILD
147endif # STAGING 143endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index b5e67b889f60..ea2e70e2fed4 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -18,18 +18,14 @@ obj-$(CONFIG_RT2870) += rt2870/
18obj-$(CONFIG_COMEDI) += comedi/ 18obj-$(CONFIG_COMEDI) += comedi/
19obj-$(CONFIG_ASUS_OLED) += asus_oled/ 19obj-$(CONFIG_ASUS_OLED) += asus_oled/
20obj-$(CONFIG_PANEL) += panel/ 20obj-$(CONFIG_PANEL) += panel/
21obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
22obj-$(CONFIG_R8187SE) += rtl8187se/ 21obj-$(CONFIG_R8187SE) += rtl8187se/
23obj-$(CONFIG_RTL8192SU) += rtl8192su/ 22obj-$(CONFIG_RTL8192SU) += rtl8192su/
24obj-$(CONFIG_RTL8192U) += rtl8192u/ 23obj-$(CONFIG_RTL8192U) += rtl8192u/
25obj-$(CONFIG_RTL8192E) += rtl8192e/ 24obj-$(CONFIG_RTL8192E) += rtl8192e/
26obj-$(CONFIG_INPUT_MIMIO) += mimio/
27obj-$(CONFIG_TRANZPORT) += frontier/ 25obj-$(CONFIG_TRANZPORT) += frontier/
28obj-$(CONFIG_DREAM) += dream/ 26obj-$(CONFIG_DREAM) += dream/
29obj-$(CONFIG_POHMELFS) += pohmelfs/ 27obj-$(CONFIG_POHMELFS) += pohmelfs/
30obj-$(CONFIG_B3DFG) += b3dfg/
31obj-$(CONFIG_IDE_PHISON) += phison/ 28obj-$(CONFIG_IDE_PHISON) += phison/
32obj-$(CONFIG_PLAN9AUTH) += p9auth/
33obj-$(CONFIG_LINE6_USB) += line6/ 29obj-$(CONFIG_LINE6_USB) += line6/
34obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/ 30obj-$(CONFIG_USB_SERIAL_QUATECH2) += serqt_usb2/
35obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/ 31obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/
@@ -39,7 +35,7 @@ obj-$(CONFIG_VT6656) += vt6656/
39obj-$(CONFIG_FB_UDL) += udlfb/ 35obj-$(CONFIG_FB_UDL) += udlfb/
40obj-$(CONFIG_HYPERV) += hv/ 36obj-$(CONFIG_HYPERV) += hv/
41obj-$(CONFIG_VME_BUS) += vme/ 37obj-$(CONFIG_VME_BUS) += vme/
42obj-$(CONFIG_RAR_REGISTER) += rar/ 38obj-$(CONFIG_RAR_REGISTER) += rar_register/
43obj-$(CONFIG_DX_SEP) += sep/ 39obj-$(CONFIG_DX_SEP) += sep/
44obj-$(CONFIG_IIO) += iio/ 40obj-$(CONFIG_IIO) += iio/
45obj-$(CONFIG_RAMZSWAP) += ramzswap/ 41obj-$(CONFIG_RAMZSWAP) += ramzswap/
@@ -53,3 +49,5 @@ obj-$(CONFIG_WAVELAN) += wavelan/
53obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/ 49obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan/
54obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/ 50obj-$(CONFIG_PCMCIA_NETWAVE) += netwave/
55obj-$(CONFIG_FB_SM7XX) += sm7xx/ 51obj-$(CONFIG_FB_SM7XX) += sm7xx/
52obj-$(CONFIG_DT3155) += dt3155/
53obj-$(CONFIG_CRYSTALHD) += crystalhd/
diff --git a/drivers/staging/altpciechdma/Kconfig b/drivers/staging/altpciechdma/Kconfig
deleted file mode 100644
index 0f4bf92cbbfb..000000000000
--- a/drivers/staging/altpciechdma/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config ALTERA_PCIE_CHDMA
2 tristate "Altera PCI Express Chaining DMA driver"
3 depends on PCI
4 default N
5 ---help---
6 A reference driver that exercises the Chaining DMA logic reference
7 design generated along the Altera FPGA PCI Express soft or hard core,
8 only if instantiated using the MegaWizard, not the SOPC builder, of
9 Quartus 8.1.
10
diff --git a/drivers/staging/altpciechdma/Makefile b/drivers/staging/altpciechdma/Makefile
deleted file mode 100644
index c08c8437f4db..000000000000
--- a/drivers/staging/altpciechdma/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma.o
2
diff --git a/drivers/staging/altpciechdma/TODO b/drivers/staging/altpciechdma/TODO
deleted file mode 100644
index 12c945fd61e1..000000000000
--- a/drivers/staging/altpciechdma/TODO
+++ /dev/null
@@ -1,15 +0,0 @@
1DONE:
2 - functionality similar to logic testbench
3
4TODO:
5 - checkpatch.pl cleanups.
6 - keep state of DMA engines.
7 - keep data structure that keeps state of each transfer.
8 - interrupt handler should iterate over outstanding descriptor tables.
9 - complete userspace cdev to read/write using the DMA engines.
10 - split off the DMA support functions in a module, re-usable by custom
11 drivers.
12
13Please coordinate work with, and send patches to
14Leon Woestenberg <leon@sidebranch.com>
15
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
deleted file mode 100644
index 2f07dd4563ac..000000000000
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ /dev/null
@@ -1,1182 +0,0 @@
1/**
2 * Driver for Altera PCIe core chaining DMA reference design.
3 *
4 * Copyright (C) 2008 Leon Woestenberg <leon.woestenberg@axon.tv>
5 * Copyright (C) 2008 Nickolas Heppermann <heppermannwdt@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 *
22 * Rationale: This driver exercises the chaining DMA read and write engine
23 * in the reference design. It is meant as a complementary reference
24 * driver that can be used for testing early designs as well as a basis to
25 * write your custom driver.
26 *
27 * Status: Test results from Leon Woestenberg <leon.woestenberg@axon.tv>:
28 *
29 * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a
30 * Dell Precision 370 PC, x86, kernel 2.6.20 from Ubuntu 7.04.
31 *
32 * Sendero Board w/ Cyclone II EP2C35F672C6N, PX1011A PCIe x1 PHY on a
33 * Freescale MPC8313E-RDB board, PowerPC, 2.6.24 w/ Freescale patches.
34 *
35 * Driver tests passed with PCIe Compiler 8.1. With PCIe 8.0 the DMA
36 * loopback test had reproducable compare errors. I assume a change
37 * in the compiler or reference design, but could not find evidence nor
38 * documentation on a change or fix in that direction.
39 *
40 * The reference design does not have readable locations and thus a
41 * dummy read, used to flush PCI posted writes, cannot be performed.
42 *
43 */
44
45#include <linux/kernel.h>
46#include <linux/cdev.h>
47#include <linux/delay.h>
48#include <linux/dma-mapping.h>
49#include <linux/init.h>
50#include <linux/interrupt.h>
51#include <linux/io.h>
52#include <linux/jiffies.h>
53#include <linux/module.h>
54#include <linux/pci.h>
55
56
57/* by default do not build the character device interface */
58/* XXX It is non-functional yet */
59#ifndef ALTPCIECHDMA_CDEV
60# define ALTPCIECHDMA_CDEV 0
61#endif
62
63/* build the character device interface? */
64#if ALTPCIECHDMA_CDEV
65# define MAX_CHDMA_SIZE (8 * 1024 * 1024)
66# include "mapper_user_to_sg.h"
67#endif
68
69/** driver name, mimicks Altera naming of the reference design */
70#define DRV_NAME "altpciechdma"
71/** number of BARs on the device */
72#define APE_BAR_NUM (6)
73/** BAR number where the RCSLAVE memory sits */
74#define APE_BAR_RCSLAVE (0)
75/** BAR number where the Descriptor Header sits */
76#define APE_BAR_HEADER (2)
77
78/** maximum size in bytes of the descriptor table, chdma logic limit */
79#define APE_CHDMA_TABLE_SIZE (4096)
80/* single transfer must not exceed 255 table entries. worst case this can be
81 * achieved by 255 scattered pages, with only a single byte in the head and
82 * tail pages. 253 * PAGE_SIZE is a safe upper bound for the transfer size.
83 */
84#define APE_CHDMA_MAX_TRANSFER_LEN (253 * PAGE_SIZE)
85
86/**
87 * Specifies those BARs to be mapped and the length of each mapping.
88 *
89 * Zero (0) means do not map, otherwise specifies the BAR lengths to be mapped.
90 * If the actual BAR length is less, this is considered an error; then
91 * reconfigure your PCIe core.
92 *
93 * @see ug_pci_express 8.0, table 7-2 at page 7-13.
94 */
95static const unsigned long bar_min_len[APE_BAR_NUM] =
96 { 32768, 0, 256, 0, 32768, 0 };
97
98/**
99 * Descriptor Header, controls the DMA read engine or write engine.
100 *
101 * The descriptor header is the main data structure for starting DMA transfers.
102 *
103 * It sits in End Point (FPGA) memory BAR[2] for 32-bit or BAR[3:2] for 64-bit.
104 * It references a descriptor table which exists in Root Complex (PC) memory.
105 * Writing the rclast field starts the DMA operation, thus all other structures
106 * and fields must be setup before doing so.
107 *
108 * @see ug_pci_express 8.0, tables 7-3, 7-4 and 7-5 at page 7-14.
109 * @note This header must be written in four 32-bit (PCI DWORD) writes.
110 */
111struct ape_chdma_header {
112 /**
113 * w0 consists of two 16-bit fields:
114 * lsb u16 number; number of descriptors in ape_chdma_table
115 * msb u16 control; global control flags
116 */
117 u32 w0;
118 /* bus address to ape_chdma_table in Root Complex memory */
119 u32 bdt_addr_h;
120 u32 bdt_addr_l;
121 /**
122 * w3 consists of two 16-bit fields:
123 * - lsb u16 rclast; last descriptor number available in Root Complex
124 * - zero (0) means the first descriptor is ready,
125 * - one (1) means two descriptors are ready, etc.
126 * - msb u16 reserved;
127 *
128 * @note writing to this memory location starts the DMA operation!
129 */
130 u32 w3;
131} __attribute__ ((packed));
132
133/**
134 * Descriptor Entry, describing a (non-scattered) single memory block transfer.
135 *
136 * There is one descriptor for each memory block involved in the transfer, a
137 * block being a contiguous address range on the bus.
138 *
139 * Multiple descriptors are chained by means of the ape_chdma_table data
140 * structure.
141 *
142 * @see ug_pci_express 8.0, tables 7-6, 7-7 and 7-8 at page 7-14 and page 7-15.
143 */
144struct ape_chdma_desc {
145 /**
146 * w0 consists of two 16-bit fields:
147 * number of DWORDS to transfer
148 * - lsb u16 length;
149 * global control
150 * - msb u16 control;
151 */
152 u32 w0;
153 /* address of memory in the End Point */
154 u32 ep_addr;
155 /* bus address of source or destination memory in the Root Complex */
156 u32 rc_addr_h;
157 u32 rc_addr_l;
158} __attribute__ ((packed));
159
160/**
161 * Descriptor Table, an array of descriptors describing a chained transfer.
162 *
163 * An array of descriptors, preceded by workspace for the End Point.
164 * It exists in Root Complex memory.
165 *
166 * The End Point can update its last completed descriptor number in the
167 * eplast field if requested by setting the EPLAST_ENA bit either
168 * globally in the header's or locally in any descriptor's control field.
169 *
170 * @note this structure may not exceed 4096 bytes. This results in a
171 * maximum of 4096 / (4 * 4) - 1 = 255 descriptors per chained transfer.
172 *
173 * @see ug_pci_express 8.0, tables 7-9, 7-10 and 7-11 at page 7-17 and page 7-18.
174 */
175struct ape_chdma_table {
176 /* workspace 0x00-0x0b, reserved */
177 u32 reserved1[3];
178 /* workspace 0x0c-0x0f, last descriptor handled by End Point */
179 u32 w3;
180 /* the actual array of descriptors
181 * 0x10-0x1f, 0x20-0x2f, ... 0xff0-0xfff (255 entries)
182 */
183 struct ape_chdma_desc desc[255];
184} __attribute__ ((packed));
185
186/**
187 * Altera PCI Express ('ape') board specific book keeping data
188 *
189 * Keeps state of the PCIe core and the Chaining DMA controller
190 * application.
191 */
192struct ape_dev {
193 /** the kernel pci device data structure provided by probe() */
194 struct pci_dev *pci_dev;
195 /**
196 * kernel virtual address of the mapped BAR memory and IO regions of
197 * the End Point. Used by map_bars()/unmap_bars().
198 */
199 void * __iomem bar[APE_BAR_NUM];
200 /** kernel virtual address for Descriptor Table in Root Complex memory */
201 struct ape_chdma_table *table_virt;
202 /**
203 * bus address for the Descriptor Table in Root Complex memory, in
204 * CPU-native endianess
205 */
206 dma_addr_t table_bus;
207 /* if the device regions could not be allocated, assume and remember it
208 * is in use by another driver; this driver must not disable the device.
209 */
210 int in_use;
211 /* whether this driver enabled msi for the device */
212 int msi_enabled;
213 /* whether this driver could obtain the regions */
214 int got_regions;
215 /* irq line successfully requested by this driver, -1 otherwise */
216 int irq_line;
217 /* board revision */
218 u8 revision;
219 /* interrupt count, incremented by the interrupt handler */
220 int irq_count;
221#if ALTPCIECHDMA_CDEV
222 /* character device */
223 dev_t cdevno;
224 struct cdev cdev;
225 /* user space scatter gather mapper */
226 struct sg_mapping_t *sgm;
227#endif
228};
229
230/**
231 * Using the subsystem vendor id and subsystem id, it is possible to
232 * distinguish between different cards bases around the same
233 * (third-party) logic core.
234 *
235 * Default Altera vendor and device ID's, and some (non-reserved)
236 * ID's are now used here that are used amongst the testers/developers.
237 */
238static const struct pci_device_id ids[] = {
239 { PCI_DEVICE(0x1172, 0xE001), },
240 { PCI_DEVICE(0x2071, 0x2071), },
241 { 0, }
242};
243MODULE_DEVICE_TABLE(pci, ids);
244
245#if ALTPCIECHDMA_CDEV
246/* prototypes for character device */
247static int sg_init(struct ape_dev *ape);
248static void sg_exit(struct ape_dev *ape);
249#endif
250
251/**
252 * altpciechdma_isr() - Interrupt handler
253 *
254 */
255static irqreturn_t altpciechdma_isr(int irq, void *dev_id)
256{
257 struct ape_dev *ape = (struct ape_dev *)dev_id;
258 if (!ape)
259 return IRQ_NONE;
260 ape->irq_count++;
261 return IRQ_HANDLED;
262}
263
264static int __devinit scan_bars(struct ape_dev *ape, struct pci_dev *dev)
265{
266 int i;
267 for (i = 0; i < APE_BAR_NUM; i++) {
268 unsigned long bar_start = pci_resource_start(dev, i);
269 if (bar_start) {
270 unsigned long bar_end = pci_resource_end(dev, i);
271 unsigned long bar_flags = pci_resource_flags(dev, i);
272 printk(KERN_DEBUG "BAR%d 0x%08lx-0x%08lx flags 0x%08lx\n",
273 i, bar_start, bar_end, bar_flags);
274 }
275 }
276 return 0;
277}
278
279/**
280 * Unmap the BAR regions that had been mapped earlier using map_bars()
281 */
282static void unmap_bars(struct ape_dev *ape, struct pci_dev *dev)
283{
284 int i;
285 for (i = 0; i < APE_BAR_NUM; i++) {
286 /* is this BAR mapped? */
287 if (ape->bar[i]) {
288 /* unmap BAR */
289 pci_iounmap(dev, ape->bar[i]);
290 ape->bar[i] = NULL;
291 }
292 }
293}
294
295/**
296 * Map the device memory regions into kernel virtual address space after
297 * verifying their sizes respect the minimum sizes needed, given by the
298 * bar_min_len[] array.
299 */
300static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
301{
302 int rc;
303 int i;
304 /* iterate through all the BARs */
305 for (i = 0; i < APE_BAR_NUM; i++) {
306 unsigned long bar_start = pci_resource_start(dev, i);
307 unsigned long bar_end = pci_resource_end(dev, i);
308 unsigned long bar_length = bar_end - bar_start + 1;
309 ape->bar[i] = NULL;
310 /* do not map, and skip, BARs with length 0 */
311 if (!bar_min_len[i])
312 continue;
313 /* do not map BARs with address 0 */
314 if (!bar_start || !bar_end) {
315 printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
316 rc = -1;
317 goto fail;
318 }
319 bar_length = bar_end - bar_start + 1;
320 /* BAR length is less than driver requires? */
321 if (bar_length < bar_min_len[i]) {
322 printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
323 "requires at least %lu bytes\n",
324 i, bar_length, bar_min_len[i]);
325 rc = -1;
326 goto fail;
327 }
328 /* map the device memory or IO region into kernel virtual
329 * address space */
330 ape->bar[i] = pci_iomap(dev, i, bar_min_len[i]);
331 if (!ape->bar[i]) {
332 printk(KERN_DEBUG "Could not map BAR #%d.\n", i);
333 rc = -1;
334 goto fail;
335 }
336 printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
337 ape->bar[i], bar_min_len[i], bar_length);
338 }
339 /* successfully mapped all required BAR regions */
340 rc = 0;
341 goto success;
342fail:
343 /* unmap any BARs that we did map */
344 unmap_bars(ape, dev);
345success:
346 return rc;
347}
348
349#if 0 /* not yet implemented fully FIXME add opcode */
350static void __devinit rcslave_test(struct ape_dev *ape, struct pci_dev *dev)
351{
352 u32 *rcslave_mem = (u32 *)ape->bar[APE_BAR_RCSLAVE];
353 u32 result = 0;
354 /** this number is assumed to be different each time this test runs */
355 u32 seed = (u32)jiffies;
356 u32 value = seed;
357 int i;
358
359 /* write loop */
360 value = seed;
361 for (i = 1024; i < 32768 / 4 ; i++) {
362 printk(KERN_DEBUG "Writing 0x%08x to 0x%p.\n",
363 (u32)value, (void *)rcslave_mem + i);
364 iowrite32(value, rcslave_mem + i);
365 value++;
366 }
367 /* read-back loop */
368 value = seed;
369 for (i = 1024; i < 32768 / 4; i++) {
370 result = ioread32(rcslave_mem + i);
371 if (result != value) {
372 printk(KERN_DEBUG "Wrote 0x%08x to 0x%p, but read back 0x%08x.\n",
373 (u32)value, (void *)rcslave_mem + i, (u32)result);
374 break;
375 }
376 value++;
377 }
378}
379#endif
380
381/* obtain the 32 most significant (high) bits of a 32-bit or 64-bit address */
382#define pci_dma_h(addr) ((addr >> 16) >> 16)
383/* obtain the 32 least significant (low) bits of a 32-bit or 64-bit address */
384#define pci_dma_l(addr) (addr & 0xffffffffUL)
385
386/* ape_fill_chdma_desc() - Fill a Altera PCI Express Chaining DMA descriptor
387 *
388 * @desc pointer to descriptor to be filled
389 * @addr root complex address
390 * @ep_addr end point address
391 * @len number of bytes, must be a multiple of 4.
392 */
393static inline void ape_chdma_desc_set(struct ape_chdma_desc *desc, dma_addr_t addr, u32 ep_addr, int len)
394{
395 BUG_ON(len & 3);
396 desc->w0 = cpu_to_le32(len / 4);
397 desc->ep_addr = cpu_to_le32(ep_addr);
398 desc->rc_addr_h = cpu_to_le32(pci_dma_h(addr));
399 desc->rc_addr_l = cpu_to_le32(pci_dma_l(addr));
400}
401
402#if ALTPCIECHDMA_CDEV
403/*
404 * ape_sg_to_chdma_table() - Create a device descriptor table from a scatterlist.
405 *
406 * The scatterlist must have been mapped by pci_map_sg(sgm->sgl).
407 *
408 * @sgl scatterlist.
409 * @nents Number of entries in the scatterlist.
410 * @first Start index in the scatterlist sgm->sgl.
411 * @ep_addr End Point address for the scatter/gather transfer.
412 * @desc pointer to first descriptor
413 *
414 * Returns Number of entries in the table on success, -1 on error.
415 */
416static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first, struct ape_chdma_desc *desc, u32 ep_addr)
417{
418 int i = first, j = 0;
419 /* inspect first entry */
420 dma_addr_t addr = sg_dma_address(&sgl[i]);
421 unsigned int len = sg_dma_len(&sgl[i]);
422 /* contiguous block */
423 dma_addr_t cont_addr = addr;
424 unsigned int cont_len = len;
425 /* iterate over remaining entries */
426 for (; j < 25 && i < nents - 1; i++) {
427 /* bus address of next entry i + 1 */
428 dma_addr_t next = sg_dma_address(&sgl[i + 1]);
429 /* length of this entry i */
430 len = sg_dma_len(&sgl[i]);
431 printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
432 (unsigned long long)addr, len);
433 /* entry i + 1 is non-contiguous with entry i? */
434 if (next != addr + len) {
435 /* TODO create entry here (we could overwrite i) */
436 printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j,
437 (unsigned long long)cont_addr, cont_len);
438 /* set descriptor for contiguous transfer */
439 ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len);
440 /* next end point memory address */
441 ep_addr += cont_len;
442 /* start new contiguous block */
443 cont_addr = next;
444 cont_len = 0;
445 j++;
446 }
447 /* add entry i + 1 to current contiguous block */
448 cont_len += len;
449 /* goto entry i + 1 */
450 addr = next;
451 }
452 /* TODO create entry here (we could overwrite i) */
453 printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
454 (unsigned long long)addr, len);
455 printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j,
456 (unsigned long long)cont_addr, cont_len);
457 j++;
458 return j;
459}
460#endif
461
462/* compare buffers */
463static inline int compare(u32 *p, u32 *q, int len)
464{
465 int result = -1;
466 int fail = 0;
467 int i;
468 for (i = 0; i < len / 4; i++) {
469 if (*p == *q) {
470 /* every so many u32 words, show equals */
471 if ((i & 255) == 0)
472 printk(KERN_DEBUG "[%p] = 0x%08x [%p] = 0x%08x\n", p, *p, q, *q);
473 } else {
474 fail++;
475 /* show the first few miscompares */
476 if (fail < 10)
477 printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
478 /* but stop after a while */
479 else if (fail == 10)
480 printk(KERN_DEBUG "---more errors follow! not printed---\n");
481 else
482 /* stop compare after this many errors */
483 break;
484 }
485 p++;
486 q++;
487 }
488 if (!fail)
489 result = 0;
490 return result;
491}
492
493/* dma_test() - Perform DMA loop back test to end point and back to root complex.
494 *
495 * Allocate a cache-coherent buffer in host memory, consisting of four pages.
496 *
497 * Fill the four memory pages such that each 32-bit word contains its own address.
498 *
499 * Now perform a loop back test, have the end point device copy the first buffer
500 * half to end point memory, then have it copy back into the second half.
501 *
502 * Create a descriptor table to copy the first buffer half into End Point
503 * memory. Instruct the End Point to do a DMA read using that table.
504 *
505 * Create a descriptor table to copy End Point memory to the second buffer
506 * half. Instruct the End Point to do a DMA write using that table.
507 *
508 * Compare results, fail or pass.
509 *
510 */
511static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
512{
513 /* test result; guilty until proven innocent */
514 int result = -1;
515 /* the DMA read header sits at address 0x00 of the DMA engine BAR */
516 struct ape_chdma_header *write_header = (struct ape_chdma_header *)ape->bar[APE_BAR_HEADER];
517 /* the write DMA header sits after the read header at address 0x10 */
518 struct ape_chdma_header *read_header = write_header + 1;
519 /* virtual address of the allocated buffer */
520 u8 *buffer_virt = 0;
521 /* bus address of the allocated buffer */
522 dma_addr_t buffer_bus = 0;
523 int i, n = 0, irq_count;
524
525 /* temporary value used to construct 32-bit data words */
526 u32 w;
527
528 printk(KERN_DEBUG "bar_tests(), PAGE_SIZE = 0x%0x\n", (int)PAGE_SIZE);
529 printk(KERN_DEBUG "write_header = 0x%p.\n", write_header);
530 printk(KERN_DEBUG "read_header = 0x%p.\n", read_header);
531 printk(KERN_DEBUG "&write_header->w3 = 0x%p\n", &write_header->w3);
532 printk(KERN_DEBUG "&read_header->w3 = 0x%p\n", &read_header->w3);
533 printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt);
534
535 if (!write_header || !read_header || !ape->table_virt)
536 goto fail;
537
538 /* allocate and map coherently-cached memory for a DMA-able buffer */
539 /* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
540 buffer_virt = (u8 *)pci_alloc_consistent(dev, PAGE_SIZE * 4, &buffer_bus);
541 if (!buffer_virt) {
542 printk(KERN_DEBUG "Could not allocate coherent DMA buffer.\n");
543 goto fail;
544 }
545 printk(KERN_DEBUG "Allocated cache-coherent DMA buffer (virtual address = %p, bus address = 0x%016llx).\n",
546 buffer_virt, (u64)buffer_bus);
547
548 /* fill first half of buffer with its virtual address as data */
549 for (i = 0; i < 4 * PAGE_SIZE; i += 4)
550#if 0
551 *(u32 *)(buffer_virt + i) = i / PAGE_SIZE + 1;
552#else
553 *(u32 *)(buffer_virt + i) = (u32)(unsigned long)(buffer_virt + i);
554#endif
555#if 0
556 compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
557#endif
558
559#if 0
560 /* fill second half of buffer with zeroes */
561 for (i = 2 * PAGE_SIZE; i < 4 * PAGE_SIZE; i += 4)
562 *(u32 *)(buffer_virt + i) = 0;
563#endif
564
565 /* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */
566 ape->table_virt->w3 = cpu_to_le32(0x0000FADE);
567
568 /* fill in first descriptor */
569 n = 0;
570 /* read 8192 bytes from RC buffer to EP address 4096 */
571 ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE);
572#if 1
573 for (i = 0; i < 255; i++)
574 ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE);
575 /* index of last descriptor */
576 n = i - 1;
577#endif
578#if 0
579 /* fill in next descriptor */
580 n++;
581 /* read 1024 bytes from RC buffer to EP address 4096 + 1024 */
582 ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 1024, 4096 + 1024, 1024);
583#endif
584
585#if 1
586 /* enable MSI after the last descriptor is completed */
587 if (ape->msi_enabled)
588 ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/;
589#endif
590#if 0
591 /* dump descriptor table for debugging */
592 printk(KERN_DEBUG "Descriptor Table (Read, in Root Complex Memory, # = %d)\n", n + 1);
593 for (i = 0; i < 4 + (n + 1) * 4; i += 4) {
594 u32 *p = (u32 *)ape->table_virt;
595 p += i;
596 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p));
597 p++;
598 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
599 p++;
600 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
601 p++;
602 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
603 }
604#endif
605 /* set available number of descriptors in table */
606 w = (u32)(n + 1);
607 w |= (1UL << 18)/*global EPLAST_EN*/;
608#if 0
609 if (ape->msi_enabled)
610 w |= (1UL << 17)/*global MSI*/;
611#endif
612 printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", w, (void *)&read_header->w0);
613 iowrite32(w, &read_header->w0);
614
615 /* write table address (higher 32-bits) */
616 printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)((ape->table_bus >> 16) >> 16), (void *)&read_header->bdt_addr_h);
617 iowrite32(pci_dma_h(ape->table_bus), &read_header->bdt_addr_h);
618
619 /* write table address (lower 32-bits) */
620 printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)(ape->table_bus & 0xffffffffUL), (void *)&read_header->bdt_addr_l);
621 iowrite32(pci_dma_l(ape->table_bus), &read_header->bdt_addr_l);
622
623 /* memory write barrier */
624 wmb();
625 printk(KERN_DEBUG "Flush posted writes\n");
626 /** FIXME Add dummy read to flush posted writes but need a readable location! */
627#if 0
628 (void)ioread32();
629#endif
630
631 /* remember IRQ count before the transfer */
632 irq_count = ape->irq_count;
633 /* write number of descriptors - this starts the DMA */
634 printk(KERN_DEBUG "\nStart DMA read\n");
635 printk(KERN_DEBUG "writing 0x%08x to 0x%p\n", (u32)n, (void *)&read_header->w3);
636 iowrite32(n, &read_header->w3);
637 printk(KERN_DEBUG "EPLAST = %lu\n", le32_to_cpu(*(u32 *)&ape->table_virt->w3) & 0xffffUL);
638
639 /** memory write barrier */
640 wmb();
641 /* dummy read to flush posted writes */
642 /* FIXME Need a readable location! */
643#if 0
644 (void)ioread32();
645#endif
646 printk(KERN_DEBUG "POLL FOR READ:\n");
647 /* poll for chain completion, 1000 times 1 millisecond */
648 for (i = 0; i < 100; i++) {
649 volatile u32 *p = &ape->table_virt->w3;
650 u32 eplast = le32_to_cpu(*p) & 0xffffUL;
651 printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
652 if (eplast == n) {
653 printk(KERN_DEBUG "DONE\n");
654 /* print IRQ count before the transfer */
655 printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
656 break;
657 }
658 udelay(100);
659 }
660
661 /* invalidate EPLAST, outside 0-255, 0xFADE is from the testbench */
662 ape->table_virt->w3 = cpu_to_le32(0x0000FADE);
663
664 /* setup first descriptor */
665 n = 0;
666 ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
667#if 1
668 for (i = 0; i < 255; i++)
669 ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
670
671 /* index of last descriptor */
672 n = i - 1;
673#endif
674#if 1 /* test variable, make a module option later */
675 if (ape->msi_enabled)
676 ape->table_virt->desc[n].w0 |= cpu_to_le32(1UL << 16)/*local MSI*/;
677#endif
678#if 0
679 /* dump descriptor table for debugging */
680 printk(KERN_DEBUG "Descriptor Table (Write, in Root Complex Memory, # = %d)\n", n + 1);
681 for (i = 0; i < 4 + (n + 1) * 4; i += 4) {
682 u32 *p = (u32 *)ape->table_virt;
683 p += i;
684 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (LEN=0x%x)\n", (u32)p, (u32)p & 15, *p, 4 * le32_to_cpu(*p));
685 p++;
686 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (EPA=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
687 p++;
688 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCH=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
689 p++;
690 printk(KERN_DEBUG "0x%08x/0x%02x: 0x%08x (RCL=0x%x)\n", (u32)p, (u32)p & 15, *p, le32_to_cpu(*p));
691 }
692#endif
693
694 /* set number of available descriptors in the table */
695 w = (u32)(n + 1);
696 /* enable updates of eplast for each descriptor completion */
697 w |= (u32)(1UL << 18)/*global EPLAST_EN*/;
698#if 0 /* test variable, make a module option later */
699 /* enable MSI for each descriptor completion */
700 if (ape->msi_enabled)
701 w |= (1UL << 17)/*global MSI*/;
702#endif
703 iowrite32(w, &write_header->w0);
704 iowrite32(pci_dma_h(ape->table_bus), &write_header->bdt_addr_h);
705 iowrite32(pci_dma_l(ape->table_bus), &write_header->bdt_addr_l);
706
707 /** memory write barrier and flush posted writes */
708 wmb();
709 /* dummy read to flush posted writes */
710 /* FIXME Need a readable location! */
711#if 0
712 (void)ioread32();
713#endif
714 irq_count = ape->irq_count;
715
716 printk(KERN_DEBUG "\nStart DMA write\n");
717 iowrite32(n, &write_header->w3);
718
719 /** memory write barrier */
720 wmb();
721 /** dummy read to flush posted writes */
722 /* (void) ioread32(); */
723
724 printk(KERN_DEBUG "POLL FOR WRITE:\n");
725 /* poll for completion, 1000 times 1 millisecond */
726 for (i = 0; i < 100; i++) {
727 volatile u32 *p = &ape->table_virt->w3;
728 u32 eplast = le32_to_cpu(*p) & 0xffffUL;
729 printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
730 if (eplast == n) {
731 printk(KERN_DEBUG "DONE\n");
732 /* print IRQ count before the transfer */
733 printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
734 break;
735 }
736 udelay(100);
737 }
738 /* soft-reset DMA write engine */
739 iowrite32(0x0000ffffUL, &write_header->w0);
740 /* soft-reset DMA read engine */
741 iowrite32(0x0000ffffUL, &read_header->w0);
742
743 /** memory write barrier */
744 wmb();
745 /* dummy read to flush posted writes */
746 /* FIXME Need a readable location! */
747#if 0
748 (void)ioread32();
749#endif
750 /* compare first half of buffer with second half, should be identical */
751 result = compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
752 printk(KERN_DEBUG "DMA loop back test %s.\n", result ? "FAILED" : "PASSED");
753
754 pci_free_consistent(dev, 4 * PAGE_SIZE, buffer_virt, buffer_bus);
755fail:
756 printk(KERN_DEBUG "bar_tests() end, result %d\n", result);
757 return result;
758}
759
760/* Called when the PCI sub system thinks we can control the given device.
761 * Inspect if we can support the device and if so take control of it.
762 *
763 * Return 0 when we have taken control of the given device.
764 *
765 * - allocate board specific bookkeeping
766 * - allocate coherently-mapped memory for the descriptor table
767 * - enable the board
768 * - verify board revision
769 * - request regions
770 * - query DMA mask
771 * - obtain and request irq
772 * - map regions into kernel address space
773 */
774static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
775{
776 int rc = 0;
777 struct ape_dev *ape = NULL;
778 u8 irq_pin, irq_line;
779 printk(KERN_DEBUG "probe(dev = 0x%p, pciid = 0x%p)\n", dev, id);
780
781 /* allocate memory for per-board book keeping */
782 ape = kzalloc(sizeof(struct ape_dev), GFP_KERNEL);
783 if (!ape) {
784 printk(KERN_DEBUG "Could not kzalloc()ate memory.\n");
785 goto err_ape;
786 }
787 ape->pci_dev = dev;
788 dev_set_drvdata(&dev->dev, ape);
789 printk(KERN_DEBUG "probe() ape = 0x%p\n", ape);
790
791 printk(KERN_DEBUG "sizeof(struct ape_chdma_table) = %d.\n",
792 (int)sizeof(struct ape_chdma_table));
793 /* the reference design has a size restriction on the table size */
794 BUG_ON(sizeof(struct ape_chdma_table) > APE_CHDMA_TABLE_SIZE);
795
796 /* allocate and map coherently-cached memory for a descriptor table */
797 /* @see LDD3 page 446 */
798 ape->table_virt = (struct ape_chdma_table *)pci_alloc_consistent(dev,
799 APE_CHDMA_TABLE_SIZE, &ape->table_bus);
800 /* could not allocate table? */
801 if (!ape->table_virt) {
802 printk(KERN_DEBUG "Could not dma_alloc()ate_coherent memory.\n");
803 goto err_table;
804 }
805
806 printk(KERN_DEBUG "table_virt = %p, table_bus = 0x%16llx.\n",
807 ape->table_virt, (u64)ape->table_bus);
808
809 /* enable device */
810 rc = pci_enable_device(dev);
811 if (rc) {
812 printk(KERN_DEBUG "pci_enable_device() failed\n");
813 goto err_enable;
814 }
815
816 /* enable bus master capability on device */
817 pci_set_master(dev);
818 /* enable message signaled interrupts */
819 rc = pci_enable_msi(dev);
820 /* could not use MSI? */
821 if (rc) {
822 /* resort to legacy interrupts */
823 printk(KERN_DEBUG "Could not enable MSI interrupting.\n");
824 ape->msi_enabled = 0;
825 /* MSI enabled, remember for cleanup */
826 } else {
827 printk(KERN_DEBUG "Enabled MSI interrupting.\n");
828 ape->msi_enabled = 1;
829 }
830
831 pci_read_config_byte(dev, PCI_REVISION_ID, &ape->revision);
832#if 0 /* example */
833 /* (for example) this driver does not support revision 0x42 */
834 if (ape->revision == 0x42) {
835 printk(KERN_DEBUG "Revision 0x42 is not supported by this driver.\n");
836 rc = -ENODEV;
837 goto err_rev;
838 }
839#endif
840 /** XXX check for native or legacy PCIe endpoint? */
841
842 rc = pci_request_regions(dev, DRV_NAME);
843 /* could not request all regions? */
844 if (rc) {
845 /* assume device is in use (and do not disable it later!) */
846 ape->in_use = 1;
847 goto err_regions;
848 }
849 ape->got_regions = 1;
850
851#if 1 /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */
852 /* query for DMA transfer */
853 /* @see Documentation/PCI/PCI-DMA-mapping.txt */
854 if (!pci_set_dma_mask(dev, DMA_BIT_MASK(64))) {
855 pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
856 /* use 64-bit DMA */
857 printk(KERN_DEBUG "Using a 64-bit DMA mask.\n");
858 } else
859#endif
860 if (!pci_set_dma_mask(dev, DMA_BIT_MASK(32))) {
861 printk(KERN_DEBUG "Could not set 64-bit DMA mask.\n");
862 pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32));
863 /* use 32-bit DMA */
864 printk(KERN_DEBUG "Using a 32-bit DMA mask.\n");
865 } else {
866 printk(KERN_DEBUG "No suitable DMA possible.\n");
867 /** @todo Choose proper error return code */
868 rc = -1;
869 goto err_mask;
870 }
871
872 rc = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
873 /* could not read? */
874 if (rc)
875 goto err_irq;
876 printk(KERN_DEBUG "IRQ pin #%d (0=none, 1=INTA#...4=INTD#).\n", irq_pin);
877
878 /* @see LDD3, page 318 */
879 rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_line);
880 /* could not read? */
881 if (rc) {
882 printk(KERN_DEBUG "Could not query PCI_INTERRUPT_LINE, error %d\n", rc);
883 goto err_irq;
884 }
885 printk(KERN_DEBUG "IRQ line #%d.\n", irq_line);
886#if 1
887 irq_line = dev->irq;
888 /* @see LDD3, page 259 */
889 rc = request_irq(irq_line, altpciechdma_isr, IRQF_SHARED, DRV_NAME, (void *)ape);
890 if (rc) {
891 printk(KERN_DEBUG "Could not request IRQ #%d, error %d\n", irq_line, rc);
892 ape->irq_line = -1;
893 goto err_irq;
894 }
895 /* remember which irq we allocated */
896 ape->irq_line = (int)irq_line;
897 printk(KERN_DEBUG "Succesfully requested IRQ #%d with dev_id 0x%p\n", irq_line, ape);
898#endif
899 /* show BARs */
900 scan_bars(ape, dev);
901 /* map BARs */
902 rc = map_bars(ape, dev);
903 if (rc)
904 goto err_map;
905#if ALTPCIECHDMA_CDEV
906 /* initialize character device */
907 rc = sg_init(ape);
908 if (rc)
909 goto err_cdev;
910#endif
911 /* perform DMA engines loop back test */
912 rc = dma_test(ape, dev);
913 (void)rc;
914 /* successfully took the device */
915 rc = 0;
916 printk(KERN_DEBUG "probe() successful.\n");
917 goto end;
918#if ALTPCIECHDMA_CDEV
919err_cdev:
920 /* unmap the BARs */
921 unmap_bars(ape, dev);
922#endif
923err_map:
924 /* free allocated irq */
925 if (ape->irq_line >= 0)
926 free_irq(ape->irq_line, (void *)ape);
927err_irq:
928 if (ape->msi_enabled)
929 pci_disable_msi(dev);
930 /* disable the device iff it is not in use */
931 if (!ape->in_use)
932 pci_disable_device(dev);
933 if (ape->got_regions)
934 pci_release_regions(dev);
935err_mask:
936err_regions:
937/*err_rev:*/
938/* clean up everything before device enable() */
939err_enable:
940 if (ape->table_virt)
941 pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus);
942/* clean up everything before allocating descriptor table */
943err_table:
944 if (ape)
945 kfree(ape);
946err_ape:
947end:
948 return rc;
949}
950
951static void __devexit remove(struct pci_dev *dev)
952{
953 struct ape_dev *ape = dev_get_drvdata(&dev->dev);
954
955 printk(KERN_DEBUG "remove(0x%p)\n", dev);
956 printk(KERN_DEBUG "remove(dev = 0x%p) where ape = 0x%p\n", dev, ape);
957
958 /* remove character device */
959#if ALTPCIECHDMA_CDEV
960 sg_exit(ape);
961#endif
962
963 if (ape->table_virt)
964 pci_free_consistent(dev, APE_CHDMA_TABLE_SIZE, ape->table_virt, ape->table_bus);
965
966 /* free IRQ
967 * @see LDD3 page 279
968 */
969 if (ape->irq_line >= 0) {
970 printk(KERN_DEBUG "Freeing IRQ #%d for dev_id 0x%08lx.\n",
971 ape->irq_line, (unsigned long)ape);
972 free_irq(ape->irq_line, (void *)ape);
973 }
974 /* MSI was enabled? */
975 if (ape->msi_enabled) {
976 /* Disable MSI @see Documentation/MSI-HOWTO.txt */
977 pci_disable_msi(dev);
978 ape->msi_enabled = 0;
979 }
980 /* unmap the BARs */
981 unmap_bars(ape, dev);
982 if (!ape->in_use)
983 pci_disable_device(dev);
984 if (ape->got_regions)
985 /* to be called after device disable */
986 pci_release_regions(dev);
987}
988
989#if ALTPCIECHDMA_CDEV
990
991/*
992 * Called when the device goes from unused to used.
993 */
994static int sg_open(struct inode *inode, struct file *file)
995{
996 struct ape_dev *ape;
997 printk(KERN_DEBUG DRV_NAME "_open()\n");
998 /* pointer to containing data structure of the character device inode */
999 ape = container_of(inode->i_cdev, struct ape_dev, cdev);
1000 /* create a reference to our device state in the opened file */
1001 file->private_data = ape;
1002 /* create virtual memory mapper */
1003 ape->sgm = sg_create_mapper(MAX_CHDMA_SIZE);
1004 return 0;
1005}
1006
1007/*
1008 * Called when the device goes from used to unused.
1009 */
1010static int sg_close(struct inode *inode, struct file *file)
1011{
1012 /* fetch device specific data stored earlier during open */
1013 struct ape_dev *ape = (struct ape_dev *)file->private_data;
1014 printk(KERN_DEBUG DRV_NAME "_close()\n");
1015 /* destroy virtual memory mapper */
1016 sg_destroy_mapper(ape->sgm);
1017 return 0;
1018}
1019
1020static ssize_t sg_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
1021{
1022 /* fetch device specific data stored earlier during open */
1023 struct ape_dev *ape = (struct ape_dev *)file->private_data;
1024 (void)ape;
1025 printk(KERN_DEBUG DRV_NAME "_read(buf=0x%p, count=%lld, pos=%llu)\n", buf, (s64)count, (u64)*pos);
1026 return count;
1027}
1028
1029/* sg_write() - Write to the device
1030 *
1031 * @buf userspace buffer
1032 * @count number of bytes in the userspace buffer
1033 *
1034 * Iterate over the userspace buffer, taking at most 255 * PAGE_SIZE bytes for
1035 * each DMA transfer.
1036 * For each transfer, get the user pages, build a sglist, map, build a
1037 * descriptor table. submit the transfer. wait for the interrupt handler
1038 * to wake us on completion.
1039 */
1040static ssize_t sg_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
1041{
1042 int hwnents, tents;
1043 size_t transfer_len, remaining = count, done = 0;
1044 u64 transfer_addr = (u64)buf;
1045 /* fetch device specific data stored earlier during open */
1046 struct ape_dev *ape = (struct ape_dev *)file->private_data;
1047 printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n",
1048 buf, (s64)count, (u64)*pos);
1049 /* TODO transfer boundaries at PAGE_SIZE granularity */
1050 while (remaining > 0) {
1051 /* limit DMA transfer size */
1052 transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining :
1053 APE_CHDMA_MAX_TRANSFER_LEN;
1054 /* get all user space buffer pages and create a scattergather list */
1055 sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/);
1056 printk(KERN_DEBUG DRV_NAME "mapped_pages=%d\n", ape->sgm->mapped_pages);
1057 /* map all entries in the scattergather list */
1058 hwnents = pci_map_sg(ape->pci_dev, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE);
1059 printk(KERN_DEBUG DRV_NAME "hwnents=%d\n", hwnents);
1060 /* build device descriptor tables and submit them to the DMA engine */
1061 tents = ape_sg_to_chdma_table(ape->sgm->sgl, hwnents, 0, &ape->table_virt->desc[0], 4096);
1062 printk(KERN_DEBUG DRV_NAME "tents=%d\n", hwnents);
1063#if 0
1064 while (tables) {
1065 /* TODO build table */
1066 /* TODO submit table to the device */
1067 /* if engine stopped and unfinished work then start engine */
1068 }
1069 put ourselves on wait queue
1070#endif
1071
1072 dma_unmap_sg(NULL, ape->sgm->sgl, ape->sgm->mapped_pages, DMA_TO_DEVICE);
1073 /* dirty and free the pages */
1074 sgm_unmap_user_pages(ape->sgm, 1/*dirtied*/);
1075 /* book keeping */
1076 transfer_addr += transfer_len;
1077 remaining -= transfer_len;
1078 done += transfer_len;
1079 }
1080 return done;
1081}
1082
1083/*
1084 * character device file operations
1085 */
1086static const struct file_operations sg_fops = {
1087 .owner = THIS_MODULE,
1088 .open = sg_open,
1089 .release = sg_close,
1090 .read = sg_read,
1091 .write = sg_write,
1092};
1093
1094/* sg_init() - Initialize character device
1095 *
1096 * XXX Should ideally be tied to the device, on device probe, not module init.
1097 */
1098static int sg_init(struct ape_dev *ape)
1099{
1100 int rc;
1101 printk(KERN_DEBUG DRV_NAME " sg_init()\n");
1102 /* allocate a dynamically allocated character device node */
1103 rc = alloc_chrdev_region(&ape->cdevno, 0/*requested minor*/, 1/*count*/, DRV_NAME);
1104 /* allocation failed? */
1105 if (rc < 0) {
1106 printk("alloc_chrdev_region() = %d\n", rc);
1107 goto fail_alloc;
1108 }
1109 /* couple the device file operations to the character device */
1110 cdev_init(&ape->cdev, &sg_fops);
1111 ape->cdev.owner = THIS_MODULE;
1112 /* bring character device live */
1113 rc = cdev_add(&ape->cdev, ape->cdevno, 1/*count*/);
1114 if (rc < 0) {
1115 printk("cdev_add() = %d\n", rc);
1116 goto fail_add;
1117 }
1118 printk(KERN_DEBUG "altpciechdma = %d:%d\n", MAJOR(ape->cdevno), MINOR(ape->cdevno));
1119 return 0;
1120fail_add:
1121 /* free the dynamically allocated character device node */
1122 unregister_chrdev_region(ape->cdevno, 1/*count*/);
1123fail_alloc:
1124 return -1;
1125}
1126
1127/* sg_exit() - Cleanup character device
1128 *
1129 * XXX Should ideally be tied to the device, on device remove, not module exit.
1130 */
1131
1132static void sg_exit(struct ape_dev *ape)
1133{
1134 printk(KERN_DEBUG DRV_NAME " sg_exit()\n");
1135 /* remove the character device */
1136 cdev_del(&ape->cdev);
1137 /* free the dynamically allocated character device node */
1138 unregister_chrdev_region(ape->cdevno, 1/*count*/);
1139}
1140
1141#endif /* ALTPCIECHDMA_CDEV */
1142
1143/* used to register the driver with the PCI kernel sub system
1144 * @see LDD3 page 311
1145 */
1146static struct pci_driver pci_driver = {
1147 .name = DRV_NAME,
1148 .id_table = ids,
1149 .probe = probe,
1150 .remove = __devexit_p(remove),
1151 /* resume, suspend are optional */
1152};
1153
1154/**
1155 * alterapciechdma_init() - Module initialization, registers devices.
1156 */
1157static int __init alterapciechdma_init(void)
1158{
1159 int rc = 0;
1160 printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n");
1161 /* register this driver with the PCI bus driver */
1162 rc = pci_register_driver(&pci_driver);
1163 if (rc < 0)
1164 return rc;
1165 return 0;
1166}
1167
1168/**
1169 * alterapciechdma_init() - Module cleanup, unregisters devices.
1170 */
1171static void __exit alterapciechdma_exit(void)
1172{
1173 printk(KERN_DEBUG DRV_NAME " exit(), built at " __DATE__ " " __TIME__ "\n");
1174 /* unregister this driver from the PCI bus driver */
1175 pci_unregister_driver(&pci_driver);
1176}
1177
1178MODULE_LICENSE("GPL");
1179
1180module_init(alterapciechdma_init);
1181module_exit(alterapciechdma_exit);
1182
diff --git a/drivers/staging/arlan/Makefile b/drivers/staging/arlan/Makefile
index 9e58e5fae7b9..5a84d4402f21 100644
--- a/drivers/staging/arlan/Makefile
+++ b/drivers/staging/arlan/Makefile
@@ -1,3 +1,3 @@
1obj-$(CONFIG_ARLAN) += arlan.o 1obj-$(CONFIG_ARLAN) += arlan.o
2 2
3arlan-objs := arlan-main.o arlan-proc.o 3arlan-objs := arlan-main.o arlan-proc.o
diff --git a/drivers/staging/arlan/arlan.h b/drivers/staging/arlan/arlan.h
index fb3ad51a1caf..ffcd3ea048aa 100644
--- a/drivers/staging/arlan/arlan.h
+++ b/drivers/staging/arlan/arlan.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 1997 Cullen Jennings 2 * Copyright (C) 1997 Cullen Jennings
3 * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500 3 * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
4 * GNU General Public License applies 4 * GNU General Public License applies
5 */ 5 */
6 6
@@ -20,14 +20,14 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <asm/system.h> 22#include <asm/system.h>
23#include <asm/io.h> 23#include <linux/io.h>
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
28 28
29 29
30//#define ARLAN_DEBUGGING 1 30/* #define ARLAN_DEBUGGING 1 */
31 31
32#define ARLAN_PROC_INTERFACE 32#define ARLAN_PROC_INTERFACE
33#define MAX_ARLANS 4 /* not more than 4 ! */ 33#define MAX_ARLANS 4 /* not more than 4 ! */
@@ -51,8 +51,8 @@ extern int arlan_debug;
51extern int arlan_entry_debug; 51extern int arlan_entry_debug;
52extern int arlan_exit_debug; 52extern int arlan_exit_debug;
53extern int testMemory; 53extern int testMemory;
54extern int arlan_command(struct net_device * dev, int command); 54extern int arlan_command(struct net_device *dev, int command);
55 55
56#define SIDUNKNOWN -1 56#define SIDUNKNOWN -1
57#define radioNodeIdUNKNOWN -1 57#define radioNodeIdUNKNOWN -1
58#define irqUNKNOWN 0 58#define irqUNKNOWN 0
@@ -65,22 +65,21 @@ extern int arlan_command(struct net_device * dev, int command);
65#define registrationModeUNKNOWN -1 65#define registrationModeUNKNOWN -1
66 66
67 67
68#define IFDEBUG( L ) if ( (L) & arlan_debug ) 68#define IFDEBUG(L) if ((L) & arlan_debug)
69#define ARLAN_FAKE_HDR_LEN 12 69#define ARLAN_FAKE_HDR_LEN 12
70 70
71#ifdef ARLAN_DEBUGGING 71#ifdef ARLAN_DEBUGGING
72 #define DEBUG 1 72 #define DEBUG 1
73 #define ARLAN_ENTRY_EXIT_DEBUGGING 1 73 #define ARLAN_ENTRY_EXIT_DEBUGGING 1
74 #define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b) 74 #define ARLAN_DEBUG(a, b) printk(KERN_DEBUG a, b)
75#else 75#else
76 #define ARLAN_DEBUG(a,b) 76 #define ARLAN_DEBUG(a, b)
77#endif 77#endif
78 78
79#define ARLAN_SHMEM_SIZE 0x2000 79#define ARLAN_SHMEM_SIZE 0x2000
80 80
81struct arlan_shmem 81struct arlan_shmem {
82{ 82 /* Header Signature */
83 /* Header Signature */
84 volatile char textRegion[48]; 83 volatile char textRegion[48];
85 volatile u_char resetFlag; 84 volatile u_char resetFlag;
86 volatile u_char diagnosticInfo; 85 volatile u_char diagnosticInfo;
@@ -91,10 +90,10 @@ struct arlan_shmem
91 volatile u_char hardwareType; 90 volatile u_char hardwareType;
92 volatile u_char majorHardwareVersion; 91 volatile u_char majorHardwareVersion;
93 volatile u_char minorHardwareVersion; 92 volatile u_char minorHardwareVersion;
94 volatile u_char radioModule;// shows EEPROM, can be overridden at 0x111 93 volatile u_char radioModule;/* shows EEPROM, can be overridden at 0x111 */
95 volatile u_char defaultChannelSet; // shows EEProm, can be overriiden at 0x10A 94 volatile u_char defaultChannelSet; /* shows EEProm, can be overriiden at 0x10A */
96 volatile u_char _2[47]; 95 volatile u_char _2[47];
97 96
98 /* Control/Status Block - 0x0080 */ 97 /* Control/Status Block - 0x0080 */
99 volatile u_char interruptInProgress; /* not used by lancpu */ 98 volatile u_char interruptInProgress; /* not used by lancpu */
100 volatile u_char cntrlRegImage; /* not used by lancpu */ 99 volatile u_char cntrlRegImage; /* not used by lancpu */
@@ -113,7 +112,7 @@ struct arlan_shmem
113 volatile u_char rxQuality; 112 volatile u_char rxQuality;
114 volatile u_char scrambled; 113 volatile u_char scrambled;
115 volatile u_char _4[1]; 114 volatile u_char _4[1];
116 115
117 /* Transmit Status - 0x00b0 */ 116 /* Transmit Status - 0x00b0 */
118 volatile u_char txStatus; 117 volatile u_char txStatus;
119 volatile u_char txAckQuality; 118 volatile u_char txAckQuality;
@@ -151,7 +150,7 @@ struct arlan_shmem
151 volatile u_short routerId; 150 volatile u_short routerId;
152 volatile u_char _10[9]; 151 volatile u_char _10[9];
153 volatile u_char txAttenuation; 152 volatile u_char txAttenuation;
154 volatile u_char systemId[4]; 153 volatile u_char systemId[4];
155 volatile u_short globalChecksum; 154 volatile u_short globalChecksum;
156 volatile u_char _11[4]; 155 volatile u_char _11[4];
157 volatile u_short maxDatagramSize; 156 volatile u_short maxDatagramSize;
@@ -207,19 +206,19 @@ struct arlan_shmem
207 volatile u_char hostcpuLock; 206 volatile u_char hostcpuLock;
208 volatile u_char lancpuLock; 207 volatile u_char lancpuLock;
209 volatile u_char resetTime[18]; 208 volatile u_char resetTime[18];
210 209
211 volatile u_char numDatagramsTransmitted[4]; 210 volatile u_char numDatagramsTransmitted[4];
212 volatile u_char numReTransmissions[4]; 211 volatile u_char numReTransmissions[4];
213 volatile u_char numFramesDiscarded[4]; 212 volatile u_char numFramesDiscarded[4];
214 volatile u_char numDatagramsReceived[4]; 213 volatile u_char numDatagramsReceived[4];
215 volatile u_char numDuplicateReceivedFrames[4]; 214 volatile u_char numDuplicateReceivedFrames[4];
216 volatile u_char numDatagramsDiscarded[4]; 215 volatile u_char numDatagramsDiscarded[4];
217 216
218 volatile u_short maxNumReTransmitDatagram; 217 volatile u_short maxNumReTransmitDatagram;
219 volatile u_short maxNumReTransmitFrames; 218 volatile u_short maxNumReTransmitFrames;
220 volatile u_short maxNumConsecutiveDuplicateFrames; 219 volatile u_short maxNumConsecutiveDuplicateFrames;
221 /* misaligned here so we have to go to characters */ 220 /* misaligned here so we have to go to characters */
222 221
223 volatile u_char numBytesTransmitted[4]; 222 volatile u_char numBytesTransmitted[4];
224 volatile u_char numBytesReceived[4]; 223 volatile u_char numBytesReceived[4];
225 volatile u_char numCRCErrors[4]; 224 volatile u_char numCRCErrors[4];
@@ -259,7 +258,7 @@ struct arlan_conf_stru {
259 int channelNumber; 258 int channelNumber;
260 int scramblingDisable; 259 int scramblingDisable;
261 int txAttenuation; 260 int txAttenuation;
262 int systemId; 261 int systemId;
263 int maxDatagramSize; 262 int maxDatagramSize;
264 int maxFrameSize; 263 int maxFrameSize;
265 int maxRetries; 264 int maxRetries;
@@ -316,8 +315,7 @@ struct arlan_conf_stru {
316 315
317extern struct arlan_conf_stru arlan_conf[MAX_ARLANS]; 316extern struct arlan_conf_stru arlan_conf[MAX_ARLANS];
318 317
319struct TxParam 318struct TxParam {
320{
321 volatile short offset; 319 volatile short offset;
322 volatile short length; 320 volatile short length;
323 volatile u_char dest[6]; 321 volatile u_char dest[6];
@@ -330,12 +328,12 @@ struct TxParam
330#define TX_RING_SIZE 2 328#define TX_RING_SIZE 2
331/* Information that need to be kept for each board. */ 329/* Information that need to be kept for each board. */
332struct arlan_private { 330struct arlan_private {
333 struct arlan_shmem __iomem * card; 331 struct arlan_shmem __iomem *card;
334 struct arlan_shmem * conf; 332 struct arlan_shmem *conf;
335 333
336 struct arlan_conf_stru * Conf; 334 struct arlan_conf_stru *Conf;
337 int bad; 335 int bad;
338 int reset; 336 int reset;
339 unsigned long lastReset; 337 unsigned long lastReset;
340 struct timer_list timer; 338 struct timer_list timer;
341 struct timer_list tx_delay_timer; 339 struct timer_list tx_delay_timer;
@@ -407,38 +405,38 @@ struct arlan_private {
407 405
408#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer) 406#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
409#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer) 407#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
410 408
411#define READSHM(to,from,atype) {\ 409#define READSHM(to, from, atype) {\
412 atype tmp;\ 410 atype tmp;\
413 memcpy_fromio(&(tmp),&(from),sizeof(atype));\ 411 memcpy_fromio(&(tmp), &(from), sizeof(atype));\
414 to = tmp;\ 412 to = tmp;\
415 } 413 }
416 414
417#define READSHMEM(from,atype)\ 415#define READSHMEM(from, atype)\
418 atype from; \ 416 atype from; \
419 READSHM(from, arlan->from, atype); 417 READSHM(from, arlan->from, atype);
420 418
421#define WRITESHM(to,from,atype) \ 419#define WRITESHM(to, from, atype) \
422 { atype tmpSHM = from;\ 420 { atype tmpSHM = from;\
423 memcpy_toio(&(to),&tmpSHM,sizeof(atype));\ 421 memcpy_toio(&(to), &tmpSHM, sizeof(atype));\
424 } 422 }
425 423
426#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \ 424#define DEBUGSHM(levelSHM, stringSHM, stuff, atype) \
427 { atype tmpSHM; \ 425 { atype tmpSHM; \
428 memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\ 426 memcpy_fromio(&tmpSHM, &(stuff), sizeof(atype));\
429 IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\ 427 IFDEBUG(levelSHM) printk(stringSHM, tmpSHM);\
430 } 428 }
431 429
432#define WRITESHMB(to, val) \ 430#define WRITESHMB(to, val) \
433 writeb(val,&(to)) 431 writeb(val, &(to))
434#define READSHMB(to) \ 432#define READSHMB(to) \
435 readb(&(to)) 433 readb(&(to))
436#define WRITESHMS(to, val) \ 434#define WRITESHMS(to, val) \
437 writew(val,&(to)) 435 writew(val, &(to))
438#define READSHMS(to) \ 436#define READSHMS(to) \
439 readw(&(to)) 437 readw(&(to))
440#define WRITESHMI(to, val) \ 438#define WRITESHMI(to, val) \
441 writel(val,&(to)) 439 writel(val, &(to))
442#define READSHMI(to) \ 440#define READSHMI(to) \
443 readl(&(to)) 441 readl(&(to))
444 442
@@ -447,51 +445,51 @@ struct arlan_private {
447 445
448 446
449#define registrationBad(dev)\ 447#define registrationBad(dev)\
450 ( ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \ 448 (( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \
451 ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0) ) 449 ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0))
452 450
453 451
454#define readControlRegister(dev)\ 452#define readControlRegister(dev)\
455 READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage) 453 READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
456 454
457#define writeControlRegister(dev, v){\ 455#define writeControlRegister(dev, v) {\
458 WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage ,((v) &0xF) );\ 456 WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage, ((v) & 0xF));\
459 WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister ,(v) );} 457 WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister, (v)); }
460 458
461 459
462#define arlan_interrupt_lancpu(dev) {\ 460#define arlan_interrupt_lancpu(dev) {\
463 int cr; \ 461 int cr; \
464 \ 462 \
465 cr = readControlRegister(dev);\ 463 cr = readControlRegister(dev);\
466 if (cr & ARLAN_CHANNEL_ATTENTION){ \ 464 if (cr & ARLAN_CHANNEL_ATTENTION) { \
467 writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\ 465 writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
468 }else \ 466 } else \
469 writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\ 467 writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
470} 468}
471 469
472#define clearChannelAttention(dev){ \ 470#define clearChannelAttention(dev) { \
473 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);} 471 writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION); }
474#define setHardwareReset(dev) {\ 472#define setHardwareReset(dev) {\
475 writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);} 473 writeControlRegister(dev, readControlRegister(dev) | ARLAN_RESET); }
476#define clearHardwareReset(dev) {\ 474#define clearHardwareReset(dev) {\
477 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);} 475 writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_RESET); }
478#define setInterruptEnable(dev){\ 476#define setInterruptEnable(dev) {\
479 writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ;} 477 writeControlRegister(dev, readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ; }
480#define clearInterruptEnable(dev){\ 478#define clearInterruptEnable(dev) {\
481 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ;} 479 writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ; }
482#define setClearInterrupt(dev){\ 480#define setClearInterrupt(dev) {\
483 writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ;} 481 writeControlRegister(dev, readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ; }
484#define clearClearInterrupt(dev){\ 482#define clearClearInterrupt(dev) {\
485 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);} 483 writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT); }
486#define setPowerOff(dev){\ 484#define setPowerOff(dev) {\
487 writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\ 485 writeControlRegister(dev, readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
488 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);} 486 writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
489#define setPowerOn(dev){\ 487#define setPowerOn(dev) {\
490 writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER)); } 488 writeControlRegister(dev, readControlRegister(dev) & ~(ARLAN_POWER)); }
491#define arlan_lock_card_access(dev){\ 489#define arlan_lock_card_access(dev) {\
492 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);} 490 writeControlRegister(dev, readControlRegister(dev) & ~ARLAN_ACCESS); }
493#define arlan_unlock_card_access(dev){\ 491#define arlan_unlock_card_access(dev) {\
494 writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); } 492 writeControlRegister(dev, readControlRegister(dev) | ARLAN_ACCESS); }
495 493
496 494
497 495
@@ -525,7 +523,6 @@ struct arlan_private {
525 | ARLAN_COMMAND_RESET) 523 | ARLAN_COMMAND_RESET)
526 524
527 525
528
529#define ARLAN_DEBUG_CHAIN_LOCKS 0x00001 526#define ARLAN_DEBUG_CHAIN_LOCKS 0x00001
530#define ARLAN_DEBUG_RESET 0x00002 527#define ARLAN_DEBUG_RESET 0x00002
531#define ARLAN_DEBUG_TIMING 0x00004 528#define ARLAN_DEBUG_TIMING 0x00004
@@ -536,4 +533,3 @@ struct arlan_private {
536#define ARLAN_DEBUG_INTERRUPT 0x00080 533#define ARLAN_DEBUG_INTERRUPT 0x00080
537#define ARLAN_DEBUG_STARTUP 0x00100 534#define ARLAN_DEBUG_STARTUP 0x00100
538#define ARLAN_DEBUG_SHUTDOWN 0x00200 535#define ARLAN_DEBUG_SHUTDOWN 0x00200
539
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 43c57b7688ab..cadb6f7321ad 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -52,6 +52,10 @@
52#define ASUS_OLED_DISP_HEIGHT 32 52#define ASUS_OLED_DISP_HEIGHT 32
53#define ASUS_OLED_PACKET_BUF_SIZE 256 53#define ASUS_OLED_PACKET_BUF_SIZE 256
54 54
55#define USB_VENDOR_ID_ASUS 0x0b05
56#define USB_DEVICE_ID_ASUS_LCM 0x1726
57#define USB_DEVICE_ID_ASUS_LCM2 0x175b
58
55MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com"); 59MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
56MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION); 60MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
57MODULE_LICENSE("GPL"); 61MODULE_LICENSE("GPL");
@@ -83,18 +87,20 @@ struct oled_dev_desc_str {
83}; 87};
84 88
85/* table of devices that work with this driver */ 89/* table of devices that work with this driver */
86static struct usb_device_id id_table[] = { 90static const struct usb_device_id id_table[] = {
87 /* Asus G1/G2 (and variants)*/ 91 /* Asus G1/G2 (and variants)*/
88 { USB_DEVICE(0x0b05, 0x1726) }, 92 { USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM) },
89 /* Asus G50V (and possibly others - G70? G71?)*/ 93 /* Asus G50V (and possibly others - G70? G71?)*/
90 { USB_DEVICE(0x0b05, 0x175b) }, 94 { USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2) },
91 { }, 95 { },
92}; 96};
93 97
94/* parameters of specific devices */ 98/* parameters of specific devices */
95static struct oled_dev_desc_str oled_dev_desc_table[] = { 99static struct oled_dev_desc_str oled_dev_desc_table[] = {
96 { 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" }, 100 { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, 128, PACK_MODE_G1,
97 { 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" }, 101 "G1/G2" },
102 { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2, 256, PACK_MODE_G50,
103 "G50" },
98 { }, 104 { },
99}; 105};
100 106
@@ -424,6 +430,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev,
424 430
425 kfree(odev->buf); 431 kfree(odev->buf);
426 odev->buf = kmalloc(odev->buf_size, GFP_KERNEL); 432 odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
433 if (odev->buf == NULL) {
434 odev->buf_size = 0;
435 printk(ASUS_OLED_ERROR "Out of memory!\n");
436 return -ENOMEM;
437 }
427 438
428 memset(odev->buf, 0xff, odev->buf_size); 439 memset(odev->buf, 0xff, odev->buf_size);
429 440
diff --git a/drivers/staging/b3dfg/Kconfig b/drivers/staging/b3dfg/Kconfig
deleted file mode 100644
index 9e6573cf97d3..000000000000
--- a/drivers/staging/b3dfg/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config B3DFG
2 tristate "Brontes 3d Frame Framegrabber"
3 depends on PCI
4 default n
5 ---help---
6 This driver provides support for the Brontes 3d Framegrabber
7 PCI card.
8
9 To compile this driver as a module, choose M here. The module
10 will be called b3dfg.
diff --git a/drivers/staging/b3dfg/Makefile b/drivers/staging/b3dfg/Makefile
deleted file mode 100644
index 91f439ffc174..000000000000
--- a/drivers/staging/b3dfg/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_B3DFG) += b3dfg.o
diff --git a/drivers/staging/b3dfg/TODO b/drivers/staging/b3dfg/TODO
deleted file mode 100644
index f5a9298b9ac1..000000000000
--- a/drivers/staging/b3dfg/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
1
2 - queue/wait buffer presents filltime results for each frame?
3 - counting of dropped frames
4 - review endianness
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
deleted file mode 100644
index 4a43c51c172a..000000000000
--- a/drivers/staging/b3dfg/b3dfg.c
+++ /dev/null
@@ -1,1100 +0,0 @@
1 /*
2 * Brontes PCI frame grabber driver
3 *
4 * Copyright (C) 2008 3M Company
5 * Contact: Justin Bronder <jsbronder@brontes3d.com>
6 * Original Authors: Daniel Drake <ddrake@brontes3d.com>
7 * Duane Griffin <duaneg@dghda.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/device.h>
25#include <linux/fs.h>
26#include <linux/interrupt.h>
27#include <linux/spinlock.h>
28#include <linux/ioctl.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/pci.h>
32#include <linux/types.h>
33#include <linux/cdev.h>
34#include <linux/list.h>
35#include <linux/poll.h>
36#include <linux/wait.h>
37#include <linux/mm.h>
38#include <linux/uaccess.h>
39#include <linux/sched.h>
40
41static unsigned int b3dfg_nbuf = 2;
42
43module_param_named(buffer_count, b3dfg_nbuf, uint, 0444);
44
45MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)");
46
47MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
48MODULE_DESCRIPTION("Brontes frame grabber driver");
49MODULE_LICENSE("GPL");
50
51#define DRIVER_NAME "b3dfg"
52#define B3DFG_MAX_DEVS 4
53#define B3DFG_FRAMES_PER_BUFFER 3
54
55#define B3DFG_BAR_REGS 0
56#define B3DFG_REGS_LENGTH 0x10000
57
58#define B3DFG_IOC_MAGIC 0xb3 /* dfg :-) */
59#define B3DFG_IOCGFRMSZ _IOR(B3DFG_IOC_MAGIC, 1, int)
60#define B3DFG_IOCTNUMBUFS _IO(B3DFG_IOC_MAGIC, 2)
61#define B3DFG_IOCTTRANS _IO(B3DFG_IOC_MAGIC, 3)
62#define B3DFG_IOCTQUEUEBUF _IO(B3DFG_IOC_MAGIC, 4)
63#define B3DFG_IOCTPOLLBUF _IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
64#define B3DFG_IOCTWAITBUF _IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
65#define B3DFG_IOCGWANDSTAT _IOR(B3DFG_IOC_MAGIC, 7, int)
66
67enum {
68 /* number of 4kb pages per frame */
69 B3D_REG_FRM_SIZE = 0x0,
70
71 /* bit 0: set to enable interrupts
72 * bit 1: set to enable cable status change interrupts */
73 B3D_REG_HW_CTRL = 0x4,
74
75 /* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
76 * bit 2 indicates the previous DMA transfer has completed
77 * bit 3 indicates wand cable status change
78 * bit 8:15 - counter of number of discarded triplets */
79 B3D_REG_DMA_STS = 0x8,
80
81 /* bit 0: wand status (1 = present, 0 = disconnected) */
82 B3D_REG_WAND_STS = 0xc,
83
84 /* bus address for DMA transfers. lower 2 bits must be zero because DMA
85 * works with 32 bit word size. */
86 B3D_REG_EC220_DMA_ADDR = 0x8000,
87
88 /* bit 20:0 - number of 32 bit words to be transferred
89 * bit 21:31 - reserved */
90 B3D_REG_EC220_TRF_SIZE = 0x8004,
91
92 /* bit 0 - error bit
93 * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
94 * bit 2 - start bit (set to start transfer)
95 * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
96 * bit 4:31 - reserved */
97 B3D_REG_EC220_DMA_STS = 0x8008,
98};
99
100enum b3dfg_buffer_state {
101 B3DFG_BUFFER_POLLED = 0,
102 B3DFG_BUFFER_PENDING,
103 B3DFG_BUFFER_POPULATED,
104};
105
106struct b3dfg_buffer {
107 unsigned char *frame[B3DFG_FRAMES_PER_BUFFER];
108 struct list_head list;
109 u8 state;
110};
111
112struct b3dfg_dev {
113
114 /* no protection needed: all finalized at initialization time */
115 struct pci_dev *pdev;
116 struct cdev chardev;
117 struct device *dev;
118 void __iomem *regs;
119 unsigned int frame_size;
120
121 /*
122 * Protects buffer state, including buffer_queue, triplet_ready,
123 * cur_dma_frame_idx & cur_dma_frame_addr.
124 */
125 spinlock_t buffer_lock;
126 struct b3dfg_buffer *buffers;
127 struct list_head buffer_queue;
128
129 /* Last frame in triplet transferred (-1 if none). */
130 int cur_dma_frame_idx;
131
132 /* Current frame's address for DMA. */
133 dma_addr_t cur_dma_frame_addr;
134
135 /*
136 * Protects cstate_tstamp.
137 * Nests inside buffer_lock.
138 */
139 spinlock_t cstate_lock;
140 unsigned long cstate_tstamp;
141
142 /*
143 * Protects triplets_dropped.
144 * Nests inside buffers_lock.
145 */
146 spinlock_t triplets_dropped_lock;
147 unsigned int triplets_dropped;
148
149 wait_queue_head_t buffer_waitqueue;
150
151 unsigned int transmission_enabled:1;
152 unsigned int triplet_ready:1;
153};
154
155static u8 b3dfg_devices[B3DFG_MAX_DEVS];
156
157static struct class *b3dfg_class;
158static dev_t b3dfg_devt;
159
160static const struct pci_device_id b3dfg_ids[] __devinitdata = {
161 { PCI_DEVICE(0x0b3d, 0x0001) },
162 { },
163};
164
165MODULE_DEVICE_TABLE(pci, b3dfg_ids);
166
167/***** user-visible types *****/
168
169struct b3dfg_poll {
170 int buffer_idx;
171 unsigned int triplets_dropped;
172};
173
174struct b3dfg_wait {
175 int buffer_idx;
176 unsigned int timeout;
177 unsigned int triplets_dropped;
178};
179
180/**** register I/O ****/
181
182static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg)
183{
184 return ioread32(fgdev->regs + reg);
185}
186
187static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value)
188{
189 iowrite32(value, fgdev->regs + reg);
190}
191
192/**** buffer management ****/
193
194/*
195 * Program EC220 for transfer of a specific frame.
196 * Called with buffer_lock held.
197 */
198static int setup_frame_transfer(struct b3dfg_dev *fgdev,
199 struct b3dfg_buffer *buf, int frame)
200{
201 unsigned char *frm_addr;
202 dma_addr_t frm_addr_dma;
203 unsigned int frm_size = fgdev->frame_size;
204
205 frm_addr = buf->frame[frame];
206 frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr,
207 frm_size, PCI_DMA_FROMDEVICE);
208 if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma))
209 return -ENOMEM;
210
211 fgdev->cur_dma_frame_addr = frm_addr_dma;
212 fgdev->cur_dma_frame_idx = frame;
213
214 b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR,
215 cpu_to_le32(frm_addr_dma));
216 b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE,
217 cpu_to_le32(frm_size >> 2));
218 b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf);
219
220 return 0;
221}
222
223/* Caller should hold buffer lock */
224static void dequeue_all_buffers(struct b3dfg_dev *fgdev)
225{
226 int i;
227 for (i = 0; i < b3dfg_nbuf; i++) {
228 struct b3dfg_buffer *buf = &fgdev->buffers[i];
229 buf->state = B3DFG_BUFFER_POLLED;
230 list_del_init(&buf->list);
231 }
232}
233
234/* queue a buffer to receive data */
235static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx)
236{
237 struct device *dev = &fgdev->pdev->dev;
238 struct b3dfg_buffer *buf;
239 unsigned long flags;
240 int r = 0;
241
242 spin_lock_irqsave(&fgdev->buffer_lock, flags);
243 if (bufidx < 0 || bufidx >= b3dfg_nbuf) {
244 dev_dbg(dev, "Invalid buffer index, %d\n", bufidx);
245 r = -ENOENT;
246 goto out;
247 }
248 buf = &fgdev->buffers[bufidx];
249
250 if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) {
251 dev_dbg(dev, "buffer %d is already queued\n", bufidx);
252 r = -EINVAL;
253 goto out;
254 }
255
256 buf->state = B3DFG_BUFFER_PENDING;
257 list_add_tail(&buf->list, &fgdev->buffer_queue);
258
259 if (fgdev->transmission_enabled && fgdev->triplet_ready) {
260 dev_dbg(dev, "triplet is ready, pushing immediately\n");
261 fgdev->triplet_ready = 0;
262 r = setup_frame_transfer(fgdev, buf, 0);
263 if (r)
264 dev_err(dev, "unable to map DMA buffer\n");
265 }
266
267out:
268 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
269 return r;
270}
271
272/* non-blocking buffer poll. returns 1 if data is present in the buffer,
273 * 0 otherwise */
274static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg)
275{
276 struct device *dev = &fgdev->pdev->dev;
277 struct b3dfg_poll p;
278 struct b3dfg_buffer *buf;
279 unsigned long flags;
280 int r = 1;
281 int arg_out = 0;
282
283 if (copy_from_user(&p, arg, sizeof(p)))
284 return -EFAULT;
285
286 if (unlikely(!fgdev->transmission_enabled)) {
287 dev_dbg(dev, "cannot poll, transmission disabled\n");
288 return -EINVAL;
289 }
290
291 if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf)
292 return -ENOENT;
293
294 buf = &fgdev->buffers[p.buffer_idx];
295
296 spin_lock_irqsave(&fgdev->buffer_lock, flags);
297
298 if (likely(buf->state == B3DFG_BUFFER_POPULATED)) {
299 arg_out = 1;
300 buf->state = B3DFG_BUFFER_POLLED;
301
302 /* IRQs already disabled by spin_lock_irqsave above. */
303 spin_lock(&fgdev->triplets_dropped_lock);
304 p.triplets_dropped = fgdev->triplets_dropped;
305 fgdev->triplets_dropped = 0;
306 spin_unlock(&fgdev->triplets_dropped_lock);
307 } else {
308 r = 0;
309 }
310
311 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
312
313 if (arg_out && copy_to_user(arg, &p, sizeof(p)))
314 r = -EFAULT;
315
316 return r;
317}
318
319static unsigned long get_cstate_change(struct b3dfg_dev *fgdev)
320{
321 unsigned long flags, when;
322
323 spin_lock_irqsave(&fgdev->cstate_lock, flags);
324 when = fgdev->cstate_tstamp;
325 spin_unlock_irqrestore(&fgdev->cstate_lock, flags);
326 return when;
327}
328
329static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf,
330 unsigned long when)
331{
332 int result;
333 unsigned long flags;
334
335 spin_lock_irqsave(&fgdev->buffer_lock, flags);
336 spin_lock(&fgdev->cstate_lock);
337 result = (!fgdev->transmission_enabled ||
338 buf->state == B3DFG_BUFFER_POPULATED ||
339 when != fgdev->cstate_tstamp);
340 spin_unlock(&fgdev->cstate_lock);
341 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
342
343 return result;
344}
345
346/* sleep until a specific buffer becomes populated */
347static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg)
348{
349 struct device *dev = &fgdev->pdev->dev;
350 struct b3dfg_wait w;
351 struct b3dfg_buffer *buf;
352 unsigned long flags, when;
353 int r;
354
355 if (copy_from_user(&w, arg, sizeof(w)))
356 return -EFAULT;
357
358 if (!fgdev->transmission_enabled) {
359 dev_dbg(dev, "cannot wait, transmission disabled\n");
360 return -EINVAL;
361 }
362
363 if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf)
364 return -ENOENT;
365
366 buf = &fgdev->buffers[w.buffer_idx];
367
368 spin_lock_irqsave(&fgdev->buffer_lock, flags);
369
370 if (buf->state == B3DFG_BUFFER_POPULATED) {
371 r = w.timeout;
372 goto out_triplets_dropped;
373 }
374
375 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
376
377 when = get_cstate_change(fgdev);
378 if (w.timeout > 0) {
379 r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue,
380 is_event_ready(fgdev, buf, when),
381 (w.timeout * HZ) / 1000);
382
383 if (unlikely(r < 0))
384 goto out;
385
386 w.timeout = r * 1000 / HZ;
387 } else {
388 r = wait_event_interruptible(fgdev->buffer_waitqueue,
389 is_event_ready(fgdev, buf, when));
390
391 if (unlikely(r)) {
392 r = -ERESTARTSYS;
393 goto out;
394 }
395 }
396
397 /* TODO: Inform the user via field(s) in w? */
398 if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) {
399 r = -EINVAL;
400 goto out;
401 }
402
403 spin_lock_irqsave(&fgdev->buffer_lock, flags);
404
405 if (buf->state != B3DFG_BUFFER_POPULATED) {
406 r = -ETIMEDOUT;
407 goto out_unlock;
408 }
409
410 buf->state = B3DFG_BUFFER_POLLED;
411
412out_triplets_dropped:
413
414 /* IRQs already disabled by spin_lock_irqsave above. */
415 spin_lock(&fgdev->triplets_dropped_lock);
416 w.triplets_dropped = fgdev->triplets_dropped;
417 fgdev->triplets_dropped = 0;
418 spin_unlock(&fgdev->triplets_dropped_lock);
419
420out_unlock:
421 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
422 if (copy_to_user(arg, &w, sizeof(w)))
423 r = -EFAULT;
424out:
425 return r;
426}
427
428/* mmap page fault handler */
429static int b3dfg_vma_fault(struct vm_area_struct *vma,
430 struct vm_fault *vmf)
431{
432 struct b3dfg_dev *fgdev = vma->vm_file->private_data;
433 unsigned long off = vmf->pgoff << PAGE_SHIFT;
434 unsigned int frame_size = fgdev->frame_size;
435 unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER;
436 unsigned char *addr;
437
438 /* determine which buffer the offset lies within */
439 unsigned int buf_idx = off / buf_size;
440 /* and the offset into the buffer */
441 unsigned int buf_off = off % buf_size;
442
443 /* determine which frame inside the buffer the offset lies in */
444 unsigned int frm_idx = buf_off / frame_size;
445 /* and the offset into the frame */
446 unsigned int frm_off = buf_off % frame_size;
447
448 if (unlikely(buf_idx >= b3dfg_nbuf))
449 return VM_FAULT_SIGBUS;
450
451 addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off;
452 vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
453 virt_to_phys(addr) >> PAGE_SHIFT);
454
455 return VM_FAULT_NOPAGE;
456}
457
458static struct vm_operations_struct b3dfg_vm_ops = {
459 .fault = b3dfg_vma_fault,
460};
461
462static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg)
463{
464 u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
465 dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat);
466 return __put_user(wndstat & 0x1, arg);
467}
468
469static int enable_transmission(struct b3dfg_dev *fgdev)
470{
471 unsigned long flags;
472 struct device *dev = &fgdev->pdev->dev;
473
474 dev_dbg(dev, "enable transmission\n");
475
476 /* check the cable is plugged in. */
477 if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) {
478 dev_dbg(dev, "cannot start transmission without wand\n");
479 return -EINVAL;
480 }
481
482 spin_lock_irqsave(&fgdev->buffer_lock, flags);
483
484 /* Handle racing enable_transmission calls. */
485 if (fgdev->transmission_enabled) {
486 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
487 goto out;
488 }
489
490 spin_lock(&fgdev->triplets_dropped_lock);
491 fgdev->triplets_dropped = 0;
492 spin_unlock(&fgdev->triplets_dropped_lock);
493
494 fgdev->triplet_ready = 0;
495 fgdev->cur_dma_frame_idx = -1;
496 fgdev->transmission_enabled = 1;
497
498 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
499
500 /* Enable DMA and cable status interrupts. */
501 b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03);
502
503out:
504 return 0;
505}
506
507static void disable_transmission(struct b3dfg_dev *fgdev)
508{
509 struct device *dev = &fgdev->pdev->dev;
510 unsigned long flags;
511 u32 tmp;
512
513 dev_dbg(dev, "disable transmission\n");
514
515 /* guarantee that no more interrupts will be serviced */
516 spin_lock_irqsave(&fgdev->buffer_lock, flags);
517 fgdev->transmission_enabled = 0;
518
519 b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
520
521 /* FIXME: temporary debugging only. if the board stops transmitting,
522 * hitting ctrl+c and seeing this message is useful for determining
523 * the state of the board. */
524 tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
525 dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp);
526
527 dequeue_all_buffers(fgdev);
528 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
529
530 wake_up_interruptible(&fgdev->buffer_waitqueue);
531}
532
533static int set_transmission(struct b3dfg_dev *fgdev, int enabled)
534{
535 int res = 0;
536
537 if (enabled && !fgdev->transmission_enabled)
538 res = enable_transmission(fgdev);
539 else if (!enabled && fgdev->transmission_enabled)
540 disable_transmission(fgdev);
541
542 return res;
543}
544
545/* Called in interrupt context. */
546static void handle_cstate_unplug(struct b3dfg_dev *fgdev)
547{
548 /* Disable all interrupts. */
549 b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
550
551 /* Stop transmission. */
552 spin_lock(&fgdev->buffer_lock);
553 fgdev->transmission_enabled = 0;
554
555 fgdev->cur_dma_frame_idx = -1;
556 fgdev->triplet_ready = 0;
557 if (fgdev->cur_dma_frame_addr) {
558 pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
559 fgdev->frame_size, PCI_DMA_FROMDEVICE);
560 fgdev->cur_dma_frame_addr = 0;
561 }
562 dequeue_all_buffers(fgdev);
563 spin_unlock(&fgdev->buffer_lock);
564}
565
566/* Called in interrupt context. */
567static void handle_cstate_change(struct b3dfg_dev *fgdev)
568{
569 u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
570 unsigned long when;
571 struct device *dev = &fgdev->pdev->dev;
572
573 dev_dbg(dev, "cable state change: %u\n", cstate);
574
575 /*
576 * When the wand is unplugged we reset our state. The hardware will
577 * have done the same internally.
578 *
579 * Note we should never see a cable *plugged* event, as interrupts
580 * should only be enabled when transmitting, which requires the cable
581 * to be plugged. If we do see one it probably means the cable has been
582 * unplugged and re-plugged very rapidly. Possibly because it has a
583 * broken wire and is momentarily losing contact.
584 *
585 * TODO: At the moment if you plug in the cable then enable transmission
586 * the hardware will raise a couple of spurious interrupts, so
587 * just ignore them for now.
588 *
589 * Once the hardware is fixed we should complain and treat it as an
590 * unplug. Or at least track how frequently it is happening and do
591 * so if too many come in.
592 */
593 if (cstate) {
594 dev_warn(dev, "ignoring unexpected plug event\n");
595 return;
596 }
597 handle_cstate_unplug(fgdev);
598
599 /*
600 * Record cable state change timestamp & wake anyone waiting
601 * on a cable state change. Be paranoid about ensuring events
602 * are not missed if we somehow get two interrupts in a jiffy.
603 */
604 spin_lock(&fgdev->cstate_lock);
605 when = jiffies_64;
606 if (when <= fgdev->cstate_tstamp)
607 when = fgdev->cstate_tstamp + 1;
608 fgdev->cstate_tstamp = when;
609 wake_up_interruptible(&fgdev->buffer_waitqueue);
610 spin_unlock(&fgdev->cstate_lock);
611}
612
613/* Called with buffer_lock held. */
614static void transfer_complete(struct b3dfg_dev *fgdev)
615{
616 struct b3dfg_buffer *buf;
617 struct device *dev = &fgdev->pdev->dev;
618
619 pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
620 fgdev->frame_size, PCI_DMA_FROMDEVICE);
621 fgdev->cur_dma_frame_addr = 0;
622
623 buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
624
625 dev_dbg(dev, "handle frame completion\n");
626 if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
627
628 /* last frame of that triplet completed */
629 dev_dbg(dev, "triplet completed\n");
630 buf->state = B3DFG_BUFFER_POPULATED;
631 list_del_init(&buf->list);
632 wake_up_interruptible(&fgdev->buffer_waitqueue);
633 }
634}
635
636/*
637 * Called with buffer_lock held.
638 *
639 * Note that idx is the (1-based) *next* frame to be transferred, while
640 * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
641 * -1 if none). Thus there should be a difference of 2 between them.
642 */
643static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
644{
645 struct b3dfg_buffer *buf;
646 struct device *dev = &fgdev->pdev->dev;
647 bool need_ack = 1;
648
649 dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
650
651 buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
652 if (idx == fgdev->cur_dma_frame_idx + 2) {
653 if (setup_frame_transfer(fgdev, buf, idx - 1))
654 dev_err(dev, "unable to map DMA buffer\n");
655 need_ack = 0;
656 } else {
657 dev_err(dev, "frame mismatch, got %d, expected %d\n",
658 idx, fgdev->cur_dma_frame_idx + 2);
659
660 /* FIXME: handle dropped triplets here */
661 }
662
663 return need_ack;
664}
665
666static irqreturn_t b3dfg_intr(int irq, void *dev_id)
667{
668 struct b3dfg_dev *fgdev = dev_id;
669 struct device *dev = &fgdev->pdev->dev;
670 u32 sts;
671 u8 dropped;
672 bool need_ack = 1;
673 irqreturn_t res = IRQ_HANDLED;
674
675 sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
676 if (unlikely(sts == 0)) {
677 dev_warn(dev, "ignore interrupt, DMA status is 0\n");
678 res = IRQ_NONE;
679 goto out;
680 }
681
682 if (unlikely(!fgdev->transmission_enabled)) {
683 dev_warn(dev, "ignore interrupt, TX disabled\n");
684 res = IRQ_HANDLED;
685 goto out;
686 }
687
688 /* Handle dropped frames, as reported by the hardware. */
689 dropped = (sts >> 8) & 0xff;
690 dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
691 sts, dropped, !!(sts & 0x4), sts & 0x3);
692 if (unlikely(dropped > 0)) {
693 spin_lock(&fgdev->triplets_dropped_lock);
694 fgdev->triplets_dropped += dropped;
695 spin_unlock(&fgdev->triplets_dropped_lock);
696 }
697
698 /* Handle a cable state change (i.e. the wand being unplugged). */
699 if (sts & 0x08) {
700 handle_cstate_change(fgdev);
701 goto out;
702 }
703
704 spin_lock(&fgdev->buffer_lock);
705 if (unlikely(list_empty(&fgdev->buffer_queue))) {
706
707 /* FIXME need more sanity checking here */
708 dev_info(dev, "buffer not ready for next transfer\n");
709 fgdev->triplet_ready = 1;
710 goto out_unlock;
711 }
712
713 /* Has a frame transfer been completed? */
714 if (sts & 0x4) {
715 u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS);
716
717 /* Check for DMA errors reported by the hardware. */
718 if (unlikely(dma_status & 0x1)) {
719 dev_err(dev, "EC220 error: %08x\n", dma_status);
720
721 /* FIXME flesh out error handling */
722 goto out_unlock;
723 }
724
725 /* Sanity check, we should have a frame index at this point. */
726 if (unlikely(fgdev->cur_dma_frame_idx == -1)) {
727 dev_err(dev, "completed but no last idx?\n");
728
729 /* FIXME flesh out error handling */
730 goto out_unlock;
731 }
732
733 transfer_complete(fgdev);
734 }
735
736 /* Is there another frame transfer pending? */
737 if (sts & 0x3)
738 need_ack = setup_next_frame_transfer(fgdev, sts & 0x3);
739 else
740 fgdev->cur_dma_frame_idx = -1;
741
742out_unlock:
743 spin_unlock(&fgdev->buffer_lock);
744out:
745 if (need_ack) {
746 dev_dbg(dev, "acknowledging interrupt\n");
747 b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b);
748 }
749 return res;
750}
751
752static int b3dfg_open(struct inode *inode, struct file *filp)
753{
754 struct b3dfg_dev *fgdev =
755 container_of(inode->i_cdev, struct b3dfg_dev, chardev);
756
757 dev_dbg(&fgdev->pdev->dev, "open\n");
758 filp->private_data = fgdev;
759 return 0;
760}
761
762static int b3dfg_release(struct inode *inode, struct file *filp)
763{
764 struct b3dfg_dev *fgdev = filp->private_data;
765 dev_dbg(&fgdev->pdev->dev, "release\n");
766 disable_transmission(fgdev);
767 return 0;
768}
769
770static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
771{
772 struct b3dfg_dev *fgdev = filp->private_data;
773
774 switch (cmd) {
775 case B3DFG_IOCGFRMSZ:
776 return __put_user(fgdev->frame_size, (int __user *) arg);
777 case B3DFG_IOCGWANDSTAT:
778 return get_wand_status(fgdev, (int __user *) arg);
779 case B3DFG_IOCTTRANS:
780 return set_transmission(fgdev, (int) arg);
781 case B3DFG_IOCTQUEUEBUF:
782 return queue_buffer(fgdev, (int) arg);
783 case B3DFG_IOCTPOLLBUF:
784 return poll_buffer(fgdev, (void __user *) arg);
785 case B3DFG_IOCTWAITBUF:
786 return wait_buffer(fgdev, (void __user *) arg);
787 default:
788 dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd);
789 return -EINVAL;
790 }
791}
792
793static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table)
794{
795 struct b3dfg_dev *fgdev = filp->private_data;
796 unsigned long flags, when;
797 int i;
798 int r = 0;
799
800 when = get_cstate_change(fgdev);
801 poll_wait(filp, &fgdev->buffer_waitqueue, poll_table);
802
803 spin_lock_irqsave(&fgdev->buffer_lock, flags);
804 for (i = 0; i < b3dfg_nbuf; i++) {
805 if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) {
806 r = POLLIN | POLLRDNORM;
807 break;
808 }
809 }
810 spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
811
812 /* TODO: Confirm this is how we want to communicate the change. */
813 if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev))
814 r = POLLERR;
815
816 return r;
817}
818
819static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma)
820{
821 struct b3dfg_dev *fgdev = filp->private_data;
822 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
823 unsigned long vsize = vma->vm_end - vma->vm_start;
824 unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3;
825 unsigned long psize = bufdatalen - offset;
826 int r = 0;
827
828 if (vsize <= psize) {
829 vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR |
830 VM_PFNMAP;
831 vma->vm_ops = &b3dfg_vm_ops;
832 } else {
833 r = -EINVAL;
834 }
835
836 return r;
837}
838
839static struct file_operations b3dfg_fops = {
840 .owner = THIS_MODULE,
841 .open = b3dfg_open,
842 .release = b3dfg_release,
843 .unlocked_ioctl = b3dfg_ioctl,
844 .poll = b3dfg_poll,
845 .mmap = b3dfg_mmap,
846};
847
848static void free_all_frame_buffers(struct b3dfg_dev *fgdev)
849{
850 int i, j;
851 for (i = 0; i < b3dfg_nbuf; i++)
852 for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++)
853 kfree(fgdev->buffers[i].frame[j]);
854 kfree(fgdev->buffers);
855}
856
857/* initialize device and any data structures. called before any interrupts
858 * are enabled. */
859static int b3dfg_init_dev(struct b3dfg_dev *fgdev)
860{
861 int i, j;
862 u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE);
863
864 /* Disable interrupts. In abnormal circumstances (e.g. after a crash)
865 * the board may still be transmitting from the previous session. If we
866 * ensure that interrupts are disabled before we later enable them, we
867 * are sure to capture a triplet from the start, rather than starting
868 * from frame 2 or 3. Disabling interrupts causes the FG to throw away
869 * all buffered data and stop buffering more until interrupts are
870 * enabled again.
871 */
872 b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
873
874 fgdev->frame_size = frm_size * 4096;
875 fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf,
876 GFP_KERNEL);
877 if (!fgdev->buffers)
878 goto err_no_buf;
879 for (i = 0; i < b3dfg_nbuf; i++) {
880 struct b3dfg_buffer *buf = &fgdev->buffers[i];
881 for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) {
882 buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL);
883 if (!buf->frame[j])
884 goto err_no_mem;
885 }
886 INIT_LIST_HEAD(&buf->list);
887 }
888
889 INIT_LIST_HEAD(&fgdev->buffer_queue);
890 init_waitqueue_head(&fgdev->buffer_waitqueue);
891 spin_lock_init(&fgdev->buffer_lock);
892 spin_lock_init(&fgdev->cstate_lock);
893 spin_lock_init(&fgdev->triplets_dropped_lock);
894 return 0;
895
896err_no_mem:
897 free_all_frame_buffers(fgdev);
898err_no_buf:
899 return -ENOMEM;
900}
901
902/* find next free minor number, returns -1 if none are availabile */
903static int get_free_minor(void)
904{
905 int i;
906 for (i = 0; i < B3DFG_MAX_DEVS; i++) {
907 if (b3dfg_devices[i] == 0)
908 return i;
909 }
910 return -1;
911}
912
913static int __devinit b3dfg_probe(struct pci_dev *pdev,
914 const struct pci_device_id *id)
915{
916 struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL);
917 int r = 0;
918 int minor = get_free_minor();
919 dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor);
920 unsigned long res_len;
921 resource_size_t res_base;
922
923 if (fgdev == NULL)
924 return -ENOMEM;
925
926 if (minor < 0) {
927 dev_err(&pdev->dev, "too many devices found!\n");
928 r = -EIO;
929 goto err_free;
930 }
931
932 b3dfg_devices[minor] = 1;
933 dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq);
934
935 cdev_init(&fgdev->chardev, &b3dfg_fops);
936 fgdev->chardev.owner = THIS_MODULE;
937
938 r = cdev_add(&fgdev->chardev, devno, 1);
939 if (r) {
940 dev_err(&pdev->dev, "cannot add char device\n");
941 goto err_release_minor;
942 }
943
944 fgdev->dev = device_create(
945 b3dfg_class,
946 &pdev->dev,
947 devno,
948 dev_get_drvdata(&pdev->dev),
949 DRIVER_NAME "%d", minor);
950
951 if (IS_ERR(fgdev->dev)) {
952 dev_err(&pdev->dev, "cannot create device\n");
953 r = PTR_ERR(fgdev->dev);
954 goto err_del_cdev;
955 }
956
957 r = pci_enable_device(pdev);
958 if (r) {
959 dev_err(&pdev->dev, "cannot enable PCI device\n");
960 goto err_dev_unreg;
961 }
962
963 res_len = pci_resource_len(pdev, B3DFG_BAR_REGS);
964 if (res_len != B3DFG_REGS_LENGTH) {
965 dev_err(&pdev->dev, "invalid register resource size\n");
966 r = -EIO;
967 goto err_disable;
968 }
969
970 if (pci_resource_flags(pdev, B3DFG_BAR_REGS)
971 != (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) {
972 dev_err(&pdev->dev, "invalid resource flags\n");
973 r = -EIO;
974 goto err_disable;
975 }
976 r = pci_request_regions(pdev, DRIVER_NAME);
977 if (r) {
978 dev_err(&pdev->dev, "cannot obtain PCI resources\n");
979 goto err_disable;
980 }
981
982 pci_set_master(pdev);
983
984 r = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
985 if (r) {
986 dev_err(&pdev->dev, "no usable DMA configuration\n");
987 goto err_free_res;
988 }
989
990 res_base = pci_resource_start(pdev, B3DFG_BAR_REGS);
991 fgdev->regs = ioremap_nocache(res_base, res_len);
992 if (!fgdev->regs) {
993 dev_err(&pdev->dev, "regs ioremap failed\n");
994 r = -EIO;
995 goto err_free_res;
996 }
997
998 fgdev->pdev = pdev;
999 pci_set_drvdata(pdev, fgdev);
1000 r = b3dfg_init_dev(fgdev);
1001 if (r < 0) {
1002 dev_err(&pdev->dev, "failed to initalize device\n");
1003 goto err_unmap;
1004 }
1005
1006 r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev);
1007 if (r) {
1008 dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq);
1009 goto err_free_bufs;
1010 }
1011
1012 return 0;
1013
1014err_free_bufs:
1015 free_all_frame_buffers(fgdev);
1016err_unmap:
1017 iounmap(fgdev->regs);
1018err_free_res:
1019 pci_release_regions(pdev);
1020err_disable:
1021 pci_disable_device(pdev);
1022err_dev_unreg:
1023 device_destroy(b3dfg_class, devno);
1024err_del_cdev:
1025 cdev_del(&fgdev->chardev);
1026err_release_minor:
1027 b3dfg_devices[minor] = 0;
1028err_free:
1029 kfree(fgdev);
1030 return r;
1031}
1032
1033static void __devexit b3dfg_remove(struct pci_dev *pdev)
1034{
1035 struct b3dfg_dev *fgdev = pci_get_drvdata(pdev);
1036 unsigned int minor = MINOR(fgdev->chardev.dev);
1037
1038 dev_dbg(&pdev->dev, "remove\n");
1039
1040 free_irq(pdev->irq, fgdev);
1041 iounmap(fgdev->regs);
1042 pci_release_regions(pdev);
1043 pci_disable_device(pdev);
1044 device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor));
1045 cdev_del(&fgdev->chardev);
1046 free_all_frame_buffers(fgdev);
1047 kfree(fgdev);
1048 b3dfg_devices[minor] = 0;
1049}
1050
1051static struct pci_driver b3dfg_driver = {
1052 .name = DRIVER_NAME,
1053 .id_table = b3dfg_ids,
1054 .probe = b3dfg_probe,
1055 .remove = __devexit_p(b3dfg_remove),
1056};
1057
1058static int __init b3dfg_module_init(void)
1059{
1060 int r;
1061
1062 if (b3dfg_nbuf < 2) {
1063 printk(KERN_ERR DRIVER_NAME
1064 ": buffer_count is out of range (must be >= 2)");
1065 return -EINVAL;
1066 }
1067
1068 printk(KERN_INFO DRIVER_NAME ": loaded\n");
1069
1070 b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME);
1071 if (IS_ERR(b3dfg_class))
1072 return PTR_ERR(b3dfg_class);
1073
1074 r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME);
1075 if (r)
1076 goto err1;
1077
1078 r = pci_register_driver(&b3dfg_driver);
1079 if (r)
1080 goto err2;
1081
1082 return r;
1083
1084err2:
1085 unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
1086err1:
1087 class_destroy(b3dfg_class);
1088 return r;
1089}
1090
1091static void __exit b3dfg_module_exit(void)
1092{
1093 printk(KERN_INFO DRIVER_NAME ": unloaded\n");
1094 pci_unregister_driver(&b3dfg_driver);
1095 unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
1096 class_destroy(b3dfg_class);
1097}
1098
1099module_init(b3dfg_module_init);
1100module_exit(b3dfg_module_exit);
diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig
index 1d74dabf9511..1e7e0a8dbc8b 100644
--- a/drivers/staging/batman-adv/Kconfig
+++ b/drivers/staging/batman-adv/Kconfig
@@ -4,7 +4,7 @@
4 4
5config BATMAN_ADV 5config BATMAN_ADV
6 tristate "B.A.T.M.A.N. Advanced Meshing Protocol" 6 tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
7 depends on PROC_FS && PACKET 7 depends on PROC_FS && NET
8 default n 8 default n
9 ---help--- 9 ---help---
10 10
@@ -14,10 +14,10 @@ config BATMAN_ADV
14 http://www.open-mesh.org/ for more information and user space 14 http://www.open-mesh.org/ for more information and user space
15 tools. 15 tools.
16 16
17config BATMAN_DEBUG 17config BATMAN_ADV_DEBUG
18 bool "B.A.T.M.A.N. debugging" 18 bool "B.A.T.M.A.N. debugging"
19 depends on BATMAN_ADV != n 19 depends on BATMAN_ADV != n
20 help 20 ---help---
21 21
22 This is an option for use by developers; most people should 22 This is an option for use by developers; most people should
23 say N here. This enables compilation of support for 23 say N here. This enables compilation of support for
diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile
index 02da87134fce..42b4e6370263 100644
--- a/drivers/staging/batman-adv/Makefile
+++ b/drivers/staging/batman-adv/Makefile
@@ -19,4 +19,4 @@
19# 19#
20 20
21obj-m += batman-adv.o 21obj-m += batman-adv.o
22batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o log.o 22batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o
diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README
index 3aaf393ebaa7..7d666ad04359 100644
--- a/drivers/staging/batman-adv/README
+++ b/drivers/staging/batman-adv/README
@@ -1,4 +1,4 @@
1[state: 07-11-2009] 1[state: 06-01-2010]
2 2
3BATMAN-ADV 3BATMAN-ADV
4---------- 4----------
@@ -15,19 +15,6 @@ above B.A.T.M.A.N. Advanced, prominent examples are: IPv4, IPv6, DHCP, IPX.
15This is batman-advanced implemented as Linux kernel driver. It does not depend 15This is batman-advanced implemented as Linux kernel driver. It does not depend
16on any network (other) driver, and can be used on wifi as well as ethernet, 16on any network (other) driver, and can be used on wifi as well as ethernet,
17vpn, etc ... (anything with ethernet-style layer 2). 17vpn, etc ... (anything with ethernet-style layer 2).
18It compiles against and should work with Linux 2.6.20 - 2.6.31. Supporting older
19versions is not planned, but it's probably easy to backport it. If you work on a
20backport, feel free to contact us. :-)
21
22COMPILE
23-------
24To compile against your currently installed kernel, just type:
25
26# make
27
28if you want to compile against some other kernel, use:
29
30# make KERNELPATH=/path/to/kernel
31 18
32USAGE 19USAGE
33----- 20-----
@@ -73,16 +60,9 @@ When configured as server, you can get a topology snapshot of your mesh:
73 60
74# cat /proc/net/batman-adv/vis 61# cat /proc/net/batman-adv/vis
75 62
76This output format is a graphviz formatted text file which can be 63The output is in a generic raw format. Use the batctl tool (See below)
77processed with graphviz-tools like dot. 64to convert this to other formats more suitable for graphing, eg
78The labels are similar/compatible to the ETX metric, 1.0 means perfect 65graphviz dot, or JSON data-interchange format.
79connection (100%), 2.0 means 50%, 3.0 means 33% and so on.
80
81Alternatively, a JSON output format is available. The format can be set
82using by writing either "dot_draw" or "json" into the vis_format file.
83"dot_draw" is selected by default.
84
85echo "json" > /proc/net/batman-adv/vis_format
86 66
87In very mobile scenarios, you might want to adjust the originator 67In very mobile scenarios, you might want to adjust the originator
88interval to a lower value. This will make the mesh more responsive to 68interval to a lower value. This will make the mesh more responsive to
@@ -96,15 +76,59 @@ To deactivate batman, do:
96 76
97# echo "" > /proc/net/batman-adv/interfaces 77# echo "" > /proc/net/batman-adv/interfaces
98 78
79LOGGING/DEBUGGING
80-----------------
81
82All error messages, warnings and information messages are sent to the
83kernel log. Depending on your operating system distribution this can be
84read in one of a number of ways. Try using the commands: dmesg,
85logread, or looking in the files /var/log/kern.log or
86/var/log/syslog. All batman-adv messages are prefixed with
87"batman-adv:" So to see just these messages try
88
89dmesg | grep batman-adv
90
91When investigating problems with your mesh network it is sometimes
92necessary to see more detail debug messages. This must be enabled when
93compiling the batman-adv module. Use "make menuconfig" and enable the
94option "B.A.T.M.A.N. debugging".
95
96The additional debug output is by default disabled. It can be enabled
97either at kernel module load time or during run time. To enable debug
98output at module load time, add the module parameter debug=<value>.
99<value> can take one of four values.
100
1010 - All debug output disabled
1021 - Enable messages related to routing / flooding / broadcasting
1032 - Enable route or hna added / changed / deleted
1043 - Enable all messages
105
106e.g.
107
108modprobe batman-adv debug=2
109
110will load the module and enable debug messages for when routes or HNAs
111change.
112
113The debug output can also be changed at runtime using the file
114/sys/module/batman-adv/parameters/debug. e.g.
115
116echo 2 > /sys/module/batman-adv/parameters/debug
117
118enables debug messages for when routes or HNAs
119
120The debug output is sent to the kernel logs. So try dmesg, logread etc
121to see the debug messages.
122
99BATCTL 123BATCTL
100------ 124------
101 125
102B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts partici- 126B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts
103pating in the virtual switch are completely transparent for all proto- 127participating in the virtual switch are completely transparent for all
104cols above layer 2. Therefore the common diagnosis tools do not work as 128protocols above layer 2. Therefore the common diagnosis tools do not
105expected. To overcome these problems batctl was created. At the moment 129work as expected. To overcome these problems batctl was created. At
106the batctl contains ping, traceroute, tcpdump and interfaces to the 130the moment the batctl contains ping, traceroute, tcpdump and
107kernel module settings. 131interfaces to the kernel module settings.
108 132
109For more information, please see the manpage (man batctl). 133For more information, please see the manpage (man batctl).
110 134
diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO
index ea6dcf94d661..2f15136b18e7 100644
--- a/drivers/staging/batman-adv/TODO
+++ b/drivers/staging/batman-adv/TODO
@@ -17,30 +17,6 @@
17-> transtable_global (read-only) [outputs the global translation table] 17-> transtable_global (read-only) [outputs the global translation table]
18-> transtable_local (read-only) [outputs the local translation table] 18-> transtable_local (read-only) [outputs the local translation table]
19 19
20=> vis "raw" data output
21* the raw format shall replace dot draw / json to offer a neutral that can
22* be converted
23* the format (comma seperated entries):
24-> "mac" -> mac address of an originator (each line begins with it)
25-> "TQ mac value" -> src mac's link quality towards mac address
26-> "HNA mac" -> HNA announced by source mac
27-> "PRIMARY" -> this is a primary interface
28-> "SEC mac" -> secondary mac address of source (requires preceeding
29-> PRIMARY)
30
31=> logging
32* the log level LOG_TYPE_CRIT, LOG_TYPE_WARN & LOG_TYPE_NOTICE will be
33* unified to use printk
34* LOG_TYPE_BATMAN & LOG_TYPE_ROUTES will also use printk but only after the
35* internal debug level has been raised
36* the internal debug level can be modified using a module parameter (debug)
37* or at run time via /sys/module/batman-adv/parameters/debug
38* make use of printk %pM support instead of converting mac addresses
39* manually
40
41=> strip out all backward compatibility support to older kernels
42 (only found in compat.h)
43
44=> fix checkpatch.pl errors 20=> fix checkpatch.pl errors
45 21
46Please send all patches to: 22Please send all patches to:
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c
index 9c6e681f6fb6..7917322a7e2a 100644
--- a/drivers/staging/batman-adv/aggregation.c
+++ b/drivers/staging/batman-adv/aggregation.c
@@ -96,6 +96,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
96 int own_packet) 96 int own_packet)
97{ 97{
98 struct forw_packet *forw_packet_aggr; 98 struct forw_packet *forw_packet_aggr;
99 unsigned long flags;
99 100
100 forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); 101 forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
101 if (!forw_packet_aggr) 102 if (!forw_packet_aggr)
@@ -115,6 +116,7 @@ static void new_aggregated_packet(unsigned char *packet_buff,
115 packet_buff, 116 packet_buff,
116 forw_packet_aggr->packet_len); 117 forw_packet_aggr->packet_len);
117 118
119 forw_packet_aggr->skb = NULL;
118 forw_packet_aggr->own = own_packet; 120 forw_packet_aggr->own = own_packet;
119 forw_packet_aggr->if_incoming = if_incoming; 121 forw_packet_aggr->if_incoming = if_incoming;
120 forw_packet_aggr->num_packets = 0; 122 forw_packet_aggr->num_packets = 0;
@@ -126,9 +128,9 @@ static void new_aggregated_packet(unsigned char *packet_buff,
126 forw_packet_aggr->direct_link_flags |= 1; 128 forw_packet_aggr->direct_link_flags |= 1;
127 129
128 /* add new packet to packet list */ 130 /* add new packet to packet list */
129 spin_lock(&forw_bat_list_lock); 131 spin_lock_irqsave(&forw_bat_list_lock, flags);
130 hlist_add_head(&forw_packet_aggr->list, &forw_bat_list); 132 hlist_add_head(&forw_packet_aggr->list, &forw_bat_list);
131 spin_unlock(&forw_bat_list_lock); 133 spin_unlock_irqrestore(&forw_bat_list_lock, flags);
132 134
133 /* start timer for this packet */ 135 /* start timer for this packet */
134 INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, 136 INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
@@ -168,9 +170,10 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
168 struct batman_packet *batman_packet = 170 struct batman_packet *batman_packet =
169 (struct batman_packet *)packet_buff; 171 (struct batman_packet *)packet_buff;
170 bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; 172 bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0;
173 unsigned long flags;
171 174
172 /* find position for the packet in the forward queue */ 175 /* find position for the packet in the forward queue */
173 spin_lock(&forw_bat_list_lock); 176 spin_lock_irqsave(&forw_bat_list_lock, flags);
174 /* own packets are not to be aggregated */ 177 /* own packets are not to be aggregated */
175 if ((atomic_read(&aggregation_enabled)) && (!own_packet)) { 178 if ((atomic_read(&aggregation_enabled)) && (!own_packet)) {
176 hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list, 179 hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list,
@@ -191,7 +194,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
191 * suitable aggregation packet found */ 194 * suitable aggregation packet found */
192 if (forw_packet_aggr == NULL) { 195 if (forw_packet_aggr == NULL) {
193 /* the following section can run without the lock */ 196 /* the following section can run without the lock */
194 spin_unlock(&forw_bat_list_lock); 197 spin_unlock_irqrestore(&forw_bat_list_lock, flags);
195 new_aggregated_packet(packet_buff, packet_len, 198 new_aggregated_packet(packet_buff, packet_len,
196 send_time, direct_link, 199 send_time, direct_link,
197 if_incoming, own_packet); 200 if_incoming, own_packet);
@@ -199,7 +202,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len,
199 aggregate(forw_packet_aggr, 202 aggregate(forw_packet_aggr,
200 packet_buff, packet_len, 203 packet_buff, packet_len,
201 direct_link); 204 direct_link);
202 spin_unlock(&forw_bat_list_lock); 205 spin_unlock_irqrestore(&forw_bat_list_lock, flags);
203 } 206 }
204} 207}
205 208
diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c
index 3c67f5f42b2b..212eef93afe4 100644
--- a/drivers/staging/batman-adv/bitarray.c
+++ b/drivers/staging/batman-adv/bitarray.c
@@ -21,7 +21,6 @@
21 21
22#include "main.h" 22#include "main.h"
23#include "bitarray.h" 23#include "bitarray.h"
24#include "log.h"
25 24
26/* returns true if the corresponding bit in the given seq_bits indicates true 25/* returns true if the corresponding bit in the given seq_bits indicates true
27 * and curr_seqno is within range of last_seqno */ 26 * and curr_seqno is within range of last_seqno */
@@ -80,8 +79,8 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
80 * from. 79 * from.
81 * 80 *
82 * left is high, right is low: FEDC BA98 7654 3210 81 * left is high, right is low: FEDC BA98 7654 3210
83 * ^^ ^^ 82 * ^^ ^^
84 * vvvv 83 * vvvv
85 * ^^^^ = from, vvvvv =to, we'd have word_num==1 and 84 * ^^^^ = from, vvvvv =to, we'd have word_num==1 and
86 * word_offset==WORD_BIT_SIZE/2 ????? in this example. 85 * word_offset==WORD_BIT_SIZE/2 ????? in this example.
87 * (=24 bits) 86 * (=24 bits)
@@ -133,13 +132,13 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
133 (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) { 132 (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) {
134 133
135 if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE) 134 if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
136 debug_log(LOG_TYPE_BATMAN, 135 bat_dbg(DBG_BATMAN,
137 "We missed a lot of packets (%i) !\n", 136 "We missed a lot of packets (%i) !\n",
138 seq_num_diff-1); 137 seq_num_diff-1);
139 138
140 if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE) 139 if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE)
141 debug_log(LOG_TYPE_BATMAN, 140 bat_dbg(DBG_BATMAN,
142 "Other host probably restarted !\n"); 141 "Other host probably restarted !\n");
143 142
144 for (i = 0; i < NUM_WORDS; i++) 143 for (i = 0; i < NUM_WORDS; i++)
145 seq_bits[i] = 0; 144 seq_bits[i] = 0;
diff --git a/drivers/staging/batman-adv/compat.h b/drivers/staging/batman-adv/compat.h
deleted file mode 100644
index f4e0a4564ba7..000000000000
--- a/drivers/staging/batman-adv/compat.h
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
3 *
4 * Marek Lindner, Simon Wunderlich
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA
19 *
20 *
21 * This file contains macros for maintaining compatibility with older versions
22 * of the Linux kernel.
23 */
24
25#include <linux/version.h> /* LINUX_VERSION_CODE */
26
27#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
28
29#define skb_set_network_header(_skb, _offset) \
30 do { (_skb)->nh.raw = (_skb)->data + (_offset); } while (0)
31
32#define skb_reset_mac_header(_skb) \
33 do { (_skb)->mac.raw = (_skb)->data; } while (0)
34
35#define list_first_entry(ptr, type, member) \
36 list_entry((ptr)->next, type, member)
37
38#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) */
39
40
41#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
42
43#define device_create(_cls, _parent, _devt, _device, _fmt) \
44 class_device_create(_cls, _parent, _devt, _device, _fmt)
45
46#define device_destroy(_cls, _device) \
47 class_device_destroy(_cls, _device)
48
49#else
50
51#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27)
52
53#define device_create(_cls, _parent, _devt, _device, _fmt) \
54 device_create_drvdata(_cls, _parent, _devt, _device, _fmt)
55
56#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) */
57
58#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) */
59
60#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
61
62#define cancel_delayed_work_sync(wq) cancel_rearming_delayed_work(wq)
63
64#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) */
65#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
66#define strict_strtoul(cp, base, res) \
67 ({ \
68 int ret = 0; \
69 char *endp; \
70 *res = simple_strtoul(cp, &endp, base); \
71 if (cp == endp) \
72 ret = -EINVAL; \
73 ret; \
74})
75#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c
index 1e7d1f88674f..e7f44215b5f3 100644
--- a/drivers/staging/batman-adv/device.c
+++ b/drivers/staging/batman-adv/device.c
@@ -19,14 +19,13 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/device.h>
22#include "main.h" 23#include "main.h"
23#include "device.h" 24#include "device.h"
24#include "log.h"
25#include "send.h" 25#include "send.h"
26#include "types.h" 26#include "types.h"
27#include "hash.h" 27#include "hash.h"
28 28#include "hard-interface.h"
29#include "compat.h"
30 29
31static struct class *batman_class; 30static struct class *batman_class;
32 31
@@ -60,7 +59,7 @@ int bat_device_setup(void)
60 /* register our device - kernel assigns a free major number */ 59 /* register our device - kernel assigns a free major number */
61 tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops); 60 tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
62 if (tmp_major < 0) { 61 if (tmp_major < 0) {
63 debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n", 62 printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n",
64 tmp_major); 63 tmp_major);
65 return 0; 64 return 0;
66 } 65 }
@@ -68,7 +67,7 @@ int bat_device_setup(void)
68 batman_class = class_create(THIS_MODULE, "batman-adv"); 67 batman_class = class_create(THIS_MODULE, "batman-adv");
69 68
70 if (IS_ERR(batman_class)) { 69 if (IS_ERR(batman_class)) {
71 debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n"); 70 printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n");
72 return 0; 71 return 0;
73 } 72 }
74 73
@@ -111,7 +110,7 @@ int bat_device_open(struct inode *inode, struct file *file)
111 } 110 }
112 111
113 if (device_client_hash[i] != device_client) { 112 if (device_client_hash[i] != device_client) {
114 debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n"); 113 printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n");
115 kfree(device_client); 114 kfree(device_client);
116 return -EXFULL; 115 return -EXFULL;
117 } 116 }
@@ -119,7 +118,7 @@ int bat_device_open(struct inode *inode, struct file *file)
119 INIT_LIST_HEAD(&device_client->queue_list); 118 INIT_LIST_HEAD(&device_client->queue_list);
120 device_client->queue_len = 0; 119 device_client->queue_len = 0;
121 device_client->index = i; 120 device_client->index = i;
122 device_client->lock = __SPIN_LOCK_UNLOCKED(device_client->lock); 121 spin_lock_init(&device_client->lock);
123 init_waitqueue_head(&device_client->queue_wait); 122 init_waitqueue_head(&device_client->queue_wait);
124 123
125 file->private_data = device_client; 124 file->private_data = device_client;
@@ -134,8 +133,9 @@ int bat_device_release(struct inode *inode, struct file *file)
134 (struct device_client *)file->private_data; 133 (struct device_client *)file->private_data;
135 struct device_packet *device_packet; 134 struct device_packet *device_packet;
136 struct list_head *list_pos, *list_pos_tmp; 135 struct list_head *list_pos, *list_pos_tmp;
136 unsigned long flags;
137 137
138 spin_lock(&device_client->lock); 138 spin_lock_irqsave(&device_client->lock, flags);
139 139
140 /* for all packets in the queue ... */ 140 /* for all packets in the queue ... */
141 list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) { 141 list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) {
@@ -147,7 +147,7 @@ int bat_device_release(struct inode *inode, struct file *file)
147 } 147 }
148 148
149 device_client_hash[device_client->index] = NULL; 149 device_client_hash[device_client->index] = NULL;
150 spin_unlock(&device_client->lock); 150 spin_unlock_irqrestore(&device_client->lock, flags);
151 151
152 kfree(device_client); 152 kfree(device_client);
153 dec_module_count(); 153 dec_module_count();
@@ -162,6 +162,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
162 (struct device_client *)file->private_data; 162 (struct device_client *)file->private_data;
163 struct device_packet *device_packet; 163 struct device_packet *device_packet;
164 int error; 164 int error;
165 unsigned long flags;
165 166
166 if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0)) 167 if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0))
167 return -EAGAIN; 168 return -EAGAIN;
@@ -178,14 +179,14 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
178 if (error) 179 if (error)
179 return error; 180 return error;
180 181
181 spin_lock(&device_client->lock); 182 spin_lock_irqsave(&device_client->lock, flags);
182 183
183 device_packet = list_first_entry(&device_client->queue_list, 184 device_packet = list_first_entry(&device_client->queue_list,
184 struct device_packet, list); 185 struct device_packet, list);
185 list_del(&device_packet->list); 186 list_del(&device_packet->list);
186 device_client->queue_len--; 187 device_client->queue_len--;
187 188
188 spin_unlock(&device_client->lock); 189 spin_unlock_irqrestore(&device_client->lock, flags);
189 190
190 error = __copy_to_user(buf, &device_packet->icmp_packet, 191 error = __copy_to_user(buf, &device_packet->icmp_packet,
191 sizeof(struct icmp_packet)); 192 sizeof(struct icmp_packet));
@@ -206,9 +207,11 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
206 struct icmp_packet icmp_packet; 207 struct icmp_packet icmp_packet;
207 struct orig_node *orig_node; 208 struct orig_node *orig_node;
208 struct batman_if *batman_if; 209 struct batman_if *batman_if;
210 uint8_t dstaddr[ETH_ALEN];
211 unsigned long flags;
209 212
210 if (len < sizeof(struct icmp_packet)) { 213 if (len < sizeof(struct icmp_packet)) {
211 debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n"); 214 bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n");
212 return -EINVAL; 215 return -EINVAL;
213 } 216 }
214 217
@@ -219,12 +222,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
219 return -EFAULT; 222 return -EFAULT;
220 223
221 if (icmp_packet.packet_type != BAT_ICMP) { 224 if (icmp_packet.packet_type != BAT_ICMP) {
222 debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); 225 bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
223 return -EINVAL; 226 return -EINVAL;
224 } 227 }
225 228
226 if (icmp_packet.msg_type != ECHO_REQUEST) { 229 if (icmp_packet.msg_type != ECHO_REQUEST) {
227 debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); 230 bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
228 return -EINVAL; 231 return -EINVAL;
229 } 232 }
230 233
@@ -240,7 +243,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
240 if (atomic_read(&module_state) != MODULE_ACTIVE) 243 if (atomic_read(&module_state) != MODULE_ACTIVE)
241 goto dst_unreach; 244 goto dst_unreach;
242 245
243 spin_lock(&orig_hash_lock); 246 spin_lock_irqsave(&orig_hash_lock, flags);
244 orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst)); 247 orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst));
245 248
246 if (!orig_node) 249 if (!orig_node)
@@ -250,9 +253,15 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
250 goto unlock; 253 goto unlock;
251 254
252 batman_if = orig_node->batman_if; 255 batman_if = orig_node->batman_if;
256 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
257
258 spin_unlock_irqrestore(&orig_hash_lock, flags);
253 259
254 if (!batman_if) 260 if (!batman_if)
255 goto unlock; 261 goto dst_unreach;
262
263 if (batman_if->if_active != IF_ACTIVE)
264 goto dst_unreach;
256 265
257 memcpy(icmp_packet.orig, 266 memcpy(icmp_packet.orig,
258 batman_if->net_dev->dev_addr, 267 batman_if->net_dev->dev_addr,
@@ -260,13 +269,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff,
260 269
261 send_raw_packet((unsigned char *)&icmp_packet, 270 send_raw_packet((unsigned char *)&icmp_packet,
262 sizeof(struct icmp_packet), 271 sizeof(struct icmp_packet),
263 batman_if, orig_node->router->addr); 272 batman_if, dstaddr);
264 273
265 spin_unlock(&orig_hash_lock);
266 goto out; 274 goto out;
267 275
268unlock: 276unlock:
269 spin_unlock(&orig_hash_lock); 277 spin_unlock_irqrestore(&orig_hash_lock, flags);
270dst_unreach: 278dst_unreach:
271 icmp_packet.msg_type = DESTINATION_UNREACHABLE; 279 icmp_packet.msg_type = DESTINATION_UNREACHABLE;
272 bat_device_add_packet(device_client, &icmp_packet); 280 bat_device_add_packet(device_client, &icmp_packet);
@@ -291,6 +299,7 @@ void bat_device_add_packet(struct device_client *device_client,
291 struct icmp_packet *icmp_packet) 299 struct icmp_packet *icmp_packet)
292{ 300{
293 struct device_packet *device_packet; 301 struct device_packet *device_packet;
302 unsigned long flags;
294 303
295 device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL); 304 device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL);
296 305
@@ -301,12 +310,12 @@ void bat_device_add_packet(struct device_client *device_client,
301 memcpy(&device_packet->icmp_packet, icmp_packet, 310 memcpy(&device_packet->icmp_packet, icmp_packet,
302 sizeof(struct icmp_packet)); 311 sizeof(struct icmp_packet));
303 312
304 spin_lock(&device_client->lock); 313 spin_lock_irqsave(&device_client->lock, flags);
305 314
306 /* while waiting for the lock the device_client could have been 315 /* while waiting for the lock the device_client could have been
307 * deleted */ 316 * deleted */
308 if (!device_client_hash[icmp_packet->uid]) { 317 if (!device_client_hash[icmp_packet->uid]) {
309 spin_unlock(&device_client->lock); 318 spin_unlock_irqrestore(&device_client->lock, flags);
310 kfree(device_packet); 319 kfree(device_packet);
311 return; 320 return;
312 } 321 }
@@ -323,7 +332,7 @@ void bat_device_add_packet(struct device_client *device_client,
323 device_client->queue_len--; 332 device_client->queue_len--;
324 } 333 }
325 334
326 spin_unlock(&device_client->lock); 335 spin_unlock_irqrestore(&device_client->lock, flags);
327 336
328 wake_up(&device_client->queue_wait); 337 wake_up(&device_client->queue_wait);
329} 338}
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index 5ea35da5ee7a..befd48839519 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -21,13 +21,11 @@
21 21
22#include "main.h" 22#include "main.h"
23#include "hard-interface.h" 23#include "hard-interface.h"
24#include "log.h"
25#include "soft-interface.h" 24#include "soft-interface.h"
26#include "send.h" 25#include "send.h"
27#include "translation-table.h" 26#include "translation-table.h"
28#include "routing.h" 27#include "routing.h"
29#include "hash.h" 28#include "hash.h"
30#include "compat.h"
31 29
32#define MIN(x, y) ((x) < (y) ? (x) : (y)) 30#define MIN(x, y) ((x) < (y) ? (x) : (y))
33 31
@@ -75,7 +73,6 @@ int hardif_min_mtu(void)
75static void check_known_mac_addr(uint8_t *addr) 73static void check_known_mac_addr(uint8_t *addr)
76{ 74{
77 struct batman_if *batman_if; 75 struct batman_if *batman_if;
78 char mac_string[ETH_STR_LEN];
79 76
80 rcu_read_lock(); 77 rcu_read_lock();
81 list_for_each_entry_rcu(batman_if, &if_list, list) { 78 list_for_each_entry_rcu(batman_if, &if_list, list) {
@@ -86,10 +83,9 @@ static void check_known_mac_addr(uint8_t *addr)
86 if (!compare_orig(batman_if->net_dev->dev_addr, addr)) 83 if (!compare_orig(batman_if->net_dev->dev_addr, addr))
87 continue; 84 continue;
88 85
89 addr_to_string(mac_string, addr); 86 printk(KERN_WARNING "batman-adv:The newly added mac address (%pM) already exists on: %s\n",
90 debug_log(LOG_TYPE_WARN, "The newly added mac address (%s) already exists on: %s\n", 87 addr, batman_if->dev);
91 mac_string, batman_if->dev); 88 printk(KERN_WARNING "batman-adv:It is strongly recommended to keep mac addresses unique to avoid problems!\n");
92 debug_log(LOG_TYPE_WARN, "It is strongly recommended to keep mac addresses unique to avoid problems!\n");
93 } 89 }
94 rcu_read_unlock(); 90 rcu_read_unlock();
95} 91}
@@ -154,9 +150,6 @@ void hardif_deactivate_interface(struct batman_if *batman_if)
154 if (batman_if->if_active != IF_ACTIVE) 150 if (batman_if->if_active != IF_ACTIVE)
155 return; 151 return;
156 152
157 if (batman_if->raw_sock)
158 sock_release(batman_if->raw_sock);
159
160 /** 153 /**
161 * batman_if->net_dev has been acquired by dev_get_by_name() in 154 * batman_if->net_dev has been acquired by dev_get_by_name() in
162 * proc_interfaces_write() and has to be unreferenced. 155 * proc_interfaces_write() and has to be unreferenced.
@@ -165,22 +158,16 @@ void hardif_deactivate_interface(struct batman_if *batman_if)
165 if (batman_if->net_dev) 158 if (batman_if->net_dev)
166 dev_put(batman_if->net_dev); 159 dev_put(batman_if->net_dev);
167 160
168 batman_if->raw_sock = NULL;
169 batman_if->net_dev = NULL;
170
171 batman_if->if_active = IF_INACTIVE; 161 batman_if->if_active = IF_INACTIVE;
172 active_ifs--; 162 active_ifs--;
173 163
174 debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n", 164 printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
175 batman_if->dev); 165 batman_if->dev);
176} 166}
177 167
178/* (re)activate given interface. */ 168/* (re)activate given interface. */
179static void hardif_activate_interface(struct batman_if *batman_if) 169static void hardif_activate_interface(struct batman_if *batman_if)
180{ 170{
181 struct sockaddr_ll bind_addr;
182 int retval;
183
184 if (batman_if->if_active != IF_INACTIVE) 171 if (batman_if->if_active != IF_INACTIVE)
185 return; 172 return;
186 173
@@ -192,35 +179,8 @@ static void hardif_activate_interface(struct batman_if *batman_if)
192 if (!batman_if->net_dev) 179 if (!batman_if->net_dev)
193 goto dev_err; 180 goto dev_err;
194 181
195 retval = sock_create_kern(PF_PACKET, SOCK_RAW,
196 __constant_htons(ETH_P_BATMAN),
197 &batman_if->raw_sock);
198
199 if (retval < 0) {
200 debug_log(LOG_TYPE_WARN, "Can't create raw socket: %i\n",
201 retval);
202 goto sock_err;
203 }
204
205 bind_addr.sll_family = AF_PACKET;
206 bind_addr.sll_ifindex = batman_if->net_dev->ifindex;
207 bind_addr.sll_protocol = 0; /* is set by the kernel */
208
209 retval = kernel_bind(batman_if->raw_sock,
210 (struct sockaddr *)&bind_addr, sizeof(bind_addr));
211
212 if (retval < 0) {
213 debug_log(LOG_TYPE_WARN, "Can't create bind raw socket: %i\n",
214 retval);
215 goto bind_err;
216 }
217
218 check_known_mac_addr(batman_if->net_dev->dev_addr); 182 check_known_mac_addr(batman_if->net_dev->dev_addr);
219 183
220 batman_if->raw_sock->sk->sk_user_data =
221 batman_if->raw_sock->sk->sk_data_ready;
222 batman_if->raw_sock->sk->sk_data_ready = batman_data_ready;
223
224 addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); 184 addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr);
225 185
226 memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, 186 memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig,
@@ -235,17 +195,12 @@ static void hardif_activate_interface(struct batman_if *batman_if)
235 if (batman_if->if_num == 0) 195 if (batman_if->if_num == 0)
236 set_main_if_addr(batman_if->net_dev->dev_addr); 196 set_main_if_addr(batman_if->net_dev->dev_addr);
237 197
238 debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n", 198 printk(KERN_INFO "batman-adv:Interface activated: %s\n",
239 batman_if->dev); 199 batman_if->dev);
240 200
241 return; 201 return;
242 202
243bind_err:
244 sock_release(batman_if->raw_sock);
245sock_err:
246 dev_put(batman_if->net_dev);
247dev_err: 203dev_err:
248 batman_if->raw_sock = NULL;
249 batman_if->net_dev = NULL; 204 batman_if->net_dev = NULL;
250} 205}
251 206
@@ -290,7 +245,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num)
290 data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS, 245 data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
291 GFP_ATOMIC); 246 GFP_ATOMIC);
292 if (!data_ptr) { 247 if (!data_ptr) {
293 debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n"); 248 printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
294 return -1; 249 return -1;
295 } 250 }
296 251
@@ -301,7 +256,7 @@ static int resize_orig(struct orig_node *orig_node, int if_num)
301 256
302 data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC); 257 data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
303 if (!data_ptr) { 258 if (!data_ptr) {
304 debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n"); 259 printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n");
305 return -1; 260 return -1;
306 } 261 }
307 262
@@ -319,16 +274,16 @@ int hardif_add_interface(char *dev, int if_num)
319 struct batman_if *batman_if; 274 struct batman_if *batman_if;
320 struct batman_packet *batman_packet; 275 struct batman_packet *batman_packet;
321 struct orig_node *orig_node; 276 struct orig_node *orig_node;
322 struct hash_it_t *hashit = NULL; 277 unsigned long flags;
278 HASHIT(hashit);
323 279
324 batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL); 280 batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
325 281
326 if (!batman_if) { 282 if (!batman_if) {
327 debug_log(LOG_TYPE_WARN, "Can't add interface (%s): out of memory\n", dev); 283 printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev);
328 return -1; 284 return -1;
329 } 285 }
330 286
331 batman_if->raw_sock = NULL;
332 batman_if->net_dev = NULL; 287 batman_if->net_dev = NULL;
333 288
334 if ((if_num == 0) && (num_hna > 0)) 289 if ((if_num == 0) && (num_hna > 0))
@@ -339,7 +294,7 @@ int hardif_add_interface(char *dev, int if_num)
339 batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL); 294 batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
340 295
341 if (!batman_if->packet_buff) { 296 if (!batman_if->packet_buff) {
342 debug_log(LOG_TYPE_WARN, "Can't add interface packet (%s): out of memory\n", dev); 297 printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev);
343 goto out; 298 goto out;
344 } 299 }
345 300
@@ -348,7 +303,7 @@ int hardif_add_interface(char *dev, int if_num)
348 batman_if->if_active = IF_INACTIVE; 303 batman_if->if_active = IF_INACTIVE;
349 INIT_RCU_HEAD(&batman_if->rcu); 304 INIT_RCU_HEAD(&batman_if->rcu);
350 305
351 debug_log(LOG_TYPE_NOTICE, "Adding interface: %s\n", dev); 306 printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev);
352 avail_ifs++; 307 avail_ifs++;
353 308
354 INIT_LIST_HEAD(&batman_if->list); 309 INIT_LIST_HEAD(&batman_if->list);
@@ -376,20 +331,20 @@ int hardif_add_interface(char *dev, int if_num)
376 331
377 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 332 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
378 * if_num */ 333 * if_num */
379 spin_lock(&orig_hash_lock); 334 spin_lock_irqsave(&orig_hash_lock, flags);
380 335
381 while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { 336 while (hash_iterate(orig_hash, &hashit)) {
382 orig_node = hashit->bucket->data; 337 orig_node = hashit.bucket->data;
383 if (resize_orig(orig_node, if_num) == -1) { 338 if (resize_orig(orig_node, if_num) == -1) {
384 spin_unlock(&orig_hash_lock); 339 spin_unlock_irqrestore(&orig_hash_lock, flags);
385 goto out; 340 goto out;
386 } 341 }
387 } 342 }
388 343
389 spin_unlock(&orig_hash_lock); 344 spin_unlock_irqrestore(&orig_hash_lock, flags);
390 345
391 if (!hardif_is_interface_up(batman_if->dev)) 346 if (!hardif_is_interface_up(batman_if->dev))
392 debug_log(LOG_TYPE_WARN, "Not using interface %s (retrying later): interface not active\n", batman_if->dev); 347 printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev);
393 else 348 else
394 hardif_activate_interface(batman_if); 349 hardif_activate_interface(batman_if);
395 350
@@ -400,8 +355,7 @@ int hardif_add_interface(char *dev, int if_num)
400 return 1; 355 return 1;
401 356
402out: 357out:
403 if (batman_if->packet_buff) 358 kfree(batman_if->packet_buff);
404 kfree(batman_if->packet_buff);
405 kfree(batman_if); 359 kfree(batman_if);
406 kfree(dev); 360 kfree(dev);
407 return -1; 361 return -1;
@@ -413,7 +367,7 @@ char hardif_get_active_if_num(void)
413} 367}
414 368
415static int hard_if_event(struct notifier_block *this, 369static int hard_if_event(struct notifier_block *this,
416 unsigned long event, void *ptr) 370 unsigned long event, void *ptr)
417{ 371{
418 struct net_device *dev = (struct net_device *)ptr; 372 struct net_device *dev = (struct net_device *)ptr;
419 struct batman_if *batman_if = get_batman_if_by_name(dev->name); 373 struct batman_if *batman_if = get_batman_if_by_name(dev->name);
@@ -436,7 +390,6 @@ static int hard_if_event(struct notifier_block *this,
436 break; 390 break;
437 /* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */ 391 /* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */
438 default: 392 default:
439 /* debug_log(LOG_TYPE_CRIT, "hard_if_event: %s %i\n", dev->name, event); */
440 break; 393 break;
441 }; 394 };
442 395
@@ -446,6 +399,122 @@ out:
446 return NOTIFY_DONE; 399 return NOTIFY_DONE;
447} 400}
448 401
402/* find batman interface by netdev. assumes rcu_read_lock on */
403static struct batman_if *find_batman_if(struct net_device *dev)
404{
405 struct batman_if *batman_if;
406
407 rcu_read_lock();
408 list_for_each_entry_rcu(batman_if, &if_list, list) {
409 if (batman_if->net_dev == dev) {
410 rcu_read_unlock();
411 return batman_if;
412 }
413 }
414 rcu_read_unlock();
415 return NULL;
416}
417
418
419/* receive a packet with the batman ethertype coming on a hard
420 * interface */
421int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
422 struct packet_type *ptype, struct net_device *orig_dev)
423{
424 struct batman_packet *batman_packet;
425 struct batman_if *batman_if;
426 struct net_device_stats *stats;
427 int ret;
428
429 skb = skb_share_check(skb, GFP_ATOMIC);
430
431 /* skb was released by skb_share_check() */
432 if (!skb)
433 goto err_out;
434
435 if (atomic_read(&module_state) != MODULE_ACTIVE)
436 goto err_free;
437
438 /* packet should hold at least type and version */
439 if (unlikely(skb_headlen(skb) < 2))
440 goto err_free;
441
442 /* expect a valid ethernet header here. */
443 if (unlikely(skb->mac_len != sizeof(struct ethhdr)
444 || !skb_mac_header(skb)))
445 goto err_free;
446
447 batman_if = find_batman_if(skb->dev);
448 if (!batman_if)
449 goto err_free;
450
451 /* discard frames on not active interfaces */
452 if (batman_if->if_active != IF_ACTIVE)
453 goto err_free;
454
455 stats = (struct net_device_stats *)dev_get_stats(skb->dev);
456 if (stats) {
457 stats->rx_packets++;
458 stats->rx_bytes += skb->len;
459 }
460
461 batman_packet = (struct batman_packet *)skb->data;
462
463 if (batman_packet->version != COMPAT_VERSION) {
464 bat_dbg(DBG_BATMAN,
465 "Drop packet: incompatible batman version (%i)\n",
466 batman_packet->version);
467 goto err_free;
468 }
469
470 /* all receive handlers return whether they received or reused
471 * the supplied skb. if not, we have to free the skb. */
472
473 switch (batman_packet->packet_type) {
474 /* batman originator packet */
475 case BAT_PACKET:
476 ret = recv_bat_packet(skb, batman_if);
477 break;
478
479 /* batman icmp packet */
480 case BAT_ICMP:
481 ret = recv_icmp_packet(skb);
482 break;
483
484 /* unicast packet */
485 case BAT_UNICAST:
486 ret = recv_unicast_packet(skb);
487 break;
488
489 /* broadcast packet */
490 case BAT_BCAST:
491 ret = recv_bcast_packet(skb);
492 break;
493
494 /* vis packet */
495 case BAT_VIS:
496 ret = recv_vis_packet(skb);
497 break;
498 default:
499 ret = NET_RX_DROP;
500 }
501
502 if (ret == NET_RX_DROP)
503 kfree_skb(skb);
504
505 /* return NET_RX_SUCCESS in any case as we
506 * most probably dropped the packet for
507 * routing-logical reasons. */
508
509 return NET_RX_SUCCESS;
510
511err_free:
512 kfree_skb(skb);
513err_out:
514 return NET_RX_DROP;
515}
516
517
449struct notifier_block hard_if_notifier = { 518struct notifier_block hard_if_notifier = {
450 .notifier_call = hard_if_event, 519 .notifier_call = hard_if_event,
451}; 520};
diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h
index 742358c00c0e..97c6ecb9e087 100644
--- a/drivers/staging/batman-adv/hard-interface.h
+++ b/drivers/staging/batman-adv/hard-interface.h
@@ -32,5 +32,9 @@ void hardif_deactivate_interface(struct batman_if *batman_if);
32char hardif_get_active_if_num(void); 32char hardif_get_active_if_num(void);
33void hardif_check_interfaces_status(void); 33void hardif_check_interfaces_status(void);
34void hardif_check_interfaces_status_wq(struct work_struct *work); 34void hardif_check_interfaces_status_wq(struct work_struct *work);
35int batman_skb_recv(struct sk_buff *skb,
36 struct net_device *dev,
37 struct packet_type *ptype,
38 struct net_device *orig_dev);
35int hardif_min_mtu(void); 39int hardif_min_mtu(void);
36void update_min_mtu(void); 40void update_min_mtu(void);
diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c
index 61cb4a20ebca..5a2018de3ff2 100644
--- a/drivers/staging/batman-adv/hash.c
+++ b/drivers/staging/batman-adv/hash.c
@@ -64,24 +64,18 @@ void hash_destroy(struct hashtable_t *hash)
64 kfree(hash); 64 kfree(hash);
65} 65}
66 66
67/* iterate though the hash. first element is selected with iter_in NULL. use 67/* iterate though the hash. First element is selected if an iterator
68 * the returned iterator to access the elements until hash_it_t returns NULL. */ 68 * initialized with HASHIT() is supplied as iter. Use the returned
69 * (or supplied) iterator to access the elements until hash_iterate returns
70 * NULL. */
71
69struct hash_it_t *hash_iterate(struct hashtable_t *hash, 72struct hash_it_t *hash_iterate(struct hashtable_t *hash,
70 struct hash_it_t *iter_in) 73 struct hash_it_t *iter)
71{ 74{
72 struct hash_it_t *iter;
73
74 if (!hash) 75 if (!hash)
75 return NULL; 76 return NULL;
76 77 if (!iter)
77 if (iter_in == NULL) { 78 return NULL;
78 iter = kmalloc(sizeof(struct hash_it_t), GFP_ATOMIC);
79 iter->index = -1;
80 iter->bucket = NULL;
81 iter->prev_bucket = NULL;
82 } else {
83 iter = iter_in;
84 }
85 79
86 /* sanity checks first (if our bucket got deleted in the last 80 /* sanity checks first (if our bucket got deleted in the last
87 * iteration): */ 81 * iteration): */
@@ -139,7 +133,6 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash,
139 } 133 }
140 134
141 /* nothing to iterate over anymore */ 135 /* nothing to iterate over anymore */
142 kfree(iter);
143 return NULL; 136 return NULL;
144} 137}
145 138
diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h
index bb60f082be6a..a70d6d6e1c7a 100644
--- a/drivers/staging/batman-adv/hash.h
+++ b/drivers/staging/batman-adv/hash.h
@@ -21,6 +21,11 @@
21 21
22#ifndef _BATMAN_HASH_H 22#ifndef _BATMAN_HASH_H
23#define _BATMAN_HASH_H 23#define _BATMAN_HASH_H
24#define HASHIT(name) struct hash_it_t name = { \
25 .index = -1, .bucket = NULL, \
26 .prev_bucket = NULL, \
27 .first_bucket = NULL }
28
24 29
25typedef int (*hashdata_compare_cb)(void *, void *); 30typedef int (*hashdata_compare_cb)(void *, void *);
26typedef int (*hashdata_choose_cb)(void *, int); 31typedef int (*hashdata_choose_cb)(void *, int);
diff --git a/drivers/staging/batman-adv/log.c b/drivers/staging/batman-adv/log.c
deleted file mode 100644
index f37c7f01a9f5..000000000000
--- a/drivers/staging/batman-adv/log.c
+++ /dev/null
@@ -1,179 +0,0 @@
1/*
2 * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors:
3 *
4 * Marek Lindner, Simon Wunderlich
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA
19 *
20 */
21
22#include "main.h"
23#include "log.h"
24
25#define LOG_BUF_MASK (log_buf_len-1)
26#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
27
28static char log_buf[LOG_BUF_LEN];
29static int log_buf_len = LOG_BUF_LEN;
30static unsigned long log_start;
31static unsigned long log_end;
32uint8_t log_level;
33
34static DEFINE_SPINLOCK(logbuf_lock);
35
36const struct file_operations proc_log_operations = {
37 .open = log_open,
38 .release = log_release,
39 .read = log_read,
40 .write = log_write,
41 .poll = log_poll,
42};
43
44static DECLARE_WAIT_QUEUE_HEAD(log_wait);
45
46static void emit_log_char(char c)
47{
48 LOG_BUF(log_end) = c;
49 log_end++;
50
51 if (log_end - log_start > log_buf_len)
52 log_start = log_end - log_buf_len;
53}
54
55static int fdebug_log(char *fmt, ...)
56{
57 int printed_len;
58 char *p;
59 va_list args;
60 static char debug_log_buf[256];
61 unsigned long flags;
62
63 spin_lock_irqsave(&logbuf_lock, flags);
64 va_start(args, fmt);
65 printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt,
66 args);
67 va_end(args);
68
69 for (p = debug_log_buf; *p != 0; p++)
70 emit_log_char(*p);
71
72 spin_unlock_irqrestore(&logbuf_lock, flags);
73
74 wake_up(&log_wait);
75
76 return 0;
77}
78
79int debug_log(int type, char *fmt, ...)
80{
81 va_list args;
82 int retval = 0;
83 char tmp_log_buf[256];
84
85 /* only critical information get into the official kernel log */
86 if (type == LOG_TYPE_CRIT) {
87 va_start(args, fmt);
88 vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
89 printk(KERN_ERR "batman-adv: %s", tmp_log_buf);
90 va_end(args);
91 }
92
93 if ((type == LOG_TYPE_CRIT) || (log_level & type)) {
94 va_start(args, fmt);
95 vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
96 fdebug_log("[%10u] %s", (jiffies / HZ), tmp_log_buf);
97 va_end(args);
98 }
99
100 return retval;
101}
102
103int log_open(struct inode *inode, struct file *file)
104{
105 inc_module_count();
106 return 0;
107}
108
109int log_release(struct inode *inode, struct file *file)
110{
111 dec_module_count();
112 return 0;
113}
114
115ssize_t log_read(struct file *file, char __user *buf, size_t count,
116 loff_t *ppos)
117{
118 int error, i = 0;
119 char c;
120 unsigned long flags;
121
122 if ((file->f_flags & O_NONBLOCK) && !(log_end - log_start))
123 return -EAGAIN;
124
125 if ((!buf) || (count < 0))
126 return -EINVAL;
127
128 if (count == 0)
129 return 0;
130
131 if (!access_ok(VERIFY_WRITE, buf, count))
132 return -EFAULT;
133
134 error = wait_event_interruptible(log_wait, (log_start - log_end));
135
136 if (error)
137 return error;
138
139 spin_lock_irqsave(&logbuf_lock, flags);
140
141 while ((!error) && (log_start != log_end) && (i < count)) {
142 c = LOG_BUF(log_start);
143
144 log_start++;
145
146 spin_unlock_irqrestore(&logbuf_lock, flags);
147
148 error = __put_user(c, buf);
149
150 spin_lock_irqsave(&logbuf_lock, flags);
151
152 buf++;
153 i++;
154
155 }
156
157 spin_unlock_irqrestore(&logbuf_lock, flags);
158
159 if (!error)
160 return i;
161
162 return error;
163}
164
165ssize_t log_write(struct file *file, const char __user *buf, size_t count,
166 loff_t *ppos)
167{
168 return count;
169}
170
171unsigned int log_poll(struct file *file, poll_table *wait)
172{
173 poll_wait(file, &log_wait, wait);
174
175 if (log_end - log_start)
176 return POLLIN | POLLRDNORM;
177
178 return 0;
179}
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c
index bb89bfc5dda6..2e0b482e710a 100644
--- a/drivers/staging/batman-adv/main.c
+++ b/drivers/staging/batman-adv/main.c
@@ -21,9 +21,9 @@
21 21
22#include "main.h" 22#include "main.h"
23#include "proc.h" 23#include "proc.h"
24#include "log.h"
25#include "routing.h" 24#include "routing.h"
26#include "send.h" 25#include "send.h"
26#include "originator.h"
27#include "soft-interface.h" 27#include "soft-interface.h"
28#include "device.h" 28#include "device.h"
29#include "translation-table.h" 29#include "translation-table.h"
@@ -31,7 +31,6 @@
31#include "types.h" 31#include "types.h"
32#include "vis.h" 32#include "vis.h"
33#include "hash.h" 33#include "hash.h"
34#include "compat.h"
35 34
36struct list_head if_list; 35struct list_head if_list;
37struct hlist_head forw_bat_list; 36struct hlist_head forw_bat_list;
@@ -44,19 +43,34 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
44 43
45atomic_t originator_interval; 44atomic_t originator_interval;
46atomic_t vis_interval; 45atomic_t vis_interval;
46atomic_t vis_mode;
47atomic_t aggregation_enabled; 47atomic_t aggregation_enabled;
48int16_t num_hna; 48int16_t num_hna;
49int16_t num_ifs; 49int16_t num_ifs;
50 50
51struct net_device *soft_device; 51struct net_device *soft_device;
52 52
53static struct task_struct *kthread_task;
54
55unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 53unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
56atomic_t module_state; 54atomic_t module_state;
57 55
56static struct packet_type batman_adv_packet_type __read_mostly = {
57 .type = __constant_htons(ETH_P_BATMAN),
58 .func = batman_skb_recv,
59};
60
58struct workqueue_struct *bat_event_workqueue; 61struct workqueue_struct *bat_event_workqueue;
59 62
63#ifdef CONFIG_BATMAN_ADV_DEBUG
64int debug;
65
66module_param(debug, int, 0644);
67
68int bat_debug_type(int type)
69{
70 return debug & type;
71}
72#endif
73
60int init_module(void) 74int init_module(void)
61{ 75{
62 int retval; 76 int retval;
@@ -70,6 +84,7 @@ int init_module(void)
70 atomic_set(&originator_interval, 1000); 84 atomic_set(&originator_interval, 1000);
71 atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only 85 atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
72 * for debugging now. */ 86 * for debugging now. */
87 atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
73 atomic_set(&aggregation_enabled, 1); 88 atomic_set(&aggregation_enabled, 1);
74 89
75 /* the name should not be longer than 10 chars - see 90 /* the name should not be longer than 10 chars - see
@@ -90,21 +105,22 @@ int init_module(void)
90 interface_setup); 105 interface_setup);
91 106
92 if (!soft_device) { 107 if (!soft_device) {
93 debug_log(LOG_TYPE_CRIT, "Unable to allocate the batman interface\n"); 108 printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n");
94 goto end; 109 goto end;
95 } 110 }
96 111
97 retval = register_netdev(soft_device); 112 retval = register_netdev(soft_device);
98 113
99 if (retval < 0) { 114 if (retval < 0) {
100 debug_log(LOG_TYPE_CRIT, "Unable to register the batman interface: %i\n", retval); 115 printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval);
101 goto free_soft_device; 116 goto free_soft_device;
102 } 117 }
103 118
104 register_netdevice_notifier(&hard_if_notifier); 119 register_netdevice_notifier(&hard_if_notifier);
120 dev_add_pack(&batman_adv_packet_type);
105 121
106 debug_log(LOG_TYPE_CRIT, "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n", 122 printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
107 SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); 123 SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
108 124
109 return 0; 125 return 0;
110 126
@@ -124,6 +140,8 @@ void cleanup_module(void)
124 soft_device = NULL; 140 soft_device = NULL;
125 } 141 }
126 142
143 dev_remove_pack(&batman_adv_packet_type);
144
127 unregister_netdevice_notifier(&hard_if_notifier); 145 unregister_netdevice_notifier(&hard_if_notifier);
128 cleanup_procfs(); 146 cleanup_procfs();
129 147
@@ -151,22 +169,12 @@ void activate_module(void)
151 if (vis_init() < 1) 169 if (vis_init() < 1)
152 goto err; 170 goto err;
153 171
154 /* (re)start kernel thread for packet processing */
155 if (!kthread_task) {
156 kthread_task = kthread_run(packet_recv_thread, NULL, "batman-adv");
157
158 if (IS_ERR(kthread_task)) {
159 debug_log(LOG_TYPE_CRIT, "Unable to start packet receive thread\n");
160 kthread_task = NULL;
161 }
162 }
163
164 update_min_mtu(); 172 update_min_mtu();
165 atomic_set(&module_state, MODULE_ACTIVE); 173 atomic_set(&module_state, MODULE_ACTIVE);
166 goto end; 174 goto end;
167 175
168err: 176err:
169 debug_log(LOG_TYPE_CRIT, "Unable to allocate memory for mesh information structures: out of mem ?\n"); 177 printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n");
170 shutdown_module(); 178 shutdown_module();
171end: 179end:
172 return; 180 return;
@@ -182,14 +190,7 @@ void shutdown_module(void)
182 190
183 vis_quit(); 191 vis_quit();
184 192
185 /* deactivate kernel thread for packet processing (if running) */ 193 /* TODO: unregister BATMAN pack */
186 if (kthread_task) {
187 atomic_set(&exit_cond, 1);
188 wake_up_interruptible(&thread_wait);
189 kthread_stop(kthread_task);
190
191 kthread_task = NULL;
192 }
193 194
194 originator_free(); 195 originator_free();
195 196
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h
index facb6b79ee52..deb41f5beda6 100644
--- a/drivers/staging/batman-adv/main.h
+++ b/drivers/staging/batman-adv/main.h
@@ -33,16 +33,16 @@
33 33
34#define TQ_MAX_VALUE 255 34#define TQ_MAX_VALUE 255
35#define JITTER 20 35#define JITTER 20
36#define TTL 50 /* Time To Live of broadcast messages */ 36#define TTL 50 /* Time To Live of broadcast messages */
37#define MAX_ADDR 16 /* number of interfaces which can be added to 37#define MAX_ADDR 16 /* number of interfaces which can be added to
38 * batman. */ 38 * batman. */
39 39
40#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no 40#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no
41 * valid packet comes in -> TODO: check 41 * valid packet comes in -> TODO: check
42 * influence on TQ_LOCAL_WINDOW_SIZE */ 42 * influence on TQ_LOCAL_WINDOW_SIZE */
43#define LOCAL_HNA_TIMEOUT 3600000 43#define LOCAL_HNA_TIMEOUT 3600000
44 44
45#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator 45#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
46 * messages in squence numbers (should be a 46 * messages in squence numbers (should be a
47 * multiple of our word size) */ 47 * multiple of our word size) */
48#define TQ_GLOBAL_WINDOW_SIZE 5 48#define TQ_GLOBAL_WINDOW_SIZE 5
@@ -69,24 +69,27 @@
69 69
70 70
71/* 71/*
72 * Logging 72 * Debug Messages
73 */ 73 */
74 74
75#define LOG_TYPE_CRIT 0 /* highest priority for fatal errors such as 75#define DBG_BATMAN 1 /* all messages related to routing / flooding /
76 * blocked sockets / failed packet delivery / 76 * broadcasting / etc */
77 * programming errors */ 77#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
78#define LOG_TYPE_WARN 1 /* warnings for small errors like wrong user 78
79 * input / damaged packets / etc */ 79#ifdef CONFIG_BATMAN_ADV_DEBUG
80#define LOG_TYPE_NOTICE 2 /* notice information for new interfaces / 80extern int debug;
81 * changed settings / new originators / etc */ 81
82#define LOG_TYPE_BATMAN 4 /* all messages related to routing / flooding / 82extern int bat_debug_type(int type);
83 * broadcasting / etc */ 83#define bat_dbg(type, fmt, arg...) do { \
84#define LOG_TYPE_ROUTES 8 /* route or hna added / changed / deleted */ 84 if (bat_debug_type(type)) \
85#define LOG_TYPE_CRIT_NAME "critical" 85 printk(KERN_DEBUG "batman-adv:" fmt, ## arg); \
86#define LOG_TYPE_WARN_NAME "warnings" 86 } \
87#define LOG_TYPE_NOTICE_NAME "notices" 87 while (0)
88#define LOG_TYPE_BATMAN_NAME "batman" 88#else /* !CONFIG_BATMAN_ADV_DEBUG */
89#define LOG_TYPE_ROUTES_NAME "routes" 89#define bat_dbg(type, fmt, arg...) do { \
90 } \
91 while (0)
92#endif
90 93
91/* 94/*
92 * Vis 95 * Vis
@@ -127,6 +130,7 @@ extern spinlock_t forw_bcast_list_lock;
127 130
128extern atomic_t originator_interval; 131extern atomic_t originator_interval;
129extern atomic_t vis_interval; 132extern atomic_t vis_interval;
133extern atomic_t vis_mode;
130extern atomic_t aggregation_enabled; 134extern atomic_t aggregation_enabled;
131extern int16_t num_hna; 135extern int16_t num_hna;
132extern int16_t num_ifs; 136extern int16_t num_ifs;
@@ -147,5 +151,3 @@ int choose_orig(void *data, int32_t size);
147int is_my_mac(uint8_t *addr); 151int is_my_mac(uint8_t *addr);
148int is_bcast(uint8_t *addr); 152int is_bcast(uint8_t *addr);
149int is_mcast(uint8_t *addr); 153int is_mcast(uint8_t *addr);
150
151
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c
new file mode 100644
index 000000000000..29c241119a3b
--- /dev/null
+++ b/drivers/staging/batman-adv/originator.c
@@ -0,0 +1,252 @@
1/*
2 * Copyright (C) 2009 B.A.T.M.A.N. contributors:
3 *
4 * Marek Lindner, Simon Wunderlich
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA
19 *
20 */
21
22/* increase the reference counter for this originator */
23
24#include "main.h"
25#include "originator.h"
26#include "hash.h"
27#include "translation-table.h"
28#include "routing.h"
29
30static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
31
32static void start_purge_timer(void)
33{
34 queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
35}
36
37int originator_init(void)
38{
39 unsigned long flags;
40 if (orig_hash)
41 return 1;
42
43 spin_lock_irqsave(&orig_hash_lock, flags);
44 orig_hash = hash_new(128, compare_orig, choose_orig);
45
46 if (!orig_hash)
47 goto err;
48
49 spin_unlock_irqrestore(&orig_hash_lock, flags);
50 start_purge_timer();
51 return 1;
52
53err:
54 spin_unlock_irqrestore(&orig_hash_lock, flags);
55 return 0;
56}
57
58void originator_free(void)
59{
60 unsigned long flags;
61
62 if (!orig_hash)
63 return;
64
65 cancel_delayed_work_sync(&purge_orig_wq);
66
67 spin_lock_irqsave(&orig_hash_lock, flags);
68 hash_delete(orig_hash, free_orig_node);
69 orig_hash = NULL;
70 spin_unlock_irqrestore(&orig_hash_lock, flags);
71}
72
73struct neigh_node *
74create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
75 uint8_t *neigh, struct batman_if *if_incoming)
76{
77 struct neigh_node *neigh_node;
78
79 bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
80
81 neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
82 if (!neigh_node)
83 return NULL;
84
85 INIT_LIST_HEAD(&neigh_node->list);
86
87 memcpy(neigh_node->addr, neigh, ETH_ALEN);
88 neigh_node->orig_node = orig_neigh_node;
89 neigh_node->if_incoming = if_incoming;
90
91 list_add_tail(&neigh_node->list, &orig_node->neigh_list);
92 return neigh_node;
93}
94
95void free_orig_node(void *data)
96{
97 struct list_head *list_pos, *list_pos_tmp;
98 struct neigh_node *neigh_node;
99 struct orig_node *orig_node = (struct orig_node *)data;
100
101 /* for all neighbors towards this originator ... */
102 list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
103 neigh_node = list_entry(list_pos, struct neigh_node, list);
104
105 list_del(list_pos);
106 kfree(neigh_node);
107 }
108
109 hna_global_del_orig(orig_node, "originator timed out");
110
111 kfree(orig_node->bcast_own);
112 kfree(orig_node->bcast_own_sum);
113 kfree(orig_node);
114}
115
116/* this function finds or creates an originator entry for the given
117 * address if it does not exits */
118struct orig_node *get_orig_node(uint8_t *addr)
119{
120 struct orig_node *orig_node;
121 struct hashtable_t *swaphash;
122 int size;
123
124 orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
125
126 if (orig_node != NULL)
127 return orig_node;
128
129 bat_dbg(DBG_BATMAN, "Creating new originator: %pM \n", addr);
130
131 orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
132 if (!orig_node)
133 return NULL;
134
135 INIT_LIST_HEAD(&orig_node->neigh_list);
136
137 memcpy(orig_node->orig, addr, ETH_ALEN);
138 orig_node->router = NULL;
139 orig_node->batman_if = NULL;
140 orig_node->hna_buff = NULL;
141
142 size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS;
143
144 orig_node->bcast_own = kzalloc(size, GFP_ATOMIC);
145 if (!orig_node->bcast_own)
146 goto free_orig_node;
147
148 size = num_ifs * sizeof(uint8_t);
149 orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
150 if (!orig_node->bcast_own_sum)
151 goto free_bcast_own;
152
153 if (hash_add(orig_hash, orig_node) < 0)
154 goto free_bcast_own_sum;
155
156 if (orig_hash->elements * 4 > orig_hash->size) {
157 swaphash = hash_resize(orig_hash, orig_hash->size * 2);
158
159 if (swaphash == NULL)
160 printk(KERN_ERR
161 "batman-adv:Couldn't resize orig hash table \n");
162 else
163 orig_hash = swaphash;
164 }
165
166 return orig_node;
167free_bcast_own_sum:
168 kfree(orig_node->bcast_own_sum);
169free_bcast_own:
170 kfree(orig_node->bcast_own);
171free_orig_node:
172 kfree(orig_node);
173 return NULL;
174}
175
176static bool purge_orig_neighbors(struct orig_node *orig_node,
177 struct neigh_node **best_neigh_node)
178{
179 struct list_head *list_pos, *list_pos_tmp;
180 struct neigh_node *neigh_node;
181 bool neigh_purged = false;
182
183 *best_neigh_node = NULL;
184
185
186 /* for all neighbors towards this originator ... */
187 list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) {
188 neigh_node = list_entry(list_pos, struct neigh_node, list);
189
190 if (time_after(jiffies,
191 (neigh_node->last_valid +
192 ((PURGE_TIMEOUT * HZ) / 1000)))) {
193
194 bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ));
195
196 neigh_purged = true;
197 list_del(list_pos);
198 kfree(neigh_node);
199 } else {
200 if ((*best_neigh_node == NULL) ||
201 (neigh_node->tq_avg > (*best_neigh_node)->tq_avg))
202 *best_neigh_node = neigh_node;
203 }
204 }
205 return neigh_purged;
206}
207
208
209static bool purge_orig_node(struct orig_node *orig_node)
210{
211 struct neigh_node *best_neigh_node;
212
213 if (time_after(jiffies,
214 (orig_node->last_valid +
215 ((2 * PURGE_TIMEOUT * HZ) / 1000)))) {
216
217 bat_dbg(DBG_BATMAN,
218 "Originator timeout: originator %pM, last_valid %lu\n",
219 orig_node->orig, (orig_node->last_valid / HZ));
220 return true;
221 } else {
222 if (purge_orig_neighbors(orig_node, &best_neigh_node))
223 update_routes(orig_node, best_neigh_node,
224 orig_node->hna_buff,
225 orig_node->hna_buff_len);
226 }
227 return false;
228}
229
230void purge_orig(struct work_struct *work)
231{
232 HASHIT(hashit);
233 struct orig_node *orig_node;
234 unsigned long flags;
235
236 spin_lock_irqsave(&orig_hash_lock, flags);
237
238 /* for all origins... */
239 while (hash_iterate(orig_hash, &hashit)) {
240 orig_node = hashit.bucket->data;
241 if (purge_orig_node(orig_node)) {
242 hash_remove_bucket(orig_hash, &hashit);
243 free_orig_node(orig_node);
244 }
245 }
246
247 spin_unlock_irqrestore(&orig_hash_lock, flags);
248
249 start_purge_timer();
250}
251
252
diff --git a/drivers/staging/batman-adv/log.h b/drivers/staging/batman-adv/originator.h
index 780e3abb48f9..6ef7a054a0a9 100644
--- a/drivers/staging/batman-adv/log.h
+++ b/drivers/staging/batman-adv/originator.h
@@ -19,14 +19,13 @@
19 * 19 *
20 */ 20 */
21 21
22extern const struct file_operations proc_log_operations; 22int originator_init(void);
23extern uint8_t log_level; 23void free_orig_node(void *data);
24void originator_free(void);
25void purge_orig(struct work_struct *work);
26struct orig_node *orig_find(char *mac);
27struct orig_node *get_orig_node(uint8_t *addr);
28struct neigh_node *
29create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
30 uint8_t *neigh, struct batman_if *if_incoming);
24 31
25int debug_log(int type, char *fmt, ...);
26int log_open(struct inode *inode, struct file *file);
27int log_release(struct inode *inode, struct file *file);
28ssize_t log_read(struct file *file, char __user *buf, size_t count,
29 loff_t *ppos);
30ssize_t log_write(struct file *file, const char __user *buf, size_t count,
31 loff_t *ppos);
32unsigned int log_poll(struct file *file, poll_table *wait);
diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h
index 5627ca326018..ad006ce8b131 100644
--- a/drivers/staging/batman-adv/packet.h
+++ b/drivers/staging/batman-adv/packet.h
@@ -90,7 +90,7 @@ struct vis_packet {
90 uint8_t entries; /* number of entries behind this struct */ 90 uint8_t entries; /* number of entries behind this struct */
91 uint8_t ttl; /* TTL */ 91 uint8_t ttl; /* TTL */
92 uint8_t vis_orig[6]; /* originator that informs about its 92 uint8_t vis_orig[6]; /* originator that informs about its
93 * neighbours */ 93 * neighbors */
94 uint8_t target_orig[6]; /* who should receive this packet */ 94 uint8_t target_orig[6]; /* who should receive this packet */
95 uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ 95 uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
96} __attribute__((packed)); 96} __attribute__((packed));
diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c
index aac3df7f13fb..7de60e84bc96 100644
--- a/drivers/staging/batman-adv/proc.c
+++ b/drivers/staging/batman-adv/proc.c
@@ -21,23 +21,18 @@
21 21
22#include "main.h" 22#include "main.h"
23#include "proc.h" 23#include "proc.h"
24#include "log.h"
25#include "routing.h" 24#include "routing.h"
26#include "translation-table.h" 25#include "translation-table.h"
27#include "hard-interface.h" 26#include "hard-interface.h"
28#include "types.h" 27#include "types.h"
29#include "hash.h" 28#include "hash.h"
30#include "vis.h" 29#include "vis.h"
31#include "compat.h"
32
33static uint8_t vis_format = DOT_DRAW;
34 30
35static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; 31static struct proc_dir_entry *proc_batman_dir, *proc_interface_file;
36static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file; 32static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file;
37static struct proc_dir_entry *proc_log_file, *proc_log_level_file;
38static struct proc_dir_entry *proc_transt_local_file; 33static struct proc_dir_entry *proc_transt_local_file;
39static struct proc_dir_entry *proc_transt_global_file; 34static struct proc_dir_entry *proc_transt_global_file;
40static struct proc_dir_entry *proc_vis_file, *proc_vis_format_file; 35static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
41static struct proc_dir_entry *proc_aggr_file; 36static struct proc_dir_entry *proc_aggr_file;
42 37
43static int proc_interfaces_read(struct seq_file *seq, void *offset) 38static int proc_interfaces_read(struct seq_file *seq, void *offset)
@@ -68,7 +63,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
68 size_t count, loff_t *data) 63 size_t count, loff_t *data)
69{ 64{
70 char *if_string, *colon_ptr = NULL, *cr_ptr = NULL; 65 char *if_string, *colon_ptr = NULL, *cr_ptr = NULL;
71 int not_copied = 0, if_num = 0; 66 int not_copied = 0, if_num = 0, add_success;
72 struct batman_if *batman_if = NULL; 67 struct batman_if *batman_if = NULL;
73 68
74 if_string = kmalloc(count, GFP_KERNEL); 69 if_string = kmalloc(count, GFP_KERNEL);
@@ -77,8 +72,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
77 return -ENOMEM; 72 return -ENOMEM;
78 73
79 if (count > IFNAMSIZ - 1) { 74 if (count > IFNAMSIZ - 1) {
80 debug_log(LOG_TYPE_WARN, 75 printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n");
81 "Can't add interface: device name is too long\n");
82 goto end; 76 goto end;
83 } 77 }
84 78
@@ -105,7 +99,7 @@ static ssize_t proc_interfaces_write(struct file *instance,
105 rcu_read_lock(); 99 rcu_read_lock();
106 list_for_each_entry_rcu(batman_if, &if_list, list) { 100 list_for_each_entry_rcu(batman_if, &if_list, list) {
107 if (strncmp(batman_if->dev, if_string, count) == 0) { 101 if (strncmp(batman_if->dev, if_string, count) == 0) {
108 debug_log(LOG_TYPE_WARN, "Given interface is already active: %s\n", if_string); 102 printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string);
109 rcu_read_unlock(); 103 rcu_read_unlock();
110 goto end; 104 goto end;
111 105
@@ -115,22 +109,17 @@ static ssize_t proc_interfaces_write(struct file *instance,
115 } 109 }
116 rcu_read_unlock(); 110 rcu_read_unlock();
117 111
118 hardif_add_interface(if_string, if_num); 112 add_success = hardif_add_interface(if_string, if_num);
113 if (add_success < 0)
114 goto end;
115
116 num_ifs = if_num + 1;
119 117
120 if ((atomic_read(&module_state) == MODULE_INACTIVE) && 118 if ((atomic_read(&module_state) == MODULE_INACTIVE) &&
121 (hardif_get_active_if_num() > 0)) 119 (hardif_get_active_if_num() > 0))
122 activate_module(); 120 activate_module();
123 121
124 rcu_read_lock();
125 if (list_empty(&if_list)) {
126 rcu_read_unlock();
127 goto end;
128 }
129 rcu_read_unlock();
130
131 num_ifs = if_num + 1;
132 return count; 122 return count;
133
134end: 123end:
135 kfree(if_string); 124 kfree(if_string);
136 return count; 125 return count;
@@ -162,20 +151,18 @@ static ssize_t proc_orig_interval_write(struct file *file,
162 151
163 retval = strict_strtoul(interval_string, 10, &originator_interval_tmp); 152 retval = strict_strtoul(interval_string, 10, &originator_interval_tmp);
164 if (retval) { 153 if (retval) {
165 debug_log(LOG_TYPE_WARN, "New originator interval invalid\n"); 154 printk(KERN_ERR "batman-adv:New originator interval invalid\n");
166 goto end; 155 goto end;
167 } 156 }
168 157
169 if (originator_interval_tmp <= JITTER * 2) { 158 if (originator_interval_tmp <= JITTER * 2) {
170 debug_log(LOG_TYPE_WARN, 159 printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n",
171 "New originator interval too small: %i (min: %i)\n", 160 originator_interval_tmp, JITTER * 2);
172 originator_interval_tmp, JITTER * 2);
173 goto end; 161 goto end;
174 } 162 }
175 163
176 debug_log(LOG_TYPE_NOTICE, 164 printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n",
177 "Changing originator interval from: %i to: %i\n", 165 atomic_read(&originator_interval), originator_interval_tmp);
178 atomic_read(&originator_interval), originator_interval_tmp);
179 166
180 atomic_set(&originator_interval, originator_interval_tmp); 167 atomic_set(&originator_interval, originator_interval_tmp);
181 168
@@ -191,11 +178,12 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file)
191 178
192static int proc_originators_read(struct seq_file *seq, void *offset) 179static int proc_originators_read(struct seq_file *seq, void *offset)
193{ 180{
194 struct hash_it_t *hashit = NULL; 181 HASHIT(hashit);
195 struct orig_node *orig_node; 182 struct orig_node *orig_node;
196 struct neigh_node *neigh_node; 183 struct neigh_node *neigh_node;
197 int batman_count = 0; 184 int batman_count = 0;
198 char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; 185 char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
186 unsigned long flags;
199 187
200 rcu_read_lock(); 188 rcu_read_lock();
201 if (list_empty(&if_list)) { 189 if (list_empty(&if_list)) {
@@ -218,11 +206,11 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
218 ((struct batman_if *)if_list.next)->addr_str); 206 ((struct batman_if *)if_list.next)->addr_str);
219 207
220 rcu_read_unlock(); 208 rcu_read_unlock();
221 spin_lock(&orig_hash_lock); 209 spin_lock_irqsave(&orig_hash_lock, flags);
222 210
223 while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { 211 while (hash_iterate(orig_hash, &hashit)) {
224 212
225 orig_node = hashit->bucket->data; 213 orig_node = hashit.bucket->data;
226 214
227 if (!orig_node->router) 215 if (!orig_node->router)
228 continue; 216 continue;
@@ -249,7 +237,7 @@ static int proc_originators_read(struct seq_file *seq, void *offset)
249 237
250 } 238 }
251 239
252 spin_unlock(&orig_hash_lock); 240 spin_unlock_irqrestore(&orig_hash_lock, flags);
253 241
254 if (batman_count == 0) 242 if (batman_count == 0)
255 seq_printf(seq, "No batman nodes in range ... \n"); 243 seq_printf(seq, "No batman nodes in range ... \n");
@@ -263,84 +251,6 @@ static int proc_originators_open(struct inode *inode, struct file *file)
263 return single_open(file, proc_originators_read, NULL); 251 return single_open(file, proc_originators_read, NULL);
264} 252}
265 253
266static int proc_log_level_read(struct seq_file *seq, void *offset)
267{
268
269 seq_printf(seq, "[x] %s (%d)\n", LOG_TYPE_CRIT_NAME, LOG_TYPE_CRIT);
270 seq_printf(seq, "[%c] %s (%d)\n",
271 (LOG_TYPE_WARN & log_level) ? 'x' : ' ',
272 LOG_TYPE_WARN_NAME, LOG_TYPE_WARN);
273 seq_printf(seq, "[%c] %s (%d)\n",
274 (LOG_TYPE_NOTICE & log_level) ? 'x' : ' ',
275 LOG_TYPE_NOTICE_NAME, LOG_TYPE_NOTICE);
276 seq_printf(seq, "[%c] %s (%d)\n",
277 (LOG_TYPE_BATMAN & log_level) ? 'x' : ' ',
278 LOG_TYPE_BATMAN_NAME, LOG_TYPE_BATMAN);
279 seq_printf(seq, "[%c] %s (%d)\n",
280 (LOG_TYPE_ROUTES & log_level) ? 'x' : ' ',
281 LOG_TYPE_ROUTES_NAME, LOG_TYPE_ROUTES);
282 return 0;
283}
284
285static int proc_log_level_open(struct inode *inode, struct file *file)
286{
287 return single_open(file, proc_log_level_read, NULL);
288}
289
290static ssize_t proc_log_level_write(struct file *instance,
291 const char __user *userbuffer,
292 size_t count, loff_t *data)
293{
294 char *log_level_string, *tokptr, *cp;
295 int finished, not_copied = 0;
296 unsigned long log_level_tmp = 0;
297
298 log_level_string = kmalloc(count, GFP_KERNEL);
299
300 if (!log_level_string)
301 return -ENOMEM;
302
303 not_copied = copy_from_user(log_level_string, userbuffer, count);
304 log_level_string[count - not_copied - 1] = 0;
305
306 if (strict_strtoul(log_level_string, 10, &log_level_tmp) < 0) {
307 /* was not a number, doing textual parsing */
308 log_level_tmp = 0;
309 tokptr = log_level_string;
310
311 for (cp = log_level_string, finished = 0; !finished; cp++) {
312 switch (*cp) {
313 case 0:
314 finished = 1;
315 case ' ':
316 case '\n':
317 case '\t':
318 *cp = 0;
319 /* compare */
320 if (strcmp(tokptr, LOG_TYPE_WARN_NAME) == 0)
321 log_level_tmp |= LOG_TYPE_WARN;
322 if (strcmp(tokptr, LOG_TYPE_NOTICE_NAME) == 0)
323 log_level_tmp |= LOG_TYPE_NOTICE;
324 if (strcmp(tokptr, LOG_TYPE_BATMAN_NAME) == 0)
325 log_level_tmp |= LOG_TYPE_BATMAN;
326 if (strcmp(tokptr, LOG_TYPE_ROUTES_NAME) == 0)
327 log_level_tmp |= LOG_TYPE_ROUTES;
328 tokptr = cp + 1;
329 break;
330 default:
331 ;
332 }
333 }
334 }
335
336 debug_log(LOG_TYPE_CRIT, "Changing log_level from: %i to: %i\n",
337 log_level, log_level_tmp);
338 log_level = log_level_tmp;
339
340 kfree(log_level_string);
341 return count;
342}
343
344static int proc_transt_local_read(struct seq_file *seq, void *offset) 254static int proc_transt_local_read(struct seq_file *seq, void *offset)
345{ 255{
346 char *buf; 256 char *buf;
@@ -405,172 +315,8 @@ static int proc_transt_global_open(struct inode *inode, struct file *file)
405 return single_open(file, proc_transt_global_read, NULL); 315 return single_open(file, proc_transt_global_read, NULL);
406} 316}
407 317
408/* insert interface to the list of interfaces of one originator */
409
410static void proc_vis_insert_interface(const uint8_t *interface,
411 struct vis_if_list **if_entry,
412 bool primary)
413{
414 /* Did we get an empty list? (then insert imediately) */
415 if(*if_entry == NULL) {
416 *if_entry = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
417 if (*if_entry == NULL)
418 return;
419
420 (*if_entry)->primary = primary;
421 (*if_entry)->next = NULL;
422 memcpy((*if_entry)->addr, interface, ETH_ALEN);
423 } else {
424 struct vis_if_list *head_if_entry = *if_entry;
425 /* Do we already have this interface in our list? */
426 while (!compare_orig((*if_entry)->addr, (void *)interface)) {
427
428 /* Or did we reach the end (then append the interface) */
429 if ((*if_entry)->next == NULL) {
430 (*if_entry)->next = kmalloc(sizeof(struct vis_if_list), GFP_KERNEL);
431 if ((*if_entry)->next == NULL)
432 return;
433
434 memcpy((*if_entry)->next->addr, interface, ETH_ALEN);
435 (*if_entry)->next->primary = primary;
436 (*if_entry)->next->next = NULL;
437 break;
438 }
439 *if_entry = (*if_entry)->next;
440 }
441 /* Rewind the list to its head */
442 *if_entry = head_if_entry;
443 }
444}
445/* read an entry */
446
447static void proc_vis_read_entry(struct seq_file *seq,
448 struct vis_info_entry *entry,
449 struct vis_if_list **if_entry,
450 uint8_t *vis_orig,
451 uint8_t current_format,
452 uint8_t first_line)
453{
454 char from[40];
455 char to[40];
456 int int_part, frac_part;
457
458 addr_to_string(to, entry->dest);
459 if (entry->quality == 0) {
460#ifndef VIS_SUBCLUSTERS_DISABLED
461 proc_vis_insert_interface(vis_orig, if_entry, true);
462#endif /* VIS_SUBCLUSTERS_DISABLED */
463 addr_to_string(from, vis_orig);
464 if (current_format == DOT_DRAW) {
465 seq_printf(seq, "\t\"%s\" -> \"%s\" [label=\"HNA\"]\n",
466 from, to);
467 } else {
468 seq_printf(seq,
469 "%s\t{ router : \"%s\", gateway : \"%s\", label : \"HNA\" }",
470 (first_line ? "" : ",\n"), from, to);
471 }
472 } else {
473#ifndef VIS_SUBCLUSTERS_DISABLED
474 proc_vis_insert_interface(entry->src, if_entry, compare_orig(entry->src, vis_orig));
475#endif /* VIS_SUBCLUSTERS_DISABLED */
476 addr_to_string(from, entry->src);
477
478 /* kernel has no printf-support for %f? it'd be better to return
479 * this in float. */
480
481 int_part = TQ_MAX_VALUE / entry->quality;
482 frac_part = 1000 * TQ_MAX_VALUE / entry->quality - int_part * 1000;
483
484 if (current_format == DOT_DRAW) {
485 seq_printf(seq,
486 "\t\"%s\" -> \"%s\" [label=\"%d.%d\"]\n",
487 from, to, int_part, frac_part);
488 } else {
489 seq_printf(seq,
490 "%s\t{ router : \"%s\", neighbour : \"%s\", label : %d.%d }",
491 (first_line ? "" : ",\n"), from, to, int_part, frac_part);
492 }
493 }
494}
495
496
497static int proc_vis_read(struct seq_file *seq, void *offset)
498{
499 struct hash_it_t *hashit = NULL;
500 struct vis_info *info;
501 struct vis_info_entry *entries;
502 struct vis_if_list *if_entries = NULL;
503 int i;
504 uint8_t current_format, first_line = 1;
505#ifndef VIS_SUBCLUSTERS_DISABLED
506 char tmp_addr_str[ETH_STR_LEN];
507 struct vis_if_list *tmp_if_next;
508#endif /* VIS_SUBCLUSTERS_DISABLED */
509
510 current_format = vis_format;
511
512 rcu_read_lock();
513 if (list_empty(&if_list) || (!is_vis_server())) {
514 rcu_read_unlock();
515 if (current_format == DOT_DRAW)
516 seq_printf(seq, "digraph {\n}\n");
517 goto end;
518 }
519
520 rcu_read_unlock();
521
522 if (current_format == DOT_DRAW)
523 seq_printf(seq, "digraph {\n");
524
525 spin_lock(&vis_hash_lock);
526 while (NULL != (hashit = hash_iterate(vis_hash, hashit))) {
527 info = hashit->bucket->data;
528 entries = (struct vis_info_entry *)
529 ((char *)info + sizeof(struct vis_info));
530
531 for (i = 0; i < info->packet.entries; i++) {
532 proc_vis_read_entry(seq, &entries[i], &if_entries,
533 info->packet.vis_orig,
534 current_format, first_line);
535 if (first_line)
536 first_line = 0;
537 }
538
539#ifndef VIS_SUBCLUSTERS_DISABLED
540 /* Generate subgraphs from the collected items */
541 if (current_format == DOT_DRAW) {
542
543 addr_to_string(tmp_addr_str, info->packet.vis_orig);
544 seq_printf(seq, "\tsubgraph \"cluster_%s\" {\n", tmp_addr_str);
545 while (if_entries != NULL) {
546
547 addr_to_string(tmp_addr_str, if_entries->addr);
548 if (if_entries->primary)
549 seq_printf(seq, "\t\t\"%s\" [peripheries=2]\n", tmp_addr_str);
550 else
551 seq_printf(seq, "\t\t\"%s\"\n", tmp_addr_str);
552
553 /* ... and empty the list while doing this */
554 tmp_if_next = if_entries->next;
555 kfree(if_entries);
556 if_entries = tmp_if_next;
557 }
558 seq_printf(seq, "\t}\n");
559 }
560#endif /* VIS_SUBCLUSTERS_DISABLED */
561 }
562 spin_unlock(&vis_hash_lock);
563
564 if (current_format == DOT_DRAW)
565 seq_printf(seq, "}\n");
566 else
567 seq_printf(seq, "\n");
568end:
569 return 0;
570}
571
572/* setting the mode of the vis server by the user */ 318/* setting the mode of the vis server by the user */
573static ssize_t proc_vis_write(struct file *file, const char __user * buffer, 319static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer,
574 size_t count, loff_t *ppos) 320 size_t count, loff_t *ppos)
575{ 321{
576 char *vis_mode_string; 322 char *vis_mode_string;
@@ -584,72 +330,84 @@ static ssize_t proc_vis_write(struct file *file, const char __user * buffer,
584 not_copied = copy_from_user(vis_mode_string, buffer, count); 330 not_copied = copy_from_user(vis_mode_string, buffer, count);
585 vis_mode_string[count - not_copied - 1] = 0; 331 vis_mode_string[count - not_copied - 1] = 0;
586 332
587 if (strcmp(vis_mode_string, "client") == 0) { 333 if ((strcmp(vis_mode_string, "client") == 0) ||
588 debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to client\n"); 334 (strcmp(vis_mode_string, "disabled") == 0)) {
589 vis_set_mode(VIS_TYPE_CLIENT_UPDATE); 335 printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n");
590 } else if (strcmp(vis_mode_string, "server") == 0) { 336 atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
591 debug_log(LOG_TYPE_NOTICE, "Setting VIS mode to server\n"); 337 } else if ((strcmp(vis_mode_string, "server") == 0) ||
592 vis_set_mode(VIS_TYPE_SERVER_SYNC); 338 (strcmp(vis_mode_string, "enabled") == 0)) {
339 printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n");
340 atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC);
593 } else 341 } else
594 debug_log(LOG_TYPE_WARN, "Unknown VIS mode: %s\n", 342 printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n",
595 vis_mode_string); 343 vis_mode_string);
596 344
597 kfree(vis_mode_string); 345 kfree(vis_mode_string);
598 return count; 346 return count;
599} 347}
600 348
601static int proc_vis_open(struct inode *inode, struct file *file) 349static int proc_vis_srv_read(struct seq_file *seq, void *offset)
602{ 350{
603 return single_open(file, proc_vis_read, NULL); 351 int vis_server = atomic_read(&vis_mode);
604} 352
353 seq_printf(seq, "[%c] client mode (server disabled) \n",
354 (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
355 seq_printf(seq, "[%c] server mode (server enabled) \n",
356 (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
605 357
606static int proc_vis_format_read(struct seq_file *seq, void *offset)
607{
608 uint8_t current_format = vis_format;
609
610 seq_printf(seq, "[%c] %s\n",
611 (current_format == DOT_DRAW) ? 'x' : ' ',
612 VIS_FORMAT_DD_NAME);
613 seq_printf(seq, "[%c] %s\n",
614 (current_format == JSON) ? 'x' : ' ',
615 VIS_FORMAT_JSON_NAME);
616 return 0; 358 return 0;
617} 359}
618 360
619static int proc_vis_format_open(struct inode *inode, struct file *file) 361static int proc_vis_srv_open(struct inode *inode, struct file *file)
620{ 362{
621 return single_open(file, proc_vis_format_read, NULL); 363 return single_open(file, proc_vis_srv_read, NULL);
622} 364}
623 365
624static ssize_t proc_vis_format_write(struct file *file, 366static int proc_vis_data_read(struct seq_file *seq, void *offset)
625 const char __user *buffer,
626 size_t count, loff_t *ppos)
627{ 367{
628 char *vis_format_string; 368 HASHIT(hashit);
629 int not_copied = 0; 369 struct vis_info *info;
370 struct vis_info_entry *entries;
371 HLIST_HEAD(vis_if_list);
372 int i;
373 char tmp_addr_str[ETH_STR_LEN];
374 unsigned long flags;
375 int vis_server = atomic_read(&vis_mode);
376
377 rcu_read_lock();
378 if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) {
379 rcu_read_unlock();
380 goto end;
381 }
630 382
631 vis_format_string = kmalloc(count, GFP_KERNEL); 383 rcu_read_unlock();
632 384
633 if (!vis_format_string) 385 spin_lock_irqsave(&vis_hash_lock, flags);
634 return -ENOMEM; 386 while (hash_iterate(vis_hash, &hashit)) {
387 info = hashit.bucket->data;
388 entries = (struct vis_info_entry *)
389 ((char *)info + sizeof(struct vis_info));
390 addr_to_string(tmp_addr_str, info->packet.vis_orig);
391 seq_printf(seq, "%s,", tmp_addr_str);
635 392
636 not_copied = copy_from_user(vis_format_string, buffer, count); 393 for (i = 0; i < info->packet.entries; i++) {
637 vis_format_string[count - not_copied - 1] = 0; 394 proc_vis_read_entry(seq, &entries[i], &vis_if_list,
638 395 info->packet.vis_orig);
639 if (strcmp(vis_format_string, VIS_FORMAT_DD_NAME) == 0) { 396 }
640 debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
641 VIS_FORMAT_DD_NAME);
642 vis_format = DOT_DRAW;
643 } else if (strcmp(vis_format_string, VIS_FORMAT_JSON_NAME) == 0) {
644 debug_log(LOG_TYPE_NOTICE, "Setting VIS output format to: %s\n",
645 VIS_FORMAT_JSON_NAME);
646 vis_format = JSON;
647 } else
648 debug_log(LOG_TYPE_WARN, "Unknown VIS output format: %s\n",
649 vis_format_string);
650 397
651 kfree(vis_format_string); 398 /* add primary/secondary records */
652 return count; 399 proc_vis_read_prim_sec(seq, &vis_if_list);
400 seq_printf(seq, "\n");
401 }
402 spin_unlock_irqrestore(&vis_hash_lock, flags);
403
404end:
405 return 0;
406}
407
408static int proc_vis_data_open(struct inode *inode, struct file *file)
409{
410 return single_open(file, proc_vis_data_read, NULL);
653} 411}
654 412
655static int proc_aggr_read(struct seq_file *seq, void *offset) 413static int proc_aggr_read(struct seq_file *seq, void *offset)
@@ -665,6 +423,7 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
665 char *aggr_string; 423 char *aggr_string;
666 int not_copied = 0; 424 int not_copied = 0;
667 unsigned long aggregation_enabled_tmp; 425 unsigned long aggregation_enabled_tmp;
426 int retval;
668 427
669 aggr_string = kmalloc(count, GFP_KERNEL); 428 aggr_string = kmalloc(count, GFP_KERNEL);
670 429
@@ -674,22 +433,21 @@ static ssize_t proc_aggr_write(struct file *file, const char __user *buffer,
674 not_copied = copy_from_user(aggr_string, buffer, count); 433 not_copied = copy_from_user(aggr_string, buffer, count);
675 aggr_string[count - not_copied - 1] = 0; 434 aggr_string[count - not_copied - 1] = 0;
676 435
677 strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp); 436 retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp);
678 437
679 if ((aggregation_enabled_tmp != 0) && (aggregation_enabled_tmp != 1)) { 438 if (retval || aggregation_enabled_tmp > 1) {
680 debug_log(LOG_TYPE_WARN, "Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp); 439 printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp);
681 goto end; 440 } else {
441 printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n",
442 (atomic_read(&aggregation_enabled) == 1 ?
443 "enabled" : "disabled"),
444 atomic_read(&aggregation_enabled),
445 (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
446 aggregation_enabled_tmp);
447 atomic_set(&aggregation_enabled,
448 (unsigned)aggregation_enabled_tmp);
682 } 449 }
683 450
684 debug_log(LOG_TYPE_NOTICE, "Changing aggregation from: %s (%i) to: %s (%li)\n",
685 (atomic_read(&aggregation_enabled) == 1 ?
686 "enabled" : "disabled"),
687 atomic_read(&aggregation_enabled),
688 (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"),
689 aggregation_enabled_tmp);
690
691 atomic_set(&aggregation_enabled, (unsigned)aggregation_enabled_tmp);
692end:
693 kfree(aggr_string); 451 kfree(aggr_string);
694 return count; 452 return count;
695} 453}
@@ -715,20 +473,20 @@ static const struct file_operations proc_aggr_fops = {
715 .release = single_release, 473 .release = single_release,
716}; 474};
717 475
718static const struct file_operations proc_vis_format_fops = { 476static const struct file_operations proc_vis_srv_fops = {
719 .owner = THIS_MODULE, 477 .owner = THIS_MODULE,
720 .open = proc_vis_format_open, 478 .open = proc_vis_srv_open,
721 .read = seq_read, 479 .read = seq_read,
722 .write = proc_vis_format_write, 480 .write = proc_vis_srv_write,
723 .llseek = seq_lseek, 481 .llseek = seq_lseek,
724 .release = single_release, 482 .release = single_release,
725}; 483};
726 484
727static const struct file_operations proc_vis_fops = { 485static const struct file_operations proc_vis_data_fops = {
728 .owner = THIS_MODULE, 486 .owner = THIS_MODULE,
729 .open = proc_vis_open, 487 .open = proc_vis_data_open,
730 .read = seq_read, 488 .read = seq_read,
731 .write = proc_vis_write, 489 .write = proc_dummy_write,
732 .llseek = seq_lseek, 490 .llseek = seq_lseek,
733 .release = single_release, 491 .release = single_release,
734}; 492};
@@ -760,15 +518,6 @@ static const struct file_operations proc_transt_global_fops = {
760 .release = single_release, 518 .release = single_release,
761}; 519};
762 520
763static const struct file_operations proc_log_level_fops = {
764 .owner = THIS_MODULE,
765 .open = proc_log_level_open,
766 .read = seq_read,
767 .write = proc_log_level_write,
768 .llseek = seq_lseek,
769 .release = single_release,
770};
771
772static const struct file_operations proc_interfaces_fops = { 521static const struct file_operations proc_interfaces_fops = {
773 .owner = THIS_MODULE, 522 .owner = THIS_MODULE,
774 .open = proc_interfaces_open, 523 .open = proc_interfaces_open,
@@ -795,12 +544,6 @@ void cleanup_procfs(void)
795 if (proc_transt_local_file) 544 if (proc_transt_local_file)
796 remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir); 545 remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir);
797 546
798 if (proc_log_file)
799 remove_proc_entry(PROC_FILE_LOG, proc_batman_dir);
800
801 if (proc_log_level_file)
802 remove_proc_entry(PROC_FILE_LOG_LEVEL, proc_batman_dir);
803
804 if (proc_originators_file) 547 if (proc_originators_file)
805 remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir); 548 remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir);
806 549
@@ -810,11 +553,11 @@ void cleanup_procfs(void)
810 if (proc_interface_file) 553 if (proc_interface_file)
811 remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir); 554 remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
812 555
813 if (proc_vis_file) 556 if (proc_vis_data_file)
814 remove_proc_entry(PROC_FILE_VIS, proc_batman_dir); 557 remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir);
815 558
816 if (proc_vis_format_file) 559 if (proc_vis_srv_file)
817 remove_proc_entry(PROC_FILE_VIS_FORMAT, proc_batman_dir); 560 remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
818 561
819 if (proc_aggr_file) 562 if (proc_aggr_file)
820 remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir); 563 remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir);
@@ -862,17 +605,6 @@ int setup_procfs(void)
862 return -EFAULT; 605 return -EFAULT;
863 } 606 }
864 607
865 proc_log_level_file = create_proc_entry(PROC_FILE_LOG_LEVEL,
866 S_IWUSR | S_IRUGO,
867 proc_batman_dir);
868 if (proc_log_level_file) {
869 proc_log_level_file->proc_fops = &proc_log_level_fops;
870 } else {
871 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_LOG_LEVEL);
872 cleanup_procfs();
873 return -EFAULT;
874 }
875
876 proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS, 608 proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS,
877 S_IRUGO, proc_batman_dir); 609 S_IRUGO, proc_batman_dir);
878 if (proc_originators_file) { 610 if (proc_originators_file) {
@@ -883,16 +615,6 @@ int setup_procfs(void)
883 return -EFAULT; 615 return -EFAULT;
884 } 616 }
885 617
886 proc_log_file = create_proc_entry(PROC_FILE_LOG,
887 S_IRUGO, proc_batman_dir);
888 if (proc_log_file) {
889 proc_log_file->proc_fops = &proc_log_operations;
890 } else {
891 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_FILE_LOG, PROC_FILE_GATEWAYS);
892 cleanup_procfs();
893 return -EFAULT;
894 }
895
896 proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL, 618 proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL,
897 S_IRUGO, proc_batman_dir); 619 S_IRUGO, proc_batman_dir);
898 if (proc_transt_local_file) { 620 if (proc_transt_local_file) {
@@ -913,23 +635,23 @@ int setup_procfs(void)
913 return -EFAULT; 635 return -EFAULT;
914 } 636 }
915 637
916 proc_vis_file = create_proc_entry(PROC_FILE_VIS, S_IWUSR | S_IRUGO, 638 proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV,
917 proc_batman_dir); 639 S_IWUSR | S_IRUGO,
918 if (proc_vis_file) { 640 proc_batman_dir);
919 proc_vis_file->proc_fops = &proc_vis_fops; 641 if (proc_vis_srv_file) {
642 proc_vis_srv_file->proc_fops = &proc_vis_srv_fops;
920 } else { 643 } else {
921 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS); 644 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV);
922 cleanup_procfs(); 645 cleanup_procfs();
923 return -EFAULT; 646 return -EFAULT;
924 } 647 }
925 648
926 proc_vis_format_file = create_proc_entry(PROC_FILE_VIS_FORMAT, 649 proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO,
927 S_IWUSR | S_IRUGO, 650 proc_batman_dir);
928 proc_batman_dir); 651 if (proc_vis_data_file) {
929 if (proc_vis_format_file) { 652 proc_vis_data_file->proc_fops = &proc_vis_data_fops;
930 proc_vis_format_file->proc_fops = &proc_vis_format_fops;
931 } else { 653 } else {
932 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_FORMAT); 654 printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA);
933 cleanup_procfs(); 655 cleanup_procfs();
934 return -EFAULT; 656 return -EFAULT;
935 } 657 }
@@ -946,5 +668,3 @@ int setup_procfs(void)
946 668
947 return 0; 669 return 0;
948} 670}
949
950
diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h
index 16d3efdebe52..cd690e0f3e44 100644
--- a/drivers/staging/batman-adv/proc.h
+++ b/drivers/staging/batman-adv/proc.h
@@ -31,19 +31,10 @@
31#define PROC_FILE_LOG_LEVEL "log_level" 31#define PROC_FILE_LOG_LEVEL "log_level"
32#define PROC_FILE_TRANST_LOCAL "transtable_local" 32#define PROC_FILE_TRANST_LOCAL "transtable_local"
33#define PROC_FILE_TRANST_GLOBAL "transtable_global" 33#define PROC_FILE_TRANST_GLOBAL "transtable_global"
34#define PROC_FILE_VIS "vis" 34#define PROC_FILE_VIS_SRV "vis_server"
35#define PROC_FILE_VIS_FORMAT "vis_format" 35#define PROC_FILE_VIS_DATA "vis_data"
36#define PROC_FILE_AGGR "aggregate_ogm" 36#define PROC_FILE_AGGR "aggregate_ogm"
37 37
38void cleanup_procfs(void); 38void cleanup_procfs(void);
39int setup_procfs(void); 39int setup_procfs(void);
40 40
41/* While scanning for vis-entries of a particular vis-originator
42 * this list collects its interfaces to create a subgraph/cluster
43 * out of them later
44 */
45struct vis_if_list {
46 uint8_t addr[ETH_ALEN];
47 bool primary;
48 struct vis_if_list *next;
49};
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c
index 4a14c363ac2b..d89048beebe1 100644
--- a/drivers/staging/batman-adv/routing.c
+++ b/drivers/staging/batman-adv/routing.c
@@ -19,304 +19,226 @@
19 * 19 *
20 */ 20 */
21 21
22
23
24
25
26#include "main.h" 22#include "main.h"
27#include "routing.h" 23#include "routing.h"
28#include "log.h"
29#include "send.h" 24#include "send.h"
25#include "hash.h"
30#include "soft-interface.h" 26#include "soft-interface.h"
31#include "hard-interface.h" 27#include "hard-interface.h"
32#include "device.h" 28#include "device.h"
33#include "translation-table.h" 29#include "translation-table.h"
30#include "originator.h"
34#include "types.h" 31#include "types.h"
35#include "hash.h"
36#include "ring_buffer.h" 32#include "ring_buffer.h"
37#include "vis.h" 33#include "vis.h"
38#include "aggregation.h" 34#include "aggregation.h"
39#include "compat.h"
40
41
42 35
43DECLARE_WAIT_QUEUE_HEAD(thread_wait); 36DECLARE_WAIT_QUEUE_HEAD(thread_wait);
44static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
45
46static atomic_t data_ready_cond;
47atomic_t exit_cond;
48
49static void start_purge_timer(void)
50{
51 queue_delayed_work(bat_event_workqueue, &purge_orig_wq, 1 * HZ);
52}
53
54int originator_init(void)
55{
56 if (orig_hash)
57 return 1;
58
59 spin_lock(&orig_hash_lock);
60 orig_hash = hash_new(128, compare_orig, choose_orig);
61
62 if (!orig_hash)
63 goto err;
64
65 spin_unlock(&orig_hash_lock);
66 start_purge_timer();
67 return 1;
68
69err:
70 spin_unlock(&orig_hash_lock);
71 return 0;
72}
73
74void originator_free(void)
75{
76 if (!orig_hash)
77 return;
78
79 cancel_delayed_work_sync(&purge_orig_wq);
80
81 spin_lock(&orig_hash_lock);
82 hash_delete(orig_hash, free_orig_node);
83 orig_hash = NULL;
84 spin_unlock(&orig_hash_lock);
85}
86 37
87static struct neigh_node *create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming) 38void slide_own_bcast_window(struct batman_if *batman_if)
88{ 39{
89 struct neigh_node *neigh_node; 40 HASHIT(hashit);
41 struct orig_node *orig_node;
42 TYPE_OF_WORD *word;
43 unsigned long flags;
90 44
91 debug_log(LOG_TYPE_BATMAN, "Creating new last-hop neighbour of originator\n"); 45 spin_lock_irqsave(&orig_hash_lock, flags);
92 46
93 neigh_node = kmalloc(sizeof(struct neigh_node), GFP_ATOMIC); 47 while (hash_iterate(orig_hash, &hashit)) {
94 memset(neigh_node, 0, sizeof(struct neigh_node)); 48 orig_node = hashit.bucket->data;
95 INIT_LIST_HEAD(&neigh_node->list); 49 word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]);
96 50
97 memcpy(neigh_node->addr, neigh, ETH_ALEN); 51 bit_get_packet(word, 1, 0);
98 neigh_node->orig_node = orig_neigh_node; 52 orig_node->bcast_own_sum[batman_if->if_num] =
99 neigh_node->if_incoming = if_incoming; 53 bit_packet_count(word);
54 }
100 55
101 list_add_tail(&neigh_node->list, &orig_node->neigh_list); 56 spin_unlock_irqrestore(&orig_hash_lock, flags);
102 return neigh_node;
103} 57}
104 58
105void free_orig_node(void *data) 59static void update_HNA(struct orig_node *orig_node,
60 unsigned char *hna_buff, int hna_buff_len)
106{ 61{
107 struct list_head *list_pos, *list_pos_tmp; 62 if ((hna_buff_len != orig_node->hna_buff_len) ||
108 struct neigh_node *neigh_node; 63 ((hna_buff_len > 0) &&
109 struct orig_node *orig_node = (struct orig_node *)data; 64 (orig_node->hna_buff_len > 0) &&
65 (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
110 66
111 /* for all neighbours towards this originator ... */ 67 if (orig_node->hna_buff_len > 0)
112 list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { 68 hna_global_del_orig(orig_node,
113 neigh_node = list_entry(list_pos, struct neigh_node, list); 69 "originator changed hna");
114 70
115 list_del(list_pos); 71 if ((hna_buff_len > 0) && (hna_buff != NULL))
116 kfree(neigh_node); 72 hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
117 } 73 }
118
119 hna_global_del_orig(orig_node, "originator timed out");
120
121 kfree(orig_node->bcast_own);
122 kfree(orig_node->bcast_own_sum);
123 kfree(orig_node);
124} 74}
125 75
126/* this function finds or creates an originator entry for the given address if it does not exits */ 76static void update_route(struct orig_node *orig_node,
127static struct orig_node *get_orig_node(uint8_t *addr) 77 struct neigh_node *neigh_node,
78 unsigned char *hna_buff, int hna_buff_len)
128{ 79{
129 struct orig_node *orig_node; 80 /* route deleted */
130 struct hashtable_t *swaphash; 81 if ((orig_node->router != NULL) && (neigh_node == NULL)) {
131 char orig_str[ETH_STR_LEN];
132
133 orig_node = ((struct orig_node *)hash_find(orig_hash, addr));
134
135 if (orig_node != NULL)
136 return orig_node;
137
138 addr_to_string(orig_str, addr);
139 debug_log(LOG_TYPE_BATMAN, "Creating new originator: %s \n", orig_str);
140
141 orig_node = kmalloc(sizeof(struct orig_node), GFP_ATOMIC);
142 memset(orig_node, 0, sizeof(struct orig_node));
143 INIT_LIST_HEAD(&orig_node->neigh_list);
144
145 memcpy(orig_node->orig, addr, ETH_ALEN);
146 orig_node->router = NULL;
147 orig_node->batman_if = NULL;
148 orig_node->hna_buff = NULL;
149 82
150 orig_node->bcast_own = kmalloc(num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC); 83 bat_dbg(DBG_ROUTES, "Deleting route towards: %pM\n",
151 memset(orig_node->bcast_own, 0, num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS); 84 orig_node->orig);
85 hna_global_del_orig(orig_node, "originator timed out");
152 86
153 orig_node->bcast_own_sum = kmalloc(num_ifs * sizeof(uint8_t), GFP_ATOMIC); 87 /* route added */
154 memset(orig_node->bcast_own_sum, 0, num_ifs * sizeof(uint8_t)); 88 } else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
155
156 hash_add(orig_hash, orig_node);
157 89
158 if (orig_hash->elements * 4 > orig_hash->size) { 90 bat_dbg(DBG_ROUTES,
159 swaphash = hash_resize(orig_hash, orig_hash->size * 2); 91 "Adding route towards: %pM (via %pM)\n",
92 orig_node->orig, neigh_node->addr);
93 hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
160 94
161 if (swaphash == NULL) 95 /* route changed */
162 debug_log(LOG_TYPE_CRIT, "Couldn't resize orig hash table \n"); 96 } else {
163 else 97 bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr);
164 orig_hash = swaphash;
165 } 98 }
166 99
167 return orig_node; 100 if (neigh_node != NULL)
168} 101 orig_node->batman_if = neigh_node->if_incoming;
169 102 else
170void slide_own_bcast_window(struct batman_if *batman_if) 103 orig_node->batman_if = NULL;
171{
172 struct hash_it_t *hashit = NULL;
173 struct orig_node *orig_node;
174
175 spin_lock(&orig_hash_lock);
176
177 while (NULL != (hashit = hash_iterate(orig_hash, hashit))) {
178 orig_node = hashit->bucket->data;
179
180 bit_get_packet((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]), 1, 0);
181 orig_node->bcast_own_sum[batman_if->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]));
182 }
183 104
184 spin_unlock(&orig_hash_lock); 105 orig_node->router = neigh_node;
185} 106}
186 107
187static void update_routes(struct orig_node *orig_node, struct neigh_node *neigh_node, unsigned char *hna_buff, int hna_buff_len) 108
109void update_routes(struct orig_node *orig_node,
110 struct neigh_node *neigh_node,
111 unsigned char *hna_buff, int hna_buff_len)
188{ 112{
189 char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
190 113
191 if (orig_node == NULL) 114 if (orig_node == NULL)
192 return; 115 return;
193 116
194 if (orig_node->router != neigh_node) { 117 if (orig_node->router != neigh_node)
195 addr_to_string(orig_str, orig_node->orig); 118 update_route(orig_node, neigh_node, hna_buff, hna_buff_len);
196
197 /* route deleted */
198 if ((orig_node->router != NULL) && (neigh_node == NULL)) {
199
200 debug_log(LOG_TYPE_ROUTES, "Deleting route towards: %s\n", orig_str);
201 hna_global_del_orig(orig_node, "originator timed out");
202
203 /* route added */
204 } else if ((orig_node->router == NULL) && (neigh_node != NULL)) {
205
206 addr_to_string(neigh_str, neigh_node->addr);
207 debug_log(LOG_TYPE_ROUTES, "Adding route towards: %s (via %s)\n", orig_str, neigh_str);
208 hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
209
210 /* route changed */
211 } else {
212
213 addr_to_string(neigh_str, neigh_node->addr);
214 addr_to_string(router_str, orig_node->router->addr);
215 debug_log(LOG_TYPE_ROUTES, "Changing route towards: %s (now via %s - was via %s)\n", orig_str, neigh_str, router_str);
216
217 }
218
219 if (neigh_node != NULL)
220 orig_node->batman_if = neigh_node->if_incoming;
221 else
222 orig_node->batman_if = NULL;
223
224 orig_node->router = neigh_node;
225
226 /* may be just HNA changed */ 119 /* may be just HNA changed */
227 } else { 120 else
228 121 update_HNA(orig_node, hna_buff, hna_buff_len);
229 if ((hna_buff_len != orig_node->hna_buff_len) || ((hna_buff_len > 0) && (orig_node->hna_buff_len > 0) && (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) {
230
231 if (orig_node->hna_buff_len > 0)
232 hna_global_del_orig(orig_node, "originator changed hna");
233
234 if ((hna_buff_len > 0) && (hna_buff != NULL))
235 hna_global_add_orig(orig_node, hna_buff, hna_buff_len);
236
237 }
238
239 }
240} 122}
241 123
242static int isBidirectionalNeigh(struct orig_node *orig_node, struct orig_node *orig_neigh_node, struct batman_packet *batman_packet, struct batman_if *if_incoming) 124static int isBidirectionalNeigh(struct orig_node *orig_node,
125 struct orig_node *orig_neigh_node,
126 struct batman_packet *batman_packet,
127 struct batman_if *if_incoming)
243{ 128{
244 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 129 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
245 char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
246 unsigned char total_count; 130 unsigned char total_count;
247 131
248 addr_to_string(orig_str, orig_node->orig);
249 addr_to_string(neigh_str, orig_neigh_node->orig);
250
251 if (orig_node == orig_neigh_node) { 132 if (orig_node == orig_neigh_node) {
252 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 133 list_for_each_entry(tmp_neigh_node,
134 &orig_node->neigh_list,
135 list) {
253 136
254 if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming)) 137 if (compare_orig(tmp_neigh_node->addr,
138 orig_neigh_node->orig) &&
139 (tmp_neigh_node->if_incoming == if_incoming))
255 neigh_node = tmp_neigh_node; 140 neigh_node = tmp_neigh_node;
256 } 141 }
257 142
258 if (neigh_node == NULL) 143 if (!neigh_node)
259 neigh_node = create_neighbor(orig_node, orig_neigh_node, orig_neigh_node->orig, if_incoming); 144 neigh_node = create_neighbor(orig_node,
145 orig_neigh_node,
146 orig_neigh_node->orig,
147 if_incoming);
148 /* create_neighbor failed, return 0 */
149 if (!neigh_node)
150 return 0;
260 151
261 neigh_node->last_valid = jiffies; 152 neigh_node->last_valid = jiffies;
262 } else { 153 } else {
263 /* find packet count of corresponding one hop neighbor */ 154 /* find packet count of corresponding one hop neighbor */
264 list_for_each_entry(tmp_neigh_node, &orig_neigh_node->neigh_list, list) { 155 list_for_each_entry(tmp_neigh_node,
156 &orig_neigh_node->neigh_list, list) {
265 157
266 if (compare_orig(tmp_neigh_node->addr, orig_neigh_node->orig) && (tmp_neigh_node->if_incoming == if_incoming)) 158 if (compare_orig(tmp_neigh_node->addr,
159 orig_neigh_node->orig) &&
160 (tmp_neigh_node->if_incoming == if_incoming))
267 neigh_node = tmp_neigh_node; 161 neigh_node = tmp_neigh_node;
268 } 162 }
269 163
270 if (neigh_node == NULL) 164 if (!neigh_node)
271 neigh_node = create_neighbor(orig_neigh_node, orig_neigh_node, orig_neigh_node->orig, if_incoming); 165 neigh_node = create_neighbor(orig_neigh_node,
166 orig_neigh_node,
167 orig_neigh_node->orig,
168 if_incoming);
169 /* create_neighbor failed, return 0 */
170 if (!neigh_node)
171 return 0;
272 } 172 }
273 173
274 orig_node->last_valid = jiffies; 174 orig_node->last_valid = jiffies;
275 175
276 /* pay attention to not get a value bigger than 100 % */ 176 /* pay attention to not get a value bigger than 100 % */
277 total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > neigh_node->real_packet_count ? neigh_node->real_packet_count : orig_neigh_node->bcast_own_sum[if_incoming->if_num]); 177 total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] >
178 neigh_node->real_packet_count ?
179 neigh_node->real_packet_count :
180 orig_neigh_node->bcast_own_sum[if_incoming->if_num]);
278 181
279 /* if we have too few packets (too less data) we set tq_own to zero */ 182 /* if we have too few packets (too less data) we set tq_own to zero */
280 /* if we receive too few packets it is not considered bidirectional */ 183 /* if we receive too few packets it is not considered bidirectional */
281 if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) 184 if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) ||
185 (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM))
282 orig_neigh_node->tq_own = 0; 186 orig_neigh_node->tq_own = 0;
283 else 187 else
284 /* neigh_node->real_packet_count is never zero as we only purge old information when getting new information */ 188 /* neigh_node->real_packet_count is never zero as we
285 orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / neigh_node->real_packet_count; 189 * only purge old information when getting new
190 * information */
191 orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) /
192 neigh_node->real_packet_count;
286 193
287 /* 194 /*
288 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE 195 * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does
289 * this does affect the nearly-symmetric links only a little, 196 * affect the nearly-symmetric links only a little, but
290 * but punishes asymmetric links more. 197 * punishes asymmetric links more. This will give a value
291 * this will give a value between 0 and TQ_MAX_VALUE 198 * between 0 and TQ_MAX_VALUE
292 */ 199 */
293 orig_neigh_node->tq_asym_penalty = TQ_MAX_VALUE - (TQ_MAX_VALUE * 200 orig_neigh_node->tq_asym_penalty =
294 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 201 TQ_MAX_VALUE -
295 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * 202 (TQ_MAX_VALUE *
296 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / 203 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
297 (TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE * TQ_LOCAL_WINDOW_SIZE); 204 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) *
298 205 (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) /
299 batman_packet->tq = ((batman_packet->tq * orig_neigh_node->tq_own * orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE)); 206 (TQ_LOCAL_WINDOW_SIZE *
300 207 TQ_LOCAL_WINDOW_SIZE *
301 debug_log(LOG_TYPE_BATMAN, "bidirectional: orig = %-15s neigh = %-15s => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n", 208 TQ_LOCAL_WINDOW_SIZE);
302 orig_str, neigh_str, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq); 209
303 210 batman_packet->tq = ((batman_packet->tq *
304 /* if link has the minimum required transmission quality consider it bidirectional */ 211 orig_neigh_node->tq_own *
212 orig_neigh_node->tq_asym_penalty) /
213 (TQ_MAX_VALUE * TQ_MAX_VALUE));
214
215 bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n",
216 orig_node->orig, orig_neigh_node->orig, total_count,
217 neigh_node->real_packet_count, orig_neigh_node->tq_own,
218 orig_neigh_node->tq_asym_penalty, batman_packet->tq);
219
220 /* if link has the minimum required transmission quality
221 * consider it bidirectional */
305 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) 222 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
306 return 1; 223 return 1;
307 224
308 return 0; 225 return 0;
309} 226}
310 227
311static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming, unsigned char *hna_buff, int hna_buff_len, char is_duplicate) 228static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr,
229 struct batman_packet *batman_packet,
230 struct batman_if *if_incoming,
231 unsigned char *hna_buff, int hna_buff_len,
232 char is_duplicate)
312{ 233{
313 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 234 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
314 int tmp_hna_buff_len; 235 int tmp_hna_buff_len;
315 236
316 debug_log(LOG_TYPE_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n"); 237 bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n");
317 238
318 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 239 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
319 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) { 240 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
241 (tmp_neigh_node->if_incoming == if_incoming)) {
320 neigh_node = tmp_neigh_node; 242 neigh_node = tmp_neigh_node;
321 continue; 243 continue;
322 } 244 }
@@ -324,19 +246,34 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
324 if (is_duplicate) 246 if (is_duplicate)
325 continue; 247 continue;
326 248
327 ring_buffer_set(tmp_neigh_node->tq_recv, &tmp_neigh_node->tq_index, 0); 249 ring_buffer_set(tmp_neigh_node->tq_recv,
328 tmp_neigh_node->tq_avg = ring_buffer_avg(tmp_neigh_node->tq_recv); 250 &tmp_neigh_node->tq_index, 0);
251 tmp_neigh_node->tq_avg =
252 ring_buffer_avg(tmp_neigh_node->tq_recv);
329 } 253 }
330 254
331 if (neigh_node == NULL) 255 if (!neigh_node) {
332 neigh_node = create_neighbor(orig_node, get_orig_node(ethhdr->h_source), ethhdr->h_source, if_incoming); 256 struct orig_node *orig_tmp;
333 else 257
334 debug_log(LOG_TYPE_BATMAN, "Updating existing last-hop neighbour of originator\n"); 258 orig_tmp = get_orig_node(ethhdr->h_source);
259 if (!orig_tmp)
260 return;
261
262 neigh_node = create_neighbor(orig_node,
263 orig_tmp,
264 ethhdr->h_source, if_incoming);
265 if (!neigh_node)
266 return;
267 } else
268 bat_dbg(DBG_BATMAN,
269 "Updating existing last-hop neighbor of originator\n");
335 270
336 orig_node->flags = batman_packet->flags; 271 orig_node->flags = batman_packet->flags;
337 neigh_node->last_valid = jiffies; 272 neigh_node->last_valid = jiffies;
338 273
339 ring_buffer_set(neigh_node->tq_recv, &neigh_node->tq_index, batman_packet->tq); 274 ring_buffer_set(neigh_node->tq_recv,
275 &neigh_node->tq_index,
276 batman_packet->tq);
340 neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); 277 neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
341 278
342 if (!is_duplicate) { 279 if (!is_duplicate) {
@@ -344,9 +281,11 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
344 neigh_node->last_ttl = batman_packet->ttl; 281 neigh_node->last_ttl = batman_packet->ttl;
345 } 282 }
346 283
347 tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? batman_packet->num_hna * ETH_ALEN : hna_buff_len); 284 tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ?
285 batman_packet->num_hna * ETH_ALEN : hna_buff_len);
348 286
349 /* if this neighbor already is our next hop there is nothing to change */ 287 /* if this neighbor already is our next hop there is nothing
288 * to change */
350 if (orig_node->router == neigh_node) 289 if (orig_node->router == neigh_node)
351 goto update_hna; 290 goto update_hna;
352 291
@@ -355,11 +294,12 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
355 (orig_node->router->tq_avg > neigh_node->tq_avg)) 294 (orig_node->router->tq_avg > neigh_node->tq_avg))
356 goto update_hna; 295 goto update_hna;
357 296
358 /* if the TQ is the same and the link not more symetric we won't consider it either */ 297 /* if the TQ is the same and the link not more symetric we
298 * won't consider it either */
359 if ((orig_node->router) && 299 if ((orig_node->router) &&
360 ((neigh_node->tq_avg == orig_node->router->tq_avg) && 300 ((neigh_node->tq_avg == orig_node->router->tq_avg) &&
361 (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] >= 301 (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num]
362 neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) 302 >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num])))
363 goto update_hna; 303 goto update_hna;
364 304
365 update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len); 305 update_routes(orig_node, neigh_node, hna_buff, tmp_hna_buff_len);
@@ -367,60 +307,72 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, stru
367 307
368update_hna: 308update_hna:
369 update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len); 309 update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len);
370 return;
371} 310}
372 311
373static char count_real_packets(struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming) 312static char count_real_packets(struct ethhdr *ethhdr,
313 struct batman_packet *batman_packet,
314 struct batman_if *if_incoming)
374{ 315{
375 struct orig_node *orig_node; 316 struct orig_node *orig_node;
376 struct neigh_node *tmp_neigh_node; 317 struct neigh_node *tmp_neigh_node;
377 char is_duplicate = 0; 318 char is_duplicate = 0;
378 319 uint16_t seq_diff;
379 320
380 orig_node = get_orig_node(batman_packet->orig); 321 orig_node = get_orig_node(batman_packet->orig);
381 if (orig_node == NULL) 322 if (orig_node == NULL)
382 return 0; 323 return 0;
383 324
384
385 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { 325 list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
386 326
387 if (!is_duplicate) 327 if (!is_duplicate)
388 is_duplicate = get_bit_status(tmp_neigh_node->real_bits, orig_node->last_real_seqno, batman_packet->seqno); 328 is_duplicate =
389 329 get_bit_status(tmp_neigh_node->real_bits,
390 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) 330 orig_node->last_real_seqno,
391 bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 1); 331 batman_packet->seqno);
332 seq_diff = batman_packet->seqno - orig_node->last_real_seqno;
333 if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) &&
334 (tmp_neigh_node->if_incoming == if_incoming))
335 bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 1);
392 else 336 else
393 bit_get_packet(tmp_neigh_node->real_bits, batman_packet->seqno - orig_node->last_real_seqno, 0); 337 bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 0);
394 338
395 tmp_neigh_node->real_packet_count = bit_packet_count(tmp_neigh_node->real_bits); 339 tmp_neigh_node->real_packet_count =
340 bit_packet_count(tmp_neigh_node->real_bits);
396 } 341 }
397 342
398 if (!is_duplicate) { 343 if (!is_duplicate) {
399 debug_log(LOG_TYPE_BATMAN, "updating last_seqno: old %d, new %d \n", orig_node->last_real_seqno, batman_packet->seqno); 344 bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d \n",
345 orig_node->last_real_seqno, batman_packet->seqno);
400 orig_node->last_real_seqno = batman_packet->seqno; 346 orig_node->last_real_seqno = batman_packet->seqno;
401 } 347 }
402 348
403 return is_duplicate; 349 return is_duplicate;
404} 350}
405 351
406void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming) 352void receive_bat_packet(struct ethhdr *ethhdr,
353 struct batman_packet *batman_packet,
354 unsigned char *hna_buff, int hna_buff_len,
355 struct batman_if *if_incoming)
407{ 356{
408 struct batman_if *batman_if; 357 struct batman_if *batman_if;
409 struct orig_node *orig_neigh_node, *orig_node; 358 struct orig_node *orig_neigh_node, *orig_node;
410 char orig_str[ETH_STR_LEN], prev_sender_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN];
411 char has_directlink_flag; 359 char has_directlink_flag;
412 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0, is_broadcast = 0, is_bidirectional, is_single_hop_neigh, is_duplicate; 360 char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
361 char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
362 char is_duplicate;
413 unsigned short if_incoming_seqno; 363 unsigned short if_incoming_seqno;
414 364
415 /* Silently drop when the batman packet is actually not a correct packet. 365 /* Silently drop when the batman packet is actually not a
366 * correct packet.
416 * 367 *
417 * This might happen if a packet is padded (e.g. Ethernet has a 368 * This might happen if a packet is padded (e.g. Ethernet has a
418 * minimum frame length of 64 byte) and the aggregation interprets 369 * minimum frame length of 64 byte) and the aggregation interprets
419 * it as an additional length. 370 * it as an additional length.
420 * 371 *
421 * TODO: A more sane solution would be to have a bit in the batman_packet 372 * TODO: A more sane solution would be to have a bit in the
422 * to detect whether the packet is the last packet in an aggregation. 373 * batman_packet to detect whether the packet is the last
423 * Here we expect that the padding is always zero (or not 0x01) 374 * packet in an aggregation. Here we expect that the padding
375 * is always zero (or not 0x01)
424 */ 376 */
425 if (batman_packet->packet_type != BAT_PACKET) 377 if (batman_packet->packet_type != BAT_PACKET)
426 return; 378 return;
@@ -428,27 +380,31 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack
428 /* could be changed by schedule_own_packet() */ 380 /* could be changed by schedule_own_packet() */
429 if_incoming_seqno = atomic_read(&if_incoming->seqno); 381 if_incoming_seqno = atomic_read(&if_incoming->seqno);
430 382
431 addr_to_string(orig_str, batman_packet->orig);
432 addr_to_string(prev_sender_str, batman_packet->prev_sender);
433 addr_to_string(neigh_str, ethhdr->h_source);
434
435 has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0); 383 has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0);
436 384
437 is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0); 385 is_single_hop_neigh = (compare_orig(ethhdr->h_source,
386 batman_packet->orig) ? 1 : 0);
438 387
439 debug_log(LOG_TYPE_BATMAN, "Received BATMAN packet via NB: %s, IF: %s [%s] (from OG: %s, via prev OG: %s, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", neigh_str, if_incoming->dev, if_incoming->addr_str, orig_str, prev_sender_str, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, batman_packet->version, has_directlink_flag); 388 bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n",
389 ethhdr->h_source, if_incoming->dev, if_incoming->addr_str,
390 batman_packet->orig, batman_packet->prev_sender,
391 batman_packet->seqno, batman_packet->tq, batman_packet->ttl,
392 batman_packet->version, has_directlink_flag);
440 393
441 list_for_each_entry_rcu(batman_if, &if_list, list) { 394 list_for_each_entry_rcu(batman_if, &if_list, list) {
442 if (batman_if->if_active != IF_ACTIVE) 395 if (batman_if->if_active != IF_ACTIVE)
443 continue; 396 continue;
444 397
445 if (compare_orig(ethhdr->h_source, batman_if->net_dev->dev_addr)) 398 if (compare_orig(ethhdr->h_source,
399 batman_if->net_dev->dev_addr))
446 is_my_addr = 1; 400 is_my_addr = 1;
447 401
448 if (compare_orig(batman_packet->orig, batman_if->net_dev->dev_addr)) 402 if (compare_orig(batman_packet->orig,
403 batman_if->net_dev->dev_addr))
449 is_my_orig = 1; 404 is_my_orig = 1;
450 405
451 if (compare_orig(batman_packet->prev_sender, batman_if->net_dev->dev_addr)) 406 if (compare_orig(batman_packet->prev_sender,
407 batman_if->net_dev->dev_addr))
452 is_my_oldorig = 1; 408 is_my_oldorig = 1;
453 409
454 if (compare_orig(ethhdr->h_source, broadcastAddr)) 410 if (compare_orig(ethhdr->h_source, broadcastAddr))
@@ -456,44 +412,61 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack
456 } 412 }
457 413
458 if (batman_packet->version != COMPAT_VERSION) { 414 if (batman_packet->version != COMPAT_VERSION) {
459 debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version); 415 bat_dbg(DBG_BATMAN,
416 "Drop packet: incompatible batman version (%i)\n",
417 batman_packet->version);
460 return; 418 return;
461 } 419 }
462 420
463 if (is_my_addr) { 421 if (is_my_addr) {
464 debug_log(LOG_TYPE_BATMAN, "Drop packet: received my own broadcast (sender: %s) \n", neigh_str); 422 bat_dbg(DBG_BATMAN,
423 "Drop packet: received my own broadcast (sender: %pM)\n",
424 ethhdr->h_source);
465 return; 425 return;
466 } 426 }
467 427
468 if (is_broadcast) { 428 if (is_broadcast) {
469 debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %s) \n", neigh_str); 429 bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM) \n", ethhdr->h_source);
470 return; 430 return;
471 } 431 }
472 432
473 if (is_my_orig) { 433 if (is_my_orig) {
434 TYPE_OF_WORD *word;
435 int offset;
436
474 orig_neigh_node = get_orig_node(ethhdr->h_source); 437 orig_neigh_node = get_orig_node(ethhdr->h_source);
475 438
476 /* neighbour has to indicate direct link and it has to come via the corresponding interface */ 439 if (!orig_neigh_node)
477 /* if received seqno equals last send seqno save new seqno for bidirectional check */ 440 return;
478 if (has_directlink_flag && compare_orig(if_incoming->net_dev->dev_addr, batman_packet->orig) && 441
479 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { 442 /* neighbor has to indicate direct link and it has to
480 bit_mark((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS]), 0); 443 * come via the corresponding interface */
481 orig_neigh_node->bcast_own_sum[if_incoming->if_num] = bit_packet_count((TYPE_OF_WORD *)&(orig_neigh_node->bcast_own[if_incoming->if_num * NUM_WORDS])); 444 /* if received seqno equals last send seqno save new
445 * seqno for bidirectional check */
446 if (has_directlink_flag &&
447 compare_orig(if_incoming->net_dev->dev_addr,
448 batman_packet->orig) &&
449 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
450 offset = if_incoming->if_num * NUM_WORDS;
451 word = &(orig_neigh_node->bcast_own[offset]);
452 bit_mark(word, 0);
453 orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
454 bit_packet_count(word);
482 } 455 }
483 456
484 debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet from myself (via neighbour) \n"); 457 bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor) \n");
485 return; 458 return;
486 } 459 }
487 460
488 if (batman_packet->tq == 0) { 461 if (batman_packet->tq == 0) {
489 count_real_packets(ethhdr, batman_packet, if_incoming); 462 count_real_packets(ethhdr, batman_packet, if_incoming);
490 463
491 debug_log(LOG_TYPE_BATMAN, "Drop packet: originator packet with tq equal 0 \n"); 464 bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0 \n");
492 return; 465 return;
493 } 466 }
494 467
495 if (is_my_oldorig) { 468 if (is_my_oldorig) {
496 debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %s) \n", neigh_str); 469 bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM) \n", ethhdr->h_source);
497 return; 470 return;
498 } 471 }
499 472
@@ -504,507 +477,502 @@ void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_pack
504 return; 477 return;
505 478
506 /* avoid temporary routing loops */ 479 /* avoid temporary routing loops */
507 if ((orig_node->router) && (orig_node->router->orig_node->router) && 480 if ((orig_node->router) &&
508 (compare_orig(orig_node->router->addr, batman_packet->prev_sender)) && 481 (orig_node->router->orig_node->router) &&
482 (compare_orig(orig_node->router->addr,
483 batman_packet->prev_sender)) &&
509 !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && 484 !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) &&
510 (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) { 485 (compare_orig(orig_node->router->addr,
511 debug_log(LOG_TYPE_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %s) \n", neigh_str); 486 orig_node->router->orig_node->router->addr))) {
487 bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM) \n", ethhdr->h_source);
512 return; 488 return;
513 } 489 }
514 490
515 /* if sender is a direct neighbor the sender mac equals originator mac */ 491 /* if sender is a direct neighbor the sender mac equals
516 orig_neigh_node = (is_single_hop_neigh ? orig_node : get_orig_node(ethhdr->h_source)); 492 * originator mac */
493 orig_neigh_node = (is_single_hop_neigh ?
494 orig_node : get_orig_node(ethhdr->h_source));
517 if (orig_neigh_node == NULL) 495 if (orig_neigh_node == NULL)
518 return; 496 return;
519 497
520 /* drop packet if sender is not a direct neighbor and if we don't route towards it */ 498 /* drop packet if sender is not a direct neighbor and if we
521 if (!is_single_hop_neigh && (orig_neigh_node->router == NULL)) { 499 * don't route towards it */
522 debug_log(LOG_TYPE_BATMAN, "Drop packet: OGM via unknown neighbor! \n"); 500 if (!is_single_hop_neigh &&
501 (orig_neigh_node->router == NULL)) {
502 bat_dbg(DBG_BATMAN, "Drop packet: OGM via unknown neighbor!\n");
523 return; 503 return;
524 } 504 }
525 505
526 is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node, batman_packet, if_incoming); 506 is_bidirectional = isBidirectionalNeigh(orig_node, orig_neigh_node,
507 batman_packet, if_incoming);
527 508
528 /* update ranking if it is not a duplicate or has the same seqno and similar ttl as the non-duplicate */ 509 /* update ranking if it is not a duplicate or has the same
529 if (is_bidirectional && (!is_duplicate || 510 * seqno and similar ttl as the non-duplicate */
530 ((orig_node->last_real_seqno == batman_packet->seqno) && 511 if (is_bidirectional &&
531 (orig_node->last_ttl - 3 <= batman_packet->ttl)))) 512 (!is_duplicate ||
532 update_orig(orig_node, ethhdr, batman_packet, if_incoming, hna_buff, hna_buff_len, is_duplicate); 513 ((orig_node->last_real_seqno == batman_packet->seqno) &&
514 (orig_node->last_ttl - 3 <= batman_packet->ttl))))
515 update_orig(orig_node, ethhdr, batman_packet,
516 if_incoming, hna_buff, hna_buff_len, is_duplicate);
533 517
534 /* is single hop (direct) neighbour */ 518 /* is single hop (direct) neighbor */
535 if (is_single_hop_neigh) { 519 if (is_single_hop_neigh) {
536 520
537 /* mark direct link on incoming interface */ 521 /* mark direct link on incoming interface */
538 schedule_forward_packet(orig_node, ethhdr, batman_packet, 1, hna_buff_len, if_incoming); 522 schedule_forward_packet(orig_node, ethhdr, batman_packet,
523 1, hna_buff_len, if_incoming);
539 524
540 debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast neighbour packet with direct link flag \n"); 525 bat_dbg(DBG_BATMAN, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n");
541 return; 526 return;
542 } 527 }
543 528
544 /* multihop originator */ 529 /* multihop originator */
545 if (!is_bidirectional) { 530 if (!is_bidirectional) {
546 debug_log(LOG_TYPE_BATMAN, "Drop packet: not received via bidirectional link\n"); 531 bat_dbg(DBG_BATMAN,
532 "Drop packet: not received via bidirectional link\n");
547 return; 533 return;
548 } 534 }
549 535
550 if (is_duplicate) { 536 if (is_duplicate) {
551 debug_log(LOG_TYPE_BATMAN, "Drop packet: duplicate packet received\n"); 537 bat_dbg(DBG_BATMAN, "Drop packet: duplicate packet received\n");
552 return; 538 return;
553 } 539 }
554 540
555 debug_log(LOG_TYPE_BATMAN, "Forwarding packet: rebroadcast originator packet \n"); 541 bat_dbg(DBG_BATMAN,
556 schedule_forward_packet(orig_node, ethhdr, batman_packet, 0, hna_buff_len, if_incoming); 542 "Forwarding packet: rebroadcast originator packet\n");
543 schedule_forward_packet(orig_node, ethhdr, batman_packet,
544 0, hna_buff_len, if_incoming);
557} 545}
558 546
559void purge_orig(struct work_struct *work) 547int recv_bat_packet(struct sk_buff *skb,
548 struct batman_if *batman_if)
560{ 549{
561 struct list_head *list_pos, *list_pos_tmp; 550 struct ethhdr *ethhdr;
562 struct hash_it_t *hashit = NULL; 551 unsigned long flags;
563 struct orig_node *orig_node; 552
564 struct neigh_node *neigh_node, *best_neigh_node; 553 /* drop packet if it has not necessary minimum size */
565 char orig_str[ETH_STR_LEN], neigh_str[ETH_STR_LEN], neigh_purged; 554 if (skb_headlen(skb) < sizeof(struct batman_packet))
566 555 return NET_RX_DROP;
567 spin_lock(&orig_hash_lock); 556
568 557 ethhdr = (struct ethhdr *)skb_mac_header(skb);
569 /* for all origins... */ 558
570 while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { 559 /* packet with broadcast indication but unicast recipient */
571 560 if (!is_bcast(ethhdr->h_dest))
572 orig_node = hashit->bucket->data; 561 return NET_RX_DROP;
573 addr_to_string(orig_str, orig_node->orig); 562
574 563 /* packet with broadcast sender address */
575 if (time_after(jiffies, orig_node->last_valid + ((2 * PURGE_TIMEOUT * HZ) / 1000))) { 564 if (is_bcast(ethhdr->h_source))
576 565 return NET_RX_DROP;
577 debug_log(LOG_TYPE_BATMAN, "Originator timeout: originator %s, last_valid %u \n", orig_str, (orig_node->last_valid / HZ)); 566
578 567 spin_lock_irqsave(&orig_hash_lock, flags);
579 hash_remove_bucket(orig_hash, hashit); 568 /* TODO: we use headlen instead of "length", because
580 free_orig_node(orig_node); 569 * only this data is paged in. */
581 570 /* TODO: is another skb_copy needed here? there will be
582 } else { 571 * written on the data, but nobody (?) should further use
583 572 * this data */
584 best_neigh_node = NULL; 573 receive_aggr_bat_packet(ethhdr,
585 neigh_purged = 0; 574 skb->data,
586 575 skb_headlen(skb),
587 /* for all neighbours towards this originator ... */ 576 batman_if);
588 list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { 577 spin_unlock_irqrestore(&orig_hash_lock, flags);
589 neigh_node = list_entry(list_pos, struct neigh_node, list); 578
590 579 kfree_skb(skb);
591 if (time_after(jiffies, neigh_node->last_valid + ((PURGE_TIMEOUT * HZ) / 1000))) { 580 return NET_RX_SUCCESS;
592 581}
593 addr_to_string(neigh_str, neigh_node->addr);
594 debug_log(LOG_TYPE_BATMAN, "Neighbour timeout: originator %s, neighbour: %s, last_valid %u \n", orig_str, neigh_str, (neigh_node->last_valid / HZ));
595
596 neigh_purged = 1;
597 list_del(list_pos);
598 kfree(neigh_node);
599
600 } else {
601
602 if ((best_neigh_node == NULL) || (neigh_node->tq_avg > best_neigh_node->tq_avg))
603 best_neigh_node = neigh_node;
604
605 }
606
607 }
608 582
609 if (neigh_purged) 583static int recv_my_icmp_packet(struct sk_buff *skb)
610 update_routes(orig_node, best_neigh_node, orig_node->hna_buff, orig_node->hna_buff_len); 584{
585 struct orig_node *orig_node;
586 struct icmp_packet *icmp_packet;
587 struct ethhdr *ethhdr;
588 struct sk_buff *skb_old;
589 struct batman_if *batman_if;
590 int ret;
591 unsigned long flags;
592 uint8_t dstaddr[ETH_ALEN];
611 593
612 } 594 icmp_packet = (struct icmp_packet *) skb->data;
595 ethhdr = (struct ethhdr *) skb_mac_header(skb);
613 596
597 /* add data to device queue */
598 if (icmp_packet->msg_type != ECHO_REQUEST) {
599 bat_device_receive_packet(icmp_packet);
600 return NET_RX_DROP;
614 } 601 }
615 602
616 spin_unlock(&orig_hash_lock); 603 /* answer echo request (ping) */
604 /* get routing information */
605 spin_lock_irqsave(&orig_hash_lock, flags);
606 orig_node = ((struct orig_node *)hash_find(orig_hash,
607 icmp_packet->orig));
608 ret = NET_RX_DROP;
609
610 if ((orig_node != NULL) &&
611 (orig_node->batman_if != NULL) &&
612 (orig_node->router != NULL)) {
613
614 /* don't lock while sending the packets ... we therefore
615 * copy the required data before sending */
616 batman_if = orig_node->batman_if;
617 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
618 spin_unlock_irqrestore(&orig_hash_lock, flags);
619
620 /* create a copy of the skb, if needed, to modify it. */
621 skb_old = NULL;
622 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
623 skb_old = skb;
624 skb = skb_copy(skb, GFP_ATOMIC);
625 if (!skb)
626 return NET_RX_DROP;
627 icmp_packet = (struct icmp_packet *) skb->data;
628 kfree_skb(skb_old);
629 }
617 630
618 start_purge_timer(); 631 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
619} 632 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
633 icmp_packet->msg_type = ECHO_REPLY;
634 icmp_packet->ttl = TTL;
620 635
621static int receive_raw_packet(struct socket *raw_sock, unsigned char *packet_buff, int packet_buff_len) 636 send_skb_packet(skb, batman_if, dstaddr);
622{ 637 ret = NET_RX_SUCCESS;
623 struct kvec iov;
624 struct msghdr msg;
625 638
626 iov.iov_base = packet_buff; 639 } else
627 iov.iov_len = packet_buff_len; 640 spin_unlock_irqrestore(&orig_hash_lock, flags);
628 641
629 msg.msg_flags = MSG_DONTWAIT; /* non-blocking */ 642 return ret;
630 msg.msg_name = NULL;
631 msg.msg_namelen = 0;
632 msg.msg_control = NULL;
633
634 return kernel_recvmsg(raw_sock, &msg, &iov, 1, packet_buff_len, MSG_DONTWAIT);
635} 643}
636 644
637int packet_recv_thread(void *data) 645static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
638{ 646{
639 struct batman_if *batman_if;
640 struct ethhdr *ethhdr;
641 struct batman_packet *batman_packet;
642 struct unicast_packet *unicast_packet;
643 struct bcast_packet *bcast_packet;
644 struct icmp_packet *icmp_packet;
645 struct vis_packet *vis_packet;
646 struct orig_node *orig_node; 647 struct orig_node *orig_node;
647 unsigned char *packet_buff, src_str[ETH_STR_LEN], dst_str[ETH_STR_LEN]; 648 struct icmp_packet *icmp_packet;
648 int vis_info_len; 649 struct ethhdr *ethhdr;
649 int result; 650 struct sk_buff *skb_old;
650 651 struct batman_if *batman_if;
651 atomic_set(&data_ready_cond, 0); 652 int ret;
652 atomic_set(&exit_cond, 0); 653 unsigned long flags;
653 packet_buff = kmalloc(PACKBUFF_SIZE, GFP_KERNEL); 654 uint8_t dstaddr[ETH_ALEN];
654 if (!packet_buff) { 655
655 debug_log(LOG_TYPE_CRIT, "Could allocate memory for the packet buffer. :(\n"); 656 icmp_packet = (struct icmp_packet *)skb->data;
656 return -1; 657 ethhdr = (struct ethhdr *)skb_mac_header(skb);
658
659 /* send TTL exceeded if packet is an echo request (traceroute) */
660 if (icmp_packet->msg_type != ECHO_REQUEST) {
661 printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n",
662 icmp_packet->orig, icmp_packet->dst);
663 return NET_RX_DROP;
657 } 664 }
658 665
659 while ((!kthread_should_stop()) && (!atomic_read(&exit_cond))) { 666 /* get routing information */
660 667 spin_lock_irqsave(&orig_hash_lock, flags);
661 wait_event_interruptible(thread_wait, (atomic_read(&data_ready_cond) || atomic_read(&exit_cond))); 668 orig_node = ((struct orig_node *)
662 669 hash_find(orig_hash, icmp_packet->orig));
663 atomic_set(&data_ready_cond, 0); 670 ret = NET_RX_DROP;
664 671
665 if (kthread_should_stop() || atomic_read(&exit_cond)) 672 if ((orig_node != NULL) &&
666 break; 673 (orig_node->batman_if != NULL) &&
667 674 (orig_node->router != NULL)) {
668 /* we only want to safely traverse the list, hard-interfaces 675
669 * won't be deleted anyway as long as this thread runs. */ 676 /* don't lock while sending the packets ... we therefore
670 677 * copy the required data before sending */
671 rcu_read_lock(); 678 batman_if = orig_node->batman_if;
672 list_for_each_entry_rcu(batman_if, &if_list, list) { 679 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
673 rcu_read_unlock(); 680 spin_unlock_irqrestore(&orig_hash_lock, flags);
674 681
675 result = -1; 682 /* create a copy of the skb, if needed, to modify it. */
676 683 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
677 while (1) { 684 skb_old = skb;
678 if (batman_if->if_active != IF_ACTIVE) { 685 skb = skb_copy(skb, GFP_ATOMIC);
679 if (batman_if->if_active != IF_TO_BE_ACTIVATED) 686 if (!skb)
680 debug_log(LOG_TYPE_NOTICE, 687 return NET_RX_DROP;
681 "Could not read from deactivated interface %s!\n", 688 icmp_packet = (struct icmp_packet *) skb->data;
682 batman_if->dev); 689 kfree_skb(skb_old);
683 690 }
684 if (batman_if->raw_sock)
685 receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
686 result = 0;
687 break;
688 }
689
690 result = receive_raw_packet(batman_if->raw_sock, packet_buff, PACKBUFF_SIZE);
691 if (result <= 0)
692 break;
693
694 if (result < sizeof(struct ethhdr) + 2)
695 continue;
696
697 ethhdr = (struct ethhdr *)packet_buff;
698 batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ethhdr));
699
700 if (batman_packet->version != COMPAT_VERSION) {
701 debug_log(LOG_TYPE_BATMAN, "Drop packet: incompatible batman version (%i) \n", batman_packet->version);
702 continue;
703 }
704
705 switch (batman_packet->packet_type) {
706 /* batman originator packet */
707 case BAT_PACKET:
708 /* packet with broadcast indication but unicast recipient */
709 if (!is_bcast(ethhdr->h_dest))
710 continue;
711
712 /* packet with broadcast sender address */
713 if (is_bcast(ethhdr->h_source))
714 continue;
715
716 /* drop packet if it has not at least one batman packet as payload */
717 if (result < sizeof(struct ethhdr) + sizeof(struct batman_packet))
718 continue;
719
720 spin_lock(&orig_hash_lock);
721 receive_aggr_bat_packet(ethhdr,
722 packet_buff + sizeof(struct ethhdr),
723 result - sizeof(struct ethhdr),
724 batman_if);
725 spin_unlock(&orig_hash_lock);
726
727 break;
728
729 /* batman icmp packet */
730 case BAT_ICMP:
731 /* packet with unicast indication but broadcast recipient */
732 if (is_bcast(ethhdr->h_dest))
733 continue;
734
735 /* packet with broadcast sender address */
736 if (is_bcast(ethhdr->h_source))
737 continue;
738
739 /* not for me */
740 if (!is_my_mac(ethhdr->h_dest))
741 continue;
742
743 /* drop packet if it has not necessary minimum size */
744 if (result < sizeof(struct ethhdr) + sizeof(struct icmp_packet))
745 continue;
746
747 icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ethhdr));
748
749 /* packet for me */
750 if (is_my_mac(icmp_packet->dst)) {
751
752 /* add data to device queue */
753 if (icmp_packet->msg_type != ECHO_REQUEST) {
754 bat_device_receive_packet(icmp_packet);
755 continue;
756 }
757
758 /* answer echo request (ping) */
759 /* get routing information */
760 spin_lock(&orig_hash_lock);
761 orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
762
763 if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
764
765 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
766 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
767 icmp_packet->msg_type = ECHO_REPLY;
768 icmp_packet->ttl = TTL;
769
770 send_raw_packet(packet_buff + sizeof(struct ethhdr),
771 result - sizeof(struct ethhdr),
772 orig_node->batman_if,
773 orig_node->router->addr);
774
775 }
776
777 spin_unlock(&orig_hash_lock);
778 continue;
779
780 }
781
782 /* TTL exceeded */
783 if (icmp_packet->ttl < 2) {
784
785 addr_to_string(src_str, icmp_packet->orig);
786 addr_to_string(dst_str, icmp_packet->dst);
787
788 debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
789
790 /* send TTL exceeded if packet is an echo request (traceroute) */
791 if (icmp_packet->msg_type != ECHO_REQUEST)
792 continue;
793
794 /* get routing information */
795 spin_lock(&orig_hash_lock);
796 orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->orig));
797
798 if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
799
800 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
801 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
802 icmp_packet->msg_type = TTL_EXCEEDED;
803 icmp_packet->ttl = TTL;
804
805 send_raw_packet(packet_buff + sizeof(struct ethhdr),
806 result - sizeof(struct ethhdr),
807 orig_node->batman_if,
808 orig_node->router->addr);
809 691
810 } 692 memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
693 memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN);
694 icmp_packet->msg_type = TTL_EXCEEDED;
695 icmp_packet->ttl = TTL;
811 696
812 spin_unlock(&orig_hash_lock); 697 send_skb_packet(skb, batman_if, dstaddr);
813 continue; 698 ret = NET_RX_SUCCESS;
814 699
815 } 700 } else
701 spin_unlock_irqrestore(&orig_hash_lock, flags);
816 702
817 /* get routing information */ 703 return ret;
818 spin_lock(&orig_hash_lock); 704}
819 orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet->dst));
820 705
821 if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
822 706
823 /* decrement ttl */ 707int recv_icmp_packet(struct sk_buff *skb)
824 icmp_packet->ttl--; 708{
709 struct icmp_packet *icmp_packet;
710 struct ethhdr *ethhdr;
711 struct orig_node *orig_node;
712 struct sk_buff *skb_old;
713 struct batman_if *batman_if;
714 int hdr_size = sizeof(struct icmp_packet);
715 int ret;
716 unsigned long flags;
717 uint8_t dstaddr[ETH_ALEN];
718
719 /* drop packet if it has not necessary minimum size */
720 if (skb_headlen(skb) < hdr_size)
721 return NET_RX_DROP;
722
723 ethhdr = (struct ethhdr *)skb_mac_header(skb);
724
725 /* packet with unicast indication but broadcast recipient */
726 if (is_bcast(ethhdr->h_dest))
727 return NET_RX_DROP;
728
729 /* packet with broadcast sender address */
730 if (is_bcast(ethhdr->h_source))
731 return NET_RX_DROP;
732
733 /* not for me */
734 if (!is_my_mac(ethhdr->h_dest))
735 return NET_RX_DROP;
736
737 icmp_packet = (struct icmp_packet *) skb->data;
738
739 /* packet for me */
740 if (is_my_mac(icmp_packet->dst))
741 return recv_my_icmp_packet(skb);
742
743 /* TTL exceeded */
744 if (icmp_packet->ttl < 2)
745 return recv_icmp_ttl_exceeded(skb);
746
747 ret = NET_RX_DROP;
748
749 /* get routing information */
750 spin_lock_irqsave(&orig_hash_lock, flags);
751 orig_node = ((struct orig_node *)
752 hash_find(orig_hash, icmp_packet->dst));
753
754 if ((orig_node != NULL) &&
755 (orig_node->batman_if != NULL) &&
756 (orig_node->router != NULL)) {
757
758 /* don't lock while sending the packets ... we therefore
759 * copy the required data before sending */
760 batman_if = orig_node->batman_if;
761 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
762 spin_unlock_irqrestore(&orig_hash_lock, flags);
763
764 /* create a copy of the skb, if needed, to modify it. */
765 if (!skb_clone_writable(skb, sizeof(struct icmp_packet))) {
766 skb_old = skb;
767 skb = skb_copy(skb, GFP_ATOMIC);
768 if (!skb)
769 return NET_RX_DROP;
770 icmp_packet = (struct icmp_packet *) skb->data;
771 kfree_skb(skb_old);
772 }
825 773
826 /* route it */ 774 /* decrement ttl */
827 send_raw_packet(packet_buff + sizeof(struct ethhdr), 775 icmp_packet->ttl--;
828 result - sizeof(struct ethhdr),
829 orig_node->batman_if,
830 orig_node->router->addr);
831 }
832 776
833 spin_unlock(&orig_hash_lock); 777 /* route it */
834 break; 778 send_skb_packet(skb, batman_if, dstaddr);
779 ret = NET_RX_SUCCESS;
835 780
836 /* unicast packet */ 781 } else
837 case BAT_UNICAST: 782 spin_unlock_irqrestore(&orig_hash_lock, flags);
838 /* packet with unicast indication but broadcast recipient */
839 if (is_bcast(ethhdr->h_dest))
840 continue;
841 783
842 /* packet with broadcast sender address */ 784 return ret;
843 if (is_bcast(ethhdr->h_source)) 785}
844 continue;
845 786
846 /* not for me */ 787int recv_unicast_packet(struct sk_buff *skb)
847 if (!is_my_mac(ethhdr->h_dest)) 788{
848 continue; 789 struct unicast_packet *unicast_packet;
790 struct orig_node *orig_node;
791 struct ethhdr *ethhdr;
792 struct batman_if *batman_if;
793 struct sk_buff *skb_old;
794 uint8_t dstaddr[ETH_ALEN];
795 int hdr_size = sizeof(struct unicast_packet);
796 int ret;
797 unsigned long flags;
849 798
850 /* drop packet if it has not necessary minimum size */ 799 /* drop packet if it has not necessary minimum size */
851 if (result < sizeof(struct ethhdr) + sizeof(struct unicast_packet)) 800 if (skb_headlen(skb) < hdr_size)
852 continue; 801 return NET_RX_DROP;
853 802
854 unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ethhdr)); 803 ethhdr = (struct ethhdr *) skb_mac_header(skb);
855 804
856 /* packet for me */ 805 /* packet with unicast indication but broadcast recipient */
857 if (is_my_mac(unicast_packet->dest)) { 806 if (is_bcast(ethhdr->h_dest))
807 return NET_RX_DROP;
858 808
859 interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct unicast_packet), result - sizeof(struct ethhdr) - sizeof(struct unicast_packet)); 809 /* packet with broadcast sender address */
860 continue; 810 if (is_bcast(ethhdr->h_source))
811 return NET_RX_DROP;
861 812
862 } 813 /* not for me */
814 if (!is_my_mac(ethhdr->h_dest))
815 return NET_RX_DROP;
863 816
864 /* TTL exceeded */ 817 unicast_packet = (struct unicast_packet *) skb->data;
865 if (unicast_packet->ttl < 2) {
866 addr_to_string(src_str, ((struct ethhdr *)(unicast_packet + 1))->h_source);
867 addr_to_string(dst_str, unicast_packet->dest);
868 818
869 debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str); 819 /* packet for me */
870 continue; 820 if (is_my_mac(unicast_packet->dest)) {
871 } 821 interface_rx(skb, hdr_size);
822 return NET_RX_SUCCESS;
823 }
872 824
873 /* get routing information */ 825 /* TTL exceeded */
874 spin_lock(&orig_hash_lock); 826 if (unicast_packet->ttl < 2) {
875 orig_node = ((struct orig_node *)hash_find(orig_hash, unicast_packet->dest)); 827 printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n",
828 ethhdr->h_source, unicast_packet->dest);
829 return NET_RX_DROP;
830 }
876 831
877 if ((orig_node != NULL) && (orig_node->batman_if != NULL) && (orig_node->router != NULL)) { 832 ret = NET_RX_DROP;
878 /* decrement ttl */ 833 /* get routing information */
879 unicast_packet->ttl--; 834 spin_lock_irqsave(&orig_hash_lock, flags);
835 orig_node = ((struct orig_node *)
836 hash_find(orig_hash, unicast_packet->dest));
837
838 if ((orig_node != NULL) &&
839 (orig_node->batman_if != NULL) &&
840 (orig_node->router != NULL)) {
841
842 /* don't lock while sending the packets ... we therefore
843 * copy the required data before sending */
844 batman_if = orig_node->batman_if;
845 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
846 spin_unlock_irqrestore(&orig_hash_lock, flags);
847
848 /* create a copy of the skb, if needed, to modify it. */
849 if (!skb_clone_writable(skb, sizeof(struct unicast_packet))) {
850 skb_old = skb;
851 skb = skb_copy(skb, GFP_ATOMIC);
852 if (!skb)
853 return NET_RX_DROP;
854 unicast_packet = (struct unicast_packet *) skb->data;
855 kfree_skb(skb_old);
856 }
857 /* decrement ttl */
858 unicast_packet->ttl--;
880 859
881 /* route it */ 860 /* route it */
882 send_raw_packet(packet_buff + sizeof(struct ethhdr), 861 send_skb_packet(skb, batman_if, dstaddr);
883 result - sizeof(struct ethhdr), 862 ret = NET_RX_SUCCESS;
884 orig_node->batman_if,
885 orig_node->router->addr);
886 }
887 863
888 spin_unlock(&orig_hash_lock); 864 } else
889 break; 865 spin_unlock_irqrestore(&orig_hash_lock, flags);
890 866
891 /* broadcast packet */ 867 return ret;
892 case BAT_BCAST: 868}
893 /* packet with broadcast indication but unicast recipient */
894 if (!is_bcast(ethhdr->h_dest))
895 continue;
896 869
897 /* packet with broadcast sender address */
898 if (is_bcast(ethhdr->h_source))
899 continue;
900 870
901 /* drop packet if it has not necessary minimum size */ 871int recv_bcast_packet(struct sk_buff *skb)
902 if (result < sizeof(struct ethhdr) + sizeof(struct bcast_packet)) 872{
903 continue; 873 struct orig_node *orig_node;
874 struct bcast_packet *bcast_packet;
875 struct ethhdr *ethhdr;
876 int hdr_size = sizeof(struct bcast_packet);
877 unsigned long flags;
904 878
905 /* ignore broadcasts sent by myself */ 879 /* drop packet if it has not necessary minimum size */
906 if (is_my_mac(ethhdr->h_source)) 880 if (skb_headlen(skb) < hdr_size)
907 continue; 881 return NET_RX_DROP;
908 882
909 bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ethhdr)); 883 ethhdr = (struct ethhdr *)skb_mac_header(skb);
910 884
911 /* ignore broadcasts originated by myself */ 885 /* packet with broadcast indication but unicast recipient */
912 if (is_my_mac(bcast_packet->orig)) 886 if (!is_bcast(ethhdr->h_dest))
913 continue; 887 return NET_RX_DROP;
914 888
915 spin_lock(&orig_hash_lock); 889 /* packet with broadcast sender address */
916 orig_node = ((struct orig_node *)hash_find(orig_hash, bcast_packet->orig)); 890 if (is_bcast(ethhdr->h_source))
891 return NET_RX_DROP;
917 892
918 if (orig_node == NULL) { 893 /* ignore broadcasts sent by myself */
919 spin_unlock(&orig_hash_lock); 894 if (is_my_mac(ethhdr->h_source))
920 continue; 895 return NET_RX_DROP;
921 }
922 896
923 /* check flood history */ 897 bcast_packet = (struct bcast_packet *) skb->data;
924 if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohs(bcast_packet->seqno))) {
925 spin_unlock(&orig_hash_lock);
926 continue;
927 }
928 898
929 /* mark broadcast in flood history */ 899 /* ignore broadcasts originated by myself */
930 if (bit_get_packet(orig_node->bcast_bits, ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno, 1)) 900 if (is_my_mac(bcast_packet->orig))
931 orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno); 901 return NET_RX_DROP;
932 902
933 spin_unlock(&orig_hash_lock); 903 spin_lock_irqsave(&orig_hash_lock, flags);
904 orig_node = ((struct orig_node *)
905 hash_find(orig_hash, bcast_packet->orig));
934 906
935 /* broadcast for me */ 907 if (orig_node == NULL) {
936 interface_rx(soft_device, packet_buff + sizeof(struct ethhdr) + sizeof(struct bcast_packet), result - sizeof(struct ethhdr) - sizeof(struct bcast_packet)); 908 spin_unlock_irqrestore(&orig_hash_lock, flags);
909 return NET_RX_DROP;
910 }
937 911
938 /* rebroadcast packet */ 912 /* check flood history */
939 add_bcast_packet_to_list(packet_buff + sizeof(struct ethhdr), 913 if (get_bit_status(orig_node->bcast_bits,
940 result - sizeof(struct ethhdr)); 914 orig_node->last_bcast_seqno,
915 ntohs(bcast_packet->seqno))) {
916 spin_unlock_irqrestore(&orig_hash_lock, flags);
917 return NET_RX_DROP;
918 }
941 919
942 break; 920 /* mark broadcast in flood history */
921 if (bit_get_packet(orig_node->bcast_bits,
922 ntohs(bcast_packet->seqno) -
923 orig_node->last_bcast_seqno, 1))
924 orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
943 925
944 /* vis packet */ 926 spin_unlock_irqrestore(&orig_hash_lock, flags);
945 case BAT_VIS:
946 /* drop if too short. */
947 if (result < sizeof(struct ethhdr) + sizeof(struct vis_packet))
948 continue;
949 927
950 /* not for me */ 928 /* rebroadcast packet */
951 if (!is_my_mac(ethhdr->h_dest)) 929 add_bcast_packet_to_list(skb);
952 continue;
953 930
954 vis_packet = (struct vis_packet *)(packet_buff + sizeof(struct ethhdr)); 931 /* broadcast for me */
955 vis_info_len = result - sizeof(struct ethhdr) - sizeof(struct vis_packet); 932 interface_rx(skb, hdr_size);
956 933
957 /* ignore own packets */ 934 return NET_RX_SUCCESS;
958 if (is_my_mac(vis_packet->vis_orig)) 935}
959 continue;
960 936
961 if (is_my_mac(vis_packet->sender_orig)) 937int recv_vis_packet(struct sk_buff *skb)
962 continue; 938{
939 struct vis_packet *vis_packet;
940 struct ethhdr *ethhdr;
941 int hdr_size = sizeof(struct vis_packet);
963 942
964 switch (vis_packet->vis_type) { 943 if (skb_headlen(skb) < hdr_size)
965 case VIS_TYPE_SERVER_SYNC: 944 return NET_RX_DROP;
966 receive_server_sync_packet(vis_packet, vis_info_len);
967 break;
968 945
969 case VIS_TYPE_CLIENT_UPDATE: 946 vis_packet = (struct vis_packet *) skb->data;
970 receive_client_update_packet(vis_packet, vis_info_len); 947 ethhdr = (struct ethhdr *)skb_mac_header(skb);
971 break;
972 948
973 default: /* ignore unknown packet */ 949 /* not for me */
974 break; 950 if (!is_my_mac(ethhdr->h_dest))
975 } 951 return NET_RX_DROP;
976 952
977 break; 953 /* ignore own packets */
978 } 954 if (is_my_mac(vis_packet->vis_orig))
955 return NET_RX_DROP;
979 956
980 } 957 if (is_my_mac(vis_packet->sender_orig))
958 return NET_RX_DROP;
981 959
982 if ((result < 0) && (result != -EAGAIN)) 960 switch (vis_packet->vis_type) {
983 debug_log(LOG_TYPE_CRIT, "Could not receive packet from interface %s: %i\n", batman_if->dev, result); 961 case VIS_TYPE_SERVER_SYNC:
962 /* TODO: handle fragmented skbs properly */
963 receive_server_sync_packet(vis_packet, skb_headlen(skb));
964 break;
984 965
985 /* lock for the next iteration */ 966 case VIS_TYPE_CLIENT_UPDATE:
986 rcu_read_lock(); 967 /* TODO: handle fragmented skbs properly */
987 } 968 receive_client_update_packet(vis_packet, skb_headlen(skb));
988 rcu_read_unlock(); 969 break;
989 970
971 default: /* ignore unknown packet */
972 break;
990 } 973 }
991 kfree(packet_buff);
992
993 /* do not exit until kthread_stop() is actually called, otherwise it will wait for us
994 * forever. */
995 while (!kthread_should_stop())
996 schedule();
997
998 return 0;
999}
1000
1001void batman_data_ready(struct sock *sk, int len)
1002{
1003 void (*data_ready)(struct sock *, int) = sk->sk_user_data;
1004
1005 data_ready(sk, len);
1006 974
1007 atomic_set(&data_ready_cond, 1); 975 /* We take a copy of the data in the packet, so we should
1008 wake_up_interruptible(&thread_wait); 976 always free the skbuf. */
977 return NET_RX_DROP;
1009} 978}
1010
diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h
index 0123ea86debb..939b8d4f733c 100644
--- a/drivers/staging/batman-adv/routing.h
+++ b/drivers/staging/batman-adv/routing.h
@@ -22,13 +22,18 @@
22#include "types.h" 22#include "types.h"
23 23
24extern wait_queue_head_t thread_wait; 24extern wait_queue_head_t thread_wait;
25extern atomic_t exit_cond;
26 25
27int originator_init(void);
28void free_orig_node(void *data);
29void originator_free(void);
30void slide_own_bcast_window(struct batman_if *batman_if); 26void slide_own_bcast_window(struct batman_if *batman_if);
31void batman_data_ready(struct sock *sk, int len); 27void receive_bat_packet(struct ethhdr *ethhdr,
32void purge_orig(struct work_struct *work); 28 struct batman_packet *batman_packet,
33int packet_recv_thread(void *data); 29 unsigned char *hna_buff, int hna_buff_len,
34void receive_bat_packet(struct ethhdr *ethhdr, struct batman_packet *batman_packet, unsigned char *hna_buff, int hna_buff_len, struct batman_if *if_incoming); 30 struct batman_if *if_incoming);
31void update_routes(struct orig_node *orig_node,
32 struct neigh_node *neigh_node,
33 unsigned char *hna_buff, int hna_buff_len);
34int recv_icmp_packet(struct sk_buff *skb);
35int recv_unicast_packet(struct sk_buff *skb);
36int recv_bcast_packet(struct sk_buff *skb);
37int recv_vis_packet(struct sk_buff *skb);
38int recv_bat_packet(struct sk_buff *skb,
39 struct batman_if *batman_if);
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c
index eb617508cca4..2a9fac8c240e 100644
--- a/drivers/staging/batman-adv/send.c
+++ b/drivers/staging/batman-adv/send.c
@@ -21,16 +21,14 @@
21 21
22#include "main.h" 22#include "main.h"
23#include "send.h" 23#include "send.h"
24#include "log.h"
25#include "routing.h" 24#include "routing.h"
26#include "translation-table.h" 25#include "translation-table.h"
26#include "soft-interface.h"
27#include "hard-interface.h" 27#include "hard-interface.h"
28#include "types.h" 28#include "types.h"
29#include "vis.h" 29#include "vis.h"
30#include "aggregation.h" 30#include "aggregation.h"
31 31
32#include "compat.h"
33
34/* apply hop penalty for a normal link */ 32/* apply hop penalty for a normal link */
35static uint8_t hop_penalty(const uint8_t tq) 33static uint8_t hop_penalty(const uint8_t tq)
36{ 34{
@@ -59,51 +57,69 @@ static unsigned long forward_send_time(void)
59 return send_time; 57 return send_time;
60} 58}
61 59
62/* sends a raw packet. */ 60/* send out an already prepared packet to the given address via the
63void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, 61 * specified batman interface */
64 struct batman_if *batman_if, uint8_t *dst_addr) 62int send_skb_packet(struct sk_buff *skb,
63 struct batman_if *batman_if,
64 uint8_t *dst_addr)
65{ 65{
66 struct ethhdr *ethhdr; 66 struct ethhdr *ethhdr;
67 struct sk_buff *skb;
68 int retval;
69 char *data;
70 67
71 if (batman_if->if_active != IF_ACTIVE) 68 if (batman_if->if_active != IF_ACTIVE)
72 return; 69 goto send_skb_err;
70
71 if (unlikely(!batman_if->net_dev))
72 goto send_skb_err;
73 73
74 if (!(batman_if->net_dev->flags & IFF_UP)) { 74 if (!(batman_if->net_dev->flags & IFF_UP)) {
75 debug_log(LOG_TYPE_WARN, 75 printk(KERN_WARNING
76 "Interface %s is not up - can't send packet via that interface (IF_TO_BE_DEACTIVATED was here) !\n", 76 "batman-adv:Interface %s is not up - can't send packet via that interface!\n",
77 batman_if->dev); 77 batman_if->dev);
78 return; 78 goto send_skb_err;
79 } 79 }
80 80
81 skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr)); 81 /* push to the ethernet header. */
82 if (!skb) 82 if (my_skb_push(skb, sizeof(struct ethhdr)) < 0)
83 return; 83 goto send_skb_err;
84 data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
85 84
86 memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len); 85 skb_reset_mac_header(skb);
87 86
88 ethhdr = (struct ethhdr *) data; 87 ethhdr = (struct ethhdr *) skb_mac_header(skb);
89 memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN); 88 memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN);
90 memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); 89 memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
91 ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); 90 ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
92 91
93 skb_reset_mac_header(skb);
94 skb_set_network_header(skb, ETH_HLEN); 92 skb_set_network_header(skb, ETH_HLEN);
95 skb->priority = TC_PRIO_CONTROL; 93 skb->priority = TC_PRIO_CONTROL;
96 skb->protocol = __constant_htons(ETH_P_BATMAN); 94 skb->protocol = __constant_htons(ETH_P_BATMAN);
95
97 skb->dev = batman_if->net_dev; 96 skb->dev = batman_if->net_dev;
98 97
99 /* dev_queue_xmit() returns a negative result on error. However on 98 /* dev_queue_xmit() returns a negative result on error. However on
100 * congestion and traffic shaping, it drops and returns NET_XMIT_DROP 99 * congestion and traffic shaping, it drops and returns NET_XMIT_DROP
101 * (which is > 0). This will not be treated as an error. */ 100 * (which is > 0). This will not be treated as an error. */
102 retval = dev_queue_xmit(skb); 101
103 if (retval < 0) 102 return dev_queue_xmit(skb);
104 debug_log(LOG_TYPE_CRIT, 103send_skb_err:
105 "Can't write to raw socket (IF_TO_BE_DEACTIVATED was here): %i\n", 104 kfree_skb(skb);
106 retval); 105 return NET_XMIT_DROP;
106}
107
108/* sends a raw packet. */
109void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
110 struct batman_if *batman_if, uint8_t *dst_addr)
111{
112 struct sk_buff *skb;
113 char *data;
114
115 skb = dev_alloc_skb(pack_buff_len + sizeof(struct ethhdr));
116 if (!skb)
117 return;
118 data = skb_put(skb, pack_buff_len + sizeof(struct ethhdr));
119 memcpy(data + sizeof(struct ethhdr), pack_buff, pack_buff_len);
120 /* pull back to the batman "network header" */
121 skb_pull(skb, sizeof(struct ethhdr));
122 send_skb_packet(skb, batman_if, dst_addr);
107} 123}
108 124
109/* Send a packet to a given interface */ 125/* Send a packet to a given interface */
@@ -114,7 +130,6 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
114 uint8_t packet_num; 130 uint8_t packet_num;
115 int16_t buff_pos; 131 int16_t buff_pos;
116 struct batman_packet *batman_packet; 132 struct batman_packet *batman_packet;
117 char orig_str[ETH_STR_LEN];
118 133
119 if (batman_if->if_active != IF_ACTIVE) 134 if (batman_if->if_active != IF_ACTIVE)
120 return; 135 return;
@@ -136,19 +151,18 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
136 else 151 else
137 batman_packet->flags &= ~DIRECTLINK; 152 batman_packet->flags &= ~DIRECTLINK;
138 153
139 addr_to_string(orig_str, batman_packet->orig);
140 fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? 154 fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
141 "Sending own" : 155 "Sending own" :
142 "Forwarding")); 156 "Forwarding"));
143 debug_log(LOG_TYPE_BATMAN, 157 bat_dbg(DBG_BATMAN,
144 "%s %spacket (originator %s, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n", 158 "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
145 fwd_str, 159 fwd_str,
146 (packet_num > 0 ? "aggregated " : ""), 160 (packet_num > 0 ? "aggregated " : ""),
147 orig_str, ntohs(batman_packet->seqno), 161 batman_packet->orig, ntohs(batman_packet->seqno),
148 batman_packet->tq, batman_packet->ttl, 162 batman_packet->tq, batman_packet->ttl,
149 (batman_packet->flags & DIRECTLINK ? 163 (batman_packet->flags & DIRECTLINK ?
150 "on" : "off"), 164 "on" : "off"),
151 batman_if->dev, batman_if->addr_str); 165 batman_if->dev, batman_if->addr_str);
152 166
153 buff_pos += sizeof(struct batman_packet) + 167 buff_pos += sizeof(struct batman_packet) +
154 (batman_packet->num_hna * ETH_ALEN); 168 (batman_packet->num_hna * ETH_ALEN);
@@ -168,32 +182,28 @@ static void send_packet(struct forw_packet *forw_packet)
168 struct batman_if *batman_if; 182 struct batman_if *batman_if;
169 struct batman_packet *batman_packet = 183 struct batman_packet *batman_packet =
170 (struct batman_packet *)(forw_packet->packet_buff); 184 (struct batman_packet *)(forw_packet->packet_buff);
171 char orig_str[ETH_STR_LEN];
172 unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); 185 unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
173 186
174 if (!forw_packet->if_incoming) { 187 if (!forw_packet->if_incoming) {
175 debug_log(LOG_TYPE_CRIT, 188 printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n");
176 "Error - can't forward packet: incoming iface not specified\n");
177 return; 189 return;
178 } 190 }
179 191
180 if (forw_packet->if_incoming->if_active != IF_ACTIVE) 192 if (forw_packet->if_incoming->if_active != IF_ACTIVE)
181 return; 193 return;
182 194
183 addr_to_string(orig_str, batman_packet->orig);
184
185 /* multihomed peer assumed */ 195 /* multihomed peer assumed */
186 /* non-primary OGMs are only broadcasted on their interface */ 196 /* non-primary OGMs are only broadcasted on their interface */
187 if ((directlink && (batman_packet->ttl == 1)) || 197 if ((directlink && (batman_packet->ttl == 1)) ||
188 (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { 198 (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
189 199
190 /* FIXME: what about aggregated packets ? */ 200 /* FIXME: what about aggregated packets ? */
191 debug_log(LOG_TYPE_BATMAN, 201 bat_dbg(DBG_BATMAN,
192 "%s packet (originator %s, seqno %d, TTL %d) on interface %s [%s]\n", 202 "%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n",
193 (forw_packet->own ? "Sending own" : "Forwarding"), 203 (forw_packet->own ? "Sending own" : "Forwarding"),
194 orig_str, ntohs(batman_packet->seqno), 204 batman_packet->orig, ntohs(batman_packet->seqno),
195 batman_packet->ttl, forw_packet->if_incoming->dev, 205 batman_packet->ttl, forw_packet->if_incoming->dev,
196 forw_packet->if_incoming->addr_str); 206 forw_packet->if_incoming->addr_str);
197 207
198 send_raw_packet(forw_packet->packet_buff, 208 send_raw_packet(forw_packet->packet_buff,
199 forw_packet->packet_len, 209 forw_packet->packet_len,
@@ -238,6 +248,7 @@ void schedule_own_packet(struct batman_if *batman_if)
238{ 248{
239 unsigned long send_time; 249 unsigned long send_time;
240 struct batman_packet *batman_packet; 250 struct batman_packet *batman_packet;
251 int vis_server = atomic_read(&vis_mode);
241 252
242 /** 253 /**
243 * the interface gets activated here to avoid race conditions between 254 * the interface gets activated here to avoid race conditions between
@@ -262,7 +273,7 @@ void schedule_own_packet(struct batman_if *batman_if)
262 /* change sequence number to network order */ 273 /* change sequence number to network order */
263 batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno)); 274 batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
264 275
265 if (is_vis_server()) 276 if (vis_server == VIS_TYPE_SERVER_SYNC)
266 batman_packet->flags = VIS_SERVER; 277 batman_packet->flags = VIS_SERVER;
267 else 278 else
268 batman_packet->flags = 0; 279 batman_packet->flags = 0;
@@ -286,7 +297,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
286 unsigned long send_time; 297 unsigned long send_time;
287 298
288 if (batman_packet->ttl <= 1) { 299 if (batman_packet->ttl <= 1) {
289 debug_log(LOG_TYPE_BATMAN, "ttl exceeded \n"); 300 bat_dbg(DBG_BATMAN, "ttl exceeded \n");
290 return; 301 return;
291 } 302 }
292 303
@@ -314,9 +325,9 @@ void schedule_forward_packet(struct orig_node *orig_node,
314 /* apply hop penalty */ 325 /* apply hop penalty */
315 batman_packet->tq = hop_penalty(batman_packet->tq); 326 batman_packet->tq = hop_penalty(batman_packet->tq);
316 327
317 debug_log(LOG_TYPE_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n", 328 bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n",
318 in_tq, tq_avg, batman_packet->tq, in_ttl - 1, 329 in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
319 batman_packet->ttl); 330 batman_packet->ttl);
320 331
321 batman_packet->seqno = htons(batman_packet->seqno); 332 batman_packet->seqno = htons(batman_packet->seqno);
322 333
@@ -333,6 +344,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
333 344
334static void forw_packet_free(struct forw_packet *forw_packet) 345static void forw_packet_free(struct forw_packet *forw_packet)
335{ 346{
347 if (forw_packet->skb)
348 kfree_skb(forw_packet->skb);
336 kfree(forw_packet->packet_buff); 349 kfree(forw_packet->packet_buff);
337 kfree(forw_packet); 350 kfree(forw_packet);
338} 351}
@@ -340,12 +353,13 @@ static void forw_packet_free(struct forw_packet *forw_packet)
340static void _add_bcast_packet_to_list(struct forw_packet *forw_packet, 353static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
341 unsigned long send_time) 354 unsigned long send_time)
342{ 355{
356 unsigned long flags;
343 INIT_HLIST_NODE(&forw_packet->list); 357 INIT_HLIST_NODE(&forw_packet->list);
344 358
345 /* add new packet to packet list */ 359 /* add new packet to packet list */
346 spin_lock(&forw_bcast_list_lock); 360 spin_lock_irqsave(&forw_bcast_list_lock, flags);
347 hlist_add_head(&forw_packet->list, &forw_bcast_list); 361 hlist_add_head(&forw_packet->list, &forw_bcast_list);
348 spin_unlock(&forw_bcast_list_lock); 362 spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
349 363
350 /* start timer for this packet */ 364 /* start timer for this packet */
351 INIT_DELAYED_WORK(&forw_packet->delayed_work, 365 INIT_DELAYED_WORK(&forw_packet->delayed_work,
@@ -354,7 +368,7 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
354 send_time); 368 send_time);
355} 369}
356 370
357void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len) 371void add_bcast_packet_to_list(struct sk_buff *skb)
358{ 372{
359 struct forw_packet *forw_packet; 373 struct forw_packet *forw_packet;
360 374
@@ -362,14 +376,16 @@ void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len)
362 if (!forw_packet) 376 if (!forw_packet)
363 return; 377 return;
364 378
365 forw_packet->packet_buff = kmalloc(packet_len, GFP_ATOMIC); 379 skb = skb_copy(skb, GFP_ATOMIC);
366 if (!forw_packet->packet_buff) { 380 if (!skb) {
367 kfree(forw_packet); 381 kfree(forw_packet);
368 return; 382 return;
369 } 383 }
370 384
371 forw_packet->packet_len = packet_len; 385 skb_reset_mac_header(skb);
372 memcpy(forw_packet->packet_buff, packet_buff, forw_packet->packet_len); 386
387 forw_packet->skb = skb;
388 forw_packet->packet_buff = NULL;
373 389
374 /* how often did we send the bcast packet ? */ 390 /* how often did we send the bcast packet ? */
375 forw_packet->num_packets = 0; 391 forw_packet->num_packets = 0;
@@ -384,16 +400,20 @@ void send_outstanding_bcast_packet(struct work_struct *work)
384 container_of(work, struct delayed_work, work); 400 container_of(work, struct delayed_work, work);
385 struct forw_packet *forw_packet = 401 struct forw_packet *forw_packet =
386 container_of(delayed_work, struct forw_packet, delayed_work); 402 container_of(delayed_work, struct forw_packet, delayed_work);
403 unsigned long flags;
404 struct sk_buff *skb1;
387 405
388 spin_lock(&forw_bcast_list_lock); 406 spin_lock_irqsave(&forw_bcast_list_lock, flags);
389 hlist_del(&forw_packet->list); 407 hlist_del(&forw_packet->list);
390 spin_unlock(&forw_bcast_list_lock); 408 spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
391 409
392 /* rebroadcast packet */ 410 /* rebroadcast packet */
393 rcu_read_lock(); 411 rcu_read_lock();
394 list_for_each_entry_rcu(batman_if, &if_list, list) { 412 list_for_each_entry_rcu(batman_if, &if_list, list) {
395 send_raw_packet(forw_packet->packet_buff, 413 /* send a copy of the saved skb */
396 forw_packet->packet_len, 414 skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
415 if (skb1)
416 send_skb_packet(skb1,
397 batman_if, broadcastAddr); 417 batman_if, broadcastAddr);
398 } 418 }
399 rcu_read_unlock(); 419 rcu_read_unlock();
@@ -415,10 +435,11 @@ void send_outstanding_bat_packet(struct work_struct *work)
415 container_of(work, struct delayed_work, work); 435 container_of(work, struct delayed_work, work);
416 struct forw_packet *forw_packet = 436 struct forw_packet *forw_packet =
417 container_of(delayed_work, struct forw_packet, delayed_work); 437 container_of(delayed_work, struct forw_packet, delayed_work);
438 unsigned long flags;
418 439
419 spin_lock(&forw_bat_list_lock); 440 spin_lock_irqsave(&forw_bat_list_lock, flags);
420 hlist_del(&forw_packet->list); 441 hlist_del(&forw_packet->list);
421 spin_unlock(&forw_bat_list_lock); 442 spin_unlock_irqrestore(&forw_bat_list_lock, flags);
422 443
423 send_packet(forw_packet); 444 send_packet(forw_packet);
424 445
@@ -438,38 +459,39 @@ void purge_outstanding_packets(void)
438{ 459{
439 struct forw_packet *forw_packet; 460 struct forw_packet *forw_packet;
440 struct hlist_node *tmp_node, *safe_tmp_node; 461 struct hlist_node *tmp_node, *safe_tmp_node;
462 unsigned long flags;
441 463
442 debug_log(LOG_TYPE_BATMAN, "purge_outstanding_packets()\n"); 464 bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
443 465
444 /* free bcast list */ 466 /* free bcast list */
445 spin_lock(&forw_bcast_list_lock); 467 spin_lock_irqsave(&forw_bcast_list_lock, flags);
446 hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, 468 hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
447 &forw_bcast_list, list) { 469 &forw_bcast_list, list) {
448 470
449 spin_unlock(&forw_bcast_list_lock); 471 spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
450 472
451 /** 473 /**
452 * send_outstanding_bcast_packet() will lock the list to 474 * send_outstanding_bcast_packet() will lock the list to
453 * delete the item from the list 475 * delete the item from the list
454 */ 476 */
455 cancel_delayed_work_sync(&forw_packet->delayed_work); 477 cancel_delayed_work_sync(&forw_packet->delayed_work);
456 spin_lock(&forw_bcast_list_lock); 478 spin_lock_irqsave(&forw_bcast_list_lock, flags);
457 } 479 }
458 spin_unlock(&forw_bcast_list_lock); 480 spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
459 481
460 /* free batman packet list */ 482 /* free batman packet list */
461 spin_lock(&forw_bat_list_lock); 483 spin_lock_irqsave(&forw_bat_list_lock, flags);
462 hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, 484 hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node,
463 &forw_bat_list, list) { 485 &forw_bat_list, list) {
464 486
465 spin_unlock(&forw_bat_list_lock); 487 spin_unlock_irqrestore(&forw_bat_list_lock, flags);
466 488
467 /** 489 /**
468 * send_outstanding_bat_packet() will lock the list to 490 * send_outstanding_bat_packet() will lock the list to
469 * delete the item from the list 491 * delete the item from the list
470 */ 492 */
471 cancel_delayed_work_sync(&forw_packet->delayed_work); 493 cancel_delayed_work_sync(&forw_packet->delayed_work);
472 spin_lock(&forw_bat_list_lock); 494 spin_lock_irqsave(&forw_bat_list_lock, flags);
473 } 495 }
474 spin_unlock(&forw_bat_list_lock); 496 spin_unlock_irqrestore(&forw_bat_list_lock, flags);
475} 497}
diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h
index 59d500917a35..5fc6f3417cb6 100644
--- a/drivers/staging/batman-adv/send.h
+++ b/drivers/staging/batman-adv/send.h
@@ -22,6 +22,9 @@
22#include "types.h" 22#include "types.h"
23 23
24void send_own_packet_work(struct work_struct *work); 24void send_own_packet_work(struct work_struct *work);
25int send_skb_packet(struct sk_buff *skb,
26 struct batman_if *batman_if,
27 uint8_t *dst_addr);
25void send_raw_packet(unsigned char *pack_buff, int pack_buff_len, 28void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
26 struct batman_if *batman_if, uint8_t *dst_addr); 29 struct batman_if *batman_if, uint8_t *dst_addr);
27void schedule_own_packet(struct batman_if *batman_if); 30void schedule_own_packet(struct batman_if *batman_if);
@@ -30,7 +33,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
30 struct batman_packet *batman_packet, 33 struct batman_packet *batman_packet,
31 uint8_t directlink, int hna_buff_len, 34 uint8_t directlink, int hna_buff_len,
32 struct batman_if *if_outgoing); 35 struct batman_if *if_outgoing);
33void add_bcast_packet_to_list(unsigned char *packet_buff, int packet_len); 36void add_bcast_packet_to_list(struct sk_buff *skb);
34void send_outstanding_bcast_packet(struct work_struct *work); 37void send_outstanding_bcast_packet(struct work_struct *work);
35void send_outstanding_bat_packet(struct work_struct *work); 38void send_outstanding_bat_packet(struct work_struct *work);
36void purge_outstanding_packets(void); 39void purge_outstanding_packets(void);
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c
index d543f50b647f..c9b35d9f7991 100644
--- a/drivers/staging/batman-adv/soft-interface.c
+++ b/drivers/staging/batman-adv/soft-interface.c
@@ -24,18 +24,15 @@
24#include "hard-interface.h" 24#include "hard-interface.h"
25#include "send.h" 25#include "send.h"
26#include "translation-table.h" 26#include "translation-table.h"
27#include "log.h"
28#include "types.h" 27#include "types.h"
29#include "hash.h" 28#include "hash.h"
30#include <linux/ethtool.h> 29#include <linux/ethtool.h>
31#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
32#include "compat.h"
33 31
34static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid 32static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
35 * broadcast storms */ 33 * broadcast storms */
36static int32_t skb_packets; 34static int32_t skb_packets;
37static int32_t skb_bad_packets; 35static int32_t skb_bad_packets;
38static int32_t lock_dropped;
39 36
40unsigned char mainIfAddr[ETH_ALEN]; 37unsigned char mainIfAddr[ETH_ALEN];
41static unsigned char mainIfAddr_default[ETH_ALEN]; 38static unsigned char mainIfAddr_default[ETH_ALEN];
@@ -68,12 +65,12 @@ int main_if_was_up(void)
68 return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0); 65 return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
69} 66}
70 67
71static int my_skb_push(struct sk_buff *skb, unsigned int len) 68int my_skb_push(struct sk_buff *skb, unsigned int len)
72{ 69{
73 int result = 0; 70 int result = 0;
74 71
75 skb_packets++; 72 skb_packets++;
76 if (skb->data - len < skb->head) { 73 if (skb_headroom(skb) < len) {
77 skb_bad_packets++; 74 skb_bad_packets++;
78 result = pskb_expand_head(skb, len, 0, GFP_ATOMIC); 75 result = pskb_expand_head(skb, len, 0, GFP_ATOMIC);
79 76
@@ -122,7 +119,7 @@ void interface_setup(struct net_device *dev)
122 119
123 /* generate random address */ 120 /* generate random address */
124 random_ether_addr(dev_addr); 121 random_ether_addr(dev_addr);
125 memcpy(dev->dev_addr, dev_addr, sizeof(dev->dev_addr)); 122 memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
126 123
127 SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); 124 SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
128 125
@@ -147,9 +144,18 @@ struct net_device_stats *interface_stats(struct net_device *dev)
147 return &priv->stats; 144 return &priv->stats;
148} 145}
149 146
150int interface_set_mac_addr(struct net_device *dev, void *addr) 147int interface_set_mac_addr(struct net_device *dev, void *p)
151{ 148{
152 return -EBUSY; 149 struct sockaddr *addr = p;
150
151 if (!is_valid_ether_addr(addr->sa_data))
152 return -EADDRNOTAVAIL;
153
154 hna_local_remove(dev->dev_addr, "mac address changed");
155 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
156 hna_local_add(dev->dev_addr);
157
158 return 0;
153} 159}
154 160
155int interface_change_mtu(struct net_device *dev, int new_mtu) 161int interface_change_mtu(struct net_device *dev, int new_mtu)
@@ -170,7 +176,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
170 struct orig_node *orig_node; 176 struct orig_node *orig_node;
171 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 177 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
172 struct bat_priv *priv = netdev_priv(dev); 178 struct bat_priv *priv = netdev_priv(dev);
179 struct batman_if *batman_if;
180 uint8_t dstaddr[6];
173 int data_len = skb->len; 181 int data_len = skb->len;
182 unsigned long flags;
174 183
175 if (atomic_read(&module_state) != MODULE_ACTIVE) 184 if (atomic_read(&module_state) != MODULE_ACTIVE)
176 goto dropped; 185 goto dropped;
@@ -186,7 +195,6 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
186 goto dropped; 195 goto dropped;
187 196
188 bcast_packet = (struct bcast_packet *)skb->data; 197 bcast_packet = (struct bcast_packet *)skb->data;
189
190 bcast_packet->version = COMPAT_VERSION; 198 bcast_packet->version = COMPAT_VERSION;
191 199
192 /* batman packet type: broadcast */ 200 /* batman packet type: broadcast */
@@ -195,27 +203,21 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
195 /* hw address of first interface is the orig mac because only 203 /* hw address of first interface is the orig mac because only
196 * this mac is known throughout the mesh */ 204 * this mac is known throughout the mesh */
197 memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN); 205 memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
206
198 /* set broadcast sequence number */ 207 /* set broadcast sequence number */
199 bcast_packet->seqno = htons(bcast_seqno); 208 bcast_packet->seqno = htons(bcast_seqno);
200 209
201 bcast_seqno++; 210 bcast_seqno++;
202 211
203 /* broadcast packet */ 212 /* broadcast packet */
204 add_bcast_packet_to_list(skb->data, skb->len); 213 add_bcast_packet_to_list(skb);
214 /* a copy is stored in the bcast list, therefore removing
215 * the original skb. */
216 kfree_skb(skb);
205 217
206 /* unicast packet */ 218 /* unicast packet */
207 } else { 219 } else {
208 220 spin_lock_irqsave(&orig_hash_lock, flags);
209 /* simply spin_lock()ing can deadlock when the lock is already
210 * hold. */
211 /* TODO: defer the work in a working queue instead of
212 * dropping */
213 if (!spin_trylock(&orig_hash_lock)) {
214 lock_dropped++;
215 debug_log(LOG_TYPE_NOTICE, "%d packets dropped because lock was hold\n", lock_dropped);
216 goto dropped;
217 }
218
219 /* get routing information */ 221 /* get routing information */
220 orig_node = ((struct orig_node *)hash_find(orig_hash, 222 orig_node = ((struct orig_node *)hash_find(orig_hash,
221 ethhdr->h_dest)); 223 ethhdr->h_dest));
@@ -244,14 +246,17 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
244 if (orig_node->batman_if->if_active != IF_ACTIVE) 246 if (orig_node->batman_if->if_active != IF_ACTIVE)
245 goto unlock; 247 goto unlock;
246 248
247 send_raw_packet(skb->data, skb->len, 249 /* don't lock while sending the packets ... we therefore
248 orig_node->batman_if, 250 * copy the required data before sending */
249 orig_node->router->addr); 251
252 batman_if = orig_node->batman_if;
253 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
254 spin_unlock_irqrestore(&orig_hash_lock, flags);
255
256 send_skb_packet(skb, batman_if, dstaddr);
250 } else { 257 } else {
251 goto unlock; 258 goto unlock;
252 } 259 }
253
254 spin_unlock(&orig_hash_lock);
255 } 260 }
256 261
257 priv->stats.tx_packets++; 262 priv->stats.tx_packets++;
@@ -259,42 +264,44 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
259 goto end; 264 goto end;
260 265
261unlock: 266unlock:
262 spin_unlock(&orig_hash_lock); 267 spin_unlock_irqrestore(&orig_hash_lock, flags);
263dropped: 268dropped:
264 priv->stats.tx_dropped++; 269 priv->stats.tx_dropped++;
265end: 270end:
266 kfree_skb(skb); 271 return NETDEV_TX_OK;
267 return 0;
268} 272}
269 273
270void interface_rx(struct net_device *dev, void *packet, int packet_len) 274void interface_rx(struct sk_buff *skb, int hdr_size)
271{ 275{
272 struct sk_buff *skb; 276 struct net_device *dev = soft_device;
273 struct bat_priv *priv = netdev_priv(dev); 277 struct bat_priv *priv = netdev_priv(dev);
274 278
275 skb = dev_alloc_skb(packet_len); 279 /* check if enough space is available for pulling, and pull */
276 280 if (!pskb_may_pull(skb, hdr_size)) {
277 if (!skb) { 281 kfree_skb(skb);
278 priv->stats.rx_dropped++; 282 return;
279 goto out;
280 } 283 }
284 skb_pull_rcsum(skb, hdr_size);
285/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/
281 286
282 memcpy(skb_put(skb, packet_len), packet, packet_len);
283
284 /* Write metadata, and then pass to the receive level */
285 skb->dev = dev; 287 skb->dev = dev;
286 skb->protocol = eth_type_trans(skb, dev); 288 skb->protocol = eth_type_trans(skb, dev);
287 skb->ip_summed = CHECKSUM_UNNECESSARY; 289
290 /* should not be neccesary anymore as we use skb_pull_rcsum()
291 * TODO: please verify this and remove this TODO
292 * -- Dec 21st 2009, Simon Wunderlich */
293
294/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/
295
296 /* TODO: set skb->pkt_type to PACKET_BROADCAST, PACKET_MULTICAST,
297 * PACKET_OTHERHOST or PACKET_HOST */
288 298
289 priv->stats.rx_packets++; 299 priv->stats.rx_packets++;
290 priv->stats.rx_bytes += packet_len; 300 priv->stats.rx_bytes += skb->len;
291 301
292 dev->last_rx = jiffies; 302 dev->last_rx = jiffies;
293 303
294 netif_rx(skb); 304 netif_rx(skb);
295
296out:
297 return;
298} 305}
299 306
300/* ethtool */ 307/* ethtool */
@@ -330,7 +337,6 @@ static u32 bat_get_msglevel(struct net_device *dev)
330 337
331static void bat_set_msglevel(struct net_device *dev, u32 value) 338static void bat_set_msglevel(struct net_device *dev, u32 value)
332{ 339{
333 return;
334} 340}
335 341
336static u32 bat_get_link(struct net_device *dev) 342static u32 bat_get_link(struct net_device *dev)
diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h
index 515e276ef53d..c0cad8134b2b 100644
--- a/drivers/staging/batman-adv/soft-interface.h
+++ b/drivers/staging/batman-adv/soft-interface.h
@@ -28,6 +28,7 @@ struct net_device_stats *interface_stats(struct net_device *dev);
28int interface_set_mac_addr(struct net_device *dev, void *addr); 28int interface_set_mac_addr(struct net_device *dev, void *addr);
29int interface_change_mtu(struct net_device *dev, int new_mtu); 29int interface_change_mtu(struct net_device *dev, int new_mtu);
30int interface_tx(struct sk_buff *skb, struct net_device *dev); 30int interface_tx(struct sk_buff *skb, struct net_device *dev);
31void interface_rx(struct net_device *dev, void *packet, int packet_len); 31void interface_rx(struct sk_buff *skb, int hdr_size);
32int my_skb_push(struct sk_buff *skb, unsigned int len);
32 33
33extern unsigned char mainIfAddr[]; 34extern unsigned char mainIfAddr[];
diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c
index c2190e177c56..d56f6654de0d 100644
--- a/drivers/staging/batman-adv/translation-table.c
+++ b/drivers/staging/batman-adv/translation-table.c
@@ -21,11 +21,9 @@
21 21
22#include "main.h" 22#include "main.h"
23#include "translation-table.h" 23#include "translation-table.h"
24#include "log.h"
25#include "soft-interface.h" 24#include "soft-interface.h"
26#include "types.h" 25#include "types.h"
27#include "hash.h" 26#include "hash.h"
28#include "compat.h"
29 27
30struct hashtable_t *hna_local_hash; 28struct hashtable_t *hna_local_hash;
31static struct hashtable_t *hna_global_hash; 29static struct hashtable_t *hna_global_hash;
@@ -62,7 +60,6 @@ void hna_local_add(uint8_t *addr)
62 struct hna_local_entry *hna_local_entry; 60 struct hna_local_entry *hna_local_entry;
63 struct hna_global_entry *hna_global_entry; 61 struct hna_global_entry *hna_global_entry;
64 struct hashtable_t *swaphash; 62 struct hashtable_t *swaphash;
65 char hna_str[ETH_STR_LEN];
66 unsigned long flags; 63 unsigned long flags;
67 64
68 spin_lock_irqsave(&hna_local_hash_lock, flags); 65 spin_lock_irqsave(&hna_local_hash_lock, flags);
@@ -75,19 +72,17 @@ void hna_local_add(uint8_t *addr)
75 return; 72 return;
76 } 73 }
77 74
78 addr_to_string(hna_str, addr);
79
80 /* only announce as many hosts as possible in the batman-packet and 75 /* only announce as many hosts as possible in the batman-packet and
81 space in batman_packet->num_hna That also should give a limit to 76 space in batman_packet->num_hna That also should give a limit to
82 MAC-flooding. */ 77 MAC-flooding. */
83 if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || 78 if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
84 (num_hna + 1 > 255)) { 79 (num_hna + 1 > 255)) {
85 debug_log(LOG_TYPE_ROUTES, "Can't add new local hna entry (%s): number of local hna entries exceeds packet size \n", hna_str); 80 bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size \n", addr);
86 return; 81 return;
87 } 82 }
88 83
89 debug_log(LOG_TYPE_ROUTES, "Creating new local hna entry: %s \n", 84 bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n",
90 hna_str); 85 addr);
91 86
92 hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); 87 hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
93 if (!hna_local_entry) 88 if (!hna_local_entry)
@@ -113,7 +108,7 @@ void hna_local_add(uint8_t *addr)
113 hna_local_hash->size * 2); 108 hna_local_hash->size * 2);
114 109
115 if (swaphash == NULL) 110 if (swaphash == NULL)
116 debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n"); 111 printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table \n");
117 else 112 else
118 hna_local_hash = swaphash; 113 hna_local_hash = swaphash;
119 } 114 }
@@ -135,18 +130,18 @@ void hna_local_add(uint8_t *addr)
135int hna_local_fill_buffer(unsigned char *buff, int buff_len) 130int hna_local_fill_buffer(unsigned char *buff, int buff_len)
136{ 131{
137 struct hna_local_entry *hna_local_entry; 132 struct hna_local_entry *hna_local_entry;
138 struct hash_it_t *hashit = NULL; 133 HASHIT(hashit);
139 int i = 0; 134 int i = 0;
140 unsigned long flags; 135 unsigned long flags;
141 136
142 spin_lock_irqsave(&hna_local_hash_lock, flags); 137 spin_lock_irqsave(&hna_local_hash_lock, flags);
143 138
144 while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { 139 while (hash_iterate(hna_local_hash, &hashit)) {
145 140
146 if (buff_len < (i + 1) * ETH_ALEN) 141 if (buff_len < (i + 1) * ETH_ALEN)
147 break; 142 break;
148 143
149 hna_local_entry = hashit->bucket->data; 144 hna_local_entry = hashit.bucket->data;
150 memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); 145 memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN);
151 146
152 i++; 147 i++;
@@ -164,18 +159,18 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
164int hna_local_fill_buffer_text(unsigned char *buff, int buff_len) 159int hna_local_fill_buffer_text(unsigned char *buff, int buff_len)
165{ 160{
166 struct hna_local_entry *hna_local_entry; 161 struct hna_local_entry *hna_local_entry;
167 struct hash_it_t *hashit = NULL; 162 HASHIT(hashit);
168 int bytes_written = 0; 163 int bytes_written = 0;
169 unsigned long flags; 164 unsigned long flags;
170 165
171 spin_lock_irqsave(&hna_local_hash_lock, flags); 166 spin_lock_irqsave(&hna_local_hash_lock, flags);
172 167
173 while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { 168 while (hash_iterate(hna_local_hash, &hashit)) {
174 169
175 if (buff_len < bytes_written + ETH_STR_LEN + 4) 170 if (buff_len < bytes_written + ETH_STR_LEN + 4)
176 break; 171 break;
177 172
178 hna_local_entry = hashit->bucket->data; 173 hna_local_entry = hashit.bucket->data;
179 174
180 bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4, 175 bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4,
181 " * %02x:%02x:%02x:%02x:%02x:%02x\n", 176 " * %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -202,27 +197,39 @@ static void _hna_local_del(void *data)
202static void hna_local_del(struct hna_local_entry *hna_local_entry, 197static void hna_local_del(struct hna_local_entry *hna_local_entry,
203 char *message) 198 char *message)
204{ 199{
205 char hna_str[ETH_STR_LEN]; 200 bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n",
206 201 hna_local_entry->addr, message);
207 addr_to_string(hna_str, hna_local_entry->addr);
208 debug_log(LOG_TYPE_ROUTES, "Deleting local hna entry (%s): %s \n",
209 hna_str, message);
210 202
211 hash_remove(hna_local_hash, hna_local_entry->addr); 203 hash_remove(hna_local_hash, hna_local_entry->addr);
212 _hna_local_del(hna_local_entry); 204 _hna_local_del(hna_local_entry);
213} 205}
214 206
207void hna_local_remove(uint8_t *addr, char *message)
208{
209 struct hna_local_entry *hna_local_entry;
210 unsigned long flags;
211
212 spin_lock_irqsave(&hna_local_hash_lock, flags);
213
214 hna_local_entry = (struct hna_local_entry *)
215 hash_find(hna_local_hash, addr);
216 if (hna_local_entry)
217 hna_local_del(hna_local_entry, message);
218
219 spin_unlock_irqrestore(&hna_local_hash_lock, flags);
220}
221
215void hna_local_purge(struct work_struct *work) 222void hna_local_purge(struct work_struct *work)
216{ 223{
217 struct hna_local_entry *hna_local_entry; 224 struct hna_local_entry *hna_local_entry;
218 struct hash_it_t *hashit = NULL; 225 HASHIT(hashit);
219 unsigned long flags; 226 unsigned long flags;
220 unsigned long timeout; 227 unsigned long timeout;
221 228
222 spin_lock_irqsave(&hna_local_hash_lock, flags); 229 spin_lock_irqsave(&hna_local_hash_lock, flags);
223 230
224 while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { 231 while (hash_iterate(hna_local_hash, &hashit)) {
225 hna_local_entry = hashit->bucket->data; 232 hna_local_entry = hashit.bucket->data;
226 233
227 timeout = hna_local_entry->last_seen + 234 timeout = hna_local_entry->last_seen +
228 ((LOCAL_HNA_TIMEOUT / 1000) * HZ); 235 ((LOCAL_HNA_TIMEOUT / 1000) * HZ);
@@ -264,13 +271,10 @@ void hna_global_add_orig(struct orig_node *orig_node,
264 struct hna_global_entry *hna_global_entry; 271 struct hna_global_entry *hna_global_entry;
265 struct hna_local_entry *hna_local_entry; 272 struct hna_local_entry *hna_local_entry;
266 struct hashtable_t *swaphash; 273 struct hashtable_t *swaphash;
267 char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN];
268 int hna_buff_count = 0; 274 int hna_buff_count = 0;
269 unsigned long flags; 275 unsigned long flags;
270 unsigned char *hna_ptr; 276 unsigned char *hna_ptr;
271 277
272 addr_to_string(orig_str, orig_node->orig);
273
274 while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { 278 while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) {
275 spin_lock_irqsave(&hna_global_hash_lock, flags); 279 spin_lock_irqsave(&hna_global_hash_lock, flags);
276 280
@@ -290,8 +294,9 @@ void hna_global_add_orig(struct orig_node *orig_node,
290 294
291 memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); 295 memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
292 296
293 addr_to_string(hna_str, hna_global_entry->addr); 297 bat_dbg(DBG_ROUTES,
294 debug_log(LOG_TYPE_ROUTES, "Creating new global hna entry: %s (via %s)\n", hna_str, orig_str); 298 "Creating new global hna entry: %pM (via %pM)\n",
299 hna_global_entry->addr, orig_node->orig);
295 300
296 spin_lock_irqsave(&hna_global_hash_lock, flags); 301 spin_lock_irqsave(&hna_global_hash_lock, flags);
297 hash_add(hna_global_hash, hna_global_entry); 302 hash_add(hna_global_hash, hna_global_entry);
@@ -316,14 +321,16 @@ void hna_global_add_orig(struct orig_node *orig_node,
316 hna_buff_count++; 321 hna_buff_count++;
317 } 322 }
318 323
319 orig_node->hna_buff_len = hna_buff_len; 324 /* initialize, and overwrite if malloc succeeds */
325 orig_node->hna_buff = NULL;
326 orig_node->hna_buff_len = 0;
320 327
321 if (orig_node->hna_buff_len > 0) { 328 if (hna_buff_len > 0) {
322 orig_node->hna_buff = kmalloc(orig_node->hna_buff_len, 329 orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC);
323 GFP_ATOMIC); 330 if (orig_node->hna_buff) {
324 memcpy(orig_node->hna_buff, hna_buff, orig_node->hna_buff_len); 331 memcpy(orig_node->hna_buff, hna_buff, hna_buff_len);
325 } else { 332 orig_node->hna_buff_len = hna_buff_len;
326 orig_node->hna_buff = NULL; 333 }
327 } 334 }
328 335
329 spin_lock_irqsave(&hna_global_hash_lock, flags); 336 spin_lock_irqsave(&hna_global_hash_lock, flags);
@@ -333,7 +340,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
333 hna_global_hash->size * 2); 340 hna_global_hash->size * 2);
334 341
335 if (swaphash == NULL) 342 if (swaphash == NULL)
336 debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n"); 343 printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table \n");
337 else 344 else
338 hna_global_hash = swaphash; 345 hna_global_hash = swaphash;
339 } 346 }
@@ -344,17 +351,17 @@ void hna_global_add_orig(struct orig_node *orig_node,
344int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) 351int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
345{ 352{
346 struct hna_global_entry *hna_global_entry; 353 struct hna_global_entry *hna_global_entry;
347 struct hash_it_t *hashit = NULL; 354 HASHIT(hashit);
348 int bytes_written = 0; 355 int bytes_written = 0;
349 unsigned long flags; 356 unsigned long flags;
350 357
351 spin_lock_irqsave(&hna_global_hash_lock, flags); 358 spin_lock_irqsave(&hna_global_hash_lock, flags);
352 359
353 while (NULL != (hashit = hash_iterate(hna_global_hash, hashit))) { 360 while (hash_iterate(hna_global_hash, &hashit)) {
354 if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10) 361 if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10)
355 break; 362 break;
356 363
357 hna_global_entry = hashit->bucket->data; 364 hna_global_entry = hashit.bucket->data;
358 365
359 bytes_written += snprintf(buff + bytes_written, 366 bytes_written += snprintf(buff + bytes_written,
360 (2 * ETH_STR_LEN) + 10, 367 (2 * ETH_STR_LEN) + 10,
@@ -381,12 +388,9 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
381void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, 388void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
382 char *message) 389 char *message)
383{ 390{
384 char hna_str[ETH_STR_LEN], orig_str[ETH_STR_LEN]; 391 bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n",
385 392 hna_global_entry->addr, hna_global_entry->orig_node->orig,
386 addr_to_string(orig_str, hna_global_entry->orig_node->orig); 393 message);
387 addr_to_string(hna_str, hna_global_entry->addr);
388
389 debug_log(LOG_TYPE_ROUTES, "Deleting global hna entry %s (via %s): %s \n", hna_str, orig_str, message);
390 394
391 hash_remove(hna_global_hash, hna_global_entry->addr); 395 hash_remove(hna_global_hash, hna_global_entry->addr);
392 kfree(hna_global_entry); 396 kfree(hna_global_entry);
diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h
index f7da81129318..281125b729fb 100644
--- a/drivers/staging/batman-adv/translation-table.h
+++ b/drivers/staging/batman-adv/translation-table.h
@@ -23,6 +23,7 @@
23 23
24int hna_local_init(void); 24int hna_local_init(void);
25void hna_local_add(uint8_t *addr); 25void hna_local_add(uint8_t *addr);
26void hna_local_remove(uint8_t *addr, char *message);
26int hna_local_fill_buffer(unsigned char *buff, int buff_len); 27int hna_local_fill_buffer(unsigned char *buff, int buff_len);
27int hna_local_fill_buffer_text(unsigned char *buff, int buff_len); 28int hna_local_fill_buffer_text(unsigned char *buff, int buff_len);
28void hna_local_purge(struct work_struct *work); 29void hna_local_purge(struct work_struct *work);
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h
index 3a0ef0c38c93..dec1b54031b6 100644
--- a/drivers/staging/batman-adv/types.h
+++ b/drivers/staging/batman-adv/types.h
@@ -39,7 +39,6 @@ struct batman_if {
39 char if_active; 39 char if_active;
40 char addr_str[ETH_STR_LEN]; 40 char addr_str[ETH_STR_LEN];
41 struct net_device *net_dev; 41 struct net_device *net_dev;
42 struct socket *raw_sock;
43 atomic_t seqno; 42 atomic_t seqno;
44 unsigned char *packet_buff; 43 unsigned char *packet_buff;
45 int packet_len; 44 int packet_len;
@@ -75,7 +74,7 @@ struct neigh_node {
75 uint8_t tq_index; 74 uint8_t tq_index;
76 uint8_t tq_avg; 75 uint8_t tq_avg;
77 uint8_t last_ttl; 76 uint8_t last_ttl;
78 unsigned long last_valid; /* when last packet via this neighbour was received */ 77 unsigned long last_valid; /* when last packet via this neighbor was received */
79 TYPE_OF_WORD real_bits[NUM_WORDS]; 78 TYPE_OF_WORD real_bits[NUM_WORDS];
80 struct orig_node *orig_node; 79 struct orig_node *orig_node;
81 struct batman_if *if_incoming; 80 struct batman_if *if_incoming;
@@ -113,6 +112,7 @@ struct forw_packet { /* structure for forw_list maintaining packet
113 struct hlist_node list; 112 struct hlist_node list;
114 unsigned long send_time; 113 unsigned long send_time;
115 uint8_t own; 114 uint8_t own;
115 struct sk_buff *skb;
116 unsigned char *packet_buff; 116 unsigned char *packet_buff;
117 uint16_t packet_len; 117 uint16_t packet_len;
118 uint32_t direct_link_flags; 118 uint32_t direct_link_flags;
@@ -121,4 +121,14 @@ struct forw_packet { /* structure for forw_list maintaining packet
121 struct batman_if *if_incoming; 121 struct batman_if *if_incoming;
122}; 122};
123 123
124/* While scanning for vis-entries of a particular vis-originator
125 * this list collects its interfaces to create a subgraph/cluster
126 * out of them later
127 */
128struct if_list_entry {
129 uint8_t addr[ETH_ALEN];
130 bool primary;
131 struct hlist_node list;
132};
133
124#endif 134#endif
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c
index f6c9acb289ed..fedec1bb3097 100644
--- a/drivers/staging/batman-adv/vis.c
+++ b/drivers/staging/batman-adv/vis.c
@@ -23,11 +23,9 @@
23#include "send.h" 23#include "send.h"
24#include "translation-table.h" 24#include "translation-table.h"
25#include "vis.h" 25#include "vis.h"
26#include "log.h"
27#include "soft-interface.h" 26#include "soft-interface.h"
28#include "hard-interface.h" 27#include "hard-interface.h"
29#include "hash.h" 28#include "hash.h"
30#include "compat.h"
31 29
32struct hashtable_t *vis_hash; 30struct hashtable_t *vis_hash;
33DEFINE_SPINLOCK(vis_hash_lock); 31DEFINE_SPINLOCK(vis_hash_lock);
@@ -50,39 +48,6 @@ static void free_info(void *data)
50 kfree(info); 48 kfree(info);
51} 49}
52 50
53/* set the mode of the visualization to client or server */
54void vis_set_mode(int mode)
55{
56 spin_lock(&vis_hash_lock);
57
58 if (my_vis_info != NULL)
59 my_vis_info->packet.vis_type = mode;
60
61 spin_unlock(&vis_hash_lock);
62}
63
64/* is_vis_server(), locked outside */
65static int is_vis_server_locked(void)
66{
67 if (my_vis_info != NULL)
68 if (my_vis_info->packet.vis_type == VIS_TYPE_SERVER_SYNC)
69 return 1;
70
71 return 0;
72}
73
74/* get the current set mode */
75int is_vis_server(void)
76{
77 int ret = 0;
78
79 spin_lock(&vis_hash_lock);
80 ret = is_vis_server_locked();
81 spin_unlock(&vis_hash_lock);
82
83 return ret;
84}
85
86/* Compare two vis packets, used by the hashing algorithm */ 51/* Compare two vis packets, used by the hashing algorithm */
87static int vis_info_cmp(void *data1, void *data2) 52static int vis_info_cmp(void *data1, void *data2)
88{ 53{
@@ -115,6 +80,68 @@ static int vis_info_choose(void *data, int size)
115 return hash % size; 80 return hash % size;
116} 81}
117 82
83/* insert interface to the list of interfaces of one originator, if it
84 * does not already exist in the list */
85static void proc_vis_insert_interface(const uint8_t *interface,
86 struct hlist_head *if_list,
87 bool primary)
88{
89 struct if_list_entry *entry;
90 struct hlist_node *pos;
91
92 hlist_for_each_entry(entry, pos, if_list, list) {
93 if (compare_orig(entry->addr, (void *)interface))
94 return;
95 }
96
97 /* its a new address, add it to the list */
98 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
99 if (!entry)
100 return;
101 memcpy(entry->addr, interface, ETH_ALEN);
102 entry->primary = primary;
103 hlist_add_head(&entry->list, if_list);
104}
105
106void proc_vis_read_prim_sec(struct seq_file *seq,
107 struct hlist_head *if_list)
108{
109 struct if_list_entry *entry;
110 struct hlist_node *pos, *n;
111 char tmp_addr_str[ETH_STR_LEN];
112
113 hlist_for_each_entry_safe(entry, pos, n, if_list, list) {
114 if (entry->primary) {
115 seq_printf(seq, "PRIMARY, ");
116 } else {
117 addr_to_string(tmp_addr_str, entry->addr);
118 seq_printf(seq, "SEC %s, ", tmp_addr_str);
119 }
120
121 hlist_del(&entry->list);
122 kfree(entry);
123 }
124}
125
126/* read an entry */
127void proc_vis_read_entry(struct seq_file *seq,
128 struct vis_info_entry *entry,
129 struct hlist_head *if_list,
130 uint8_t *vis_orig)
131{
132 char to[40];
133
134 addr_to_string(to, entry->dest);
135 if (entry->quality == 0) {
136 proc_vis_insert_interface(vis_orig, if_list, true);
137 seq_printf(seq, "HNA %s, ", to);
138 } else {
139 proc_vis_insert_interface(entry->src, if_list,
140 compare_orig(entry->src, vis_orig));
141 seq_printf(seq, "TQ %s %d, ", to, entry->quality);
142 }
143}
144
118/* tries to add one entry to the receive list. */ 145/* tries to add one entry to the receive list. */
119static void recv_list_add(struct list_head *recv_list, char *mac) 146static void recv_list_add(struct list_head *recv_list, char *mac)
120{ 147{
@@ -208,21 +235,23 @@ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
208{ 235{
209 struct vis_info *info; 236 struct vis_info *info;
210 int is_new; 237 int is_new;
238 unsigned long flags;
239 int vis_server = atomic_read(&vis_mode);
211 240
212 spin_lock(&vis_hash_lock); 241 spin_lock_irqsave(&vis_hash_lock, flags);
213 info = add_packet(vis_packet, vis_info_len, &is_new); 242 info = add_packet(vis_packet, vis_info_len, &is_new);
214 if (info == NULL) 243 if (info == NULL)
215 goto end; 244 goto end;
216 245
217 /* only if we are server ourselves and packet is newer than the one in 246 /* only if we are server ourselves and packet is newer than the one in
218 * hash.*/ 247 * hash.*/
219 if (is_vis_server_locked() && is_new) { 248 if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) {
220 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); 249 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
221 if (list_empty(&info->send_list)) 250 if (list_empty(&info->send_list))
222 list_add_tail(&info->send_list, &send_list); 251 list_add_tail(&info->send_list, &send_list);
223 } 252 }
224end: 253end:
225 spin_unlock(&vis_hash_lock); 254 spin_unlock_irqrestore(&vis_hash_lock, flags);
226} 255}
227 256
228/* handle an incoming client update packet and schedule forward if needed. */ 257/* handle an incoming client update packet and schedule forward if needed. */
@@ -231,12 +260,14 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
231{ 260{
232 struct vis_info *info; 261 struct vis_info *info;
233 int is_new; 262 int is_new;
263 unsigned long flags;
264 int vis_server = atomic_read(&vis_mode);
234 265
235 /* clients shall not broadcast. */ 266 /* clients shall not broadcast. */
236 if (is_bcast(vis_packet->target_orig)) 267 if (is_bcast(vis_packet->target_orig))
237 return; 268 return;
238 269
239 spin_lock(&vis_hash_lock); 270 spin_lock_irqsave(&vis_hash_lock, flags);
240 info = add_packet(vis_packet, vis_info_len, &is_new); 271 info = add_packet(vis_packet, vis_info_len, &is_new);
241 if (info == NULL) 272 if (info == NULL)
242 goto end; 273 goto end;
@@ -244,7 +275,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
244 275
245 276
246 /* send only if we're the target server or ... */ 277 /* send only if we're the target server or ... */
247 if (is_vis_server_locked() && 278 if (vis_server == VIS_TYPE_SERVER_SYNC &&
248 is_my_mac(info->packet.target_orig) && 279 is_my_mac(info->packet.target_orig) &&
249 is_new) { 280 is_new) {
250 info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ 281 info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
@@ -258,7 +289,7 @@ void receive_client_update_packet(struct vis_packet *vis_packet,
258 list_add_tail(&info->send_list, &send_list); 289 list_add_tail(&info->send_list, &send_list);
259 } 290 }
260end: 291end:
261 spin_unlock(&vis_hash_lock); 292 spin_unlock_irqrestore(&vis_hash_lock, flags);
262} 293}
263 294
264/* Walk the originators and find the VIS server with the best tq. Set the packet 295/* Walk the originators and find the VIS server with the best tq. Set the packet
@@ -267,12 +298,12 @@ end:
267 * Must be called with the originator hash locked */ 298 * Must be called with the originator hash locked */
268static int find_best_vis_server(struct vis_info *info) 299static int find_best_vis_server(struct vis_info *info)
269{ 300{
270 struct hash_it_t *hashit = NULL; 301 HASHIT(hashit);
271 struct orig_node *orig_node; 302 struct orig_node *orig_node;
272 int best_tq = -1; 303 int best_tq = -1;
273 304
274 while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { 305 while (hash_iterate(orig_hash, &hashit)) {
275 orig_node = hashit->bucket->data; 306 orig_node = hashit.bucket->data;
276 if ((orig_node != NULL) && 307 if ((orig_node != NULL) &&
277 (orig_node->router != NULL) && 308 (orig_node->router != NULL) &&
278 (orig_node->flags & VIS_SERVER) && 309 (orig_node->flags & VIS_SERVER) &&
@@ -298,7 +329,8 @@ static bool vis_packet_full(struct vis_info *info)
298 * returns 0 on success, -1 if no packet could be generated */ 329 * returns 0 on success, -1 if no packet could be generated */
299static int generate_vis_packet(void) 330static int generate_vis_packet(void)
300{ 331{
301 struct hash_it_t *hashit = NULL; 332 HASHIT(hashit_local);
333 HASHIT(hashit_global);
302 struct orig_node *orig_node; 334 struct orig_node *orig_node;
303 struct vis_info *info = (struct vis_info *)my_vis_info; 335 struct vis_info *info = (struct vis_info *)my_vis_info;
304 struct vis_info_entry *entry, *entry_array; 336 struct vis_info_entry *entry, *entry_array;
@@ -307,27 +339,27 @@ static int generate_vis_packet(void)
307 unsigned long flags; 339 unsigned long flags;
308 340
309 info->first_seen = jiffies; 341 info->first_seen = jiffies;
342 info->packet.vis_type = atomic_read(&vis_mode);
310 343
311 spin_lock(&orig_hash_lock); 344 spin_lock_irqsave(&orig_hash_lock, flags);
312 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); 345 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
313 info->packet.ttl = TTL; 346 info->packet.ttl = TTL;
314 info->packet.seqno++; 347 info->packet.seqno++;
315 info->packet.entries = 0; 348 info->packet.entries = 0;
316 349
317 if (!is_vis_server_locked()) { 350 if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
318 best_tq = find_best_vis_server(info); 351 best_tq = find_best_vis_server(info);
319 if (best_tq < 0) { 352 if (best_tq < 0) {
320 spin_unlock(&orig_hash_lock); 353 spin_unlock_irqrestore(&orig_hash_lock, flags);
321 return -1; 354 return -1;
322 } 355 }
323 } 356 }
324 hashit = NULL;
325 357
326 entry_array = (struct vis_info_entry *) 358 entry_array = (struct vis_info_entry *)
327 ((char *)info + sizeof(struct vis_info)); 359 ((char *)info + sizeof(struct vis_info));
328 360
329 while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { 361 while (hash_iterate(orig_hash, &hashit_global)) {
330 orig_node = hashit->bucket->data; 362 orig_node = hashit_global.bucket->data;
331 if (orig_node->router != NULL 363 if (orig_node->router != NULL
332 && compare_orig(orig_node->router->addr, orig_node->orig) 364 && compare_orig(orig_node->router->addr, orig_node->orig)
333 && orig_node->batman_if 365 && orig_node->batman_if
@@ -342,18 +374,17 @@ static int generate_vis_packet(void)
342 info->packet.entries++; 374 info->packet.entries++;
343 375
344 if (vis_packet_full(info)) { 376 if (vis_packet_full(info)) {
345 spin_unlock(&orig_hash_lock); 377 spin_unlock_irqrestore(&orig_hash_lock, flags);
346 return 0; 378 return 0;
347 } 379 }
348 } 380 }
349 } 381 }
350 382
351 spin_unlock(&orig_hash_lock); 383 spin_unlock_irqrestore(&orig_hash_lock, flags);
352 384
353 hashit = NULL;
354 spin_lock_irqsave(&hna_local_hash_lock, flags); 385 spin_lock_irqsave(&hna_local_hash_lock, flags);
355 while (NULL != (hashit = hash_iterate(hna_local_hash, hashit))) { 386 while (hash_iterate(hna_local_hash, &hashit_local)) {
356 hna_local_entry = hashit->bucket->data; 387 hna_local_entry = hashit_local.bucket->data;
357 entry = &entry_array[info->packet.entries]; 388 entry = &entry_array[info->packet.entries];
358 memset(entry->src, 0, ETH_ALEN); 389 memset(entry->src, 0, ETH_ALEN);
359 memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); 390 memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN);
@@ -371,16 +402,16 @@ static int generate_vis_packet(void)
371 402
372static void purge_vis_packets(void) 403static void purge_vis_packets(void)
373{ 404{
374 struct hash_it_t *hashit = NULL; 405 HASHIT(hashit);
375 struct vis_info *info; 406 struct vis_info *info;
376 407
377 while (NULL != (hashit = hash_iterate(vis_hash, hashit))) { 408 while (hash_iterate(vis_hash, &hashit)) {
378 info = hashit->bucket->data; 409 info = hashit.bucket->data;
379 if (info == my_vis_info) /* never purge own data. */ 410 if (info == my_vis_info) /* never purge own data. */
380 continue; 411 continue;
381 if (time_after(jiffies, 412 if (time_after(jiffies,
382 info->first_seen + (VIS_TIMEOUT/1000)*HZ)) { 413 info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
383 hash_remove_bucket(vis_hash, hashit); 414 hash_remove_bucket(vis_hash, &hashit);
384 free_info(info); 415 free_info(info);
385 } 416 }
386 } 417 }
@@ -388,14 +419,15 @@ static void purge_vis_packets(void)
388 419
389static void broadcast_vis_packet(struct vis_info *info, int packet_length) 420static void broadcast_vis_packet(struct vis_info *info, int packet_length)
390{ 421{
391 struct hash_it_t *hashit = NULL; 422 HASHIT(hashit);
392 struct orig_node *orig_node; 423 struct orig_node *orig_node;
424 unsigned long flags;
393 425
394 spin_lock(&orig_hash_lock); 426 spin_lock_irqsave(&orig_hash_lock, flags);
395 427
396 /* send to all routers in range. */ 428 /* send to all routers in range. */
397 while (NULL != (hashit = hash_iterate(orig_hash, hashit))) { 429 while (hash_iterate(orig_hash, &hashit)) {
398 orig_node = hashit->bucket->data; 430 orig_node = hashit.bucket->data;
399 431
400 /* if it's a vis server and reachable, send it. */ 432 /* if it's a vis server and reachable, send it. */
401 if (orig_node && 433 if (orig_node &&
@@ -418,14 +450,15 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
418 } 450 }
419 } 451 }
420 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); 452 memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
421 spin_unlock(&orig_hash_lock); 453 spin_unlock_irqrestore(&orig_hash_lock, flags);
422} 454}
423 455
424static void unicast_vis_packet(struct vis_info *info, int packet_length) 456static void unicast_vis_packet(struct vis_info *info, int packet_length)
425{ 457{
426 struct orig_node *orig_node; 458 struct orig_node *orig_node;
459 unsigned long flags;
427 460
428 spin_lock(&orig_hash_lock); 461 spin_lock_irqsave(&orig_hash_lock, flags);
429 orig_node = ((struct orig_node *) 462 orig_node = ((struct orig_node *)
430 hash_find(orig_hash, info->packet.target_orig)); 463 hash_find(orig_hash, info->packet.target_orig));
431 464
@@ -436,7 +469,7 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length)
436 orig_node->batman_if, 469 orig_node->batman_if,
437 orig_node->router->addr); 470 orig_node->router->addr);
438 } 471 }
439 spin_unlock(&orig_hash_lock); 472 spin_unlock_irqrestore(&orig_hash_lock, flags);
440} 473}
441 474
442/* only send one vis packet. called from send_vis_packets() */ 475/* only send one vis packet. called from send_vis_packets() */
@@ -445,8 +478,7 @@ static void send_vis_packet(struct vis_info *info)
445 int packet_length; 478 int packet_length;
446 479
447 if (info->packet.ttl < 2) { 480 if (info->packet.ttl < 2) {
448 debug_log(LOG_TYPE_NOTICE, 481 printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
449 "Error - can't send vis packet: ttl exceeded\n");
450 return; 482 return;
451 } 483 }
452 484
@@ -467,8 +499,9 @@ static void send_vis_packet(struct vis_info *info)
467static void send_vis_packets(struct work_struct *work) 499static void send_vis_packets(struct work_struct *work)
468{ 500{
469 struct vis_info *info, *temp; 501 struct vis_info *info, *temp;
502 unsigned long flags;
470 503
471 spin_lock(&vis_hash_lock); 504 spin_lock_irqsave(&vis_hash_lock, flags);
472 purge_vis_packets(); 505 purge_vis_packets();
473 506
474 if (generate_vis_packet() == 0) 507 if (generate_vis_packet() == 0)
@@ -479,7 +512,7 @@ static void send_vis_packets(struct work_struct *work)
479 list_del_init(&info->send_list); 512 list_del_init(&info->send_list);
480 send_vis_packet(info); 513 send_vis_packet(info);
481 } 514 }
482 spin_unlock(&vis_hash_lock); 515 spin_unlock_irqrestore(&vis_hash_lock, flags);
483 start_vis_timer(); 516 start_vis_timer();
484} 517}
485static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets); 518static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
@@ -488,20 +521,21 @@ static DECLARE_DELAYED_WORK(vis_timer_wq, send_vis_packets);
488 * initialized (e.g. bat0 is initialized, interfaces have been added) */ 521 * initialized (e.g. bat0 is initialized, interfaces have been added) */
489int vis_init(void) 522int vis_init(void)
490{ 523{
524 unsigned long flags;
491 if (vis_hash) 525 if (vis_hash)
492 return 1; 526 return 1;
493 527
494 spin_lock(&vis_hash_lock); 528 spin_lock_irqsave(&vis_hash_lock, flags);
495 529
496 vis_hash = hash_new(256, vis_info_cmp, vis_info_choose); 530 vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
497 if (!vis_hash) { 531 if (!vis_hash) {
498 debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n"); 532 printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n");
499 goto err; 533 goto err;
500 } 534 }
501 535
502 my_vis_info = kmalloc(1000, GFP_ATOMIC); 536 my_vis_info = kmalloc(1000, GFP_ATOMIC);
503 if (!my_vis_info) { 537 if (!my_vis_info) {
504 debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n"); 538 printk(KERN_ERR "batman-adv:Can't initialize vis packet\n");
505 goto err; 539 goto err;
506 } 540 }
507 541
@@ -511,7 +545,6 @@ int vis_init(void)
511 INIT_LIST_HEAD(&my_vis_info->send_list); 545 INIT_LIST_HEAD(&my_vis_info->send_list);
512 my_vis_info->packet.version = COMPAT_VERSION; 546 my_vis_info->packet.version = COMPAT_VERSION;
513 my_vis_info->packet.packet_type = BAT_VIS; 547 my_vis_info->packet.packet_type = BAT_VIS;
514 my_vis_info->packet.vis_type = VIS_TYPE_CLIENT_UPDATE;
515 my_vis_info->packet.ttl = TTL; 548 my_vis_info->packet.ttl = TTL;
516 my_vis_info->packet.seqno = 0; 549 my_vis_info->packet.seqno = 0;
517 my_vis_info->packet.entries = 0; 550 my_vis_info->packet.entries = 0;
@@ -522,19 +555,19 @@ int vis_init(void)
522 memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN); 555 memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
523 556
524 if (hash_add(vis_hash, my_vis_info) < 0) { 557 if (hash_add(vis_hash, my_vis_info) < 0) {
525 debug_log(LOG_TYPE_CRIT, 558 printk(KERN_ERR
526 "Can't add own vis packet into hash\n"); 559 "batman-adv:Can't add own vis packet into hash\n");
527 free_info(my_vis_info); /* not in hash, need to remove it 560 free_info(my_vis_info); /* not in hash, need to remove it
528 * manually. */ 561 * manually. */
529 goto err; 562 goto err;
530 } 563 }
531 564
532 spin_unlock(&vis_hash_lock); 565 spin_unlock_irqrestore(&vis_hash_lock, flags);
533 start_vis_timer(); 566 start_vis_timer();
534 return 1; 567 return 1;
535 568
536err: 569err:
537 spin_unlock(&vis_hash_lock); 570 spin_unlock_irqrestore(&vis_hash_lock, flags);
538 vis_quit(); 571 vis_quit();
539 return 0; 572 return 0;
540} 573}
@@ -542,23 +575,23 @@ err:
542/* shutdown vis-server */ 575/* shutdown vis-server */
543void vis_quit(void) 576void vis_quit(void)
544{ 577{
578 unsigned long flags;
545 if (!vis_hash) 579 if (!vis_hash)
546 return; 580 return;
547 581
548 cancel_delayed_work_sync(&vis_timer_wq); 582 cancel_delayed_work_sync(&vis_timer_wq);
549 583
550 spin_lock(&vis_hash_lock); 584 spin_lock_irqsave(&vis_hash_lock, flags);
551 /* properly remove, kill timers ... */ 585 /* properly remove, kill timers ... */
552 hash_delete(vis_hash, free_info); 586 hash_delete(vis_hash, free_info);
553 vis_hash = NULL; 587 vis_hash = NULL;
554 my_vis_info = NULL; 588 my_vis_info = NULL;
555 spin_unlock(&vis_hash_lock); 589 spin_unlock_irqrestore(&vis_hash_lock, flags);
556} 590}
557 591
558/* schedule packets for (re)transmission */ 592/* schedule packets for (re)transmission */
559static void start_vis_timer(void) 593static void start_vis_timer(void)
560{ 594{
561 queue_delayed_work(bat_event_workqueue, &vis_timer_wq, 595 queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
562 (atomic_read(&vis_interval)/1000) * HZ); 596 (atomic_read(&vis_interval) * HZ) / 1000);
563} 597}
564
diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h
index 276fabab4e88..0cdafde0ec3a 100644
--- a/drivers/staging/batman-adv/vis.h
+++ b/drivers/staging/batman-adv/vis.h
@@ -45,16 +45,15 @@ struct recvlist_node {
45 uint8_t mac[ETH_ALEN]; 45 uint8_t mac[ETH_ALEN];
46}; 46};
47 47
48enum vis_formats {
49 DOT_DRAW,
50 JSON,
51};
52
53extern struct hashtable_t *vis_hash; 48extern struct hashtable_t *vis_hash;
54extern spinlock_t vis_hash_lock; 49extern spinlock_t vis_hash_lock;
55 50
56void vis_set_mode(int mode); 51void proc_vis_read_entry(struct seq_file *seq,
57int is_vis_server(void); 52 struct vis_info_entry *entry,
53 struct hlist_head *if_list,
54 uint8_t *vis_orig);
55void proc_vis_read_prim_sec(struct seq_file *seq,
56 struct hlist_head *if_list);
58void receive_server_sync_packet(struct vis_packet *vis_packet, 57void receive_server_sync_packet(struct vis_packet *vis_packet,
59 int vis_info_len); 58 int vis_info_len);
60void receive_client_update_packet(struct vis_packet *vis_packet, 59void receive_client_update_packet(struct vis_packet *vis_packet,
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index a9fdcda5db7a..581aa5fee2e3 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -26,7 +26,6 @@
26 26
27#define __NO_VERSION__ 27#define __NO_VERSION__
28#include "comedi.h" 28#include "comedi.h"
29#include <linux/smp_lock.h>
30#include <linux/uaccess.h> 29#include <linux/uaccess.h>
31 30
32#include "comedi_compat32.h" 31#include "comedi_compat32.h"
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 8117748ad5a5..aca96747e5e2 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -63,7 +63,7 @@ module_param(comedi_debug, int, 0644);
63int comedi_autoconfig = 1; 63int comedi_autoconfig = 1;
64module_param(comedi_autoconfig, bool, 0444); 64module_param(comedi_autoconfig, bool, 0444);
65 65
66int comedi_num_legacy_minors = 0; 66int comedi_num_legacy_minors;
67module_param(comedi_num_legacy_minors, int, 0444); 67module_param(comedi_num_legacy_minors, int, 0444);
68 68
69static DEFINE_SPINLOCK(comedi_file_info_table_lock); 69static DEFINE_SPINLOCK(comedi_file_info_table_lock);
@@ -1510,7 +1510,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
1510} 1510}
1511 1511
1512static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes, 1512static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
1513 loff_t * offset) 1513 loff_t *offset)
1514{ 1514{
1515 struct comedi_subdevice *s; 1515 struct comedi_subdevice *s;
1516 struct comedi_async *async; 1516 struct comedi_async *async;
@@ -1612,7 +1612,7 @@ done:
1612} 1612}
1613 1613
1614static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes, 1614static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
1615 loff_t * offset) 1615 loff_t *offset)
1616{ 1616{
1617 struct comedi_subdevice *s; 1617 struct comedi_subdevice *s;
1618 struct comedi_async *async; 1618 struct comedi_async *async;
@@ -2004,12 +2004,10 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
2004 if (async->cb_mask & s->async->events) { 2004 if (async->cb_mask & s->async->events) {
2005 if (comedi_get_subdevice_runflags(s) & SRF_USER) { 2005 if (comedi_get_subdevice_runflags(s) & SRF_USER) {
2006 wake_up_interruptible(&async->wait_head); 2006 wake_up_interruptible(&async->wait_head);
2007 if (s->subdev_flags & SDF_CMD_READ) { 2007 if (s->subdev_flags & SDF_CMD_READ)
2008 kill_fasync(&dev->async_queue, SIGIO, POLL_IN); 2008 kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
2009 } 2009 if (s->subdev_flags & SDF_CMD_WRITE)
2010 if (s->subdev_flags & SDF_CMD_WRITE) {
2011 kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); 2010 kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
2012 }
2013 } else { 2011 } else {
2014 if (async->cb_func) 2012 if (async->cb_func)
2015 async->cb_func(s->async->events, async->cb_arg); 2013 async->cb_func(s->async->events, async->cb_arg);
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index c2a632d31c61..44d6b62c230d 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -44,7 +44,7 @@
44#include <linux/cdev.h> 44#include <linux/cdev.h>
45#include <linux/dma-mapping.h> 45#include <linux/dma-mapping.h>
46 46
47#include <asm/io.h> 47#include <linux/io.h>
48#include <asm/system.h> 48#include <asm/system.h>
49 49
50static int postconfig(struct comedi_device *dev); 50static int postconfig(struct comedi_device *dev);
@@ -99,11 +99,10 @@ static void cleanup_device(struct comedi_device *dev)
99static void __comedi_device_detach(struct comedi_device *dev) 99static void __comedi_device_detach(struct comedi_device *dev)
100{ 100{
101 dev->attached = 0; 101 dev->attached = 0;
102 if (dev->driver) { 102 if (dev->driver)
103 dev->driver->detach(dev); 103 dev->driver->detach(dev);
104 } else { 104 else
105 printk("BUG: dev->driver=NULL in comedi_device_detach()\n"); 105 printk("BUG: dev->driver=NULL in comedi_device_detach()\n");
106 }
107 cleanup_device(dev); 106 cleanup_device(dev);
108} 107}
109 108
@@ -380,9 +379,8 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
380 if (ret < 0) 379 if (ret < 0)
381 return ret; 380 return ret;
382 381
383 if (insn->insn == INSN_READ) { 382 if (insn->insn == INSN_READ)
384 data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1; 383 data[0] = (new_data[1] >> (chan - base_bitfield_channel)) & 1;
385 }
386 384
387 return 1; 385 return 1;
388} 386}
@@ -429,9 +427,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
429 new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; 427 new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
430 428
431 /* if no change is required, do nothing */ 429 /* if no change is required, do nothing */
432 if (async->prealloc_buf && async->prealloc_bufsz == new_size) { 430 if (async->prealloc_buf && async->prealloc_bufsz == new_size)
433 return 0; 431 return 0;
434 } 432
435 /* deallocate old buffer */ 433 /* deallocate old buffer */
436 if (async->prealloc_buf) { 434 if (async->prealloc_buf) {
437 vunmap(async->prealloc_buf); 435 vunmap(async->prealloc_buf);
@@ -494,9 +492,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
494 (void *) 492 (void *)
495 get_zeroed_page(GFP_KERNEL); 493 get_zeroed_page(GFP_KERNEL);
496 } 494 }
497 if (async->buf_page_list[i].virt_addr == NULL) { 495 if (async->buf_page_list[i].virt_addr == NULL)
498 break; 496 break;
499 } 497
500 mem_map_reserve(virt_to_page 498 mem_map_reserve(virt_to_page
501 (async->buf_page_list[i]. 499 (async->buf_page_list[i].
502 virt_addr)); 500 virt_addr));
@@ -619,9 +617,9 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async,
619{ 617{
620 unsigned int free_end = async->buf_read_count + async->prealloc_bufsz; 618 unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
621 619
622 if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) { 620 if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
623 nbytes = free_end - async->buf_write_alloc_count; 621 nbytes = free_end - async->buf_write_alloc_count;
624 } 622
625 async->buf_write_alloc_count += nbytes; 623 async->buf_write_alloc_count += nbytes;
626 /* barrier insures the read of buf_read_count above occurs before 624 /* barrier insures the read of buf_read_count above occurs before
627 we write data to the write-alloc'ed buffer space */ 625 we write data to the write-alloc'ed buffer space */
@@ -635,9 +633,9 @@ unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
635{ 633{
636 unsigned int free_end = async->buf_read_count + async->prealloc_bufsz; 634 unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
637 635
638 if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0) { 636 if ((int)(async->buf_write_alloc_count + nbytes - free_end) > 0)
639 nbytes = 0; 637 nbytes = 0;
640 } 638
641 async->buf_write_alloc_count += nbytes; 639 async->buf_write_alloc_count += nbytes;
642 /* barrier insures the read of buf_read_count above occurs before 640 /* barrier insures the read of buf_read_count above occurs before
643 we write data to the write-alloc'ed buffer space */ 641 we write data to the write-alloc'ed buffer space */
@@ -657,9 +655,9 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
657 async->buf_write_count += nbytes; 655 async->buf_write_count += nbytes;
658 async->buf_write_ptr += nbytes; 656 async->buf_write_ptr += nbytes;
659 comedi_buf_munge(async, async->buf_write_count - async->munge_count); 657 comedi_buf_munge(async, async->buf_write_count - async->munge_count);
660 if (async->buf_write_ptr >= async->prealloc_bufsz) { 658 if (async->buf_write_ptr >= async->prealloc_bufsz)
661 async->buf_write_ptr %= async->prealloc_bufsz; 659 async->buf_write_ptr %= async->prealloc_bufsz;
662 } 660
663 return nbytes; 661 return nbytes;
664} 662}
665 663
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
index 0af12fd2a40a..fbc26a027de4 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
index f3e47e5791db..a6898e4bbb62 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
index a15c952c0fab..0e498e9eb080 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
index 0fc2285c9ef8..204d7987700a 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
index 138a84f572c8..148ce6f67f0d 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
index a445dab50eac..6360de59e0e9 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
index 7e1254475792..344df9462198 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
index d3d78d37de5c..de6f77246890 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
index 6e9e7ed4dba9..97c10aaa691d 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
@@ -173,11 +173,10 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
173 } while (dw_eeprom_busy == EEPROM_BUSY); 173 } while (dw_eeprom_busy == EEPROM_BUSY);
174 174
175 /* Select the upper address part */ 175 /* Select the upper address part */
176 if (i_Counter == 0) { 176 if (i_Counter == 0)
177 b_ReadLowByte = pb_ReadByte[0]; 177 b_ReadLowByte = pb_ReadByte[0];
178 } else { 178 else
179 b_ReadHighByte = pb_ReadByte[0]; 179 b_ReadHighByte = pb_ReadByte[0];
180 }
181 180
182 /* Sleep */ 181 /* Sleep */
183 msleep(1); 182 msleep(1);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index a56535fbcd3e..8db5ab63e363 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
index 3ab27cf0facc..caeb6fd2d9b1 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -77,8 +77,8 @@ struct addi_board {
77 int i_NbrAoChannel; /* num of D/A chans */ 77 int i_NbrAoChannel; /* num of D/A chans */
78 int i_AiMaxdata; /* resolution of A/D */ 78 int i_AiMaxdata; /* resolution of A/D */
79 int i_AoMaxdata; /* resolution of D/A */ 79 int i_AoMaxdata; /* resolution of D/A */
80 const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */ 80 const struct comedi_lrange *pr_AiRangelist; /* rangelist for A/D */
81 const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */ 81 const struct comedi_lrange *pr_AoRangelist; /* rangelist for D/A */
82 82
83 int i_NbrDiChannel; /* Number of DI channels */ 83 int i_NbrDiChannel; /* Number of DI channels */
84 int i_NbrDoChannel; /* Number of DO channels */ 84 int i_NbrDoChannel; /* Number of DO channels */
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
index 69b427390e53..bea329f44d80 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
index 47517a938ec5..d7d768ee7c23 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
index 016721efdbfb..791297266fc0 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
index 723a97bab44c..fe06789699f3 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
@@ -54,7 +54,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
54#include "hwdrv_apci1032.h" 54#include "hwdrv_apci1032.h"
55#include <linux/delay.h> 55#include <linux/delay.h>
56/* Global variables */ 56/* Global variables */
57unsigned int ui_InterruptStatus = 0; 57unsigned int ui_InterruptStatus;
58 58
59/* 59/*
60+----------------------------------------------------------------------------+ 60+----------------------------------------------------------------------------+
@@ -108,9 +108,9 @@ int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde
108 ui_TmpValue = 108 ui_TmpValue =
109 inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); 109 inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
110 } /* if (data[1] == ADDIDATA_OR) */ 110 } /* if (data[1] == ADDIDATA_OR) */
111 else { 111 else
112 outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); 112 outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
113 } /* else if(data[1] == ADDIDATA_OR) */ 113 /* else if(data[1] == ADDIDATA_OR) */
114 } /* if( data[0] == ADDIDATA_ENABLE) */ 114 } /* if( data[0] == ADDIDATA_ENABLE) */
115 else { 115 else {
116 ul_Command1 = ul_Command1 & 0xFFFF0000; 116 ul_Command1 = ul_Command1 & 0xFFFF0000;
@@ -221,9 +221,9 @@ int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub
221 } /* switch(ui_NoOfChannels) */ 221 } /* switch(ui_NoOfChannels) */
222 } /* if(data[1]==0) */ 222 } /* if(data[1]==0) */
223 else { 223 else {
224 if (data[1] == 1) { 224 if (data[1] == 1)
225 *data = ui_InterruptStatus; 225 *data = ui_InterruptStatus;
226 } /* if(data[1]==1) */ 226 /* if(data[1]==1) */
227 } /* else if(data[1]==0) */ 227 } /* else if(data[1]==0) */
228 return insn->n; 228 return insn->n;
229} 229}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
index 36b929ffecbd..d5e06ad6acc2 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
index 866eb8d75820..7948c41f60f5 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index 3ae663bc754e..4413279c880b 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
index 988e3fc2b857..8bc88adfbb59 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
index d348cd5687aa..89783b1eb0bd 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
index ec817082d170..2d325163c169 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
index aa159dccc36a..e01889c3c4fc 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
index 172fba8dbfe5..f93ddd4eb06c 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
@@ -45,7 +45,7 @@ You shoud also find the complete GPL in the COPYING file accompanying this sourc
45*/ 45*/
46 46
47#include "hwdrv_apci3120.h" 47#include "hwdrv_apci3120.h"
48static unsigned int ui_Temp = 0; 48static unsigned int ui_Temp;
49 49
50/* FUNCTION DEFINITIONS */ 50/* FUNCTION DEFINITIONS */
51 51
@@ -98,25 +98,22 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su
98 98
99 devpriv->b_InterruptMode = APCI3120_EOS_MODE; 99 devpriv->b_InterruptMode = APCI3120_EOS_MODE;
100 100
101 if (data[1]) { 101 if (data[1])
102 devpriv->b_EocEosInterrupt = APCI3120_ENABLE; 102 devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
103 } else 103 else
104 devpriv->b_EocEosInterrupt = APCI3120_DISABLE; 104 devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
105 /* Copy channel list and Range List to devpriv */ 105 /* Copy channel list and Range List to devpriv */
106 106
107 devpriv->ui_AiNbrofChannels = data[3]; 107 devpriv->ui_AiNbrofChannels = data[3];
108 for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) { 108 for (i = 0; i < devpriv->ui_AiNbrofChannels; i++)
109 devpriv->ui_AiChannelList[i] = data[4 + i]; 109 devpriv->ui_AiChannelList[i] = data[4 + i];
110 }
111 110
112 } else /* EOC */ 111 } else { /* EOC */
113 {
114 devpriv->b_InterruptMode = APCI3120_EOC_MODE; 112 devpriv->b_InterruptMode = APCI3120_EOC_MODE;
115 if (data[1]) { 113 if (data[1])
116 devpriv->b_EocEosInterrupt = APCI3120_ENABLE; 114 devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
117 } else { 115 else
118 devpriv->b_EocEosInterrupt = APCI3120_DISABLE; 116 devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
119 }
120 } 117 }
121 118
122 return insn->n; 119 return insn->n;
@@ -166,13 +163,9 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd
166 devpriv->us_OutputRegister = 0; 163 devpriv->us_OutputRegister = 0;
167/* devpriv->b_DigitalOutputRegister=0; */ 164/* devpriv->b_DigitalOutputRegister=0; */
168 165
169 if (insn->unused[0] == 222) /* second insn read */ 166 if (insn->unused[0] == 222) { /* second insn read */
170 { 167 for (i = 0; i < insn->n; i++)
171
172 for (i = 0; i < insn->n; i++) {
173 data[i] = devpriv->ui_AiReadData[i]; 168 data[i] = devpriv->ui_AiReadData[i];
174 }
175
176 } else { 169 } else {
177 devpriv->tsk_Current = current; /* Save the current process task structure */ 170 devpriv->tsk_Current = current; /* Save the current process task structure */
178/* 171/*
@@ -519,9 +512,8 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
519 512
520 /* step 2: make sure trigger sources are unique and mutually compatible */ 513 /* step 2: make sure trigger sources are unique and mutually compatible */
521 514
522 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) { 515 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
523 err++; 516 err++;
524 }
525 517
526 if (cmd->scan_begin_src != TRIG_TIMER && 518 if (cmd->scan_begin_src != TRIG_TIMER &&
527 cmd->scan_begin_src != TRIG_FOLLOW) 519 cmd->scan_begin_src != TRIG_FOLLOW)
@@ -548,16 +540,14 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
548 err++; 540 err++;
549 } 541 }
550 542
551 if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ 543 if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */
552 {
553 if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) { 544 if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
554 cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs; 545 cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
555 err++; 546 err++;
556 } 547 }
557 } 548 }
558 549
559 if (cmd->convert_src == TRIG_TIMER) /* Test Acquisition timing */ 550 if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */
560 {
561 if (cmd->scan_begin_src == TRIG_TIMER) { 551 if (cmd->scan_begin_src == TRIG_TIMER) {
562 if ((cmd->convert_arg) 552 if ((cmd->convert_arg)
563 && (cmd->convert_arg < 553 && (cmd->convert_arg <
@@ -653,11 +643,10 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde
653 /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */ 643 /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */
654 devpriv->ui_AiDataLength = s->async->prealloc_bufsz; 644 devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
655 645
656 if (cmd->stop_src == TRIG_COUNT) { 646 if (cmd->stop_src == TRIG_COUNT)
657 devpriv->ui_AiNbrofScans = cmd->stop_arg; 647 devpriv->ui_AiNbrofScans = cmd->stop_arg;
658 } else { 648 else
659 devpriv->ui_AiNbrofScans = 0; 649 devpriv->ui_AiNbrofScans = 0;
660 }
661 650
662 devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ 651 devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */
663 devpriv->ui_AiTimer1 = 0; 652 devpriv->ui_AiTimer1 = 0;
@@ -849,9 +838,8 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
849 } 838 }
850/*** EL241003 End ******************************************************************************/ 839/*** EL241003 End ******************************************************************************/
851 840
852 if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) { 841 if (devpriv->b_ExttrigEnable == APCI3120_ENABLE)
853 i_APCI3120_ExttrigEnable(dev); /* activate EXT trigger */ 842 i_APCI3120_ExttrigEnable(dev); /* activate EXT trigger */
854 }
855 switch (mode) { 843 switch (mode) {
856 case 1: 844 case 1:
857 /* init timer0 in mode 2 */ 845 /* init timer0 in mode 2 */
@@ -1049,12 +1037,10 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
1049 dmalen1 = 4; 1037 dmalen1 = 4;
1050 } 1038 }
1051 } else { /* isn't output buff smaller that our DMA buff? */ 1039 } else { /* isn't output buff smaller that our DMA buff? */
1052 if (dmalen0 > (devpriv->ui_AiDataLength)) { 1040 if (dmalen0 > (devpriv->ui_AiDataLength))
1053 dmalen0 = devpriv->ui_AiDataLength; 1041 dmalen0 = devpriv->ui_AiDataLength;
1054 } 1042 if (dmalen1 > (devpriv->ui_AiDataLength))
1055 if (dmalen1 > (devpriv->ui_AiDataLength)) {
1056 dmalen1 = devpriv->ui_AiDataLength; 1043 dmalen1 = devpriv->ui_AiDataLength;
1057 }
1058 } 1044 }
1059 devpriv->ui_DmaBufferUsesize[0] = dmalen0; 1045 devpriv->ui_DmaBufferUsesize[0] = dmalen0;
1060 devpriv->ui_DmaBufferUsesize[1] = dmalen1; 1046 devpriv->ui_DmaBufferUsesize[1] = dmalen1;
@@ -1356,11 +1342,10 @@ int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevi
1356 /* store range list to card */ 1342 /* store range list to card */
1357 us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */ 1343 us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */
1358 1344
1359 if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) { 1345 if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES)
1360 us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ 1346 us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */
1361 } else { 1347 else
1362 us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */ 1348 us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */
1363 }
1364 1349
1365 gain = CR_RANGE(chanlist[i]); /* get gain number */ 1350 gain = CR_RANGE(chanlist[i]); /* get gain number */
1366 us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ 1351 us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */
@@ -1514,8 +1499,7 @@ void v_APCI3120_Interrupt(int irq, void *d)
1514 /* Check If EOS interrupt */ 1499 /* Check If EOS interrupt */
1515 if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) { 1500 if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) {
1516 1501
1517 if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) /* enable this in without DMA ??? */ 1502 if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) { /* enable this in without DMA ??? */
1518 {
1519 1503
1520 if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) { 1504 if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
1521 ui_Check = 0; 1505 ui_Check = 0;
@@ -1966,8 +1950,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
1966 APCI3120_DISABLE_EOS_INT; 1950 APCI3120_DISABLE_EOS_INT;
1967 outb(devpriv->b_ModeSelectRegister, 1951 outb(devpriv->b_ModeSelectRegister,
1968 devpriv->iobase + APCI3120_WRITE_MODE_SELECT); 1952 devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
1969 if (data[0] == APCI3120_TIMER) /* initialize timer */ 1953 if (data[0] == APCI3120_TIMER) { /* initialize timer */
1970 {
1971 /* devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | 1954 /* devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister |
1972 * APCI3120_ENABLE_TIMER_INT; */ 1955 * APCI3120_ENABLE_TIMER_INT; */
1973 1956
@@ -2006,8 +1989,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic
2006 /* timer2 in Timer mode enabled */ 1989 /* timer2 in Timer mode enabled */
2007 devpriv->b_Timer2Mode = APCI3120_TIMER; 1990 devpriv->b_Timer2Mode = APCI3120_TIMER;
2008 1991
2009 } else /* Initialize Watch dog */ 1992 } else { /* Initialize Watch dog */
2010 {
2011 1993
2012 /* Set the Timer 2 in mode 5(Watchdog) */ 1994 /* Set the Timer 2 in mode 5(Watchdog) */
2013 1995
@@ -2092,8 +2074,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
2092 return -EINVAL; 2074 return -EINVAL;
2093 } 2075 }
2094 2076
2095 if (data[0] == 2) /* write new value */ 2077 if (data[0] == 2) { /* write new value */
2096 {
2097 if (devpriv->b_Timer2Mode != APCI3120_TIMER) { 2078 if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
2098 comedi_error(dev, 2079 comedi_error(dev,
2099 "write :timer2 not configured in TIMER MODE"); 2080 "write :timer2 not configured in TIMER MODE");
@@ -2113,13 +2094,11 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
2113 2094
2114 /* Reset FC_TIMER BIT */ 2095 /* Reset FC_TIMER BIT */
2115 inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER); 2096 inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
2116 if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */ 2097 if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */
2117 {
2118 /* Enable Timer */ 2098 /* Enable Timer */
2119 devpriv->b_ModeSelectRegister = 2099 devpriv->b_ModeSelectRegister =
2120 devpriv->b_ModeSelectRegister & 0x0B; 2100 devpriv->b_ModeSelectRegister & 0x0B;
2121 } else /* start watch dog */ 2101 } else { /* start watch dog */
2122 {
2123 /* Enable WatchDog */ 2102 /* Enable WatchDog */
2124 devpriv->b_ModeSelectRegister = 2103 devpriv->b_ModeSelectRegister =
2125 (devpriv-> 2104 (devpriv->
@@ -2146,8 +2125,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice
2146 outb(devpriv->b_ModeSelectRegister, 2125 outb(devpriv->b_ModeSelectRegister,
2147 devpriv->iobase + APCI3120_WRITE_MODE_SELECT); 2126 devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
2148 2127
2149 if (devpriv->b_Timer2Mode == APCI3120_TIMER) /* start timer */ 2128 if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* start timer */
2150 {
2151 /* For Timer mode is Gate2 must be activated **timer started */ 2129 /* For Timer mode is Gate2 must be activated **timer started */
2152 devpriv->us_OutputRegister = 2130 devpriv->us_OutputRegister =
2153 devpriv-> 2131 devpriv->
@@ -2299,8 +2277,7 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice
2299 /* combining both words */ 2277 /* combining both words */
2300 data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16)); 2278 data[0] = (unsigned int) ((us_TmpValue) | ((us_TmpValue_2) << 16));
2301 2279
2302 } else /* Read watch dog status */ 2280 } else { /* Read watch dog status */
2303 {
2304 2281
2305 us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS); 2282 us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS);
2306 us_StatusValue = 2283 us_StatusValue =
@@ -2441,10 +2418,9 @@ int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
2441 devpriv->b_OutputMemoryStatus = APCI3120_DISABLE; 2418 devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
2442 devpriv->b_DigitalOutputRegister = 0; 2419 devpriv->b_DigitalOutputRegister = 0;
2443 } 2420 }
2444 if (!devpriv->b_OutputMemoryStatus) { 2421 if (!devpriv->b_OutputMemoryStatus)
2445 ui_Temp = 0; 2422 ui_Temp = 0;
2446 2423 /* if(!devpriv->b_OutputMemoryStatus ) */
2447 } /* if(!devpriv->b_OutputMemoryStatus ) */
2448 2424
2449 return insn->n; 2425 return insn->n;
2450} 2426}
@@ -2504,23 +2480,23 @@ int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev,
2504 2480
2505/* 2481/*
2506+----------------------------------------------------------------------------+ 2482+----------------------------------------------------------------------------+
2507| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,| 2483| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
2508|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | 2484|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
2509| | 2485| |
2510+----------------------------------------------------------------------------+ 2486+----------------------------------------------------------------------------+
2511| Task : Write digiatl output | 2487| Task : Write digiatl output |
2512| | 2488| |
2513+----------------------------------------------------------------------------+ 2489+----------------------------------------------------------------------------+
2514| Input Parameters : struct comedi_device *dev | 2490| Input Parameters : struct comedi_device *dev |
2515| struct comedi_subdevice *s | 2491| struct comedi_subdevice *s |
2516| struct comedi_insn *insn | 2492| struct comedi_insn *insn |
2517| unsigned int *data | 2493| unsigned int *data |
2518 data[0] Value to be written 2494 data[0] Value to be written
2519 data[1] :1 Set digital o/p ON 2495 data[1] :1 Set digital o/p ON
2520 data[1] 2 Set digital o/p OFF with memory ON 2496 data[1] 2 Set digital o/p OFF with memory ON
2521+----------------------------------------------------------------------------+ 2497+----------------------------------------------------------------------------+
2522| Return Value : | 2498| Return Value : |
2523| | 2499| |
2524+----------------------------------------------------------------------------+ 2500+----------------------------------------------------------------------------+
2525*/ 2501*/
2526 2502
@@ -2615,8 +2591,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
2615 ui_Channel = CR_CHAN(insn->chanspec); 2591 ui_Channel = CR_CHAN(insn->chanspec);
2616 2592
2617 /* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */ 2593 /* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */
2618 if (ui_Range) /* if 1 then unipolar */ 2594 if (ui_Range) { /* if 1 then unipolar */
2619 {
2620 2595
2621 if (data[0] != 0) 2596 if (data[0] != 0)
2622 data[0] = 2597 data[0] =
@@ -2627,8 +2602,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
2627 ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 << 2602 ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
2628 13) | 8192); 2603 13) | 8192);
2629 2604
2630 } else /* if 0 then bipolar */ 2605 } else { /* if 0 then bipolar */
2631 {
2632 data[0] = 2606 data[0] =
2633 ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) | 2607 ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
2634 data[0]); 2608 data[0]);
@@ -2639,8 +2613,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
2639 * out put n values at the given channel. printk("\nwaiting for 2613 * out put n values at the given channel. printk("\nwaiting for
2640 * DA_READY BIT"); 2614 * DA_READY BIT");
2641 */ 2615 */
2642 do /* Waiting of DA_READY BIT */ 2616 do { /* Waiting of DA_READY BIT */
2643 {
2644 us_TmpValue = 2617 us_TmpValue =
2645 ((unsigned short) inw(devpriv->iobase + 2618 ((unsigned short) inw(devpriv->iobase +
2646 APCI3120_RD_STATUS)) & 0x0001; 2619 APCI3120_RD_STATUS)) & 0x0001;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index 98c23872e374..560c848f6258 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
index 7b38d177394b..4ed441a1adc8 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
index 1d1e5fc2ea9a..3692326d474a 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -17,7 +17,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
17 17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19
20You shoud also find the complete GPL in the COPYING file accompanying this source code. 20You should also find the complete GPL in the COPYING file accompanying this source code.
21 21
22@endverbatim 22@endverbatim
23*/ 23*/
@@ -1206,7 +1206,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1206 1206
1207 if (b_Channel < 8) { 1207 if (b_Channel < 8) {
1208 /*****************************************************************************/ 1208 /*****************************************************************************/
1209 /* Read port 0 (first digital output port) and set/reset the selcted channel */ 1209 /* Read port 0 (first digital output port) and set/reset the selected channel */
1210 /*****************************************************************************/ 1210 /*****************************************************************************/
1211 1211
1212 dw_Status = inl(devpriv->iobase + 80); 1212 dw_Status = inl(devpriv->iobase + 80);
@@ -1228,7 +1228,7 @@ int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1228 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) 1228 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1229 == 0xFF) { 1229 == 0xFF) {
1230 /*****************************************************************************/ 1230 /*****************************************************************************/
1231 /* Read port 2 (first digital output port) and set/reset the selcted channel */ 1231 /* Read port 2 (first digital output port) and set/reset the selected channel */
1232 /*****************************************************************************/ 1232 /*****************************************************************************/
1233 1233
1234 dw_Status = inl(devpriv->iobase + 112); 1234 dw_Status = inl(devpriv->iobase + 112);
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 791ea8334e1e..9934a3cf2548 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -88,9 +88,9 @@ Configuration options:
88#define IORANGE_9118 64 /* I hope */ 88#define IORANGE_9118 64 /* I hope */
89#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */ 89#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */
90 90
91#define PCI9118_CNT0 0x00 /* R/W: 8254 couter 0 */ 91#define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */
92#define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */ 92#define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */
93#define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */ 93#define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */
94#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */ 94#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
95#define PCI9118_AD_DATA 0x10 /* R: A/D data */ 95#define PCI9118_AD_DATA 0x10 /* R: A/D data */
96#define PCI9118_DA1 0x10 /* W: D/A registers */ 96#define PCI9118_DA1 0x10 /* W: D/A registers */
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
index c5ed8bb97602..f3ba645bf63b 100644
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -42,23 +42,23 @@ If you do not specify any options, they will default to
42 option 1: I/O base address. The following table is provided as a help 42 option 1: I/O base address. The following table is provided as a help
43 of the hardware jumpers. 43 of the hardware jumpers.
44 44
45 address jumper JADR 45 address jumper JADR
46 0x300 1 (factory default) 46 0x300 1 (factory default)
47 0x320 2 47 0x320 2
48 0x340 3 48 0x340 3
49 0x360 4 49 0x360 4
50 0x380 5 50 0x380 5
51 0x3A0 6 51 0x3A0 6
52 52
53 option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar 53 option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
54 54
55 selection comedi_config option JUB 55 selection comedi_config option JUB
56 bipolar 0 2-3 (factory default) 56 bipolar 0 2-3 (factory default)
57 unipolar 1 1-2 57 unipolar 1 1-2
58 58
59 option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential 59 option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential
60 60
61 selection comedi_config option JCHA JCHB 61 selection comedi_config option JCHA JCHB
62 single-ended 0 1-2 1-2 (factory default) 62 single-ended 0 1-2 1-2 (factory default)
63 differential 1 2-3 2-3 63 differential 1 2-3 2-3
64 64
@@ -140,7 +140,7 @@ static const struct adq12b_board adq12b_boards[] = {
140 .ai_bits = 12, 140 .ai_bits = 12,
141 .di_chans = 8, 141 .di_chans = 8,
142 .do_chans = 5 142 .do_chans = 5
143 }*/ 143 }*/
144}; 144};
145 145
146#define thisboard ((const struct adq12b_board *)dev->board_ptr) 146#define thisboard ((const struct adq12b_board *)dev->board_ptr)
@@ -164,14 +164,15 @@ struct adq12b_private {
164static int adq12b_attach(struct comedi_device *dev, 164static int adq12b_attach(struct comedi_device *dev,
165 struct comedi_devconfig *it); 165 struct comedi_devconfig *it);
166static int adq12b_detach(struct comedi_device *dev); 166static int adq12b_detach(struct comedi_device *dev);
167
167static struct comedi_driver driver_adq12b = { 168static struct comedi_driver driver_adq12b = {
168driver_name:"adq12b", 169 .driver_name = "adq12b",
169module:THIS_MODULE, 170 .module = THIS_MODULE,
170attach:adq12b_attach, 171 .attach = adq12b_attach,
171detach:adq12b_detach, 172 .detach = adq12b_detach,
172board_name:&adq12b_boards[0].name, 173 .board_name = &adq12b_boards[0].name,
173offset:sizeof(struct adq12b_board), 174 .offset = sizeof(struct adq12b_board),
174num_names:ARRAY_SIZE(adq12b_boards), 175 .num_names = ARRAY_SIZE(adq12b_boards),
175}; 176};
176 177
177static int adq12b_ai_rinsn(struct comedi_device *dev, 178static int adq12b_ai_rinsn(struct comedi_device *dev,
@@ -200,15 +201,16 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
200 unipolar = it->options[1]; 201 unipolar = it->options[1];
201 differential = it->options[2]; 202 differential = it->options[2];
202 203
203 printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n", 204 printk(KERN_INFO "comedi%d: adq12b called with options base=0x%03lx, "
204 dev->minor, iobase, (unipolar == 1) ? "unipolar" : "bipolar", 205 "%s and %s\n", dev->minor, iobase,
206 (unipolar == 1) ? "unipolar" : "bipolar",
205 (differential == 1) ? "differential" : "single-ended"); 207 (differential == 1) ? "differential" : "single-ended");
206 208
207 /* if no address was specified, try the default 0x300 */ 209 /* if no address was specified, try the default 0x300 */
208 if (iobase == 0) { 210 if (iobase == 0) {
209 printk 211 printk(KERN_WARNING "comedi%d: adq12b warning: I/O base "
210 ("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n", 212 "address not specified. Trying the default 0x300.\n",
211 dev->minor); 213 dev->minor);
212 iobase = 0x300; 214 iobase = 0x300;
213 } 215 }
214 216
@@ -259,11 +261,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
259 s->n_chan = thisboard->ai_se_chans; 261 s->n_chan = thisboard->ai_se_chans;
260 } 262 }
261 263
262 if (unipolar) { 264 if (unipolar)
263 s->range_table = &range_adq12b_ai_unipolar; 265 s->range_table = &range_adq12b_ai_unipolar;
264 } else { 266 else
265 s->range_table = &range_adq12b_ai_bipolar; 267 s->range_table = &range_adq12b_ai_bipolar;
266 }
267 268
268 s->maxdata = (1 << thisboard->ai_bits) - 1; 269 s->maxdata = (1 << thisboard->ai_bits) - 1;
269 270
@@ -289,7 +290,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
289 s->range_table = &range_digital; 290 s->range_table = &range_digital;
290 s->insn_bits = adq12b_do_insn_bits; 291 s->insn_bits = adq12b_do_insn_bits;
291 292
292 printk("attached\n"); 293 printk(KERN_INFO "attached\n");
293 294
294 return 0; 295 return 0;
295} 296}
@@ -309,7 +310,7 @@ static int adq12b_detach(struct comedi_device *dev)
309 310
310 kfree(devpriv); 311 kfree(devpriv);
311 312
312 printk("comedi%d: adq12b: removed\n", dev->minor); 313 printk(KERN_INFO "comedi%d: adq12b: removed\n", dev->minor);
313 314
314 return 0; 315 return 0;
315} 316}
@@ -344,17 +345,18 @@ static int adq12b_ai_rinsn(struct comedi_device *dev,
344 /* wait for end of convertion */ 345 /* wait for end of convertion */
345 i = 0; 346 i = 0;
346 do { 347 do {
347/* udelay(1); */ 348 /* udelay(1); */
348 status = inb(dev->iobase + ADQ12B_STINR); 349 status = inb(dev->iobase + ADQ12B_STINR);
349 status = status & ADQ12B_EOC; 350 status = status & ADQ12B_EOC;
350 } while (status == 0 && ++i < TIMEOUT); 351 } while (status == 0 && ++i < TIMEOUT);
351/* } while (++i < 10); */ 352 /* } while (++i < 10); */
352 353
353 /* read data */ 354 /* read data */
354 hi = inb(dev->iobase + ADQ12B_ADHIG); 355 hi = inb(dev->iobase + ADQ12B_ADHIG);
355 lo = inb(dev->iobase + ADQ12B_ADLOW); 356 lo = inb(dev->iobase + ADQ12B_ADLOW);
356 357
357 /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo); */ 358 /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n",
359 channel, range, status, hi, lo); */
358 data[n] = (hi << 8) | lo; 360 data[n] = (hi << 8) | lo;
359 361
360 } 362 }
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index 951e57949f7f..394d2ea19c2e 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -84,9 +84,9 @@ Configuration options:
84#define PCI171x_DAREF 14 /* W: D/A reference control */ 84#define PCI171x_DAREF 14 /* W: D/A reference control */
85#define PCI171x_DI 16 /* R: digi inputs */ 85#define PCI171x_DI 16 /* R: digi inputs */
86#define PCI171x_DO 16 /* R: digi inputs */ 86#define PCI171x_DO 16 /* R: digi inputs */
87#define PCI171x_CNT0 24 /* R/W: 8254 couter 0 */ 87#define PCI171x_CNT0 24 /* R/W: 8254 counter 0 */
88#define PCI171x_CNT1 26 /* R/W: 8254 couter 1 */ 88#define PCI171x_CNT1 26 /* R/W: 8254 counter 1 */
89#define PCI171x_CNT2 28 /* R/W: 8254 couter 2 */ 89#define PCI171x_CNT2 28 /* R/W: 8254 counter 2 */
90#define PCI171x_CNTCTRL 30 /* W: 8254 counter control */ 90#define PCI171x_CNTCTRL 30 /* W: 8254 counter control */
91 91
92/* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */ 92/* upper bits from status register (PCI171x_STATUS) (lower is same woth control reg) */
@@ -724,6 +724,7 @@ static int move_block_from_fifo(struct comedi_device *dev,
724 devpriv->ai_act_scan++; 724 devpriv->ai_act_scan++;
725 } 725 }
726 } 726 }
727 s->async->cur_chan = j;
727 DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n"); 728 DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
728 return 0; 729 return 0;
729} 730}
@@ -1034,14 +1035,6 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
1034 } 1035 }
1035 } 1036 }
1036 1037
1037 if (!cmd->chanlist_len) {
1038 cmd->chanlist_len = 1;
1039 err++;
1040 }
1041 if (cmd->chanlist_len > this_board->n_aichan) {
1042 cmd->chanlist_len = this_board->n_aichan;
1043 err++;
1044 }
1045 if (cmd->scan_end_arg != cmd->chanlist_len) { 1038 if (cmd->scan_end_arg != cmd->chanlist_len) {
1046 cmd->scan_end_arg = cmd->chanlist_len; 1039 cmd->scan_end_arg = cmd->chanlist_len;
1047 err++; 1040 err++;
@@ -1230,6 +1223,12 @@ static void setup_channel_list(struct comedi_device *dev,
1230 DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, 1223 DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
1231 devpriv->act_chanlist[i]); 1224 devpriv->act_chanlist[i]);
1232 } 1225 }
1226#ifdef PCI171x_PARANOIDCHECK
1227 for ( ; i < n_chan; i++) { /* store remainder of channel list */
1228 devpriv->act_chanlist[i] =
1229 (CR_CHAN(chanlist[i]) << 12) & 0xf000;
1230 }
1231#endif
1233 1232
1234 devpriv->ai_et_MuxVal = 1233 devpriv->ai_et_MuxVal =
1235 CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); 1234 CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 3857fd566d21..4baef9ff932a 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -98,7 +98,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
98 int iobase; 98 int iobase;
99 struct comedi_subdevice *s; 99 struct comedi_subdevice *s;
100 100
101 printk("comedi%d: aio_iiro_16: ", dev->minor); 101 printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor);
102 102
103 dev->board_name = thisboard->name; 103 dev->board_name = thisboard->name;
104 104
@@ -140,7 +140,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
140 140
141static int aio_iiro_16_detach(struct comedi_device *dev) 141static int aio_iiro_16_detach(struct comedi_device *dev)
142{ 142{
143 printk("comedi%d: aio_iiro_16: remove\n", dev->minor); 143 printk(KERN_INFO "comedi%d: aio_iiro_16: remove\n", dev->minor);
144 144
145 if (dev->iobase) 145 if (dev->iobase)
146 release_region(dev->iobase, AIO_IIRO_16_SIZE); 146 release_region(dev->iobase, AIO_IIRO_16_SIZE);
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 69ab2813dd2e..204f30ef6e96 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -48,8 +48,8 @@ Passing a zero for an option is the same as leaving it unspecified.
48 48
49SUBDEVICES 49SUBDEVICES
50 50
51 PC218E PC212E PC215E/PCI215 51 PC218E PC212E PC215E/PCI215
52 ------------- ------------- ------------- 52 ------------- ------------- -------------
53 Subdevices 7 6 5 53 Subdevices 7 6 5
54 0 CTR-X1 PPI-X PPI-X 54 0 CTR-X1 PPI-X PPI-X
55 1 CTR-X2 CTR-Y1 PPI-Y 55 1 CTR-X2 CTR-Y1 PPI-Y
@@ -59,8 +59,8 @@ SUBDEVICES
59 5 CTR-Z2 INTERRUPT 59 5 CTR-Z2 INTERRUPT
60 6 INTERRUPT 60 6 INTERRUPT
61 61
62 PC214E PC272E/PCI272 62 PC214E PC272E/PCI272
63 ------------- ------------- 63 ------------- -------------
64 Subdevices 4 4 64 Subdevices 4 4
65 0 PPI-X PPI-X 65 0 PPI-X PPI-X
66 1 PPI-Y PPI-Y 66 1 PPI-Y PPI-Y
@@ -96,8 +96,8 @@ instructions are supported:
96 0 to 7 as follows: 96 0 to 7 as follows:
97 97
98 0. CLK n, the counter channel's dedicated CLK input from the SK1 98 0. CLK n, the counter channel's dedicated CLK input from the SK1
99 connector. (N.B. for other values, the counter channel's CLKn 99 connector. (N.B. for other values, the counter channel's CLKn
100 pin on the SK1 connector is an output!) 100 pin on the SK1 connector is an output!)
101 1. Internal 10 MHz clock. 101 1. Internal 10 MHz clock.
102 2. Internal 1 MHz clock. 102 2. Internal 1 MHz clock.
103 3. Internal 100 kHz clock. 103 3. Internal 100 kHz clock.
@@ -105,8 +105,8 @@ instructions are supported:
105 5. Internal 1 kHz clock. 105 5. Internal 1 kHz clock.
106 6. OUT n-1, the output of counter channel n-1 (see note 1 below). 106 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
107 7. Ext Clock, the counter chip's dedicated Ext Clock input from 107 7. Ext Clock, the counter chip's dedicated Ext Clock input from
108 the SK1 connector. This pin is shared by all three counter 108 the SK1 connector. This pin is shared by all three counter
109 channels on the chip. 109 channels on the chip.
110 110
111 INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current 111 INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
112 clock source in data[1]. For internal clock sources, data[2] is set 112 clock source in data[1]. For internal clock sources, data[2] is set
@@ -120,10 +120,10 @@ instructions are supported:
120 0. VCC (internal +5V d.c.), i.e. gate permanently enabled. 120 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
121 1. GND (internal 0V d.c.), i.e. gate permanently disabled. 121 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
122 2. GAT n, the counter channel's dedicated GAT input from the SK1 122 2. GAT n, the counter channel's dedicated GAT input from the SK1
123 connector. (N.B. for other values, the counter channel's GATn 123 connector. (N.B. for other values, the counter channel's GATn
124 pin on the SK1 connector is an output!) 124 pin on the SK1 connector is an output!)
125 3. /OUT n-2, the inverted output of counter channel n-2 (see note 125 3. /OUT n-2, the inverted output of counter channel n-2 (see note
126 2 below). 126 2 below).
127 4. Reserved. 127 4. Reserved.
128 5. Reserved. 128 5. Reserved.
129 6. Reserved. 129 6. Reserved.
@@ -153,8 +153,8 @@ below.
153 153
154INTERRUPT SOURCES 154INTERRUPT SOURCES
155 155
156 PC218E PC212E PC215E/PCI215 156 PC218E PC212E PC215E/PCI215
157 ------------- ------------- ------------- 157 ------------- ------------- -------------
158 Sources 6 6 6 158 Sources 6 6 6
159 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0 159 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
160 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3 160 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
@@ -163,8 +163,8 @@ INTERRUPT SOURCES
163 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT 163 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
164 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT 164 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
165 165
166 PC214E PC272E/PCI272 166 PC214E PC272E/PCI272
167 ------------- ------------- 167 ------------- -------------
168 Sources 1 6 168 Sources 1 6
169 0 JUMPER-J5 PPI-X-C0 169 0 JUMPER-J5 PPI-X-C0
170 1 PPI-X-C3 170 1 PPI-X-C3
@@ -435,11 +435,13 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table);
435 * Useful for shorthand access to the particular board structure 435 * Useful for shorthand access to the particular board structure
436 */ 436 */
437#define thisboard ((const struct dio200_board *)dev->board_ptr) 437#define thisboard ((const struct dio200_board *)dev->board_ptr)
438#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout]) 438#define thislayout (&dio200_layouts[((struct dio200_board *) \
439 dev->board_ptr)->layout])
439 440
440/* this structure is for data unique to this hardware driver. If 441/* this structure is for data unique to this hardware driver. If
441 several hardware drivers keep similar information in this structure, 442 several hardware drivers keep similar information in this structure,
442 feel free to suggest moving the variable to the struct comedi_device struct. */ 443 feel free to suggest moving the variable to the struct comedi_device struct.
444 */
443struct dio200_private { 445struct dio200_private {
444#ifdef CONFIG_COMEDI_PCI 446#ifdef CONFIG_COMEDI_PCI
445 struct pci_dev *pci_dev; /* PCI device */ 447 struct pci_dev *pci_dev; /* PCI device */
@@ -603,9 +605,8 @@ static void dio200_stop_intr(struct comedi_device *dev,
603 605
604 subpriv->active = 0; 606 subpriv->active = 0;
605 subpriv->enabled_isns = 0; 607 subpriv->enabled_isns = 0;
606 if (subpriv->has_int_sce) { 608 if (subpriv->has_int_sce)
607 outb(0, subpriv->iobase); 609 outb(0, subpriv->iobase);
608 }
609} 610}
610 611
611/* 612/*
@@ -629,16 +630,14 @@ static int dio200_start_intr(struct comedi_device *dev,
629 /* Determine interrupt sources to enable. */ 630 /* Determine interrupt sources to enable. */
630 isn_bits = 0; 631 isn_bits = 0;
631 if (cmd->chanlist) { 632 if (cmd->chanlist) {
632 for (n = 0; n < cmd->chanlist_len; n++) { 633 for (n = 0; n < cmd->chanlist_len; n++)
633 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n])); 634 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
634 }
635 } 635 }
636 isn_bits &= subpriv->valid_isns; 636 isn_bits &= subpriv->valid_isns;
637 /* Enable interrupt sources. */ 637 /* Enable interrupt sources. */
638 subpriv->enabled_isns = isn_bits; 638 subpriv->enabled_isns = isn_bits;
639 if (subpriv->has_int_sce) { 639 if (subpriv->has_int_sce)
640 outb(isn_bits, subpriv->iobase); 640 outb(isn_bits, subpriv->iobase);
641 }
642 } 641 }
643 642
644 return retval; 643 return retval;
@@ -662,14 +661,13 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
662 661
663 spin_lock_irqsave(&subpriv->spinlock, flags); 662 spin_lock_irqsave(&subpriv->spinlock, flags);
664 s->async->inttrig = 0; 663 s->async->inttrig = 0;
665 if (subpriv->active) { 664 if (subpriv->active)
666 event = dio200_start_intr(dev, s); 665 event = dio200_start_intr(dev, s);
667 } 666
668 spin_unlock_irqrestore(&subpriv->spinlock, flags); 667 spin_unlock_irqrestore(&subpriv->spinlock, flags);
669 668
670 if (event) { 669 if (event)
671 comedi_event(dev, s); 670 comedi_event(dev, s);
672 }
673 671
674 return 1; 672 return 1;
675} 673}
@@ -726,9 +724,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
726 * Reenable them NOW to minimize the time they are disabled. 724 * Reenable them NOW to minimize the time they are disabled.
727 */ 725 */
728 cur_enabled = subpriv->enabled_isns; 726 cur_enabled = subpriv->enabled_isns;
729 if (subpriv->has_int_sce) { 727 if (subpriv->has_int_sce)
730 outb(cur_enabled, subpriv->iobase); 728 outb(cur_enabled, subpriv->iobase);
731 }
732 729
733 if (subpriv->active) { 730 if (subpriv->active) {
734 /* 731 /*
@@ -747,9 +744,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
747 len = s->async->cmd.chanlist_len; 744 len = s->async->cmd.chanlist_len;
748 for (n = 0; n < len; n++) { 745 for (n = 0; n < len; n++) {
749 ch = CR_CHAN(s->async->cmd.chanlist[n]); 746 ch = CR_CHAN(s->async->cmd.chanlist[n]);
750 if (triggered & (1U << ch)) { 747 if (triggered & (1U << ch))
751 val |= (1U << n); 748 val |= (1U << n);
752 }
753 } 749 }
754 /* Write the scan to the buffer. */ 750 /* Write the scan to the buffer. */
755 if (comedi_buf_put(s->async, val)) { 751 if (comedi_buf_put(s->async, val)) {
@@ -781,9 +777,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev,
781 } 777 }
782 spin_unlock_irqrestore(&subpriv->spinlock, flags); 778 spin_unlock_irqrestore(&subpriv->spinlock, flags);
783 779
784 if (oldevents != s->async->events) { 780 if (oldevents != s->async->events)
785 comedi_event(dev, s); 781 comedi_event(dev, s);
786 }
787 782
788 return (triggered != 0); 783 return (triggered != 0);
789} 784}
@@ -798,9 +793,9 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev,
798 unsigned long flags; 793 unsigned long flags;
799 794
800 spin_lock_irqsave(&subpriv->spinlock, flags); 795 spin_lock_irqsave(&subpriv->spinlock, flags);
801 if (subpriv->active) { 796 if (subpriv->active)
802 dio200_stop_intr(dev, s); 797 dio200_stop_intr(dev, s);
803 } 798
804 spin_unlock_irqrestore(&subpriv->spinlock, flags); 799 spin_unlock_irqrestore(&subpriv->spinlock, flags);
805 800
806 return 0; 801 return 0;
@@ -846,7 +841,8 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev,
846 if (err) 841 if (err)
847 return 1; 842 return 1;
848 843
849 /* step 2: make sure trigger sources are unique and mutually compatible */ 844 /* step 2: make sure trigger sources are unique and mutually
845 compatible */
850 846
851 /* these tests are true if more than one _src bit is set */ 847 /* these tests are true if more than one _src bit is set */
852 if ((cmd->start_src & (cmd->start_src - 1)) != 0) 848 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
@@ -952,9 +948,8 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev,
952 } 948 }
953 spin_unlock_irqrestore(&subpriv->spinlock, flags); 949 spin_unlock_irqrestore(&subpriv->spinlock, flags);
954 950
955 if (event) { 951 if (event)
956 comedi_event(dev, s); 952 comedi_event(dev, s);
957 }
958 953
959 return 0; 954 return 0;
960} 955}
@@ -980,9 +975,8 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
980 subpriv->valid_isns = valid_isns; 975 subpriv->valid_isns = valid_isns;
981 spin_lock_init(&subpriv->spinlock); 976 spin_lock_init(&subpriv->spinlock);
982 977
983 if (has_int_sce) { 978 if (has_int_sce)
984 outb(0, subpriv->iobase); /* Disable interrupt sources. */ 979 outb(0, subpriv->iobase); /* Disable interrupt sources. */
985 }
986 980
987 s->private = subpriv; 981 s->private = subpriv;
988 s->type = COMEDI_SUBD_DI; 982 s->type = COMEDI_SUBD_DI;
@@ -1013,10 +1007,7 @@ dio200_subdev_intr_cleanup(struct comedi_device *dev,
1013 struct comedi_subdevice *s) 1007 struct comedi_subdevice *s)
1014{ 1008{
1015 struct dio200_subdev_intr *subpriv = s->private; 1009 struct dio200_subdev_intr *subpriv = s->private;
1016 1010 kfree(subpriv);
1017 if (subpriv) {
1018 kfree(subpriv);
1019 }
1020} 1011}
1021 1012
1022/* 1013/*
@@ -1027,9 +1018,8 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
1027 struct comedi_device *dev = d; 1018 struct comedi_device *dev = d;
1028 int handled; 1019 int handled;
1029 1020
1030 if (!dev->attached) { 1021 if (!dev->attached)
1031 return IRQ_NONE; 1022 return IRQ_NONE;
1032 }
1033 1023
1034 if (devpriv->intr_sd >= 0) { 1024 if (devpriv->intr_sd >= 0) {
1035 handled = dio200_handle_read_intr(dev, 1025 handled = dio200_handle_read_intr(dev,
@@ -1266,10 +1256,7 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev,
1266 struct comedi_subdevice *s) 1256 struct comedi_subdevice *s)
1267{ 1257{
1268 struct dio200_subdev_intr *subpriv = s->private; 1258 struct dio200_subdev_intr *subpriv = s->private;
1269 1259 kfree(subpriv);
1270 if (subpriv) {
1271 kfree(subpriv);
1272 }
1273} 1260}
1274 1261
1275/* 1262/*
@@ -1348,9 +1335,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1348#endif 1335#endif
1349 { 1336 {
1350 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); 1337 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
1351 if (ret < 0) { 1338 if (ret < 0)
1352 return ret; 1339 return ret;
1353 }
1354 } 1340 }
1355 dev->iobase = iobase; 1341 dev->iobase = iobase;
1356 1342
@@ -1371,17 +1357,17 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1371 ret = dio200_subdev_8254_init(dev, s, iobase, 1357 ret = dio200_subdev_8254_init(dev, s, iobase,
1372 layout->sdinfo[n], 1358 layout->sdinfo[n],
1373 layout->has_clk_gat_sce); 1359 layout->has_clk_gat_sce);
1374 if (ret < 0) { 1360 if (ret < 0)
1375 return ret; 1361 return ret;
1376 } 1362
1377 break; 1363 break;
1378 case sd_8255: 1364 case sd_8255:
1379 /* digital i/o subdevice (8255) */ 1365 /* digital i/o subdevice (8255) */
1380 ret = subdev_8255_init(dev, s, 0, 1366 ret = subdev_8255_init(dev, s, 0,
1381 iobase + layout->sdinfo[n]); 1367 iobase + layout->sdinfo[n]);
1382 if (ret < 0) { 1368 if (ret < 0)
1383 return ret; 1369 return ret;
1384 } 1370
1385 break; 1371 break;
1386 case sd_intr: 1372 case sd_intr:
1387 /* 'INTERRUPT' subdevice */ 1373 /* 'INTERRUPT' subdevice */
@@ -1392,9 +1378,9 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1392 layout->sdinfo[n], 1378 layout->sdinfo[n],
1393 layout-> 1379 layout->
1394 has_int_sce); 1380 has_int_sce);
1395 if (ret < 0) { 1381 if (ret < 0)
1396 return ret; 1382 return ret;
1397 } 1383
1398 devpriv->intr_sd = n; 1384 devpriv->intr_sd = n;
1399 } else { 1385 } else {
1400 s->type = COMEDI_SUBD_UNUSED; 1386 s->type = COMEDI_SUBD_UNUSED;
@@ -1407,9 +1393,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1407 } 1393 }
1408 1394
1409 sdx = devpriv->intr_sd; 1395 sdx = devpriv->intr_sd;
1410 if (sdx >= 0 && sdx < dev->n_subdevices) { 1396 if (sdx >= 0 && sdx < dev->n_subdevices)
1411 dev->read_subdev = &dev->subdevices[sdx]; 1397 dev->read_subdev = &dev->subdevices[sdx];
1412 }
1413 1398
1414 dev->board_name = thisboard->name; 1399 dev->board_name = thisboard->name;
1415 1400
@@ -1434,11 +1419,10 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1434 printk("(pci %s) ", pci_name(pci_dev)); 1419 printk("(pci %s) ", pci_name(pci_dev));
1435#endif 1420#endif
1436 } 1421 }
1437 if (irq) { 1422 if (irq)
1438 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); 1423 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
1439 } else { 1424 else
1440 printk("(no irq) "); 1425 printk("(no irq) ");
1441 }
1442 1426
1443 printk("attached\n"); 1427 printk("attached\n");
1444 1428
@@ -1461,9 +1445,8 @@ static int dio200_detach(struct comedi_device *dev)
1461 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, 1445 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
1462 DIO200_DRIVER_NAME); 1446 DIO200_DRIVER_NAME);
1463 1447
1464 if (dev->irq) { 1448 if (dev->irq)
1465 free_irq(dev->irq, dev); 1449 free_irq(dev->irq, dev);
1466 }
1467 if (dev->subdevices) { 1450 if (dev->subdevices) {
1468 layout = thislayout; 1451 layout = thislayout;
1469 for (n = 0; n < dev->n_subdevices; n++) { 1452 for (n = 0; n < dev->n_subdevices; n++) {
@@ -1486,22 +1469,19 @@ static int dio200_detach(struct comedi_device *dev)
1486 if (devpriv) { 1469 if (devpriv) {
1487#ifdef CONFIG_COMEDI_PCI 1470#ifdef CONFIG_COMEDI_PCI
1488 if (devpriv->pci_dev) { 1471 if (devpriv->pci_dev) {
1489 if (dev->iobase) { 1472 if (dev->iobase)
1490 comedi_pci_disable(devpriv->pci_dev); 1473 comedi_pci_disable(devpriv->pci_dev);
1491 }
1492 pci_dev_put(devpriv->pci_dev); 1474 pci_dev_put(devpriv->pci_dev);
1493 } else 1475 } else
1494#endif 1476#endif
1495 { 1477 {
1496 if (dev->iobase) { 1478 if (dev->iobase)
1497 release_region(dev->iobase, DIO200_IO_SIZE); 1479 release_region(dev->iobase, DIO200_IO_SIZE);
1498 }
1499 } 1480 }
1500 } 1481 }
1501 if (dev->board_name) { 1482 if (dev->board_name)
1502 printk(KERN_INFO "comedi%d: %s removed\n", 1483 printk(KERN_INFO "comedi%d: %s removed\n",
1503 dev->minor, dev->board_name); 1484 dev->minor, dev->board_name);
1504 }
1505 1485
1506 return 0; 1486 return 0;
1507} 1487}
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index 1032a8110d6e..a307d68d79c6 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -78,18 +78,18 @@ unused.
78 */ 78 */
79/* Disable interrupt, also clear any interrupt there */ 79/* Disable interrupt, also clear any interrupt there */
80#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \ 80#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \
81 | PLX9052_INTCSR_LI1POL_HIGH \ 81 | PLX9052_INTCSR_LI1POL_HIGH \
82 | PLX9052_INTCSR_LI2POL_HIGH \ 82 | PLX9052_INTCSR_LI2POL_HIGH \
83 | PLX9052_INTCSR_PCIENAB_DISABLED \ 83 | PLX9052_INTCSR_PCIENAB_DISABLED \
84 | PLX9052_INTCSR_LI1SEL_EDGE \ 84 | PLX9052_INTCSR_LI1SEL_EDGE \
85 | PLX9052_INTCSR_LI1CLRINT_ASSERTED) 85 | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
86/* Enable interrupt, also clear any interrupt there. */ 86/* Enable interrupt, also clear any interrupt there. */
87#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \ 87#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \
88 | PLX9052_INTCSR_LI1POL_HIGH \ 88 | PLX9052_INTCSR_LI1POL_HIGH \
89 | PLX9052_INTCSR_LI2POL_HIGH \ 89 | PLX9052_INTCSR_LI2POL_HIGH \
90 | PLX9052_INTCSR_PCIENAB_ENABLED \ 90 | PLX9052_INTCSR_PCIENAB_ENABLED \
91 | PLX9052_INTCSR_LI1SEL_EDGE \ 91 | PLX9052_INTCSR_LI1SEL_EDGE \
92 | PLX9052_INTCSR_LI1CLRINT_ASSERTED) 92 | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
93 93
94/* 94/*
95 * Board descriptions for Amplicon PC36AT and PCI236. 95 * Board descriptions for Amplicon PC36AT and PCI236.
@@ -150,12 +150,13 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table);
150 150
151/* this structure is for data unique to this hardware driver. If 151/* this structure is for data unique to this hardware driver. If
152 several hardware drivers keep similar information in this structure, 152 several hardware drivers keep similar information in this structure,
153 feel free to suggest moving the variable to the struct comedi_device struct. */ 153 feel free to suggest moving the variable to the struct comedi_device struct.
154 */
154struct pc236_private { 155struct pc236_private {
155#ifdef CONFIG_COMEDI_PCI 156#ifdef CONFIG_COMEDI_PCI
156 /* PCI device */ 157 /* PCI device */
157 struct pci_dev *pci_dev; 158 struct pci_dev *pci_dev;
158 unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ 159 unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
159#endif 160#endif
160 int enable_irq; 161 int enable_irq;
161}; 162};
@@ -345,9 +346,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
345#endif 346#endif
346 { 347 {
347 ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); 348 ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
348 if (ret < 0) { 349 if (ret < 0)
349 return ret; 350 return ret;
350 }
351 } 351 }
352 dev->iobase = iobase; 352 dev->iobase = iobase;
353 353
@@ -399,11 +399,10 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
399 printk("(pci %s) ", pci_name(pci_dev)); 399 printk("(pci %s) ", pci_name(pci_dev));
400#endif 400#endif
401 } 401 }
402 if (irq) { 402 if (irq)
403 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); 403 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
404 } else { 404 else
405 printk("(no irq) "); 405 printk("(no irq) ");
406 }
407 406
408 printk("attached\n"); 407 printk("attached\n");
409 408
@@ -422,27 +421,24 @@ static int pc236_detach(struct comedi_device *dev)
422{ 421{
423 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, 422 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
424 PC236_DRIVER_NAME); 423 PC236_DRIVER_NAME);
425 if (devpriv) { 424 if (devpriv)
426 pc236_intr_disable(dev); 425 pc236_intr_disable(dev);
427 } 426
428 if (dev->irq) 427 if (dev->irq)
429 free_irq(dev->irq, dev); 428 free_irq(dev->irq, dev);
430 if (dev->subdevices) { 429 if (dev->subdevices)
431 subdev_8255_cleanup(dev, dev->subdevices + 0); 430 subdev_8255_cleanup(dev, dev->subdevices + 0);
432 }
433 if (devpriv) { 431 if (devpriv) {
434#ifdef CONFIG_COMEDI_PCI 432#ifdef CONFIG_COMEDI_PCI
435 if (devpriv->pci_dev) { 433 if (devpriv->pci_dev) {
436 if (dev->iobase) { 434 if (dev->iobase)
437 comedi_pci_disable(devpriv->pci_dev); 435 comedi_pci_disable(devpriv->pci_dev);
438 }
439 pci_dev_put(devpriv->pci_dev); 436 pci_dev_put(devpriv->pci_dev);
440 } else 437 } else
441#endif 438#endif
442 { 439 {
443 if (dev->iobase) { 440 if (dev->iobase)
444 release_region(dev->iobase, PC236_IO_SIZE); 441 release_region(dev->iobase, PC236_IO_SIZE);
445 }
446 } 442 }
447 } 443 }
448 if (dev->board_name) { 444 if (dev->board_name) {
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index d9836879355e..b41e5e5963aa 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -1536,20 +1536,12 @@ static int pci224_detach(struct comedi_device *dev)
1536 1536
1537 s = dev->subdevices + 0; 1537 s = dev->subdevices + 0;
1538 /* AO subdevice */ 1538 /* AO subdevice */
1539 if (s->range_table_list) { 1539 kfree(s->range_table_list);
1540 kfree(s->range_table_list);
1541 }
1542 } 1540 }
1543 if (devpriv) { 1541 if (devpriv) {
1544 if (devpriv->ao_readback) { 1542 kfree(devpriv->ao_readback);
1545 kfree(devpriv->ao_readback); 1543 kfree(devpriv->ao_scan_vals);
1546 } 1544 kfree(devpriv->ao_scan_order);
1547 if (devpriv->ao_scan_vals) {
1548 kfree(devpriv->ao_scan_vals);
1549 }
1550 if (devpriv->ao_scan_order) {
1551 kfree(devpriv->ao_scan_order);
1552 }
1553 if (devpriv->pci_dev) { 1545 if (devpriv->pci_dev) {
1554 if (dev->iobase) { 1546 if (dev->iobase) {
1555 comedi_pci_disable(devpriv->pci_dev); 1547 comedi_pci_disable(devpriv->pci_dev);
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
index abb0532182ba..fb0d5fa71765 100644
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -45,7 +45,7 @@ http://robot0.ge.uiuc.edu/~spong/mecha/
45#include <linux/interrupt.h> 45#include <linux/interrupt.h>
46#include <linux/timex.h> 46#include <linux/timex.h>
47#include <linux/timer.h> 47#include <linux/timer.h>
48#include <asm/io.h> 48#include <linux/io.h>
49#include <linux/pnp.h> 49#include <linux/pnp.h>
50 50
51#include "../comedidev.h" 51#include "../comedidev.h"
@@ -220,11 +220,11 @@ static int C6X_encInput(unsigned long baseAddr, unsigned channel)
220 /* printk("Inside C6X_encInput\n"); */ 220 /* printk("Inside C6X_encInput\n"); */
221 221
222 enc.value = 0; 222 enc.value = 0;
223 if (channel == 0) { 223 if (channel == 0)
224 ppcmd = 0x48; 224 ppcmd = 0x48;
225 } else { 225 else
226 ppcmd = 0x50; 226 ppcmd = 0x50;
227 } 227
228 WriteByteToHwPort(baseAddr, ppcmd); 228 WriteByteToHwPort(baseAddr, ppcmd);
229 tmp = ReadByteFromHwPort(baseAddr + 1); 229 tmp = ReadByteFromHwPort(baseAddr + 1);
230 while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) { 230 while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
@@ -391,9 +391,8 @@ static int c6xdigio_ei_insn_read(struct comedi_device *dev,
391 int n; 391 int n;
392 int chan = CR_CHAN(insn->chanspec); 392 int chan = CR_CHAN(insn->chanspec);
393 393
394 for (n = 0; n < insn->n; n++) { 394 for (n = 0; n < insn->n; n++)
395 data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff); 395 data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
396 }
397 396
398 return n; 397 return n;
399} 398}
@@ -420,9 +419,9 @@ static void board_init(struct comedi_device *dev)
420 419
421static const struct pnp_device_id c6xdigio_pnp_tbl[] = { 420static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
422 /* Standard LPT Printer Port */ 421 /* Standard LPT Printer Port */
423 {.id = "PNP0400",.driver_data = 0}, 422 {.id = "PNP0400", .driver_data = 0},
424 /* ECP Printer Port */ 423 /* ECP Printer Port */
425 {.id = "PNP0401",.driver_data = 0}, 424 {.id = "PNP0401", .driver_data = 0},
426 {} 425 {}
427}; 426};
428 427
@@ -452,15 +451,14 @@ static int c6xdigio_attach(struct comedi_device *dev,
452 if (result < 0) 451 if (result < 0)
453 return result; 452 return result;
454 453
455 /* Make sure that PnP ports gets activated */ 454 /* Make sure that PnP ports get activated */
456 pnp_register_driver(&c6xdigio_pnp_driver); 455 pnp_register_driver(&c6xdigio_pnp_driver);
457 456
458 irq = it->options[1]; 457 irq = it->options[1];
459 if (irq > 0) { 458 if (irq > 0)
460 printk("comedi%d: irq = %u ignored\n", dev->minor, irq); 459 printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
461 } else if (irq == 0) { 460 else if (irq == 0)
462 printk("comedi%d: no irq\n", dev->minor); 461 printk("comedi%d: no irq\n", dev->minor);
463 }
464 462
465 s = dev->subdevices + 0; 463 s = dev->subdevices + 0;
466 /* pwm output subdevice */ 464 /* pwm output subdevice */
@@ -483,19 +481,19 @@ static int c6xdigio_attach(struct comedi_device *dev,
483 s->maxdata = 0xffffff; 481 s->maxdata = 0xffffff;
484 s->range_table = &range_unknown; 482 s->range_table = &range_unknown;
485 483
486 /* s = dev->subdevices + 2; */ 484 /* s = dev->subdevices + 2; */
487 /* pwm output subdevice */ 485 /* pwm output subdevice */
488 /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ 486 /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */
489 /* s->subdev_flags = SDF_WRITEABLE; */ 487 /* s->subdev_flags = SDF_WRITEABLE; */
490 /* s->n_chan = 1; */ 488 /* s->n_chan = 1; */
491 /* s->trig[0] = c6xdigio_ei_init; */ 489 /* s->trig[0] = c6xdigio_ei_init; */
492 /* s->insn_read = c6xdigio_ei_init_insn_read; */ 490 /* s->insn_read = c6xdigio_ei_init_insn_read; */
493 /* s->insn_write = c6xdigio_ei_init_insn_write; */ 491 /* s->insn_write = c6xdigio_ei_init_insn_write; */
494 /* s->maxdata = 0xFFFF; // Really just a don't care */ 492 /* s->maxdata = 0xFFFF; // Really just a don't care */
495 /* s->range_table = &range_unknown; // Not sure what to put here */ 493 /* s->range_table = &range_unknown; // Not sure what to put here */
496 494
497 /* I will call this init anyway but more than likely the DSP board will not be connect */ 495 /* I will call this init anyway but more than likely the DSP board */
498 /* when device driver is loaded. */ 496 /* will not be connected when device driver is loaded. */
499 board_init(dev); 497 board_init(dev);
500 498
501 return 0; 499 return 0;
@@ -503,16 +501,17 @@ static int c6xdigio_attach(struct comedi_device *dev,
503 501
504static int c6xdigio_detach(struct comedi_device *dev) 502static int c6xdigio_detach(struct comedi_device *dev)
505{ 503{
506/* board_halt(dev); may not need this */ 504 /* board_halt(dev); may not need this */
507 505
508 printk("comedi%d: c6xdigio: remove\n", dev->minor); 506 printk("comedi%d: c6xdigio: remove\n", dev->minor);
509 507
510 if (dev->iobase) { 508 if (dev->iobase)
511 release_region(dev->iobase, C6XDIGIO_SIZE); 509 release_region(dev->iobase, C6XDIGIO_SIZE);
512 } 510
513 if (dev->irq) { 511 /* Not using IRQ so I am not sure if I need this */
512 if (dev->irq)
514 free_irq(dev->irq, dev); 513 free_irq(dev->irq, dev);
515 } /* Not using IRQ so I am not sure if I need this */ 514
516 pnp_unregister_driver(&c6xdigio_pnp_driver); 515 pnp_unregister_driver(&c6xdigio_pnp_driver);
517 516
518 return 0; 517 return 0;
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index f3e66c440a38..434591de37c5 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -518,7 +518,7 @@ static int trimpot_7376_write(struct comedi_device *dev, uint8_t value);
518static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 518static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
519 uint8_t value); 519 uint8_t value);
520static int nvram_read(struct comedi_device *dev, unsigned int address, 520static int nvram_read(struct comedi_device *dev, unsigned int address,
521 uint8_t * data); 521 uint8_t *data);
522 522
523static inline unsigned int cal_enable_bits(struct comedi_device *dev) 523static inline unsigned int cal_enable_bits(struct comedi_device *dev)
524{ 524{
@@ -760,9 +760,8 @@ static int cb_pcidas_detach(struct comedi_device *dev)
760 if (dev->subdevices) 760 if (dev->subdevices)
761 subdev_8255_cleanup(dev, dev->subdevices + 2); 761 subdev_8255_cleanup(dev, dev->subdevices + 2);
762 if (devpriv && devpriv->pci_dev) { 762 if (devpriv && devpriv->pci_dev) {
763 if (devpriv->s5933_config) { 763 if (devpriv->s5933_config)
764 comedi_pci_disable(devpriv->pci_dev); 764 comedi_pci_disable(devpriv->pci_dev);
765 }
766 pci_dev_put(devpriv->pci_dev); 765 pci_dev_put(devpriv->pci_dev);
767 } 766 }
768 767
@@ -1248,9 +1247,8 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev,
1248 cmd->flags & TRIG_ROUND_MASK); 1247 cmd->flags & TRIG_ROUND_MASK);
1249 1248
1250 /* set number of conversions */ 1249 /* set number of conversions */
1251 if (cmd->stop_src == TRIG_COUNT) { 1250 if (cmd->stop_src == TRIG_COUNT)
1252 devpriv->count = cmd->chanlist_len * cmd->stop_arg; 1251 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
1253 }
1254 /* enable interrupts */ 1252 /* enable interrupts */
1255 spin_lock_irqsave(&dev->spinlock, flags); 1253 spin_lock_irqsave(&dev->spinlock, flags);
1256 devpriv->adc_fifo_bits |= INTE; 1254 devpriv->adc_fifo_bits |= INTE;
@@ -1449,9 +1447,8 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1449 devpriv->ao_divisor2, 2); 1447 devpriv->ao_divisor2, 2);
1450 } 1448 }
1451 /* set number of conversions */ 1449 /* set number of conversions */
1452 if (cmd->stop_src == TRIG_COUNT) { 1450 if (cmd->stop_src == TRIG_COUNT)
1453 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; 1451 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1454 }
1455 /* set pacer source */ 1452 /* set pacer source */
1456 spin_lock_irqsave(&dev->spinlock, flags); 1453 spin_lock_irqsave(&dev->spinlock, flags);
1457 switch (cmd->scan_begin_src) { 1454 switch (cmd->scan_begin_src) {
@@ -1494,9 +1491,8 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1494 num_points * sizeof(short)); 1491 num_points * sizeof(short));
1495 num_points = num_bytes / sizeof(short); 1492 num_points = num_bytes / sizeof(short);
1496 1493
1497 if (cmd->stop_src == TRIG_COUNT) { 1494 if (cmd->stop_src == TRIG_COUNT)
1498 devpriv->ao_count -= num_points; 1495 devpriv->ao_count -= num_points;
1499 }
1500 /* write data to board's fifo */ 1496 /* write data to board's fifo */
1501 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); 1497 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1502 1498
@@ -1534,9 +1530,8 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1534 static const int timeout = 10000; 1530 static const int timeout = 10000;
1535 unsigned long flags; 1531 unsigned long flags;
1536 1532
1537 if (dev->attached == 0) { 1533 if (dev->attached == 0)
1538 return IRQ_NONE; 1534 return IRQ_NONE;
1539 }
1540 1535
1541 async = s->async; 1536 async = s->async;
1542 async->events = 0; 1537 async->events = 0;
@@ -1558,15 +1553,13 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1558 1553
1559 status = inw(devpriv->control_status + INT_ADCFIFO); 1554 status = inw(devpriv->control_status + INT_ADCFIFO);
1560#ifdef CB_PCIDAS_DEBUG 1555#ifdef CB_PCIDAS_DEBUG
1561 if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) { 1556 if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0)
1562 comedi_error(dev, "spurious interrupt"); 1557 comedi_error(dev, "spurious interrupt");
1563 }
1564#endif 1558#endif
1565 1559
1566 /* check for analog output interrupt */ 1560 /* check for analog output interrupt */
1567 if (status & (DAHFI | DAEMI)) { 1561 if (status & (DAHFI | DAEMI))
1568 handle_ao_interrupt(dev, status); 1562 handle_ao_interrupt(dev, status);
1569 }
1570 /* check for analog input interrupts */ 1563 /* check for analog input interrupts */
1571 /* if fifo half-full */ 1564 /* if fifo half-full */
1572 if (status & ADHFI) { 1565 if (status & ADHFI) {
@@ -1675,9 +1668,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1675 num_points * sizeof(short)); 1668 num_points * sizeof(short));
1676 num_points = num_bytes / sizeof(short); 1669 num_points = num_bytes / sizeof(short);
1677 1670
1678 if (async->cmd.stop_src == TRIG_COUNT) { 1671 if (async->cmd.stop_src == TRIG_COUNT)
1679 devpriv->ao_count -= num_points; 1672 devpriv->ao_count -= num_points;
1680 }
1681 /* write data to board's fifo */ 1673 /* write data to board's fifo */
1682 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, 1674 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1683 num_points); 1675 num_points);
@@ -1852,7 +1844,7 @@ static int wait_for_nvram_ready(unsigned long s5933_base_addr)
1852} 1844}
1853 1845
1854static int nvram_read(struct comedi_device *dev, unsigned int address, 1846static int nvram_read(struct comedi_device *dev, unsigned int address,
1855 uint8_t * data) 1847 uint8_t *data)
1856{ 1848{
1857 unsigned long iobase = devpriv->s5933_config; 1849 unsigned long iobase = devpriv->s5933_config;
1858 1850
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 782357732eed..81829d6fd287 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -410,9 +410,8 @@ static int cb_pcidda_detach(struct comedi_device *dev)
410 */ 410 */
411 if (devpriv) { 411 if (devpriv) {
412 if (devpriv->pci_dev) { 412 if (devpriv->pci_dev) {
413 if (devpriv->dac) { 413 if (devpriv->dac)
414 comedi_pci_disable(devpriv->pci_dev); 414 comedi_pci_disable(devpriv->pci_dev);
415 }
416 pci_dev_put(devpriv->pci_dev); 415 pci_dev_put(devpriv->pci_dev);
417 } 416 }
418 } 417 }
@@ -677,9 +676,8 @@ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
677 676
678 for (i = 1; i <= value_width; i++) { 677 for (i = 1; i <= value_width; i++) {
679 /* read bits most significant bit first */ 678 /* read bits most significant bit first */
680 if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) { 679 if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
681 value |= 1 << (value_width - i); 680 value |= 1 << (value_width - i);
682 }
683 } 681 }
684 682
685 return value; 683 return value;
@@ -716,9 +714,8 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
716 /* send serial output stream to eeprom */ 714 /* send serial output stream to eeprom */
717 cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT; 715 cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
718 /* deactivate caldacs (one caldac for every two channels) */ 716 /* deactivate caldacs (one caldac for every two channels) */
719 for (i = 0; i < max_num_caldacs; i++) { 717 for (i = 0; i < max_num_caldacs; i++)
720 cal2_bits |= DESELECT_CALDAC_BIT(i); 718 cal2_bits |= DESELECT_CALDAC_BIT(i);
721 }
722 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); 719 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
723 720
724 /* tell eeprom we want to read */ 721 /* tell eeprom we want to read */
@@ -756,9 +753,8 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev,
756*/ 753*/
757 cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT; 754 cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
758 /* deactivate caldacs (one caldac for every two channels) */ 755 /* deactivate caldacs (one caldac for every two channels) */
759 for (i = 0; i < max_num_caldacs; i++) { 756 for (i = 0; i < max_num_caldacs; i++)
760 cal2_bits |= DESELECT_CALDAC_BIT(i); 757 cal2_bits |= DESELECT_CALDAC_BIT(i);
761 }
762 /* activate the caldac we want */ 758 /* activate the caldac we want */
763 cal2_bits &= ~DESELECT_CALDAC_BIT(caldac); 759 cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
764 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); 760 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
index 7daad0a17fb1..38ccd105fa35 100644
--- a/drivers/staging/comedi/drivers/cb_pcidio.c
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -283,17 +283,15 @@ static int pcidio_detach(struct comedi_device *dev)
283 printk("comedi%d: cb_pcidio: remove\n", dev->minor); 283 printk("comedi%d: cb_pcidio: remove\n", dev->minor);
284 if (devpriv) { 284 if (devpriv) {
285 if (devpriv->pci_dev) { 285 if (devpriv->pci_dev) {
286 if (devpriv->dio_reg_base) { 286 if (devpriv->dio_reg_base)
287 comedi_pci_disable(devpriv->pci_dev); 287 comedi_pci_disable(devpriv->pci_dev);
288 }
289 pci_dev_put(devpriv->pci_dev); 288 pci_dev_put(devpriv->pci_dev);
290 } 289 }
291 } 290 }
292 if (dev->subdevices) { 291 if (dev->subdevices) {
293 int i; 292 int i;
294 for (i = 0; i < thisboard->n_8255; i++) { 293 for (i = 0; i < thisboard->n_8255; i++)
295 subdev_8255_cleanup(dev, dev->subdevices + i); 294 subdev_8255_cleanup(dev, dev->subdevices + i);
296 }
297 } 295 }
298 return 0; 296 return 0;
299} 297}
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index cbbca05acb96..2e61727fc9a0 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -330,11 +330,10 @@ found:
330 330
331 s = dev->subdevices + 2; 331 s = dev->subdevices + 2;
332 /* digital i/o subdevice */ 332 /* digital i/o subdevice */
333 if (thisboard->has_dio) { 333 if (thisboard->has_dio)
334 subdev_8255_init(dev, s, NULL, devpriv->BADR4); 334 subdev_8255_init(dev, s, NULL, devpriv->BADR4);
335 } else { 335 else
336 s->type = COMEDI_SUBD_UNUSED; 336 s->type = COMEDI_SUBD_UNUSED;
337 }
338 337
339 printk("attached\n"); 338 printk("attached\n");
340 339
@@ -365,9 +364,8 @@ static int cb_pcimdas_detach(struct comedi_device *dev)
365 free_irq(dev->irq, dev); 364 free_irq(dev->irq, dev);
366 if (devpriv) { 365 if (devpriv) {
367 if (devpriv->pci_dev) { 366 if (devpriv->pci_dev) {
368 if (devpriv->BADR0) { 367 if (devpriv->BADR0)
369 comedi_pci_disable(devpriv->pci_dev); 368 comedi_pci_disable(devpriv->pci_dev);
370 }
371 pci_dev_put(devpriv->pci_dev); 369 pci_dev_put(devpriv->pci_dev);
372 } 370 }
373 } 371 }
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
index 980fa0aacf92..e32a31763d50 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdda.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -284,11 +284,10 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
284 s->n_chan = thisboard->ao_chans; 284 s->n_chan = thisboard->ao_chans;
285 s->maxdata = figure_out_maxdata(thisboard->ao_bits); 285 s->maxdata = figure_out_maxdata(thisboard->ao_bits);
286 /* this is hard-coded here */ 286 /* this is hard-coded here */
287 if (it->options[2]) { 287 if (it->options[2])
288 s->range_table = &range_bipolar10; 288 s->range_table = &range_bipolar10;
289 } else { 289 else
290 s->range_table = &range_bipolar5; 290 s->range_table = &range_bipolar5;
291 }
292 s->insn_write = &ao_winsn; 291 s->insn_write = &ao_winsn;
293 s->insn_read = &ao_rinsn; 292 s->insn_read = &ao_rinsn;
294 293
@@ -337,9 +336,8 @@ static int detach(struct comedi_device *dev)
337 } 336 }
338 337
339 if (devpriv->pci_dev) { 338 if (devpriv->pci_dev) {
340 if (devpriv->registers) { 339 if (devpriv->registers)
341 comedi_pci_disable(devpriv->pci_dev); 340 comedi_pci_disable(devpriv->pci_dev);
342 }
343 pci_dev_put(devpriv->pci_dev); 341 pci_dev_put(devpriv->pci_dev);
344 } 342 }
345 343
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index cf39a24ddd4c..d7260cc86985 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -417,7 +417,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
417 int sdev = -1, nchans, tmp; 417 int sdev = -1, nchans, tmp;
418 struct BondedDevice *bdev = NULL; 418 struct BondedDevice *bdev = NULL;
419 419
420 if (minor < 0 || minor > COMEDI_NUM_BOARD_MINORS) { 420 if (minor < 0 || minor >= COMEDI_NUM_BOARD_MINORS) {
421 ERROR("Minor %d is invalid!\n", minor); 421 ERROR("Minor %d is invalid!\n", minor);
422 return 0; 422 return 0;
423 } 423 }
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
index b16d652f7763..9511814e6413 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -173,9 +173,8 @@ static int contec_detach(struct comedi_device *dev)
173 printk("comedi%d: contec: remove\n", dev->minor); 173 printk("comedi%d: contec: remove\n", dev->minor);
174 174
175 if (devpriv && devpriv->pci_dev) { 175 if (devpriv && devpriv->pci_dev) {
176 if (dev->iobase) { 176 if (dev->iobase)
177 comedi_pci_disable(devpriv->pci_dev); 177 comedi_pci_disable(devpriv->pci_dev);
178 }
179 pci_dev_put(devpriv->pci_dev); 178 pci_dev_put(devpriv->pci_dev);
180 } 179 }
181 180
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 9b945e5fdd32..f12ef1cd6f53 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -34,7 +34,7 @@ This is the PCMCIA-specific support split off from the
34das08 driver. 34das08 driver.
35 35
36Options (for pcm-das08): 36Options (for pcm-das08):
37 NONE 37 NONE
38 38
39Command support does not exist, but could be added for this board. 39Command support does not exist, but could be added for this board.
40*/ 40*/
@@ -52,7 +52,7 @@ Command support does not exist, but could be added for this board.
52#include <pcmcia/cistpl.h> 52#include <pcmcia/cistpl.h>
53#include <pcmcia/ds.h> 53#include <pcmcia/ds.h>
54 54
55static struct pcmcia_device *cur_dev = NULL; 55static struct pcmcia_device *cur_dev;
56 56
57#define thisboard ((const struct das08_board_struct *)dev->board_ptr) 57#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
58 58
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index 92487f58fd8b..a404a1831911 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -45,7 +45,7 @@ This driver has suffered bitrot.
45 45
46#define DAS6402_SIZE 16 46#define DAS6402_SIZE 16
47 47
48#define N_WORDS 3000*64 48#define N_WORDS (3000*64)
49 49
50#define STOP 0 50#define STOP 0
51#define START 1 51#define START 1
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index ecb97cdbce26..aadc4971c909 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -399,9 +399,8 @@ static irqreturn_t das800_interrupt(int irq, void *d)
399 } else { 399 } else {
400 fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */ 400 fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */
401 } 401 }
402 if (fifo_empty) { 402 if (fifo_empty)
403 break; 403 break;
404 }
405 /* strip off extraneous bits for 12 bit cards */ 404 /* strip off extraneous bits for 12 bit cards */
406 if (thisboard->resolution == 12) 405 if (thisboard->resolution == 12)
407 dataPoint = (dataPoint >> 4) & 0xfff; 406 dataPoint = (dataPoint >> 4) & 0xfff;
@@ -457,9 +456,8 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
457 int board; 456 int board;
458 457
459 printk("comedi%d: das800: io 0x%lx", dev->minor, iobase); 458 printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
460 if (irq) { 459 if (irq)
461 printk(", irq %u", irq); 460 printk(", irq %u", irq);
462 }
463 printk("\n"); 461 printk("\n");
464 462
465 /* allocate and initialize dev->private */ 463 /* allocate and initialize dev->private */
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 9db9a467c8f8..d5cbd515c370 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -1048,11 +1048,10 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev,
1048 * value COMEDI_INPUT or COMEDI_OUTPUT. */ 1048 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1049 1049
1050 /* if output clear the bit, otherwise set it */ 1050 /* if output clear the bit, otherwise set it */
1051 if (data[0] == COMEDI_OUTPUT) { 1051 if (data[0] == COMEDI_OUTPUT)
1052 devpriv->dio_config &= ~chanbit; 1052 devpriv->dio_config &= ~chanbit;
1053 } else { 1053 else
1054 devpriv->dio_config |= chanbit; 1054 devpriv->dio_config |= chanbit;
1055 }
1056 /* get access to the DIO regs */ 1055 /* get access to the DIO regs */
1057 dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC); 1056 dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
1058 /* set the DIO's to the new configuration setting */ 1057 /* set the DIO's to the new configuration setting */
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index 7b9af5d755e0..3f365aee4822 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -18,10 +18,10 @@ Configuration options:
18 [1] - unused 18 [1] - unused
19 [2] - A/D reference 0=differential, 1=single-ended 19 [2] - A/D reference 0=differential, 1=single-ended
20 [3] - A/D range 20 [3] - A/D range
21 0 = [-10,10] 21 0 = [-10, 10]
22 1 = [0,10] 22 1 = [0,10]
23 [4] - D/A 0 range 23 [4] - D/A 0 range
24 0 = [-10,10] 24 0 = [-10, 10]
25 1 = [-5,5] 25 1 = [-5,5]
26 2 = [-2.5,2.5] 26 2 = [-2.5,2.5]
27 3 = [0,10] 27 3 = [0,10]
@@ -279,9 +279,8 @@ static int dt2801_readdata(struct comedi_device *dev, int *data)
279 279
280 do { 280 do {
281 stat = inb_p(dev->iobase + DT2801_STATUS); 281 stat = inb_p(dev->iobase + DT2801_STATUS);
282 if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) { 282 if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY))
283 return stat; 283 return stat;
284 }
285 if (stat & DT_S_DATA_OUT_READY) { 284 if (stat & DT_S_DATA_OUT_READY) {
286 *data = inb_p(dev->iobase + DT2801_DATA); 285 *data = inb_p(dev->iobase + DT2801_DATA);
287 return 0; 286 return 0;
@@ -315,9 +314,8 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
315 do { 314 do {
316 stat = inb_p(dev->iobase + DT2801_STATUS); 315 stat = inb_p(dev->iobase + DT2801_STATUS);
317 316
318 if (stat & DT_S_COMPOSITE_ERROR) { 317 if (stat & DT_S_COMPOSITE_ERROR)
319 return stat; 318 return stat;
320 }
321 if (!(stat & DT_S_DATA_IN_FULL)) { 319 if (!(stat & DT_S_DATA_IN_FULL)) {
322 outb_p(data & 0xff, dev->iobase + DT2801_DATA); 320 outb_p(data & 0xff, dev->iobase + DT2801_DATA);
323 return 0; 321 return 0;
@@ -354,18 +352,15 @@ static int dt2801_wait_for_ready(struct comedi_device *dev)
354 int stat; 352 int stat;
355 353
356 stat = inb_p(dev->iobase + DT2801_STATUS); 354 stat = inb_p(dev->iobase + DT2801_STATUS);
357 if (stat & DT_S_READY) { 355 if (stat & DT_S_READY)
358 return 0; 356 return 0;
359 }
360 do { 357 do {
361 stat = inb_p(dev->iobase + DT2801_STATUS); 358 stat = inb_p(dev->iobase + DT2801_STATUS);
362 359
363 if (stat & DT_S_COMPOSITE_ERROR) { 360 if (stat & DT_S_COMPOSITE_ERROR)
364 return stat; 361 return stat;
365 } 362 if (stat & DT_S_READY)
366 if (stat & DT_S_READY) {
367 return 0; 363 return 0;
368 }
369 } while (--timeout > 0); 364 } while (--timeout > 0);
370 365
371 return -ETIME; 366 return -ETIME;
@@ -382,9 +377,8 @@ static int dt2801_writecmd(struct comedi_device *dev, int command)
382 printk 377 printk
383 ("dt2801: composite-error in dt2801_writecmd(), ignoring\n"); 378 ("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
384 } 379 }
385 if (!(stat & DT_S_READY)) { 380 if (!(stat & DT_S_READY))
386 printk("dt2801: !ready in dt2801_writecmd(), ignoring\n"); 381 printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
387 }
388 outb_p(command, dev->iobase + DT2801_CMD); 382 outb_p(command, dev->iobase + DT2801_CMD);
389 383
390 return 0; 384 return 0;
@@ -418,9 +412,8 @@ static int dt2801_reset(struct comedi_device *dev)
418 if (stat & DT_S_READY) 412 if (stat & DT_S_READY)
419 break; 413 break;
420 } while (timeout--); 414 } while (timeout--);
421 if (!timeout) { 415 if (!timeout)
422 printk("dt2801: timeout 1 status=0x%02x\n", stat); 416 printk("dt2801: timeout 1 status=0x%02x\n", stat);
423 }
424 417
425 /* printk("dt2801: reading dummy\n"); */ 418 /* printk("dt2801: reading dummy\n"); */
426 /* dt2801_readdata(dev,&board_code); */ 419 /* dt2801_readdata(dev,&board_code); */
@@ -436,9 +429,8 @@ static int dt2801_reset(struct comedi_device *dev)
436 if (stat & DT_S_READY) 429 if (stat & DT_S_READY)
437 break; 430 break;
438 } while (timeout--); 431 } while (timeout--);
439 if (!timeout) { 432 if (!timeout)
440 printk("dt2801: timeout 2 status=0x%02x\n", stat); 433 printk("dt2801: timeout 2 status=0x%02x\n", stat);
441 }
442 434
443 DPRINTK("dt2801: reading code\n"); 435 DPRINTK("dt2801: reading code\n");
444 dt2801_readdata(dev, &board_code); 436 dt2801_readdata(dev, &board_code);
@@ -623,11 +615,10 @@ static int dt2801_detach(struct comedi_device *dev)
623static int dt2801_error(struct comedi_device *dev, int stat) 615static int dt2801_error(struct comedi_device *dev, int stat)
624{ 616{
625 if (stat < 0) { 617 if (stat < 0) {
626 if (stat == -ETIME) { 618 if (stat == -ETIME)
627 printk("dt2801: timeout\n"); 619 printk("dt2801: timeout\n");
628 } else { 620 else
629 printk("dt2801: error %d\n", stat); 621 printk("dt2801: error %d\n", stat);
630 }
631 return stat; 622 return stat;
632 } 623 }
633 printk("dt2801: error status 0x%02x, resetting...\n", stat); 624 printk("dt2801: error status 0x%02x, resetting...\n", stat);
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index d1db93c043a8..d1a4f7822433 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -34,19 +34,19 @@ Configuration options:
34 [0] - I/O port base base address 34 [0] - I/O port base base address
35 [1] - IRQ (unused) 35 [1] - IRQ (unused)
36 [2] - Voltage unipolar/bipolar configuration 36 [2] - Voltage unipolar/bipolar configuration
37 0 == unipolar 5V (0V -- +5V) 37 0 == unipolar 5V (0V -- +5V)
38 1 == bipolar 5V (-5V -- +5V) 38 1 == bipolar 5V (-5V -- +5V)
39 [3] - Current offset configuration 39 [3] - Current offset configuration
40 0 == disabled (0mA -- +32mAV) 40 0 == disabled (0mA -- +32mAV)
41 1 == enabled (+4mA -- +20mAV) 41 1 == enabled (+4mA -- +20mAV)
42 [4] - Firmware program configuration 42 [4] - Firmware program configuration
43 0 == program 1 (see manual table 5-4) 43 0 == program 1 (see manual table 5-4)
44 1 == program 2 (see manual table 5-4) 44 1 == program 2 (see manual table 5-4)
45 2 == program 3 (see manual table 5-4) 45 2 == program 3 (see manual table 5-4)
46 3 == program 4 (see manual table 5-4) 46 3 == program 4 (see manual table 5-4)
47 [5] - Analog output 0 range configuration 47 [5] - Analog output 0 range configuration
48 0 == voltage 48 0 == voltage
49 1 == current 49 1 == current
50 [6] - Analog output 1 range configuration (same options) 50 [6] - Analog output 1 range configuration (same options)
51 [7] - Analog output 2 range configuration (same options) 51 [7] - Analog output 2 range configuration (same options)
52 [8] - Analog output 3 range configuration (same options) 52 [8] - Analog output 3 range configuration (same options)
@@ -61,17 +61,11 @@ Configuration options:
61#include <linux/ioport.h> 61#include <linux/ioport.h>
62#include <linux/delay.h> 62#include <linux/delay.h>
63 63
64static const struct comedi_lrange range_dt2815_ao_32_current = { 1, { 64static const struct comedi_lrange
65 RANGE_mA(0, 65 range_dt2815_ao_32_current = {1, {RANGE_mA(0, 32)} };
66 32)
67 }
68};
69 66
70static const struct comedi_lrange range_dt2815_ao_20_current = { 1, { 67static const struct comedi_lrange
71 RANGE_mA(4, 68 range_dt2815_ao_20_current = {1, {RANGE_mA(4, 20)} };
72 20)
73 }
74};
75 69
76#define DT2815_SIZE 2 70#define DT2815_SIZE 2
77 71
@@ -118,9 +112,8 @@ static int dt2815_ao_insn_read(struct comedi_device *dev,
118 int i; 112 int i;
119 int chan = CR_CHAN(insn->chanspec); 113 int chan = CR_CHAN(insn->chanspec);
120 114
121 for (i = 0; i < insn->n; i++) { 115 for (i = 0; i < insn->n; i++)
122 data[i] = devpriv->ao_readback[chan]; 116 data[i] = devpriv->ao_readback[chan];
123 }
124 117
125 return i; 118 return i;
126} 119}
@@ -139,9 +132,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
139 132
140 status = dt2815_wait_for_status(dev, 0x00); 133 status = dt2815_wait_for_status(dev, 0x00);
141 if (status != 0) { 134 if (status != 0) {
142 printk 135 printk(KERN_WARNING "dt2815: failed to write low byte "
143 ("dt2815: failed to write low byte on %d reason %x\n", 136 "on %d reason %x\n", chan, status);
144 chan, status);
145 return -EBUSY; 137 return -EBUSY;
146 } 138 }
147 139
@@ -149,9 +141,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
149 141
150 status = dt2815_wait_for_status(dev, 0x10); 142 status = dt2815_wait_for_status(dev, 0x10);
151 if (status != 0x10) { 143 if (status != 0x10) {
152 printk 144 printk(KERN_WARNING "dt2815: failed to write high byte "
153 ("dt2815: failed to write high byte on %d reason %x\n", 145 "on %d reason %x\n", chan, status);
154 chan, status);
155 return -EBUSY; 146 return -EBUSY;
156 } 147 }
157 devpriv->ao_readback[chan] = data[i]; 148 devpriv->ao_readback[chan] = data[i];
@@ -163,24 +154,24 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
163 options[0] Board base address 154 options[0] Board base address
164 options[1] IRQ (not applicable) 155 options[1] IRQ (not applicable)
165 options[2] Voltage unipolar/bipolar configuration 156 options[2] Voltage unipolar/bipolar configuration
166 0 == unipolar 5V (0V -- +5V) 157 0 == unipolar 5V (0V -- +5V)
167 1 == bipolar 5V (-5V -- +5V) 158 1 == bipolar 5V (-5V -- +5V)
168 options[3] Current offset configuration 159 options[3] Current offset configuration
169 0 == disabled (0mA -- +32mAV) 160 0 == disabled (0mA -- +32mAV)
170 1 == enabled (+4mA -- +20mAV) 161 1 == enabled (+4mA -- +20mAV)
171 options[4] Firmware program configuration 162 options[4] Firmware program configuration
172 0 == program 1 (see manual table 5-4) 163 0 == program 1 (see manual table 5-4)
173 1 == program 2 (see manual table 5-4) 164 1 == program 2 (see manual table 5-4)
174 2 == program 3 (see manual table 5-4) 165 2 == program 3 (see manual table 5-4)
175 3 == program 4 (see manual table 5-4) 166 3 == program 4 (see manual table 5-4)
176 options[5] Analog output 0 range configuration 167 options[5] Analog output 0 range configuration
177 0 == voltage 168 0 == voltage
178 1 == current 169 1 == current
179 options[6] Analog output 1 range configuration 170 options[6] Analog output 1 range configuration
180 ... 171 ...
181 options[12] Analog output 7 range configuration 172 options[12] Analog output 7 range configuration
182 0 == voltage 173 0 == voltage
183 1 == current 174 1 == current
184 */ 175 */
185 176
186static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) 177static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -191,9 +182,9 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
191 unsigned long iobase; 182 unsigned long iobase;
192 183
193 iobase = it->options[0]; 184 iobase = it->options[0];
194 printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase); 185 printk(KERN_INFO "comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
195 if (!request_region(iobase, DT2815_SIZE, "dt2815")) { 186 if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
196 printk("I/O port conflict\n"); 187 printk(KERN_WARNING "I/O port conflict\n");
197 return -EIO; 188 return -EIO;
198 } 189 }
199 190
@@ -236,19 +227,17 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
236 unsigned int program; 227 unsigned int program;
237 program = (it->options[4] & 0x3) << 3 | 0x7; 228 program = (it->options[4] & 0x3) << 3 | 0x7;
238 outb(program, dev->iobase + DT2815_DATA); 229 outb(program, dev->iobase + DT2815_DATA);
239 printk(", program: 0x%x (@t=%d)\n", program, i); 230 printk(KERN_INFO ", program: 0x%x (@t=%d)\n",
231 program, i);
240 break; 232 break;
241 } else if (status != 0x00) { 233 } else if (status != 0x00) {
242 printk("dt2815: unexpected status 0x%x (@t=%d)\n", 234 printk(KERN_WARNING "dt2815: unexpected status 0x%x "
243 status, i); 235 "(@t=%d)\n", status, i);
244 if (status & 0x60) { 236 if (status & 0x60)
245 outb(0x00, dev->iobase + DT2815_STATUS); 237 outb(0x00, dev->iobase + DT2815_STATUS);
246 }
247 } 238 }
248 } 239 }
249 240
250 printk("\n");
251
252 return 0; 241 return 0;
253} 242}
254 243
@@ -260,7 +249,7 @@ static void dt2815_free_resources(struct comedi_device *dev)
260 249
261static int dt2815_detach(struct comedi_device *dev) 250static int dt2815_detach(struct comedi_device *dev)
262{ 251{
263 printk("comedi%d: dt2815: remove\n", dev->minor); 252 printk(KERN_INFO "comedi%d: dt2815: remove\n", dev->minor);
264 253
265 dt2815_free_resources(dev); 254 dt2815_free_resources(dev);
266 255
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 312f4f282bd7..96caae36279c 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -264,7 +264,7 @@ struct dt9812_usb_cmd {
264 264
265static DECLARE_MUTEX(dt9812_mutex); 265static DECLARE_MUTEX(dt9812_mutex);
266 266
267static struct usb_device_id dt9812_table[] = { 267static const struct usb_device_id dt9812_table[] = {
268 {USB_DEVICE(0x0867, 0x9812)}, 268 {USB_DEVICE(0x0867, 0x9812)},
269 {} /* Terminating entry */ 269 {} /* Terminating entry */
270}; 270};
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
index 8fca18043357..a10a2b070a24 100644
--- a/drivers/staging/comedi/drivers/fl512.c
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -76,14 +76,14 @@ static int fl512_ai_insn(struct comedi_device *dev,
76 unsigned long iobase = dev->iobase; 76 unsigned long iobase = dev->iobase;
77 77
78 for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */ 78 for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */
79 /* XXX probably can move next step out of for() loop -- will make 79 /* XXX probably can move next step out of for() loop -- will
80 * AI a little bit faster. */ 80 * make AI a little bit faster. */
81 outb(chan, iobase + 2); /* select chan */ 81 outb(chan, iobase + 2); /* select chan */
82 outb(0, iobase + 3); /* start conversion */ 82 outb(0, iobase + 3); /* start conversion */
83 /* XXX should test "done" flag instead of delay */ 83 /* XXX should test "done" flag instead of delay */
84 udelay(30); /* sleep 30 usec */ 84 udelay(30); /* sleep 30 usec */
85 lo_byte = inb(iobase + 2); /* low 8 byte */ 85 lo_byte = inb(iobase + 2); /* low 8 byte */
86 hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */ 86 hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
87 data[n] = lo_byte + (hi_byte << 8); 87 data[n] = lo_byte + (hi_byte << 8);
88 } 88 }
89 return n; 89 return n;
@@ -101,8 +101,10 @@ static int fl512_ao_insn(struct comedi_device *dev,
101 unsigned long iobase = dev->iobase; /* get base address */ 101 unsigned long iobase = dev->iobase; /* get base address */
102 102
103 for (n = 0; n < insn->n; n++) { /* write n data set */ 103 for (n = 0; n < insn->n; n++) { /* write n data set */
104 outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); /* write low byte */ 104 /* write low byte */
105 outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); /* write high byte */ 105 outb(data[n] & 0x0ff, iobase + 4 + 2 * chan);
106 /* write high byte */
107 outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan);
106 inb(iobase + 4 + 2 * chan); /* trig */ 108 inb(iobase + 4 + 2 * chan); /* trig */
107 109
108 devpriv->ao_readback[chan] = data[n]; 110 devpriv->ao_readback[chan] = data[n];
@@ -121,9 +123,8 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
121 int n; 123 int n;
122 int chan = CR_CHAN(insn->chanspec); 124 int chan = CR_CHAN(insn->chanspec);
123 125
124 for (n = 0; n < insn->n; n++) { 126 for (n = 0; n < insn->n; n++)
125 data[n] = devpriv->ao_readback[chan]; 127 data[n] = devpriv->ao_readback[chan];
126 }
127 128
128 return n; 129 return n;
129} 130}
@@ -134,13 +135,15 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
134static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) 135static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
135{ 136{
136 unsigned long iobase; 137 unsigned long iobase;
137 struct comedi_subdevice *s; /* pointer to the subdevice: 138
138 Analog in, Analog out, ( not made ->and Digital IO) */ 139 /* pointer to the subdevice: Analog in, Analog out,
140 (not made ->and Digital IO) */
141 struct comedi_subdevice *s;
139 142
140 iobase = it->options[0]; 143 iobase = it->options[0];
141 printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase); 144 printk(KERN_INFO "comedi:%d fl512: 0x%04lx", dev->minor, iobase);
142 if (!request_region(iobase, FL512_SIZE, "fl512")) { 145 if (!request_region(iobase, FL512_SIZE, "fl512")) {
143 printk(" I/O port conflict\n"); 146 printk(KERN_WARNING " I/O port conflict\n");
144 return -EIO; 147 return -EIO;
145 } 148 }
146 dev->iobase = iobase; 149 dev->iobase = iobase;
@@ -149,7 +152,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
149 return -ENOMEM; 152 return -ENOMEM;
150 153
151#if DEBUG 154#if DEBUG
152 printk("malloc ok\n"); 155 printk(KERN_DEBUG "malloc ok\n");
153#endif 156#endif
154 157
155 if (alloc_subdevices(dev, 2) < 0) 158 if (alloc_subdevices(dev, 2) < 0)
@@ -160,24 +163,37 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
160 */ 163 */
161 /* Analog indput */ 164 /* Analog indput */
162 s = dev->subdevices + 0; 165 s = dev->subdevices + 0;
163 s->type = COMEDI_SUBD_AI; /* define subdevice as Analog In */ 166 /* define subdevice as Analog In */
164 s->subdev_flags = SDF_READABLE | SDF_GROUND; /* you can read it from userspace */ 167 s->type = COMEDI_SUBD_AI;
165 s->n_chan = 16; /* Number of Analog input channels */ 168 /* you can read it from userspace */
166 s->maxdata = 0x0fff; /* accept only 12 bits of data */ 169 s->subdev_flags = SDF_READABLE | SDF_GROUND;
167 s->range_table = &range_fl512; /* device use one of the ranges */ 170 /* Number of Analog input channels */
168 s->insn_read = fl512_ai_insn; /* function to call when read AD */ 171 s->n_chan = 16;
169 printk("comedi: fl512: subdevice 0 initialized\n"); 172 /* accept only 12 bits of data */
173 s->maxdata = 0x0fff;
174 /* device use one of the ranges */
175 s->range_table = &range_fl512;
176 /* function to call when read AD */
177 s->insn_read = fl512_ai_insn;
178 printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n");
170 179
171 /* Analog output */ 180 /* Analog output */
172 s = dev->subdevices + 1; 181 s = dev->subdevices + 1;
173 s->type = COMEDI_SUBD_AO; /* define subdevice as Analog OUT */ 182 /* define subdevice as Analog OUT */
174 s->subdev_flags = SDF_WRITABLE; /* you can write it from userspace */ 183 s->type = COMEDI_SUBD_AO;
175 s->n_chan = 2; /* Number of Analog output channels */ 184 /* you can write it from userspace */
176 s->maxdata = 0x0fff; /* accept only 12 bits of data */ 185 s->subdev_flags = SDF_WRITABLE;
177 s->range_table = &range_fl512; /* device use one of the ranges */ 186 /* Number of Analog output channels */
178 s->insn_write = fl512_ao_insn; /* function to call when write DA */ 187 s->n_chan = 2;
179 s->insn_read = fl512_ao_insn_readback; /* function to call when reading DA */ 188 /* accept only 12 bits of data */
180 printk("comedi: fl512: subdevice 1 initialized\n"); 189 s->maxdata = 0x0fff;
190 /* device use one of the ranges */
191 s->range_table = &range_fl512;
192 /* function to call when write DA */
193 s->insn_write = fl512_ao_insn;
194 /* function to call when reading DA */
195 s->insn_read = fl512_ao_insn_readback;
196 printk(KERN_INFO "comedi: fl512: subdevice 1 initialized\n");
181 197
182 return 1; 198 return 1;
183} 199}
@@ -186,6 +202,6 @@ static int fl512_detach(struct comedi_device *dev)
186{ 202{
187 if (dev->iobase) 203 if (dev->iobase)
188 release_region(dev->iobase, FL512_SIZE); 204 release_region(dev->iobase, FL512_SIZE);
189 printk("comedi%d: fl512: dummy i detach\n", dev->minor); 205 printk(KERN_INFO "comedi%d: fl512: dummy i detach\n", dev->minor);
190 return 0; 206 return 0;
191} 207}
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index bd397840dcba..fe5b4953f7ec 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -954,6 +954,8 @@ out:
954 return result; 954 return result;
955} 955}
956 956
957MODULE_FIRMWARE("comedi/jr3pci.idm");
958
957static int jr3_pci_detach(struct comedi_device *dev) 959static int jr3_pci_detach(struct comedi_device *dev)
958{ 960{
959 int i; 961 int i;
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index cb4da2ae8429..12e72c828157 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -284,7 +284,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev,
284 outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH); 284 outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
285/* printk("Channel %d: \n", insn->chanspec); */ 285/* printk("Channel %d: \n", insn->chanspec); */
286 if (!insn->n) { 286 if (!insn->n) {
287 printk("MPC624: Warning, no data to aquire\n"); 287 printk("MPC624: Warning, no data to acquire\n");
288 return 0; 288 return 0;
289 } 289 }
290 290
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index bbf75eb6d7f2..c223f76031f6 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -26,12 +26,13 @@
26/* 26/*
27Driver: ni_65xx 27Driver: ni_65xx
28Description: National Instruments 65xx static dio boards 28Description: National Instruments 65xx static dio boards
29Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net> 29Author: Jon Grierson <jd@renko.co.uk>,
30 Frank Mori Hess <fmhess@users.sourceforge.net>
30Status: testing 31Status: testing
31Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511, 32Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510,
32 PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515, 33 PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514,
33 PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521, 34 PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519,
34 PCI-6528, PXI-6528 35 PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
35Updated: Wed Oct 18 08:59:11 EDT 2006 36Updated: Wed Oct 18 08:59:11 EDT 2006
36 37
37Based on the PCI-6527 driver by ds. 38Based on the PCI-6527 driver by ds.
@@ -418,9 +419,10 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
418 return -EINVAL; 419 return -EINVAL;
419 base_bitfield_channel = CR_CHAN(insn->chanspec); 420 base_bitfield_channel = CR_CHAN(insn->chanspec);
420 for (j = 0; j < max_ports_per_bitfield; ++j) { 421 for (j = 0; j < max_ports_per_bitfield; ++j) {
421 const unsigned port_offset = ni_65xx_port_by_channel(base_bitfield_channel) + j; 422 const unsigned port_offset =
423 ni_65xx_port_by_channel(base_bitfield_channel) + j;
422 const unsigned port = 424 const unsigned port =
423 sprivate(s)->base_port + port_offset; 425 sprivate(s)->base_port + port_offset;
424 unsigned base_port_channel; 426 unsigned base_port_channel;
425 unsigned port_mask, port_data, port_read_bits; 427 unsigned port_mask, port_data, port_read_bits;
426 int bitshift; 428 int bitshift;
@@ -463,11 +465,11 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
463 * subdevice.) */ 465 * subdevice.) */
464 port_read_bits ^= 0xFF; 466 port_read_bits ^= 0xFF;
465 } 467 }
466 if (bitshift > 0) { 468 if (bitshift > 0)
467 port_read_bits <<= bitshift; 469 port_read_bits <<= bitshift;
468 } else { 470 else
469 port_read_bits >>= -bitshift; 471 port_read_bits >>= -bitshift;
470 } 472
471 read_bits |= port_read_bits; 473 read_bits |= port_read_bits;
472 } 474 }
473 data[1] = read_bits; 475 data[1] = read_bits;
@@ -532,7 +534,8 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
532 if (err) 534 if (err)
533 return 1; 535 return 1;
534 536
535 /* step 2: make sure trigger sources are unique and mutually compatible */ 537 /* step 2: make sure trigger sources are unique and mutually
538 compatible */
536 539
537 if (err) 540 if (err)
538 return 2; 541 return 2;
@@ -652,7 +655,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
652 unsigned i; 655 unsigned i;
653 int ret; 656 int ret;
654 657
655 printk("comedi%d: ni_65xx:", dev->minor); 658 printk(KERN_INFO "comedi%d: ni_65xx:", dev->minor);
656 659
657 ret = alloc_private(dev, sizeof(struct ni_65xx_private)); 660 ret = alloc_private(dev, sizeof(struct ni_65xx_private));
658 if (ret < 0) 661 if (ret < 0)
@@ -664,15 +667,15 @@ static int ni_65xx_attach(struct comedi_device *dev,
664 667
665 ret = mite_setup(private(dev)->mite); 668 ret = mite_setup(private(dev)->mite);
666 if (ret < 0) { 669 if (ret < 0) {
667 printk("error setting up mite\n"); 670 printk(KERN_WARNING "error setting up mite\n");
668 return ret; 671 return ret;
669 } 672 }
670 673
671 dev->board_name = board(dev)->name; 674 dev->board_name = board(dev)->name;
672 dev->irq = mite_irq(private(dev)->mite); 675 dev->irq = mite_irq(private(dev)->mite);
673 printk(" %s", dev->board_name); 676 printk(KERN_INFO " %s", dev->board_name);
674 677
675 printk(" ID=0x%02x", 678 printk(KERN_INFO " ID=0x%02x",
676 readb(private(dev)->mite->daq_io_addr + ID_Register)); 679 readb(private(dev)->mite->daq_io_addr + ID_Register));
677 680
678 ret = alloc_subdevices(dev, 4); 681 ret = alloc_subdevices(dev, 4);
@@ -773,7 +776,7 @@ static int ni_65xx_attach(struct comedi_device *dev,
773 "ni_65xx", dev); 776 "ni_65xx", dev);
774 if (ret < 0) { 777 if (ret < 0) {
775 dev->irq = 0; 778 dev->irq = 0;
776 printk(" irq not available"); 779 printk(KERN_WARNING " irq not available");
777 } 780 }
778 781
779 printk("\n"); 782 printk("\n");
@@ -790,21 +793,17 @@ static int ni_65xx_detach(struct comedi_device *dev)
790 Master_Interrupt_Control); 793 Master_Interrupt_Control);
791 } 794 }
792 795
793 if (dev->irq) { 796 if (dev->irq)
794 free_irq(dev->irq, dev); 797 free_irq(dev->irq, dev);
795 }
796 798
797 if (private(dev)) { 799 if (private(dev)) {
798 unsigned i; 800 unsigned i;
799 for (i = 0; i < dev->n_subdevices; ++i) { 801 for (i = 0; i < dev->n_subdevices; ++i) {
800 if (dev->subdevices[i].private) { 802 kfree(dev->subdevices[i].private);
801 kfree(dev->subdevices[i].private); 803 dev->subdevices[i].private = NULL;
802 dev->subdevices[i].private = NULL;
803 }
804 } 804 }
805 if (private(dev)->mite) { 805 if (private(dev)->mite)
806 mite_unsetup(private(dev)->mite); 806 mite_unsetup(private(dev)->mite);
807 }
808 } 807 }
809 return 0; 808 return 0;
810} 809}
@@ -830,7 +829,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot)
830 } 829 }
831 } 830 }
832 } 831 }
833 printk("no device found\n"); 832 printk(KERN_WARNING "no device found\n");
834 mite_list_devices(); 833 mite_list_devices();
835 return -EIO; 834 return -EIO;
836} 835}
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index 404d3c516ed1..017630fb2424 100644
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -52,7 +52,8 @@ enum ni_660x_constants {
52}; 52};
53 53
54#define NUM_PFI_CHANNELS 40 54#define NUM_PFI_CHANNELS 40
55/* really there are only up to 3 dma channels, but the register layout allows for 4 */ 55/* really there are only up to 3 dma channels, but the register layout allows
56for 4 */
56#define MAX_DMA_CHANNEL 4 57#define MAX_DMA_CHANNEL 4
57 58
58/* See Register-Level Programmer Manual page 3.1 */ 59/* See Register-Level Programmer Manual page 3.1 */
@@ -198,7 +199,7 @@ struct NI_660xRegisterData {
198 const char *name; /* Register Name */ 199 const char *name; /* Register Name */
199 int offset; /* Offset from base address from GPCT chip */ 200 int offset; /* Offset from base address from GPCT chip */
200 enum ni_660x_register_direction direction; 201 enum ni_660x_register_direction direction;
201 enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */ 202 enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
202}; 203};
203 204
204static const struct NI_660xRegisterData registerData[NumRegisters] = { 205static const struct NI_660xRegisterData registerData[NumRegisters] = {
@@ -382,8 +383,8 @@ enum global_interrupt_config_register_bits {
382}; 383};
383 384
384/* Offset of the GPCT chips from the base-adress of the card */ 385/* Offset of the GPCT chips from the base-adress of the card */
385static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* First chip is at base-address + 386/* First chip is at base-address + 0x00, etc. */
386 0x00, etc. */ 387static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
387 388
388/* Board description*/ 389/* Board description*/
389struct ni_660x_board { 390struct ni_660x_board {
@@ -691,13 +692,13 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
691 ni_660x_register = G0StatusRegister; 692 ni_660x_register = G0StatusRegister;
692 break; 693 break;
693 case NITIO_G1_Status_Reg: 694 case NITIO_G1_Status_Reg:
694 ni_660x_register = G0StatusRegister; 695 ni_660x_register = G1StatusRegister;
695 break; 696 break;
696 case NITIO_G2_Status_Reg: 697 case NITIO_G2_Status_Reg:
697 ni_660x_register = G0StatusRegister; 698 ni_660x_register = G2StatusRegister;
698 break; 699 break;
699 case NITIO_G3_Status_Reg: 700 case NITIO_G3_Status_Reg:
700 ni_660x_register = G0StatusRegister; 701 ni_660x_register = G3StatusRegister;
701 break; 702 break;
702 case NITIO_G0_Interrupt_Enable_Reg: 703 case NITIO_G0_Interrupt_Enable_Reg:
703 ni_660x_register = G0InterruptEnable; 704 ni_660x_register = G0InterruptEnable;
@@ -712,7 +713,7 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
712 ni_660x_register = G3InterruptEnable; 713 ni_660x_register = G3InterruptEnable;
713 break; 714 break;
714 default: 715 default:
715 printk("%s: unhandled register 0x%x in switch.\n", 716 printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n",
716 __func__, reg); 717 __func__, reg);
717 BUG(); 718 BUG();
718 return 0; 719 return 0;
@@ -737,7 +738,7 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
737 writel(bits, write_address); 738 writel(bits, write_address);
738 break; 739 break;
739 default: 740 default:
740 printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", 741 printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
741 __FILE__, __func__, reg); 742 __FILE__, __func__, reg);
742 BUG(); 743 BUG();
743 break; 744 break;
@@ -760,7 +761,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
760 return readl(read_address); 761 return readl(read_address);
761 break; 762 break;
762 default: 763 default:
763 printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", 764 printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
764 __FILE__, __func__, reg); 765 __FILE__, __func__, reg);
765 BUG(); 766 BUG();
766 break; 767 break;
@@ -993,9 +994,9 @@ static int ni_660x_allocate_private(struct comedi_device *dev)
993 spin_lock_init(&private(dev)->mite_channel_lock); 994 spin_lock_init(&private(dev)->mite_channel_lock);
994 spin_lock_init(&private(dev)->interrupt_lock); 995 spin_lock_init(&private(dev)->interrupt_lock);
995 spin_lock_init(&private(dev)->soft_reg_copy_lock); 996 spin_lock_init(&private(dev)->soft_reg_copy_lock);
996 for (i = 0; i < NUM_PFI_CHANNELS; ++i) { 997 for (i = 0; i < NUM_PFI_CHANNELS; ++i)
997 private(dev)->pfi_output_selects[i] = pfi_output_select_counter; 998 private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
998 } 999
999 return 0; 1000 return 0;
1000} 1001}
1001 1002
@@ -1008,9 +1009,8 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
1008 for (j = 0; j < counters_per_chip; ++j) { 1009 for (j = 0; j < counters_per_chip; ++j) {
1009 private(dev)->mite_rings[i][j] = 1010 private(dev)->mite_rings[i][j] =
1010 mite_alloc_ring(private(dev)->mite); 1011 mite_alloc_ring(private(dev)->mite);
1011 if (private(dev)->mite_rings[i][j] == NULL) { 1012 if (private(dev)->mite_rings[i][j] == NULL)
1012 return -ENOMEM; 1013 return -ENOMEM;
1013 }
1014 } 1014 }
1015 } 1015 }
1016 return 0; 1016 return 0;
@@ -1022,9 +1022,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev)
1022 unsigned j; 1022 unsigned j;
1023 1023
1024 for (i = 0; i < board(dev)->n_chips; ++i) { 1024 for (i = 0; i < board(dev)->n_chips; ++i) {
1025 for (j = 0; j < counters_per_chip; ++j) { 1025 for (j = 0; j < counters_per_chip; ++j)
1026 mite_free_ring(private(dev)->mite_rings[i][j]); 1026 mite_free_ring(private(dev)->mite_rings[i][j]);
1027 }
1028 } 1027 }
1029} 1028}
1030 1029
@@ -1036,7 +1035,7 @@ static int ni_660x_attach(struct comedi_device *dev,
1036 unsigned i; 1035 unsigned i;
1037 unsigned global_interrupt_config_bits; 1036 unsigned global_interrupt_config_bits;
1038 1037
1039 printk("comedi%d: ni_660x: ", dev->minor); 1038 printk(KERN_INFO "comedi%d: ni_660x: ", dev->minor);
1040 1039
1041 ret = ni_660x_allocate_private(dev); 1040 ret = ni_660x_allocate_private(dev);
1042 if (ret < 0) 1041 if (ret < 0)
@@ -1049,7 +1048,7 @@ static int ni_660x_attach(struct comedi_device *dev,
1049 1048
1050 ret = mite_setup2(private(dev)->mite, 1); 1049 ret = mite_setup2(private(dev)->mite, 1);
1051 if (ret < 0) { 1050 if (ret < 0) {
1052 printk("error setting up mite\n"); 1051 printk(KERN_WARNING "error setting up mite\n");
1053 return ret; 1052 return ret;
1054 } 1053 }
1055 comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev); 1054 comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
@@ -1057,7 +1056,7 @@ static int ni_660x_attach(struct comedi_device *dev,
1057 if (ret < 0) 1056 if (ret < 0)
1058 return ret; 1057 return ret;
1059 1058
1060 printk(" %s ", dev->board_name); 1059 printk(KERN_INFO " %s ", dev->board_name);
1061 1060
1062 dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS; 1061 dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
1063 1062
@@ -1078,15 +1077,16 @@ static int ni_660x_attach(struct comedi_device *dev,
1078 s->insn_bits = ni_660x_dio_insn_bits; 1077 s->insn_bits = ni_660x_dio_insn_bits;
1079 s->insn_config = ni_660x_dio_insn_config; 1078 s->insn_config = ni_660x_dio_insn_config;
1080 s->io_bits = 0; /* all bits default to input */ 1079 s->io_bits = 0; /* all bits default to input */
1081 /* we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */ 1080 /* we use the ioconfig registers to control dio direction, so zero
1081 output enables in stc dio control reg */
1082 ni_660x_write_register(dev, 0, 0, STCDIOControl); 1082 ni_660x_write_register(dev, 0, 0, STCDIOControl);
1083 1083
1084 private(dev)->counter_dev = ni_gpct_device_construct(dev, 1084 private(dev)->counter_dev = ni_gpct_device_construct(dev,
1085 &ni_gpct_write_register, 1085 &ni_gpct_write_register,
1086 &ni_gpct_read_register, 1086 &ni_gpct_read_register,
1087 ni_gpct_variant_660x, 1087 ni_gpct_variant_660x,
1088 ni_660x_num_counters 1088 ni_660x_num_counters
1089 (dev)); 1089 (dev));
1090 if (private(dev)->counter_dev == NULL) 1090 if (private(dev)->counter_dev == NULL)
1091 return -ENOMEM; 1091 return -ENOMEM;
1092 for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { 1092 for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
@@ -1118,12 +1118,12 @@ static int ni_660x_attach(struct comedi_device *dev,
1118 s->type = COMEDI_SUBD_UNUSED; 1118 s->type = COMEDI_SUBD_UNUSED;
1119 } 1119 }
1120 } 1120 }
1121 for (i = 0; i < board(dev)->n_chips; ++i) { 1121 for (i = 0; i < board(dev)->n_chips; ++i)
1122 init_tio_chip(dev, i); 1122 init_tio_chip(dev, i);
1123 } 1123
1124 for (i = 0; i < ni_660x_num_counters(dev); ++i) { 1124 for (i = 0; i < ni_660x_num_counters(dev); ++i)
1125 ni_tio_init_counter(&private(dev)->counter_dev->counters[i]); 1125 ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
1126 } 1126
1127 for (i = 0; i < NUM_PFI_CHANNELS; ++i) { 1127 for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
1128 if (i < min_counter_pfi_chan) 1128 if (i < min_counter_pfi_chan)
1129 ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); 1129 ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
@@ -1134,13 +1134,13 @@ static int ni_660x_attach(struct comedi_device *dev,
1134 } 1134 }
1135 /* to be safe, set counterswap bits on tio chips after all the counter 1135 /* to be safe, set counterswap bits on tio chips after all the counter
1136 outputs have been set to high impedance mode */ 1136 outputs have been set to high impedance mode */
1137 for (i = 0; i < board(dev)->n_chips; ++i) { 1137 for (i = 0; i < board(dev)->n_chips; ++i)
1138 set_tio_counterswap(dev, i); 1138 set_tio_counterswap(dev, i);
1139 } 1139
1140 ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt, 1140 ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
1141 IRQF_SHARED, "ni_660x", dev); 1141 IRQF_SHARED, "ni_660x", dev);
1142 if (ret < 0) { 1142 if (ret < 0) {
1143 printk(" irq not available\n"); 1143 printk(KERN_WARNING " irq not available\n");
1144 return ret; 1144 return ret;
1145 } 1145 }
1146 dev->irq = mite_irq(private(dev)->mite); 1146 dev->irq = mite_irq(private(dev)->mite);
@@ -1149,13 +1149,13 @@ static int ni_660x_attach(struct comedi_device *dev,
1149 global_interrupt_config_bits |= Cascade_Int_Enable_Bit; 1149 global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
1150 ni_660x_write_register(dev, 0, global_interrupt_config_bits, 1150 ni_660x_write_register(dev, 0, global_interrupt_config_bits,
1151 GlobalInterruptConfigRegister); 1151 GlobalInterruptConfigRegister);
1152 printk("attached\n"); 1152 printk(KERN_INFO "attached\n");
1153 return 0; 1153 return 0;
1154} 1154}
1155 1155
1156static int ni_660x_detach(struct comedi_device *dev) 1156static int ni_660x_detach(struct comedi_device *dev)
1157{ 1157{
1158 printk("comedi%d: ni_660x: remove\n", dev->minor); 1158 printk(KERN_INFO "comedi%d: ni_660x: remove\n", dev->minor);
1159 1159
1160 /* Free irq */ 1160 /* Free irq */
1161 if (dev->irq) 1161 if (dev->irq)
@@ -1193,9 +1193,8 @@ static void init_tio_chip(struct comedi_device *dev, int chipset)
1193 private(dev)-> 1193 private(dev)->
1194 dma_configuration_soft_copies[chipset], 1194 dma_configuration_soft_copies[chipset],
1195 DMAConfigRegister); 1195 DMAConfigRegister);
1196 for (i = 0; i < NUM_PFI_CHANNELS; ++i) { 1196 for (i = 0; i < NUM_PFI_CHANNELS; ++i)
1197 ni_660x_write_register(dev, chipset, 0, IOConfigReg(i)); 1197 ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
1198 }
1199} 1198}
1200 1199
1201static int 1200static int
@@ -1234,7 +1233,7 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
1234 } 1233 }
1235 } 1234 }
1236 } 1235 }
1237 printk("no device found\n"); 1236 printk(KERN_WARNING "no device found\n");
1238 mite_list_devices(); 1237 mite_list_devices();
1239 return -EIO; 1238 return -EIO;
1240} 1239}
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 9b43547e80a1..1e792d592f73 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -93,7 +93,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
93 { 93 {
94 PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 94 PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
95 PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 95 PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
96 /* { PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ 96 /*{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },*/
97 { 97 {
98 0} 98 0}
99}; 99};
@@ -151,7 +151,7 @@ static int ni_670x_attach(struct comedi_device *dev,
151 int ret; 151 int ret;
152 int i; 152 int i;
153 153
154 printk("comedi%d: ni_670x: ", dev->minor); 154 printk(KERN_INFO "comedi%d: ni_670x: ", dev->minor);
155 155
156 ret = alloc_private(dev, sizeof(struct ni_670x_private)); 156 ret = alloc_private(dev, sizeof(struct ni_670x_private));
157 if (ret < 0) 157 if (ret < 0)
@@ -163,12 +163,12 @@ static int ni_670x_attach(struct comedi_device *dev,
163 163
164 ret = mite_setup(devpriv->mite); 164 ret = mite_setup(devpriv->mite);
165 if (ret < 0) { 165 if (ret < 0) {
166 printk("error setting up mite\n"); 166 printk(KERN_WARNING "error setting up mite\n");
167 return ret; 167 return ret;
168 } 168 }
169 dev->board_name = thisboard->name; 169 dev->board_name = thisboard->name;
170 dev->irq = mite_irq(devpriv->mite); 170 dev->irq = mite_irq(devpriv->mite);
171 printk(" %s", dev->board_name); 171 printk(KERN_INFO " %s", dev->board_name);
172 172
173 if (alloc_subdevices(dev, 2) < 0) 173 if (alloc_subdevices(dev, 2) < 0)
174 return -ENOMEM; 174 return -ENOMEM;
@@ -207,21 +207,22 @@ static int ni_670x_attach(struct comedi_device *dev,
207 s->insn_bits = ni_670x_dio_insn_bits; 207 s->insn_bits = ni_670x_dio_insn_bits;
208 s->insn_config = ni_670x_dio_insn_config; 208 s->insn_config = ni_670x_dio_insn_config;
209 209
210 writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET); /* Config of misc registers */ 210 /* Config of misc registers */
211 writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET); /* Config of ao registers */ 211 writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET);
212 /* Config of ao registers */
213 writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET);
212 214
213 printk("attached\n"); 215 printk(KERN_INFO "attached\n");
214 216
215 return 1; 217 return 1;
216} 218}
217 219
218static int ni_670x_detach(struct comedi_device *dev) 220static int ni_670x_detach(struct comedi_device *dev)
219{ 221{
220 printk("comedi%d: ni_670x: remove\n", dev->minor); 222 printk(KERN_INFO "comedi%d: ni_670x: remove\n", dev->minor);
223
224 kfree(dev->subdevices[0].range_table_list);
221 225
222 if (dev->subdevices[0].range_table_list) {
223 kfree(dev->subdevices[0].range_table_list);
224 }
225 if (dev->private && devpriv->mite) 226 if (dev->private && devpriv->mite)
226 mite_unsetup(devpriv->mite); 227 mite_unsetup(devpriv->mite);
227 228
@@ -250,8 +251,11 @@ static int ni_670x_ao_winsn(struct comedi_device *dev,
250 vch(15) : 30 | ich(31) : 31 */ 251 vch(15) : 30 | ich(31) : 31 */
251 252
252 for (i = 0; i < insn->n; i++) { 253 for (i = 0; i < insn->n; i++) {
253 writel(((chan & 15) << 1) | ((chan & 16) >> 4), devpriv->mite->daq_io_addr + AO_CHAN_OFFSET); /* First write in channel register which channel to use */ 254 /* First write in channel register which channel to use */
254 writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET); /* write channel value */ 255 writel(((chan & 15) << 1) | ((chan & 16) >> 4),
256 devpriv->mite->daq_io_addr + AO_CHAN_OFFSET);
257 /* write channel value */
258 writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET);
255 devpriv->ao_readback[chan] = data[i]; 259 devpriv->ao_readback[chan] = data[i];
256 } 260 }
257 261
@@ -344,7 +348,7 @@ static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot)
344 } 348 }
345 } 349 }
346 } 350 }
347 printk("no device found\n"); 351 printk(KERN_INFO "no device found\n");
348 mite_list_devices(); 352 mite_list_devices();
349 return -EIO; 353 return -EIO;
350} 354}
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index 8ead31164d5c..003d00b595b0 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -329,11 +329,11 @@ static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
329} 329}
330 330
331static struct pnp_device_id device_ids[] = { 331static struct pnp_device_id device_ids[] = {
332 {.id = "NIC1900",.driver_data = 0}, 332 {.id = "NIC1900", .driver_data = 0},
333 {.id = "NIC2400",.driver_data = 0}, 333 {.id = "NIC2400", .driver_data = 0},
334 {.id = "NIC2500",.driver_data = 0}, 334 {.id = "NIC2500", .driver_data = 0},
335 {.id = "NIC2600",.driver_data = 0}, 335 {.id = "NIC2600", .driver_data = 0},
336 {.id = "NIC2700",.driver_data = 0}, 336 {.id = "NIC2700", .driver_data = 0},
337 {.id = ""} 337 {.id = ""}
338}; 338};
339 339
@@ -362,9 +362,9 @@ static int ni_atmio_detach(struct comedi_device *dev)
362 362
363 if (dev->iobase) 363 if (dev->iobase)
364 release_region(dev->iobase, NI_SIZE); 364 release_region(dev->iobase, NI_SIZE);
365 if (dev->irq) { 365 if (dev->irq)
366 free_irq(dev->irq, dev); 366 free_irq(dev->irq, dev);
367 } 367
368 if (devpriv->isapnp_dev) 368 if (devpriv->isapnp_dev)
369 pnp_device_detach(devpriv->isapnp_dev); 369 pnp_device_detach(devpriv->isapnp_dev);
370 370
@@ -387,8 +387,8 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
387 387
388 if (pnp_device_attach(isapnp_dev) < 0) { 388 if (pnp_device_attach(isapnp_dev) < 0) {
389 printk 389 printk
390 ("ni_atmio: %s found but already active, skipping.\n", 390 ("ni_atmio: %s found but already active, skipping.\n",
391 ni_boards[i].name); 391 ni_boards[i].name);
392 continue; 392 continue;
393 } 393 }
394 if (pnp_activate_dev(isapnp_dev) < 0) { 394 if (pnp_activate_dev(isapnp_dev) < 0) {
@@ -496,9 +496,9 @@ static int ni_atmio_attach(struct comedi_device *dev,
496 /* generic E series stuff in ni_mio_common.c */ 496 /* generic E series stuff in ni_mio_common.c */
497 497
498 ret = ni_E_init(dev, it); 498 ret = ni_E_init(dev, it);
499 if (ret < 0) { 499 if (ret < 0)
500 return ret; 500 return ret;
501 } 501
502 502
503 return 0; 503 return 0;
504} 504}
@@ -509,16 +509,16 @@ static int ni_getboardtype(struct comedi_device *dev)
509 int i; 509 int i;
510 510
511 for (i = 0; i < n_ni_boards; i++) { 511 for (i = 0; i < n_ni_boards; i++) {
512 if (ni_boards[i].device_id == device_id) { 512 if (ni_boards[i].device_id == device_id)
513 return i; 513 return i;
514 } 514
515 } 515 }
516 if (device_id == 255) { 516 if (device_id == 255)
517 printk(" can't find board\n"); 517 printk(" can't find board\n");
518 } else if (device_id == 0) { 518 else if (device_id == 0)
519 printk(" EEPROM read error (?) or device not found\n"); 519 printk(" EEPROM read error (?) or device not found\n");
520 } else { 520 else
521 printk(" unknown device ID %d -- contact author\n", device_id); 521 printk(" unknown device ID %d -- contact author\n", device_id);
522 } 522
523 return -1; 523 return -1;
524} 524}
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index ef5e1183d47d..c9b0395a6103 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -76,13 +76,15 @@ struct dio700_board {
76static const struct dio700_board dio700_boards[] = { 76static const struct dio700_board dio700_boards[] = {
77 { 77 {
78 .name = "daqcard-700", 78 .name = "daqcard-700",
79 .device_id = 0x4743, /* 0x10b is manufacturer id, 0x4743 is device id */ 79 /* 0x10b is manufacturer id, 0x4743 is device id */
80 .device_id = 0x4743,
80 .bustype = pcmcia_bustype, 81 .bustype = pcmcia_bustype,
81 .have_dio = 1, 82 .have_dio = 1,
82 }, 83 },
83 { 84 {
84 .name = "ni_daq_700", 85 .name = "ni_daq_700",
85 .device_id = 0x4743, /* 0x10b is manufacturer id, 0x4743 is device id */ 86 /* 0x10b is manufacturer id, 0x4743 is device id */
87 .device_id = 0x4743,
86 .bustype = pcmcia_bustype, 88 .bustype = pcmcia_bustype,
87 .have_dio = 1, 89 .have_dio = 1,
88 }, 90 },
@@ -309,11 +311,11 @@ int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s,
309 return -ENOMEM; 311 return -ENOMEM;
310 312
311 CALLBACK_ARG = arg; 313 CALLBACK_ARG = arg;
312 if (cb == NULL) { 314 if (cb == NULL)
313 CALLBACK_FUNC = subdev_700_cb; 315 CALLBACK_FUNC = subdev_700_cb;
314 } else { 316 else
315 CALLBACK_FUNC = cb; 317 CALLBACK_FUNC = cb;
316 } 318
317 s->insn_bits = subdev_700_insn; 319 s->insn_bits = subdev_700_insn;
318 s->insn_config = subdev_700_insn_config; 320 s->insn_config = subdev_700_insn_config;
319 321
@@ -345,12 +347,10 @@ int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
345 347
346void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) 348void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
347{ 349{
348 if (s->private) { 350 if (s->private)
349 if (subdevpriv->have_irq) { 351 if (subdevpriv->have_irq)
350 }
351 352
352 kfree(s->private); 353 kfree(s->private);
353 }
354} 354}
355 355
356EXPORT_SYMBOL(subdev_700_init); 356EXPORT_SYMBOL(subdev_700_init);
@@ -390,9 +390,9 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it)
390 printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, 390 printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
391 thisboard->name, iobase); 391 thisboard->name, iobase);
392#ifdef incomplete 392#ifdef incomplete
393 if (irq) { 393 if (irq)
394 printk(", irq %u", irq); 394 printk(", irq %u", irq);
395 } 395
396#endif 396#endif
397 397
398 printk("\n"); 398 printk("\n");
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index dc3f398cb3ed..3c88caaa9dab 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -90,8 +90,10 @@ NI manuals:
90 90
91#define DRV_NAME "ni_labpc" 91#define DRV_NAME "ni_labpc"
92 92
93#define LABPC_SIZE 32 /* size of io region used by board */ 93/* size of io region used by board */
94#define LABPC_TIMER_BASE 500 /* 2 MHz master clock */ 94#define LABPC_SIZE 32
95/* 2 MHz master clock */
96#define LABPC_TIMER_BASE 500
95 97
96/* Registers for the lab-pc+ */ 98/* Registers for the lab-pc+ */
97 99
@@ -99,69 +101,110 @@ NI manuals:
99#define COMMAND1_REG 0x0 101#define COMMAND1_REG 0x0
100#define ADC_GAIN_MASK (0x7 << 4) 102#define ADC_GAIN_MASK (0x7 << 4)
101#define ADC_CHAN_BITS(x) ((x) & 0x7) 103#define ADC_CHAN_BITS(x) ((x) & 0x7)
102#define ADC_SCAN_EN_BIT 0x80 /* enables multi channel scans */ 104/* enables multi channel scans */
105#define ADC_SCAN_EN_BIT 0x80
103#define COMMAND2_REG 0x1 106#define COMMAND2_REG 0x1
104#define PRETRIG_BIT 0x1 /* enable pretriggering (used in conjunction with SWTRIG) */ 107/* enable pretriggering (used in conjunction with SWTRIG) */
105#define HWTRIG_BIT 0x2 /* enable paced conversions on external trigger */ 108#define PRETRIG_BIT 0x1
106#define SWTRIG_BIT 0x4 /* enable paced conversions */ 109/* enable paced conversions on external trigger */
107#define CASCADE_BIT 0x8 /* use two cascaded counters for pacing */ 110#define HWTRIG_BIT 0x2
111/* enable paced conversions */
112#define SWTRIG_BIT 0x4
113/* use two cascaded counters for pacing */
114#define CASCADE_BIT 0x8
108#define DAC_PACED_BIT(channel) (0x40 << ((channel) & 0x1)) 115#define DAC_PACED_BIT(channel) (0x40 << ((channel) & 0x1))
109#define COMMAND3_REG 0x2 116#define COMMAND3_REG 0x2
110#define DMA_EN_BIT 0x1 /* enable dma transfers */ 117/* enable dma transfers */
111#define DIO_INTR_EN_BIT 0x2 /* enable interrupts for 8255 */ 118#define DMA_EN_BIT 0x1
112#define DMATC_INTR_EN_BIT 0x4 /* enable dma terminal count interrupt */ 119/* enable interrupts for 8255 */
113#define TIMER_INTR_EN_BIT 0x8 /* enable timer interrupt */ 120#define DIO_INTR_EN_BIT 0x2
114#define ERR_INTR_EN_BIT 0x10 /* enable error interrupt */ 121/* enable dma terminal count interrupt */
115#define ADC_FNE_INTR_EN_BIT 0x20 /* enable fifo not empty interrupt */ 122#define DMATC_INTR_EN_BIT 0x4
123/* enable timer interrupt */
124#define TIMER_INTR_EN_BIT 0x8
125/* enable error interrupt */
126#define ERR_INTR_EN_BIT 0x10
127/* enable fifo not empty interrupt */
128#define ADC_FNE_INTR_EN_BIT 0x20
116#define ADC_CONVERT_REG 0x3 129#define ADC_CONVERT_REG 0x3
117#define DAC_LSB_REG(channel) (0x4 + 2 * ((channel) & 0x1)) 130#define DAC_LSB_REG(channel) (0x4 + 2 * ((channel) & 0x1))
118#define DAC_MSB_REG(channel) (0x5 + 2 * ((channel) & 0x1)) 131#define DAC_MSB_REG(channel) (0x5 + 2 * ((channel) & 0x1))
119#define ADC_CLEAR_REG 0x8 132#define ADC_CLEAR_REG 0x8
120#define DMATC_CLEAR_REG 0xa 133#define DMATC_CLEAR_REG 0xa
121#define TIMER_CLEAR_REG 0xc 134#define TIMER_CLEAR_REG 0xc
122#define COMMAND6_REG 0xe /* 1200 boards only */ 135/* 1200 boards only */
123#define ADC_COMMON_BIT 0x1 /* select ground or common-mode reference */ 136#define COMMAND6_REG 0xe
124#define ADC_UNIP_BIT 0x2 /* adc unipolar */ 137/* select ground or common-mode reference */
125#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1)) /* dac unipolar */ 138#define ADC_COMMON_BIT 0x1
126#define ADC_FHF_INTR_EN_BIT 0x20 /* enable fifo half full interrupt */ 139/* adc unipolar */
127#define A1_INTR_EN_BIT 0x40 /* enable interrupt on end of hardware count */ 140#define ADC_UNIP_BIT 0x2
128#define ADC_SCAN_UP_BIT 0x80 /* scan up from channel zero instead of down to zero */ 141/* dac unipolar */
142#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1))
143/* enable fifo half full interrupt */
144#define ADC_FHF_INTR_EN_BIT 0x20
145/* enable interrupt on end of hardware count */
146#define A1_INTR_EN_BIT 0x40
147/* scan up from channel zero instead of down to zero */
148#define ADC_SCAN_UP_BIT 0x80
129#define COMMAND4_REG 0xf 149#define COMMAND4_REG 0xf
130#define INTERVAL_SCAN_EN_BIT 0x1 /* enables 'interval' scanning */ 150/* enables 'interval' scanning */
131#define EXT_SCAN_EN_BIT 0x2 /* enables external signal on counter b1 output to trigger scan */ 151#define INTERVAL_SCAN_EN_BIT 0x1
132#define EXT_CONVERT_OUT_BIT 0x4 /* chooses direction (output or input) for EXTCONV* line */ 152/* enables external signal on counter b1 output to trigger scan */
133#define ADC_DIFF_BIT 0x8 /* chooses differential inputs for adc (in conjunction with board jumper) */ 153#define EXT_SCAN_EN_BIT 0x2
154/* chooses direction (output or input) for EXTCONV* line */
155#define EXT_CONVERT_OUT_BIT 0x4
156/* chooses differential inputs for adc (in conjunction with board jumper) */
157#define ADC_DIFF_BIT 0x8
134#define EXT_CONVERT_DISABLE_BIT 0x10 158#define EXT_CONVERT_DISABLE_BIT 0x10
135#define COMMAND5_REG 0x1c /* 1200 boards only, calibration stuff */ 159/* 1200 boards only, calibration stuff */
136#define EEPROM_WRITE_UNPROTECT_BIT 0x4 /* enable eeprom for write */ 160#define COMMAND5_REG 0x1c
137#define DITHER_EN_BIT 0x8 /* enable dithering */ 161/* enable eeprom for write */
138#define CALDAC_LOAD_BIT 0x10 /* load calibration dac */ 162#define EEPROM_WRITE_UNPROTECT_BIT 0x4
139#define SCLOCK_BIT 0x20 /* serial clock - rising edge writes, falling edge reads */ 163/* enable dithering */
140#define SDATA_BIT 0x40 /* serial data bit for writing to eeprom or calibration dacs */ 164#define DITHER_EN_BIT 0x8
141#define EEPROM_EN_BIT 0x80 /* enable eeprom for read/write */ 165/* load calibration dac */
166#define CALDAC_LOAD_BIT 0x10
167/* serial clock - rising edge writes, falling edge reads */
168#define SCLOCK_BIT 0x20
169/* serial data bit for writing to eeprom or calibration dacs */
170#define SDATA_BIT 0x40
171/* enable eeprom for read/write */
172#define EEPROM_EN_BIT 0x80
142#define INTERVAL_COUNT_REG 0x1e 173#define INTERVAL_COUNT_REG 0x1e
143#define INTERVAL_LOAD_REG 0x1f 174#define INTERVAL_LOAD_REG 0x1f
144#define INTERVAL_LOAD_BITS 0x1 175#define INTERVAL_LOAD_BITS 0x1
145 176
146/* read-only registers */ 177/* read-only registers */
147#define STATUS1_REG 0x0 178#define STATUS1_REG 0x0
148#define DATA_AVAIL_BIT 0x1 /* data is available in fifo */ 179/* data is available in fifo */
149#define OVERRUN_BIT 0x2 /* overrun has occurred */ 180#define DATA_AVAIL_BIT 0x1
150#define OVERFLOW_BIT 0x4 /* fifo overflow */ 181/* overrun has occurred */
151#define TIMER_BIT 0x8 /* timer interrupt has occured */ 182#define OVERRUN_BIT 0x2
152#define DMATC_BIT 0x10 /* dma terminal count has occured */ 183/* fifo overflow */
153#define EXT_TRIG_BIT 0x40 /* external trigger has occured */ 184#define OVERFLOW_BIT 0x4
154#define STATUS2_REG 0x1d /* 1200 boards only */ 185/* timer interrupt has occured */
155#define EEPROM_OUT_BIT 0x1 /* programmable eeprom serial output */ 186#define TIMER_BIT 0x8
156#define A1_TC_BIT 0x2 /* counter A1 terminal count */ 187/* dma terminal count has occured */
157#define FNHF_BIT 0x4 /* fifo not half full */ 188#define DMATC_BIT 0x10
189/* external trigger has occured */
190#define EXT_TRIG_BIT 0x40
191/* 1200 boards only */
192#define STATUS2_REG 0x1d
193/* programmable eeprom serial output */
194#define EEPROM_OUT_BIT 0x1
195/* counter A1 terminal count */
196#define A1_TC_BIT 0x2
197/* fifo not half full */
198#define FNHF_BIT 0x4
158#define ADC_FIFO_REG 0xa 199#define ADC_FIFO_REG 0xa
159 200
160#define DIO_BASE_REG 0x10 201#define DIO_BASE_REG 0x10
161#define COUNTER_A_BASE_REG 0x14 202#define COUNTER_A_BASE_REG 0x14
162#define COUNTER_A_CONTROL_REG (COUNTER_A_BASE_REG + 0x3) 203#define COUNTER_A_CONTROL_REG (COUNTER_A_BASE_REG + 0x3)
163#define INIT_A0_BITS 0x14 /* check modes put conversion pacer output in harmless state (a0 mode 2) */ 204/* check modes put conversion pacer output in harmless state (a0 mode 2) */
164#define INIT_A1_BITS 0x70 /* put hardware conversion counter output in harmless state (a1 mode 0) */ 205#define INIT_A0_BITS 0x14
206/* put hardware conversion counter output in harmless state (a1 mode 0) */
207#define INIT_A1_BITS 0x70
165#define COUNTER_B_BASE_REG 0x18 208#define COUNTER_B_BASE_REG 0x18
166 209
167static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it); 210static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it);
@@ -423,7 +466,7 @@ static const struct labpc_board_struct labpc_boards[] = {
423 .ai_scan_up = 1, 466 .ai_scan_up = 1,
424 .memory_mapped_io = 1, 467 .memory_mapped_io = 1,
425 }, 468 },
426 /* dummy entry so pci board works when comedi_config is passed driver name */ 469/* dummy entry so pci board works when comedi_config is passed driver name */
427 { 470 {
428 .name = DRV_NAME, 471 .name = DRV_NAME,
429 .bustype = pci_bustype, 472 .bustype = pci_bustype,
@@ -436,8 +479,10 @@ static const struct labpc_board_struct labpc_boards[] = {
436 */ 479 */
437#define thisboard ((struct labpc_board_struct *)dev->board_ptr) 480#define thisboard ((struct labpc_board_struct *)dev->board_ptr)
438 481
439static const int dma_buffer_size = 0xff00; /* size in bytes of dma buffer */ 482/* size in bytes of dma buffer */
440static const int sample_size = 2; /* 2 bytes per sample */ 483static const int dma_buffer_size = 0xff00;
484/* 2 bytes per sample */
485static const int sample_size = 2;
441 486
442#define devpriv ((struct labpc_private *)dev->private) 487#define devpriv ((struct labpc_private *)dev->private)
443 488
@@ -483,12 +528,10 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
483 528
484 printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name, 529 printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
485 iobase); 530 iobase);
486 if (irq) { 531 if (irq)
487 printk(", irq %u", irq); 532 printk(", irq %u", irq);
488 } 533 if (dma_chan)
489 if (dma_chan) {
490 printk(", dma %u", dma_chan); 534 printk(", dma %u", dma_chan);
491 }
492 printk("\n"); 535 printk("\n");
493 536
494 if (iobase == 0) { 537 if (iobase == 0) {
@@ -513,7 +556,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
513 devpriv->read_byte = labpc_inb; 556 devpriv->read_byte = labpc_inb;
514 devpriv->write_byte = labpc_outb; 557 devpriv->write_byte = labpc_outb;
515 } 558 }
516 /* initialize board's command registers */ 559 /* initialize board's command registers */
517 devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); 560 devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
518 devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); 561 devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
519 devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG); 562 devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
@@ -538,12 +581,12 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
538 } 581 }
539 dev->irq = irq; 582 dev->irq = irq;
540 583
541 /* grab dma channel */ 584 /* grab dma channel */
542 if (dma_chan > 3) { 585 if (dma_chan > 3) {
543 printk(" invalid dma channel %u\n", dma_chan); 586 printk(" invalid dma channel %u\n", dma_chan);
544 return -EINVAL; 587 return -EINVAL;
545 } else if (dma_chan) { 588 } else if (dma_chan) {
546 /* allocate dma buffer */ 589 /* allocate dma buffer */
547 devpriv->dma_buffer = 590 devpriv->dma_buffer =
548 kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA); 591 kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
549 if (devpriv->dma_buffer == NULL) { 592 if (devpriv->dma_buffer == NULL) {
@@ -575,7 +618,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
575 SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; 618 SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
576 s->n_chan = 8; 619 s->n_chan = 8;
577 s->len_chanlist = 8; 620 s->len_chanlist = 8;
578 s->maxdata = (1 << 12) - 1; /* 12 bit resolution */ 621 s->maxdata = (1 << 12) - 1; /* 12 bit resolution */
579 s->range_table = thisboard->ai_range_table; 622 s->range_table = thisboard->ai_range_table;
580 s->do_cmd = labpc_ai_cmd; 623 s->do_cmd = labpc_ai_cmd;
581 s->do_cmdtest = labpc_ai_cmdtest; 624 s->do_cmdtest = labpc_ai_cmdtest;
@@ -585,8 +628,11 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
585 /* analog output */ 628 /* analog output */
586 s = dev->subdevices + 1; 629 s = dev->subdevices + 1;
587 if (thisboard->has_ao) { 630 if (thisboard->has_ao) {
588/* Could provide command support, except it only has a one sample 631 /*
589 * hardware buffer for analog output and no underrun flag. */ 632 * Could provide command support, except it only has a
633 * one sample hardware buffer for analog output and no
634 * underrun flag.
635 */
590 s->type = COMEDI_SUBD_AO; 636 s->type = COMEDI_SUBD_AO;
591 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; 637 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
592 s->n_chan = NUM_AO_CHAN; 638 s->n_chan = NUM_AO_CHAN;
@@ -608,7 +654,8 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
608 654
609 /* 8255 dio */ 655 /* 8255 dio */
610 s = dev->subdevices + 2; 656 s = dev->subdevices + 2;
611 /* if board uses io memory we have to give a custom callback function to the 8255 driver */ 657 /* if board uses io memory we have to give a custom callback
658 * function to the 8255 driver */
612 if (thisboard->memory_mapped_io) 659 if (thisboard->memory_mapped_io)
613 subdev_8255_init(dev, s, labpc_dio_mem_callback, 660 subdev_8255_init(dev, s, labpc_dio_mem_callback,
614 (unsigned long)(dev->iobase + DIO_BASE_REG)); 661 (unsigned long)(dev->iobase + DIO_BASE_REG));
@@ -640,14 +687,12 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
640 s->insn_read = labpc_eeprom_read_insn; 687 s->insn_read = labpc_eeprom_read_insn;
641 s->insn_write = labpc_eeprom_write_insn; 688 s->insn_write = labpc_eeprom_write_insn;
642 689
643 for (i = 0; i < EEPROM_SIZE; i++) { 690 for (i = 0; i < EEPROM_SIZE; i++)
644 devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i); 691 devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
645 }
646#ifdef LABPC_DEBUG 692#ifdef LABPC_DEBUG
647 printk(" eeprom:"); 693 printk(" eeprom:");
648 for (i = 0; i < EEPROM_SIZE; i++) { 694 for (i = 0; i < EEPROM_SIZE; i++)
649 printk(" %i:0x%x ", i, devpriv->eeprom_data[i]); 695 printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
650 }
651 printk("\n"); 696 printk("\n");
652#endif 697#endif
653 } else 698 } else
@@ -669,7 +714,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
669 if (alloc_private(dev, sizeof(struct labpc_private)) < 0) 714 if (alloc_private(dev, sizeof(struct labpc_private)) < 0)
670 return -ENOMEM; 715 return -ENOMEM;
671 716
672 /* get base address, irq etc. based on bustype */ 717 /* get base address, irq etc. based on bustype */
673 switch (thisboard->bustype) { 718 switch (thisboard->bustype) {
674 case isa_bustype: 719 case isa_bustype:
675 iobase = it->options[0]; 720 iobase = it->options[0];
@@ -679,9 +724,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
679 case pci_bustype: 724 case pci_bustype:
680#ifdef CONFIG_COMEDI_PCI 725#ifdef CONFIG_COMEDI_PCI
681 retval = labpc_find_device(dev, it->options[0], it->options[1]); 726 retval = labpc_find_device(dev, it->options[0], it->options[1]);
682 if (retval < 0) { 727 if (retval < 0)
683 return retval; 728 return retval;
684 }
685 retval = mite_setup(devpriv->mite); 729 retval = mite_setup(devpriv->mite);
686 if (retval < 0) 730 if (retval < 0)
687 return retval; 731 return retval;
@@ -715,7 +759,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
715 for (mite = mite_devices; mite; mite = mite->next) { 759 for (mite = mite_devices; mite; mite = mite->next) {
716 if (mite->used) 760 if (mite->used)
717 continue; 761 continue;
718 /* if bus/slot are specified then make sure we have the right bus/slot */ 762/* if bus/slot are specified then make sure we have the right bus/slot */
719 if (bus || slot) { 763 if (bus || slot) {
720 if (bus != mite->pcidev->bus->number 764 if (bus != mite->pcidev->bus->number
721 || slot != PCI_SLOT(mite->pcidev->devfn)) 765 || slot != PCI_SLOT(mite->pcidev->devfn))
@@ -726,7 +770,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
726 continue; 770 continue;
727 if (mite_device_id(mite) == labpc_boards[i].device_id) { 771 if (mite_device_id(mite) == labpc_boards[i].device_id) {
728 devpriv->mite = mite; 772 devpriv->mite = mite;
729 /* fixup board pointer, in case we were using the dummy "ni_labpc" entry */ 773/* fixup board pointer, in case we were using the dummy "ni_labpc" entry */
730 dev->board_ptr = &labpc_boards[i]; 774 dev->board_ptr = &labpc_boards[i];
731 return 0; 775 return 0;
732 } 776 }
@@ -994,7 +1038,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
994 cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE) 1038 cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
995 err++; 1039 err++;
996 1040
997 /* can't have external stop and start triggers at once */ 1041 /* can't have external stop and start triggers at once */
998 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT) 1042 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
999 err++; 1043 err++;
1000 1044
@@ -1008,9 +1052,9 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
1008 err++; 1052 err++;
1009 } 1053 }
1010 1054
1011 if (!cmd->chanlist_len) { 1055 if (!cmd->chanlist_len)
1012 err++; 1056 err++;
1013 } 1057
1014 if (cmd->scan_end_arg != cmd->chanlist_len) { 1058 if (cmd->scan_end_arg != cmd->chanlist_len) {
1015 cmd->scan_end_arg = cmd->chanlist_len; 1059 cmd->scan_end_arg = cmd->chanlist_len;
1016 err++; 1060 err++;
@@ -1022,7 +1066,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
1022 err++; 1066 err++;
1023 } 1067 }
1024 } 1068 }
1025 /* make sure scan timing is not too fast */ 1069 /* make sure scan timing is not too fast */
1026 if (cmd->scan_begin_src == TRIG_TIMER) { 1070 if (cmd->scan_begin_src == TRIG_TIMER) {
1027 if (cmd->convert_src == TRIG_TIMER && 1071 if (cmd->convert_src == TRIG_TIMER &&
1028 cmd->scan_begin_arg < 1072 cmd->scan_begin_arg <
@@ -1038,7 +1082,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
1038 err++; 1082 err++;
1039 } 1083 }
1040 } 1084 }
1041 /* stop source */ 1085 /* stop source */
1042 switch (cmd->stop_src) { 1086 switch (cmd->stop_src) {
1043 case TRIG_COUNT: 1087 case TRIG_COUNT:
1044 if (!cmd->stop_arg) { 1088 if (!cmd->stop_arg) {
@@ -1095,7 +1139,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1095 range = CR_RANGE(cmd->chanlist[0]); 1139 range = CR_RANGE(cmd->chanlist[0]);
1096 aref = CR_AREF(cmd->chanlist[0]); 1140 aref = CR_AREF(cmd->chanlist[0]);
1097 1141
1098 /* make sure board is disabled before setting up aquisition */ 1142 /* make sure board is disabled before setting up aquisition */
1099 spin_lock_irqsave(&dev->spinlock, flags); 1143 spin_lock_irqsave(&dev->spinlock, flags);
1100 devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT; 1144 devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
1101 devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); 1145 devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
@@ -1105,9 +1149,9 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1105 devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG); 1149 devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
1106 1150
1107 /* initialize software conversion count */ 1151 /* initialize software conversion count */
1108 if (cmd->stop_src == TRIG_COUNT) { 1152 if (cmd->stop_src == TRIG_COUNT)
1109 devpriv->count = cmd->stop_arg * cmd->chanlist_len; 1153 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
1110 } 1154
1111 /* setup hardware conversion counter */ 1155 /* setup hardware conversion counter */
1112 if (cmd->stop_src == TRIG_EXT) { 1156 if (cmd->stop_src == TRIG_EXT) {
1113 /* load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0 */ 1157 /* load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0 */
@@ -1176,17 +1220,18 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1176 channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]); 1220 channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
1177 else 1221 else
1178 channel = CR_CHAN(cmd->chanlist[0]); 1222 channel = CR_CHAN(cmd->chanlist[0]);
1179 /* munge channel bits for differential / scan disabled mode */ 1223 /* munge channel bits for differential / scan disabled mode */
1180 if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF) 1224 if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
1181 channel *= 2; 1225 channel *= 2;
1182 devpriv->command1_bits |= ADC_CHAN_BITS(channel); 1226 devpriv->command1_bits |= ADC_CHAN_BITS(channel);
1183 devpriv->command1_bits |= thisboard->ai_range_code[range]; 1227 devpriv->command1_bits |= thisboard->ai_range_code[range];
1184 devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); 1228 devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
1185 /* manual says to set scan enable bit on second pass */ 1229 /* manual says to set scan enable bit on second pass */
1186 if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP || 1230 if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP ||
1187 labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) { 1231 labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) {
1188 devpriv->command1_bits |= ADC_SCAN_EN_BIT; 1232 devpriv->command1_bits |= ADC_SCAN_EN_BIT;
1189 /* need a brief delay before enabling scan, or scan list will get screwed when you switch 1233 /* need a brief delay before enabling scan, or scan
1234 * list will get screwed when you switch
1190 * between scan up to scan down mode - dunno why */ 1235 * between scan up to scan down mode - dunno why */
1191 udelay(1); 1236 udelay(1);
1192 devpriv->write_byte(devpriv->command1_bits, 1237 devpriv->write_byte(devpriv->command1_bits,
@@ -1338,7 +1383,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
1338 cmd = &async->cmd; 1383 cmd = &async->cmd;
1339 async->events = 0; 1384 async->events = 0;
1340 1385
1341 /* read board status */ 1386 /* read board status */
1342 devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG); 1387 devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
1343 if (thisboard->register_layout == labpc_1200_layout) 1388 if (thisboard->register_layout == labpc_1200_layout)
1344 devpriv->status2_bits = 1389 devpriv->status2_bits =
@@ -1352,7 +1397,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
1352 } 1397 }
1353 1398
1354 if (devpriv->status1_bits & OVERRUN_BIT) { 1399 if (devpriv->status1_bits & OVERRUN_BIT) {
1355 /* clear error interrupt */ 1400 /* clear error interrupt */
1356 devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG); 1401 devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
1357 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 1402 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1358 comedi_event(dev, s); 1403 comedi_event(dev, s);
@@ -1361,7 +1406,10 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
1361 } 1406 }
1362 1407
1363 if (devpriv->current_transfer == isa_dma_transfer) { 1408 if (devpriv->current_transfer == isa_dma_transfer) {
1364 /* if a dma terminal count of external stop trigger has occurred */ 1409 /*
1410 * if a dma terminal count of external stop trigger
1411 * has occurred
1412 */
1365 if (devpriv->status1_bits & DMATC_BIT || 1413 if (devpriv->status1_bits & DMATC_BIT ||
1366 (thisboard->register_layout == labpc_1200_layout 1414 (thisboard->register_layout == labpc_1200_layout
1367 && devpriv->status2_bits & A1_TC_BIT)) { 1415 && devpriv->status2_bits & A1_TC_BIT)) {
@@ -1479,9 +1527,9 @@ static void labpc_drain_dma(struct comedi_device *dev)
1479 } 1527 }
1480 1528
1481 /* write data to comedi buffer */ 1529 /* write data to comedi buffer */
1482 for (i = 0; i < num_points; i++) { 1530 for (i = 0; i < num_points; i++)
1483 cfc_write_to_buffer(s, devpriv->dma_buffer[i]); 1531 cfc_write_to_buffer(s, devpriv->dma_buffer[i]);
1484 } 1532
1485 if (async->cmd.stop_src == TRIG_COUNT) 1533 if (async->cmd.stop_src == TRIG_COUNT)
1486 devpriv->count -= num_points; 1534 devpriv->count -= num_points;
1487 1535
@@ -1503,7 +1551,7 @@ static void handle_isa_dma(struct comedi_device *dev)
1503 devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG); 1551 devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
1504} 1552}
1505 1553
1506/* makes sure all data aquired by board is transfered to comedi (used 1554/* makes sure all data acquired by board is transfered to comedi (used
1507 * when aquisition is terminated by stop_src == TRIG_EXT). */ 1555 * when aquisition is terminated by stop_src == TRIG_EXT). */
1508static void labpc_drain_dregs(struct comedi_device *dev) 1556static void labpc_drain_dregs(struct comedi_device *dev)
1509{ 1557{
@@ -1537,41 +1585,41 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1537 chan = CR_CHAN(insn->chanspec); 1585 chan = CR_CHAN(insn->chanspec);
1538 range = CR_RANGE(insn->chanspec); 1586 range = CR_RANGE(insn->chanspec);
1539 devpriv->command1_bits |= thisboard->ai_range_code[range]; 1587 devpriv->command1_bits |= thisboard->ai_range_code[range];
1540 /* munge channel bits for differential/scan disabled mode */ 1588 /* munge channel bits for differential/scan disabled mode */
1541 if (CR_AREF(insn->chanspec) == AREF_DIFF) 1589 if (CR_AREF(insn->chanspec) == AREF_DIFF)
1542 chan *= 2; 1590 chan *= 2;
1543 devpriv->command1_bits |= ADC_CHAN_BITS(chan); 1591 devpriv->command1_bits |= ADC_CHAN_BITS(chan);
1544 devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); 1592 devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
1545 1593
1546 /* setup command6 register for 1200 boards */ 1594 /* setup command6 register for 1200 boards */
1547 if (thisboard->register_layout == labpc_1200_layout) { 1595 if (thisboard->register_layout == labpc_1200_layout) {
1548 /* reference inputs to ground or common? */ 1596 /* reference inputs to ground or common? */
1549 if (CR_AREF(insn->chanspec) != AREF_GROUND) 1597 if (CR_AREF(insn->chanspec) != AREF_GROUND)
1550 devpriv->command6_bits |= ADC_COMMON_BIT; 1598 devpriv->command6_bits |= ADC_COMMON_BIT;
1551 else 1599 else
1552 devpriv->command6_bits &= ~ADC_COMMON_BIT; 1600 devpriv->command6_bits &= ~ADC_COMMON_BIT;
1553 /* bipolar or unipolar range? */ 1601 /* bipolar or unipolar range? */
1554 if (thisboard->ai_range_is_unipolar[range]) 1602 if (thisboard->ai_range_is_unipolar[range])
1555 devpriv->command6_bits |= ADC_UNIP_BIT; 1603 devpriv->command6_bits |= ADC_UNIP_BIT;
1556 else 1604 else
1557 devpriv->command6_bits &= ~ADC_UNIP_BIT; 1605 devpriv->command6_bits &= ~ADC_UNIP_BIT;
1558 /* don't interrupt on fifo half full */ 1606 /* don't interrupt on fifo half full */
1559 devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT; 1607 devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
1560 /* don't enable interrupt on counter a1 terminal count? */ 1608 /* don't enable interrupt on counter a1 terminal count? */
1561 devpriv->command6_bits &= ~A1_INTR_EN_BIT; 1609 devpriv->command6_bits &= ~A1_INTR_EN_BIT;
1562 /* write to register */ 1610 /* write to register */
1563 devpriv->write_byte(devpriv->command6_bits, 1611 devpriv->write_byte(devpriv->command6_bits,
1564 dev->iobase + COMMAND6_REG); 1612 dev->iobase + COMMAND6_REG);
1565 } 1613 }
1566 /* setup command4 register */ 1614 /* setup command4 register */
1567 devpriv->command4_bits = 0; 1615 devpriv->command4_bits = 0;
1568 devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT; 1616 devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
1569 /* single-ended/differential */ 1617 /* single-ended/differential */
1570 if (CR_AREF(insn->chanspec) == AREF_DIFF) 1618 if (CR_AREF(insn->chanspec) == AREF_DIFF)
1571 devpriv->command4_bits |= ADC_DIFF_BIT; 1619 devpriv->command4_bits |= ADC_DIFF_BIT;
1572 devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG); 1620 devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
1573 1621
1574 /* initialize pacer counter output to make sure it doesn't cause any problems */ 1622 /* initialize pacer counter output to make sure it doesn't cause any problems */
1575 devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG); 1623 devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
1576 1624
1577 labpc_clear_adc_fifo(dev); 1625 labpc_clear_adc_fifo(dev);
@@ -1608,7 +1656,7 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1608 1656
1609 channel = CR_CHAN(insn->chanspec); 1657 channel = CR_CHAN(insn->chanspec);
1610 1658
1611 /* turn off pacing of analog output channel */ 1659 /* turn off pacing of analog output channel */
1612 /* note: hardware bug in daqcard-1200 means pacing cannot 1660 /* note: hardware bug in daqcard-1200 means pacing cannot
1613 * be independently enabled/disabled for its the two channels */ 1661 * be independently enabled/disabled for its the two channels */
1614 spin_lock_irqsave(&dev->spinlock, flags); 1662 spin_lock_irqsave(&dev->spinlock, flags);
@@ -1616,7 +1664,7 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1616 devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG); 1664 devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
1617 spin_unlock_irqrestore(&dev->spinlock, flags); 1665 spin_unlock_irqrestore(&dev->spinlock, flags);
1618 1666
1619 /* set range */ 1667 /* set range */
1620 if (thisboard->register_layout == labpc_1200_layout) { 1668 if (thisboard->register_layout == labpc_1200_layout) {
1621 range = CR_RANGE(insn->chanspec); 1669 range = CR_RANGE(insn->chanspec);
1622 if (range & AO_RANGE_IS_UNIPOLAR) 1670 if (range & AO_RANGE_IS_UNIPOLAR)
@@ -1627,13 +1675,13 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1627 devpriv->write_byte(devpriv->command6_bits, 1675 devpriv->write_byte(devpriv->command6_bits,
1628 dev->iobase + COMMAND6_REG); 1676 dev->iobase + COMMAND6_REG);
1629 } 1677 }
1630 /* send data */ 1678 /* send data */
1631 lsb = data[0] & 0xff; 1679 lsb = data[0] & 0xff;
1632 msb = (data[0] >> 8) & 0xff; 1680 msb = (data[0] >> 8) & 0xff;
1633 devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel)); 1681 devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
1634 devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel)); 1682 devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
1635 1683
1636 /* remember value for readback */ 1684 /* remember value for readback */
1637 devpriv->ao_value[channel] = data[0]; 1685 devpriv->ao_value[channel] = data[0];
1638 1686
1639 return 1; 1687 return 1;
@@ -1705,14 +1753,14 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
1705 1753
1706 if (cmd.convert_src == TRIG_TIMER) 1754 if (cmd.convert_src == TRIG_TIMER)
1707 freq = 1000000000 / cmd.convert_arg; 1755 freq = 1000000000 / cmd.convert_arg;
1708 /* return some default value */ 1756 /* return some default value */
1709 else 1757 else
1710 freq = 0xffffffff; 1758 freq = 0xffffffff;
1711 1759
1712 /* make buffer fill in no more than 1/3 second */ 1760 /* make buffer fill in no more than 1/3 second */
1713 size = (freq / 3) * sample_size; 1761 size = (freq / 3) * sample_size;
1714 1762
1715 /* set a minimum and maximum size allowed */ 1763 /* set a minimum and maximum size allowed */
1716 if (size > dma_buffer_size) 1764 if (size > dma_buffer_size)
1717 size = dma_buffer_size - dma_buffer_size % sample_size; 1765 size = dma_buffer_size - dma_buffer_size % sample_size;
1718 else if (size < sample_size) 1766 else if (size < sample_size)
@@ -1724,13 +1772,21 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
1724/* figures out what counter values to use based on command */ 1772/* figures out what counter values to use based on command */
1725static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) 1773static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
1726{ 1774{
1727 const int max_counter_value = 0x10000; /* max value for 16 bit counter in mode 2 */ 1775 /* max value for 16 bit counter in mode 2 */
1728 const int min_counter_value = 2; /* min value for 16 bit counter in mode 2 */ 1776 const int max_counter_value = 0x10000;
1777 /* min value for 16 bit counter in mode 2 */
1778 const int min_counter_value = 2;
1729 unsigned int base_period; 1779 unsigned int base_period;
1730 1780
1731 /* if both convert and scan triggers are TRIG_TIMER, then they both rely on counter b0 */ 1781 /*
1782 * if both convert and scan triggers are TRIG_TIMER, then they
1783 * both rely on counter b0
1784 */
1732 if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) { 1785 if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) {
1733 /* pick the lowest b0 divisor value we can (for maximum input clock speed on convert and scan counters) */ 1786 /*
1787 * pick the lowest b0 divisor value we can (for maximum input
1788 * clock speed on convert and scan counters)
1789 */
1734 devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) / 1790 devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) /
1735 (LABPC_TIMER_BASE * max_counter_value) + 1; 1791 (LABPC_TIMER_BASE * max_counter_value) + 1;
1736 if (devpriv->divisor_b0 < min_counter_value) 1792 if (devpriv->divisor_b0 < min_counter_value)
@@ -1780,7 +1836,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
1780 base_period * devpriv->divisor_a0); 1836 base_period * devpriv->divisor_a0);
1781 labpc_set_ai_scan_period(cmd, 1837 labpc_set_ai_scan_period(cmd,
1782 base_period * devpriv->divisor_b1); 1838 base_period * devpriv->divisor_b1);
1783 /* if only one TRIG_TIMER is used, we can employ the generic cascaded timing functions */ 1839 /*
1840 * if only one TRIG_TIMER is used, we can employ the generic
1841 * cascaded timing functions
1842 */
1784 } else if (labpc_ai_scan_period(cmd)) { 1843 } else if (labpc_ai_scan_period(cmd)) {
1785 unsigned int scan_period; 1844 unsigned int scan_period;
1786 1845
@@ -1864,9 +1923,8 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
1864 udelay(1); 1923 udelay(1);
1865 devpriv->status2_bits = 1924 devpriv->status2_bits =
1866 devpriv->read_byte(dev->iobase + STATUS2_REG); 1925 devpriv->read_byte(dev->iobase + STATUS2_REG);
1867 if (devpriv->status2_bits & EEPROM_OUT_BIT) { 1926 if (devpriv->status2_bits & EEPROM_OUT_BIT)
1868 value |= 1 << (value_width - i); 1927 value |= 1 << (value_width - i);
1869 }
1870 } 1928 }
1871 1929
1872 return value; 1930 return value;
@@ -1876,8 +1934,10 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
1876 unsigned int address) 1934 unsigned int address)
1877{ 1935{
1878 unsigned int value; 1936 unsigned int value;
1879 const int read_instruction = 0x3; /* bits to tell eeprom to expect a read */ 1937 /* bits to tell eeprom to expect a read */
1880 const int write_length = 8; /* 8 bit write lengths to eeprom */ 1938 const int read_instruction = 0x3;
1939 /* 8 bit write lengths to eeprom */
1940 const int write_length = 8;
1881 1941
1882 /* enable read/write to eeprom */ 1942 /* enable read/write to eeprom */
1883 devpriv->command5_bits &= ~EEPROM_EN_BIT; 1943 devpriv->command5_bits &= ~EEPROM_EN_BIT;
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index d6d49c3bbf1c..bd16f913af23 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -3795,7 +3795,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
3795#endif 3795#endif
3796 int retval = 0; 3796 int retval = 0;
3797 unsigned i; 3797 unsigned i;
3798 const unsigned timeout = 100; 3798 const unsigned timeout = 1000;
3799 3799
3800 s->async->inttrig = NULL; 3800 s->async->inttrig = NULL;
3801 3801
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 2d88a5be65ff..9d337516409d 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -1,8 +1,8 @@
1/* 1/*
2 comedi/drivers/ni_pcidio.c 2 comedi/drivers/ni_pcidio.c
3 driver for National Instruments PCI-DIO-96/PCI-6508 3 driver for National Instruments PCI-DIO-96/PCI-6508
4 National Instruments PCI-DIO-32HS 4 National Instruments PCI-DIO-32HS
5 National Instruments PCI-6503 5 National Instruments PCI-6503
6 6
7 COMEDI - Linux Control and Measurement Device Interface 7 COMEDI - Linux Control and Measurement Device Interface
8 Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org> 8 Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
@@ -518,7 +518,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
518 ni_pcidio_print_status(status); 518 ni_pcidio_print_status(status);
519 519
520 /* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */ 520 /* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */
521 /* printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096)); */ 521 /* printk("buf[4096]=%08x\n",
522 *(unsigned int *)(async->prealloc_buf+4096)); */
522 523
523 spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags); 524 spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
524 if (devpriv->di_mite_chan) 525 if (devpriv->di_mite_chan)
@@ -526,7 +527,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
526#ifdef MITE_DEBUG 527#ifdef MITE_DEBUG
527 mite_print_chsr(m_status); 528 mite_print_chsr(m_status);
528#endif 529#endif
529 /* printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN)); */ 530 /* printk("mite_bytes_transferred: %d\n",
531 mite_bytes_transferred(mite,DI_DMA_CHAN)); */
532
530 /* mite_dump_regs(mite); */ 533 /* mite_dump_regs(mite); */
531 if (m_status & CHSR_INT) { 534 if (m_status & CHSR_INT) {
532 if (m_status & CHSR_LINKC) { 535 if (m_status & CHSR_LINKC) {
@@ -565,7 +568,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
565 DPRINTK("too much work in interrupt\n"); 568 DPRINTK("too much work in interrupt\n");
566 writeb(0x00, 569 writeb(0x00,
567 devpriv->mite->daq_io_addr + 570 devpriv->mite->daq_io_addr +
568 Master_DMA_And_Interrupt_Control); 571 Master_DMA_And_Interrupt_Control
572 );
569 goto out; 573 goto out;
570 } 574 }
571 AuxData = 575 AuxData =
@@ -579,8 +583,10 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
579 flags = readb(devpriv->mite->daq_io_addr + 583 flags = readb(devpriv->mite->daq_io_addr +
580 Group_1_Flags); 584 Group_1_Flags);
581 } 585 }
582 /* DPRINTK("buf_int_count: %d\n",async->buf_int_count); */ 586 /* DPRINTK("buf_int_count: %d\n",
583 /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status); */ 587 async->buf_int_count); */
588 /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
589 IntEn,flags,status); */
584 /* ni_pcidio_print_flags(flags); */ 590 /* ni_pcidio_print_flags(flags); */
585 /* ni_pcidio_print_status(status); */ 591 /* ni_pcidio_print_status(status); */
586 async->events |= COMEDI_CB_BLOCK; 592 async->events |= COMEDI_CB_BLOCK;
@@ -627,8 +633,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
627 flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); 633 flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
628 status = readb(devpriv->mite->daq_io_addr + 634 status = readb(devpriv->mite->daq_io_addr +
629 Interrupt_And_Window_Status); 635 Interrupt_And_Window_Status);
630 /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n", */ 636 /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
631 /* IntEn,flags,status); */ 637 "status=0x%02x\n", IntEn, flags, status); */
632 /* ni_pcidio_print_flags(flags); */ 638 /* ni_pcidio_print_flags(flags); */
633 /* ni_pcidio_print_status(status); */ 639 /* ni_pcidio_print_status(status); */
634 } 640 }
@@ -655,11 +661,10 @@ static void ni_pcidio_print_flags(unsigned int flags)
655{ 661{
656 int i; 662 int i;
657 663
658 printk("group_1_flags:"); 664 printk(KERN_INFO "group_1_flags:");
659 for (i = 7; i >= 0; i--) { 665 for (i = 7; i >= 0; i--) {
660 if (flags & (1 << i)) { 666 if (flags & (1 << i))
661 printk(" %s", flags_strings[i]); 667 printk(" %s", flags_strings[i]);
662 }
663 } 668 }
664 printk("\n"); 669 printk("\n");
665} 670}
@@ -673,11 +678,10 @@ static void ni_pcidio_print_status(unsigned int flags)
673{ 678{
674 int i; 679 int i;
675 680
676 printk("group_status:"); 681 printk(KERN_INFO "group_status:");
677 for (i = 7; i >= 0; i--) { 682 for (i = 7; i >= 0; i--) {
678 if (flags & (1 << i)) { 683 if (flags & (1 << i))
679 printk(" %s", status_strings[i]); 684 printk(" %s", status_strings[i]);
680 }
681 } 685 }
682 printk("\n"); 686 printk("\n");
683} 687}
@@ -793,7 +797,8 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
793 if (err) 797 if (err)
794 return 1; 798 return 1;
795 799
796 /* step 2: make sure trigger sources are unique and mutually compatible */ 800 /* step 2: make sure trigger sources are unique and mutually
801 compatible */
797 802
798 /* note that mutual compatibility is not an issue here */ 803 /* note that mutual compatibility is not an issue here */
799 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT) 804 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
@@ -974,7 +979,8 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
974 979
975 /* clear and enable interrupts */ 980 /* clear and enable interrupts */
976 writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear); 981 writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
977 /* writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear); */ 982 /* writeb(ClearExpired,
983 devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
978 984
979 writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control); 985 writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
980 writeb(0x03, 986 writeb(0x03,
@@ -1052,7 +1058,7 @@ static int ni_pcidio_change(struct comedi_device *dev,
1052} 1058}
1053 1059
1054static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, 1060static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
1055 u8 * data, int data_len) 1061 u8 *data, int data_len)
1056{ 1062{
1057 static const int timeout = 1000; 1063 static const int timeout = 1000;
1058 int i, j; 1064 int i, j;
@@ -1066,9 +1072,8 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
1066 udelay(1); 1072 udelay(1);
1067 } 1073 }
1068 if (i == timeout) { 1074 if (i == timeout) {
1069 printk 1075 printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
1070 ("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", 1076 "waiting for status 0x2\n", fpga_index);
1071 fpga_index);
1072 return -EIO; 1077 return -EIO;
1073 } 1078 }
1074 writew(0x80 | fpga_index, 1079 writew(0x80 | fpga_index,
@@ -1079,9 +1084,8 @@ static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
1079 udelay(1); 1084 udelay(1);
1080 } 1085 }
1081 if (i == timeout) { 1086 if (i == timeout) {
1082 printk 1087 printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
1083 ("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", 1088 "waiting for status 0x3\n", fpga_index);
1084 fpga_index);
1085 return -EIO; 1089 return -EIO;
1086 } 1090 }
1087 for (j = 0; j + 1 < data_len;) { 1091 for (j = 0; j + 1 < data_len;) {
@@ -1174,9 +1178,10 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1174 int n_subdevices; 1178 int n_subdevices;
1175 unsigned int irq; 1179 unsigned int irq;
1176 1180
1177 printk("comedi%d: nidio:", dev->minor); 1181 printk(KERN_INFO "comedi%d: nidio:", dev->minor);
1178 1182
1179 if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0) 1183 ret = alloc_private(dev, sizeof(struct nidio96_private));
1184 if (ret < 0)
1180 return ret; 1185 return ret;
1181 spin_lock_init(&devpriv->mite_channel_lock); 1186 spin_lock_init(&devpriv->mite_channel_lock);
1182 1187
@@ -1186,7 +1191,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1186 1191
1187 ret = mite_setup(devpriv->mite); 1192 ret = mite_setup(devpriv->mite);
1188 if (ret < 0) { 1193 if (ret < 0) {
1189 printk("error setting up mite\n"); 1194 printk(KERN_WARNING "error setting up mite\n");
1190 return ret; 1195 return ret;
1191 } 1196 }
1192 comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); 1197 comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
@@ -1196,18 +1201,19 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1196 1201
1197 dev->board_name = this_board->name; 1202 dev->board_name = this_board->name;
1198 irq = mite_irq(devpriv->mite); 1203 irq = mite_irq(devpriv->mite);
1199 printk(" %s", dev->board_name); 1204 printk(KERN_INFO " %s", dev->board_name);
1200 if (this_board->uses_firmware) { 1205 if (this_board->uses_firmware) {
1201 ret = pci_6534_upload_firmware(dev, it->options); 1206 ret = pci_6534_upload_firmware(dev, it->options);
1202 if (ret < 0) 1207 if (ret < 0)
1203 return ret; 1208 return ret;
1204 } 1209 }
1205 if (!this_board->is_diodaq) { 1210 if (!this_board->is_diodaq)
1206 n_subdevices = this_board->n_8255; 1211 n_subdevices = this_board->n_8255;
1207 } else { 1212 else
1208 n_subdevices = 1; 1213 n_subdevices = 1;
1209 } 1214
1210 if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) 1215 ret = alloc_subdevices(dev, n_subdevices);
1216 if (ret < 0)
1211 return ret; 1217 return ret;
1212 1218
1213 if (!this_board->is_diodaq) { 1219 if (!this_board->is_diodaq) {
@@ -1220,7 +1226,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1220 } 1226 }
1221 } else { 1227 } else {
1222 1228
1223 printk(" rev=%d", 1229 printk(KERN_INFO " rev=%d",
1224 readb(devpriv->mite->daq_io_addr + Chip_Version)); 1230 readb(devpriv->mite->daq_io_addr + Chip_Version));
1225 1231
1226 s = dev->subdevices + 0; 1232 s = dev->subdevices + 0;
@@ -1253,9 +1259,9 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1253 1259
1254 ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, 1260 ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
1255 "ni_pcidio", dev); 1261 "ni_pcidio", dev);
1256 if (ret < 0) { 1262 if (ret < 0)
1257 printk(" irq not available"); 1263 printk(KERN_WARNING " irq not available");
1258 } 1264
1259 dev->irq = irq; 1265 dev->irq = irq;
1260 } 1266 }
1261 1267
@@ -1269,9 +1275,8 @@ static int nidio_detach(struct comedi_device *dev)
1269 int i; 1275 int i;
1270 1276
1271 if (this_board && !this_board->is_diodaq) { 1277 if (this_board && !this_board->is_diodaq) {
1272 for (i = 0; i < this_board->n_8255; i++) { 1278 for (i = 0; i < this_board->n_8255; i++)
1273 subdev_8255_cleanup(dev, dev->subdevices + i); 1279 subdev_8255_cleanup(dev, dev->subdevices + i);
1274 }
1275 } 1280 }
1276 1281
1277 if (dev->irq) 1282 if (dev->irq)
@@ -1310,7 +1315,7 @@ static int nidio_find_device(struct comedi_device *dev, int bus, int slot)
1310 } 1315 }
1311 } 1316 }
1312 } 1317 }
1313 printk("no device found\n"); 1318 printk(KERN_WARNING "no device found\n");
1314 mite_list_devices(); 1319 mite_list_devices();
1315 return -EIO; 1320 return -EIO;
1316} 1321}
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index 4914784f6995..a499f7070f72 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -207,11 +207,10 @@ static irqreturn_t pcl711_interrupt(int irq, void *d)
207 207
208 /* FIXME! Nothing else sets ntrig! */ 208 /* FIXME! Nothing else sets ntrig! */
209 if (!(--devpriv->ntrig)) { 209 if (!(--devpriv->ntrig)) {
210 if (this_board->is_8112) { 210 if (this_board->is_8112)
211 outb(1, dev->iobase + PCL711_MODE); 211 outb(1, dev->iobase + PCL711_MODE);
212 } else { 212 else
213 outb(0, dev->iobase + PCL711_MODE); 213 outb(0, dev->iobase + PCL711_MODE);
214 }
215 214
216 s->async->events |= COMEDI_CB_EOA; 215 s->async->events |= COMEDI_CB_EOA;
217 } 216 }
@@ -232,15 +231,15 @@ static void pcl711_set_changain(struct comedi_device *dev, int chan)
232 /* 231 /*
233 * Set the correct channel. The two channel banks are switched 232 * Set the correct channel. The two channel banks are switched
234 * using the mask value. 233 * using the mask value.
235 * NB: To use differential channels, you should use mask = 0x30, 234 * NB: To use differential channels, you should use
236 * but I haven't written the support for this yet. /JJ 235 * mask = 0x30, but I haven't written the support for this
236 * yet. /JJ
237 */ 237 */
238 238
239 if (chan_register >= 8) { 239 if (chan_register >= 8)
240 chan_register = 0x20 | (chan_register & 0x7); 240 chan_register = 0x20 | (chan_register & 0x7);
241 } else { 241 else
242 chan_register |= 0x10; 242 chan_register |= 0x10;
243 }
244 } else { 243 } else {
245 outb(chan_register, dev->iobase + PCL711_MUX); 244 outb(chan_register, dev->iobase + PCL711_MUX);
246 } 245 }
@@ -256,15 +255,13 @@ static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
256 255
257 for (n = 0; n < insn->n; n++) { 256 for (n = 0; n < insn->n; n++) {
258 /* 257 /*
259 * Write the correct mode (software polling) and start polling by writing 258 * Write the correct mode (software polling) and start polling
260 * to the trigger register 259 * by writing to the trigger register
261 */ 260 */
262 outb(1, dev->iobase + PCL711_MODE); 261 outb(1, dev->iobase + PCL711_MODE);
263 262
264 if (this_board->is_8112) { 263 if (!this_board->is_8112)
265 } else {
266 outb(0, dev->iobase + PCL711_SOFTTRIG); 264 outb(0, dev->iobase + PCL711_SOFTTRIG);
267 }
268 265
269 i = PCL711_TIMEOUT; 266 i = PCL711_TIMEOUT;
270 while (--i) { 267 while (--i) {
@@ -462,9 +459,8 @@ static int pcl711_ao_insn_read(struct comedi_device *dev,
462 int n; 459 int n;
463 int chan = CR_CHAN(insn->chanspec); 460 int chan = CR_CHAN(insn->chanspec);
464 461
465 for (n = 0; n < insn->n; n++) { 462 for (n = 0; n < insn->n; n++)
466 data[n] = devpriv->ao_readback[chan]; 463 data[n] = devpriv->ao_readback[chan];
467 }
468 464
469 return n; 465 return n;
470 466
@@ -619,9 +615,8 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
619 this is the "base value" for the mode register, which is 615 this is the "base value" for the mode register, which is
620 used for the irq on the PCL711 616 used for the irq on the PCL711
621 */ 617 */
622 if (this_board->is_pcl711b) { 618 if (this_board->is_pcl711b)
623 devpriv->mode = (dev->irq << 4); 619 devpriv->mode = (dev->irq << 4);
624 }
625 620
626 /* clear DAC */ 621 /* clear DAC */
627 outb(0, dev->iobase + PCL711_DA0_LO); 622 outb(0, dev->iobase + PCL711_DA0_LO);
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index df1f4ef14616..0f103c328064 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -17,7 +17,7 @@
17 [0] - IO Base 17 [0] - IO Base
18 [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time! 18 [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
19 [2] -number of DIO: 19 [2] -number of DIO:
20 0, 144: 144 DIO configuration 20 0, 144: 144 DIO configuration
21 1, 96: 96 DIO configuration 21 1, 96: 96 DIO configuration
22*/ 22*/
23/* 23/*
@@ -137,8 +137,8 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
137 iorange = this_board->io_range; 137 iorange = this_board->io_range;
138 if ((this_board->can_have96) && ((it->options[1] == 1) 138 if ((this_board->can_have96) && ((it->options[1] == 1)
139 || (it->options[1] == 96))) 139 || (it->options[1] == 96)))
140 iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */ 140 iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */
141 printk("comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor, 141 printk(KERN_INFO "comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
142 this_board->name, iobase); 142 this_board->name, iobase);
143 if (!request_region(iobase, iorange, "pcl724")) { 143 if (!request_region(iobase, iorange, "pcl724")) {
144 printk("I/O port conflict\n"); 144 printk("I/O port conflict\n");
@@ -155,16 +155,16 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
155 irq = it->options[1]; 155 irq = it->options[1];
156 if (irq) { /* we want to use IRQ */ 156 if (irq) { /* we want to use IRQ */
157 if (((1 << irq) & this_board->IRQbits) == 0) { 157 if (((1 << irq) & this_board->IRQbits) == 0) {
158 printk 158 printk(KERN_WARNING
159 (", IRQ %u is out of allowed range, DISABLING IT", 159 ", IRQ %u is out of allowed range, "
160 irq); 160 "DISABLING IT", irq);
161 irq = 0; /* Bad IRQ */ 161 irq = 0; /* Bad IRQ */
162 } else { 162 } else {
163 if (request_irq 163 if (request_irq
164 (irq, interrupt_pcl724, 0, "pcl724", dev)) { 164 (irq, interrupt_pcl724, 0, "pcl724", dev)) {
165 printk 165 printk(KERN_WARNING
166 (", unable to allocate IRQ %u, DISABLING IT", 166 ", unable to allocate IRQ %u, "
167 irq); 167 "DISABLING IT", irq);
168 irq = 0; /* Can't use IRQ */ 168 irq = 0; /* Can't use IRQ */
169 } else { 169 } else {
170 printk(", irq=%u", irq); 170 printk(", irq=%u", irq);
@@ -207,16 +207,14 @@ static int pcl724_detach(struct comedi_device *dev)
207{ 207{
208 int i; 208 int i;
209 209
210/* printk("comedi%d: pcl724: remove\n",dev->minor); */ 210 /* printk("comedi%d: pcl724: remove\n",dev->minor); */
211 211
212 for (i = 0; i < dev->n_subdevices; i++) { 212 for (i = 0; i < dev->n_subdevices; i++)
213 subdev_8255_cleanup(dev, dev->subdevices + i); 213 subdev_8255_cleanup(dev, dev->subdevices + i);
214 }
215 214
216#ifdef PCL724_IRQ 215#ifdef PCL724_IRQ
217 if (dev->irq) { 216 if (dev->irq)
218 free_irq(dev->irq, dev); 217 free_irq(dev->irq, dev);
219 }
220#endif 218#endif
221 219
222 release_region(dev->iobase, this_board->io_range); 220 release_region(dev->iobase, this_board->io_range);
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c
index 1da4941fce49..60261f4ba5b4 100644
--- a/drivers/staging/comedi/drivers/pcl725.c
+++ b/drivers/staging/comedi/drivers/pcl725.c
@@ -66,7 +66,7 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
66 unsigned long iobase; 66 unsigned long iobase;
67 67
68 iobase = it->options[0]; 68 iobase = it->options[0];
69 printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); 69 printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
70 if (!request_region(iobase, PCL725_SIZE, "pcl725")) { 70 if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
71 printk("I/O port conflict\n"); 71 printk("I/O port conflict\n");
72 return -EIO; 72 return -EIO;
@@ -96,14 +96,14 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
96 s->insn_bits = pcl725_di_insn; 96 s->insn_bits = pcl725_di_insn;
97 s->range_table = &range_digital; 97 s->range_table = &range_digital;
98 98
99 printk("\n"); 99 printk(KERN_INFO "\n");
100 100
101 return 0; 101 return 0;
102} 102}
103 103
104static int pcl725_detach(struct comedi_device *dev) 104static int pcl725_detach(struct comedi_device *dev)
105{ 105{
106 printk("comedi%d: pcl725: remove\n", dev->minor); 106 printk(KERN_INFO "comedi%d: pcl725: remove\n", dev->minor);
107 107
108 if (dev->iobase) 108 if (dev->iobase)
109 release_region(dev->iobase, PCL725_SIZE); 109 release_region(dev->iobase, PCL725_SIZE);
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index c9859c90c152..e5e7bed21de0 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -99,7 +99,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
99 99
100 iobase = it->options[0]; 100 iobase = it->options[0];
101 iorange = this_board->io_range; 101 iorange = this_board->io_range;
102 printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor, 102 printk(KERN_INFO "comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
103 this_board->name, iobase); 103 this_board->name, iobase);
104 if (!request_region(iobase, iorange, "pcl730")) { 104 if (!request_region(iobase, iorange, "pcl730")) {
105 printk("I/O port conflict\n"); 105 printk("I/O port conflict\n");
@@ -152,14 +152,14 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
152 s->range_table = &range_digital; 152 s->range_table = &range_digital;
153 s->private = (void *)PCL730_DIO_LO; 153 s->private = (void *)PCL730_DIO_LO;
154 154
155 printk("\n"); 155 printk(KERN_INFO "\n");
156 156
157 return 0; 157 return 0;
158} 158}
159 159
160static int pcl730_detach(struct comedi_device *dev) 160static int pcl730_detach(struct comedi_device *dev)
161{ 161{
162 printk("comedi%d: pcl730: remove\n", dev->minor); 162 printk(KERN_INFO "comedi%d: pcl730: remove\n", dev->minor);
163 163
164 if (dev->iobase) 164 if (dev->iobase)
165 release_region(dev->iobase, this_board->io_range); 165 release_region(dev->iobase, this_board->io_range);
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 0a5bc3d6da8c..d4634c4f02dc 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -955,6 +955,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
955 unsigned int mask, timeout; 955 unsigned int mask, timeout;
956 struct comedi_device *dev = d; 956 struct comedi_device *dev = d;
957 struct comedi_subdevice *s = dev->subdevices + 0; 957 struct comedi_subdevice *s = dev->subdevices + 0;
958 unsigned int next_chan;
958 959
959 s->async->events = 0; 960 s->async->events = 0;
960 961
@@ -993,9 +994,18 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
993 ((inb(dev->iobase + PCL812_AD_HI) << 8) | 994 ((inb(dev->iobase + PCL812_AD_HI) << 8) |
994 inb(dev->iobase + PCL812_AD_LO)) & mask); 995 inb(dev->iobase + PCL812_AD_LO)) & mask);
995 996
997 /* Set up next channel. Added by abbotti 2010-01-20, but untested. */
998 next_chan = s->async->cur_chan + 1;
999 if (next_chan >= devpriv->ai_n_chan)
1000 next_chan = 0;
1001 if (devpriv->ai_chanlist[s->async->cur_chan] !=
1002 devpriv->ai_chanlist[next_chan])
1003 setup_range_channel(dev, s, devpriv->ai_chanlist[next_chan], 0);
1004
996 outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */ 1005 outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
997 1006
998 if (s->async->cur_chan == 0) { /* one scan done */ 1007 s->async->cur_chan = next_chan;
1008 if (next_chan == 0) { /* one scan done */
999 devpriv->ai_act_scan++; 1009 devpriv->ai_act_scan++;
1000 if (!(devpriv->ai_neverending)) 1010 if (!(devpriv->ai_neverending))
1001 if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ 1011 if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
@@ -1021,7 +1031,9 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
1021 for (i = len; i; i--) { 1031 for (i = len; i; i--) {
1022 comedi_buf_put(s->async, ptr[bufptr++]); /* get one sample */ 1032 comedi_buf_put(s->async, ptr[bufptr++]); /* get one sample */
1023 1033
1024 if (s->async->cur_chan == 0) { 1034 s->async->cur_chan++;
1035 if (s->async->cur_chan >= devpriv->ai_n_chan) {
1036 s->async->cur_chan = 0;
1025 devpriv->ai_act_scan++; 1037 devpriv->ai_act_scan++;
1026 if (!devpriv->ai_neverending) 1038 if (!devpriv->ai_neverending)
1027 if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */ 1039 if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 852fe2458fdc..9820759ec54f 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -202,6 +202,7 @@ struct pcl816_private {
202 unsigned int ai_act_chanlist[16]; /* MUX setting for actual AI operations */ 202 unsigned int ai_act_chanlist[16]; /* MUX setting for actual AI operations */
203 unsigned int ai_act_chanlist_len; /* how long is actual MUX list */ 203 unsigned int ai_act_chanlist_len; /* how long is actual MUX list */
204 unsigned int ai_act_chanlist_pos; /* actual position in MUX list */ 204 unsigned int ai_act_chanlist_pos; /* actual position in MUX list */
205 unsigned int ai_n_chan; /* how many channels per scan */
205 unsigned int ai_poll_ptr; /* how many sampes transfer poll */ 206 unsigned int ai_poll_ptr; /* how many sampes transfer poll */
206 struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ 207 struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */
207#ifdef unused 208#ifdef unused
@@ -213,9 +214,12 @@ struct pcl816_private {
213/* 214/*
214============================================================================== 215==============================================================================
215*/ 216*/
216static int check_and_setup_channel_list(struct comedi_device *dev, 217static int check_channel_list(struct comedi_device *dev,
217 struct comedi_subdevice *s, 218 struct comedi_subdevice *s,
218 unsigned int *chanlist, int chanlen); 219 unsigned int *chanlist, unsigned int chanlen);
220static void setup_channel_list(struct comedi_device *dev,
221 struct comedi_subdevice *s,
222 unsigned int *chanlist, unsigned int seglen);
219static int pcl816_ai_cancel(struct comedi_device *dev, 223static int pcl816_ai_cancel(struct comedi_device *dev,
220 struct comedi_subdevice *s); 224 struct comedi_subdevice *s);
221static void start_pacer(struct comedi_device *dev, int mode, 225static void start_pacer(struct comedi_device *dev, int mode,
@@ -320,7 +324,9 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
320 if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len) 324 if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len)
321 devpriv->ai_act_chanlist_pos = 0; 325 devpriv->ai_act_chanlist_pos = 0;
322 326
323 if (s->async->cur_chan == 0) { 327 s->async->cur_chan++;
328 if (s->async->cur_chan >= devpriv->ai_n_chan) {
329 s->async->cur_chan = 0;
324 devpriv->ai_act_scan++; 330 devpriv->ai_act_scan++;
325 } 331 }
326 332
@@ -353,6 +359,11 @@ static void transfer_from_dma_buf(struct comedi_device *dev,
353 if (++devpriv->ai_act_chanlist_pos >= 359 if (++devpriv->ai_act_chanlist_pos >=
354 devpriv->ai_act_chanlist_len) { 360 devpriv->ai_act_chanlist_len) {
355 devpriv->ai_act_chanlist_pos = 0; 361 devpriv->ai_act_chanlist_pos = 0;
362 }
363
364 s->async->cur_chan++;
365 if (s->async->cur_chan >= devpriv->ai_n_chan) {
366 s->async->cur_chan = 0;
356 devpriv->ai_act_scan++; 367 devpriv->ai_act_scan++;
357 } 368 }
358 369
@@ -558,14 +569,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
558 } 569 }
559 } 570 }
560 571
561 if (!cmd->chanlist_len) {
562 cmd->chanlist_len = 1;
563 err++;
564 }
565 if (cmd->chanlist_len > this_board->n_aichan) {
566 cmd->chanlist_len = this_board->n_aichan;
567 err++;
568 }
569 if (cmd->scan_end_arg != cmd->chanlist_len) { 572 if (cmd->scan_end_arg != cmd->chanlist_len) {
570 cmd->scan_end_arg = cmd->chanlist_len; 573 cmd->scan_end_arg = cmd->chanlist_len;
571 err++; 574 err++;
@@ -603,6 +606,14 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
603 return 4; 606 return 4;
604 } 607 }
605 608
609 /* step 5: complain about special chanlist considerations */
610
611 if (cmd->chanlist) {
612 if (!check_channel_list(dev, s, cmd->chanlist,
613 cmd->chanlist_len))
614 return 5; /* incorrect channels list */
615 }
616
606 return 0; 617 return 0;
607} 618}
608 619
@@ -610,6 +621,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
610{ 621{
611 unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq; 622 unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
612 struct comedi_cmd *cmd = &s->async->cmd; 623 struct comedi_cmd *cmd = &s->async->cmd;
624 unsigned int seglen;
613 625
614 if (cmd->start_src != TRIG_NOW) 626 if (cmd->start_src != TRIG_NOW)
615 return -EINVAL; 627 return -EINVAL;
@@ -642,11 +654,13 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
642 654
643 start_pacer(dev, -1, 0, 0); /* stop pacer */ 655 start_pacer(dev, -1, 0, 0); /* stop pacer */
644 656
645 if (!check_and_setup_channel_list(dev, s, cmd->chanlist, 657 seglen = check_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len);
646 cmd->chanlist_len)) 658 if (seglen < 1)
647 return -EINVAL; 659 return -EINVAL;
660 setup_channel_list(dev, s, cmd->chanlist, seglen);
648 udelay(1); 661 udelay(1);
649 662
663 devpriv->ai_n_chan = cmd->chanlist_len;
650 devpriv->ai_act_scan = 0; 664 devpriv->ai_act_scan = 0;
651 s->async->cur_chan = 0; 665 s->async->cur_chan = 0;
652 devpriv->irq_blocked = 1; 666 devpriv->irq_blocked = 1;
@@ -871,12 +885,12 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
871/* 885/*
872============================================================================== 886==============================================================================
873 Check if channel list from user is builded correctly 887 Check if channel list from user is builded correctly
874 If it's ok, then program scan/gain logic 888 If it's ok, then return non-zero length of repeated segment of channel list
875*/ 889*/
876static int 890static int
877check_and_setup_channel_list(struct comedi_device *dev, 891check_channel_list(struct comedi_device *dev,
878 struct comedi_subdevice *s, unsigned int *chanlist, 892 struct comedi_subdevice *s, unsigned int *chanlist,
879 int chanlen) 893 unsigned int chanlen)
880{ 894{
881 unsigned int chansegment[16]; 895 unsigned int chansegment[16];
882 unsigned int i, nowmustbechan, seglen, segpos; 896 unsigned int i, nowmustbechan, seglen, segpos;
@@ -930,6 +944,20 @@ check_and_setup_channel_list(struct comedi_device *dev,
930 seglen = 1; 944 seglen = 1;
931 } 945 }
932 946
947 return seglen; /* we can serve this with MUX logic */
948}
949
950/*
951==============================================================================
952 Program scan/gain logic with channel list.
953*/
954static void
955setup_channel_list(struct comedi_device *dev,
956 struct comedi_subdevice *s, unsigned int *chanlist,
957 unsigned int seglen)
958{
959 unsigned int i;
960
933 devpriv->ai_act_chanlist_len = seglen; 961 devpriv->ai_act_chanlist_len = seglen;
934 devpriv->ai_act_chanlist_pos = 0; 962 devpriv->ai_act_chanlist_pos = 0;
935 963
@@ -942,8 +970,6 @@ check_and_setup_channel_list(struct comedi_device *dev,
942 udelay(1); 970 udelay(1);
943 971
944 outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */ 972 outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */
945
946 return 1; /* we can serve this with MUX logic */
947} 973}
948 974
949#ifdef unused 975#ifdef unused
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index d0481013a837..c9d75385755d 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -557,8 +557,14 @@ conv_finish:
557 comedi_event(dev, s); 557 comedi_event(dev, s);
558 return IRQ_HANDLED; 558 return IRQ_HANDLED;
559 } 559 }
560 if (s->async->cur_chan == 0) { 560 devpriv->act_chanlist_pos++;
561 if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
562 devpriv->act_chanlist_pos = 0;
563 }
564 s->async->cur_chan++;
565 if (s->async->cur_chan >= devpriv->ai_n_chan) {
561 /* printk("E"); */ 566 /* printk("E"); */
567 s->async->cur_chan = 0;
562 devpriv->ai_act_scan--; 568 devpriv->ai_act_scan--;
563 } 569 }
564 570
@@ -627,9 +633,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
627 633
628 devpriv->act_chanlist_pos++; 634 devpriv->act_chanlist_pos++;
629 if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) { 635 if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
630 devpriv->ai_act_scan--;
631 devpriv->act_chanlist_pos = 0; 636 devpriv->act_chanlist_pos = 0;
632 } 637 }
638 s->async->cur_chan++;
639 if (s->async->cur_chan >= devpriv->ai_n_chan) {
640 s->async->cur_chan = 0;
641 devpriv->ai_act_scan--;
642 }
633 643
634 if (!devpriv->neverending_ai) 644 if (!devpriv->neverending_ai)
635 if (devpriv->ai_act_scan == 0) { /* all data sampled */ 645 if (devpriv->ai_act_scan == 0) { /* all data sampled */
@@ -717,7 +727,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
717 comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); /* get one sample */ 727 comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); /* get one sample */
718 bufptr &= (devpriv->dmasamplsize - 1); 728 bufptr &= (devpriv->dmasamplsize - 1);
719 729
720 if (s->async->cur_chan == 0) { 730 devpriv->act_chanlist_pos++;
731 if (devpriv->act_chanlist_pos >=
732 devpriv->act_chanlist_len) {
733 devpriv->act_chanlist_pos = 0;
734 }
735 s->async->cur_chan++;
736 if (s->async->cur_chan >= devpriv->ai_n_chan) {
737 s->async->cur_chan = 0;
721 devpriv->ai_act_scan--; 738 devpriv->ai_act_scan--;
722 } 739 }
723 740
@@ -796,7 +813,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
796 813
797 comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); /* get one sample */ 814 comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); /* get one sample */
798 815
799 if (s->async->cur_chan == 0) { 816 devpriv->act_chanlist_pos++;
817 if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
818 devpriv->act_chanlist_pos = 0;
819 }
820 s->async->cur_chan++;
821 if (s->async->cur_chan >= devpriv->ai_n_chan) {
822 s->async->cur_chan = 0;
800 devpriv->ai_act_scan--; 823 devpriv->ai_act_scan--;
801 } 824 }
802 825
@@ -1369,14 +1392,6 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
1369 } 1392 }
1370 } 1393 }
1371 1394
1372 if (!cmd->chanlist_len) {
1373 cmd->chanlist_len = 1;
1374 err++;
1375 }
1376 if (cmd->chanlist_len > s->n_chan) {
1377 cmd->chanlist_len = s->n_chan;
1378 err++;
1379 }
1380 if (cmd->scan_end_arg != cmd->chanlist_len) { 1395 if (cmd->scan_end_arg != cmd->chanlist_len) {
1381 cmd->scan_end_arg = cmd->chanlist_len; 1396 cmd->scan_end_arg = cmd->chanlist_len;
1382 err++; 1397 err++;
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
index 52811824b05a..ed6103079232 100644
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -121,25 +121,22 @@ static int compute_buffer(int config, int devno, struct comedi_subdevice *s)
121{ 121{
122 /* 1 in io_bits indicates output */ 122 /* 1 in io_bits indicates output */
123 if (s->io_bits & 0x0000ff) { 123 if (s->io_bits & 0x0000ff) {
124 if (devno == 0) { 124 if (devno == 0)
125 config |= BUF_A0; 125 config |= BUF_A0;
126 } else { 126 else
127 config |= BUF_A1; 127 config |= BUF_A1;
128 }
129 } 128 }
130 if (s->io_bits & 0x00ff00) { 129 if (s->io_bits & 0x00ff00) {
131 if (devno == 0) { 130 if (devno == 0)
132 config |= BUF_B0; 131 config |= BUF_B0;
133 } else { 132 else
134 config |= BUF_B1; 133 config |= BUF_B1;
135 }
136 } 134 }
137 if (s->io_bits & 0xff0000) { 135 if (s->io_bits & 0xff0000) {
138 if (devno == 0) { 136 if (devno == 0)
139 config |= BUF_C0; 137 config |= BUF_C0;
140 } else { 138 else
141 config |= BUF_C1; 139 config |= BUF_C1;
142 }
143 } 140 }
144 return config; 141 return config;
145} 142}
@@ -155,26 +152,27 @@ static void do_3724_config(struct comedi_device *dev,
155 buffer_config = 0; 152 buffer_config = 0;
156 153
157 /* 1 in io_bits indicates output, 1 in config indicates input */ 154 /* 1 in io_bits indicates output, 1 in config indicates input */
158 if (!(s->io_bits & 0x0000ff)) { 155 if (!(s->io_bits & 0x0000ff))
159 config |= CR_A_IO; 156 config |= CR_A_IO;
160 } 157
161 if (!(s->io_bits & 0x00ff00)) { 158 if (!(s->io_bits & 0x00ff00))
162 config |= CR_B_IO; 159 config |= CR_B_IO;
163 } 160
164 if (!(s->io_bits & 0xff0000)) { 161 if (!(s->io_bits & 0xff0000))
165 config |= CR_C_IO; 162 config |= CR_C_IO;
166 }
167 163
168 buffer_config = compute_buffer(0, 0, dev->subdevices); 164 buffer_config = compute_buffer(0, 0, dev->subdevices);
169 buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1); 165 buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1);
170 166
171 if (s == dev->subdevices) { 167 if (s == dev->subdevices)
172 port_8255_cfg = dev->iobase + _8255_CR; 168 port_8255_cfg = dev->iobase + _8255_CR;
173 } else { 169 else
174 port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR; 170 port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR;
175 } 171
176 outb(buffer_config, dev->iobase + 8); /* update buffer register */ 172 outb(buffer_config, dev->iobase + 8); /* update buffer register */
177 /* printk("pcm3724 buffer_config (%lx) %d, %x\n", dev->iobase + _8255_CR, chanspec, buffer_config); */ 173 /* printk("pcm3724 buffer_config (%lx) %d, %x\n",
174 dev->iobase + _8255_CR, chanspec, buffer_config); */
175
178 outb(config, port_8255_cfg); 176 outb(config, port_8255_cfg);
179} 177}
180 178
@@ -189,29 +187,29 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s,
189 priv = (struct priv_pcm3724 *)(dev->private); 187 priv = (struct priv_pcm3724 *)(dev->private);
190 188
191 mask = 1 << CR_CHAN(chanspec); 189 mask = 1 << CR_CHAN(chanspec);
192 if (s == dev->subdevices) { /* subdev 0 */ 190 if (s == dev->subdevices) /* subdev 0 */
193 priv->dio_1 |= mask; 191 priv->dio_1 |= mask;
194 } else { /* subdev 1 */ 192 else /* subdev 1 */
195 priv->dio_2 |= mask; 193 priv->dio_2 |= mask;
196 } 194
197 if (priv->dio_1 & 0xff0000) { 195 if (priv->dio_1 & 0xff0000)
198 gatecfg |= GATE_C0; 196 gatecfg |= GATE_C0;
199 } 197
200 if (priv->dio_1 & 0xff00) { 198 if (priv->dio_1 & 0xff00)
201 gatecfg |= GATE_B0; 199 gatecfg |= GATE_B0;
202 } 200
203 if (priv->dio_1 & 0xff) { 201 if (priv->dio_1 & 0xff)
204 gatecfg |= GATE_A0; 202 gatecfg |= GATE_A0;
205 } 203
206 if (priv->dio_2 & 0xff0000) { 204 if (priv->dio_2 & 0xff0000)
207 gatecfg |= GATE_C1; 205 gatecfg |= GATE_C1;
208 } 206
209 if (priv->dio_2 & 0xff00) { 207 if (priv->dio_2 & 0xff00)
210 gatecfg |= GATE_B1; 208 gatecfg |= GATE_B1;
211 } 209
212 if (priv->dio_2 & 0xff) { 210 if (priv->dio_2 & 0xff)
213 gatecfg |= GATE_A1; 211 gatecfg |= GATE_A1;
214 } 212
215 /* printk("gate control %x\n", gatecfg); */ 213 /* printk("gate control %x\n", gatecfg); */
216 outb(gatecfg, dev->iobase + 9); 214 outb(gatecfg, dev->iobase + 9);
217} 215}
@@ -225,15 +223,14 @@ static int subdev_3724_insn_config(struct comedi_device *dev,
225 unsigned int bits; 223 unsigned int bits;
226 224
227 mask = 1 << CR_CHAN(insn->chanspec); 225 mask = 1 << CR_CHAN(insn->chanspec);
228 if (mask & 0x0000ff) { 226 if (mask & 0x0000ff)
229 bits = 0x0000ff; 227 bits = 0x0000ff;
230 } else if (mask & 0x00ff00) { 228 else if (mask & 0x00ff00)
231 bits = 0x00ff00; 229 bits = 0x00ff00;
232 } else if (mask & 0x0f0000) { 230 else if (mask & 0x0f0000)
233 bits = 0x0f0000; 231 bits = 0x0f0000;
234 } else { 232 else
235 bits = 0xf00000; 233 bits = 0xf00000;
236 }
237 234
238 switch (data[0]) { 235 switch (data[0]) {
239 case INSN_CONFIG_DIO_INPUT: 236 case INSN_CONFIG_DIO_INPUT:
@@ -272,7 +269,7 @@ static int pcm3724_attach(struct comedi_device *dev,
272 ((struct priv_pcm3724 *)(dev->private))->dio_1 = 0; 269 ((struct priv_pcm3724 *)(dev->private))->dio_1 = 0;
273 ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0; 270 ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0;
274 271
275 printk("comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, 272 printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
276 this_board->name, iobase); 273 this_board->name, iobase);
277 if (!iobase || !request_region(iobase, iorange, "pcm3724")) { 274 if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
278 printk("I/O port conflict\n"); 275 printk("I/O port conflict\n");
@@ -281,7 +278,7 @@ static int pcm3724_attach(struct comedi_device *dev,
281 278
282 dev->iobase = iobase; 279 dev->iobase = iobase;
283 dev->board_name = this_board->name; 280 dev->board_name = this_board->name;
284 printk("\n"); 281 printk(KERN_INFO "\n");
285 282
286 n_subdevices = this_board->numofports; 283 n_subdevices = this_board->numofports;
287 284
@@ -302,13 +299,11 @@ static int pcm3724_detach(struct comedi_device *dev)
302 int i; 299 int i;
303 300
304 if (dev->subdevices) { 301 if (dev->subdevices) {
305 for (i = 0; i < dev->n_subdevices; i++) { 302 for (i = 0; i < dev->n_subdevices; i++)
306 subdev_8255_cleanup(dev, dev->subdevices + i); 303 subdev_8255_cleanup(dev, dev->subdevices + i);
307 }
308 } 304 }
309 if (dev->iobase) { 305 if (dev->iobase)
310 release_region(dev->iobase, this_board->io_range); 306 release_region(dev->iobase, this_board->io_range);
311 }
312 307
313 return 0; 308 return 0;
314} 309}
diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c
index 9e4adbd89dda..22b7aae63add 100644
--- a/drivers/staging/comedi/drivers/pcm3730.c
+++ b/drivers/staging/comedi/drivers/pcm3730.c
@@ -73,7 +73,7 @@ static int pcm3730_attach(struct comedi_device *dev,
73 unsigned long iobase; 73 unsigned long iobase;
74 74
75 iobase = it->options[0]; 75 iobase = it->options[0];
76 printk("comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase); 76 printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
77 if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) { 77 if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
78 printk("I/O port conflict\n"); 78 printk("I/O port conflict\n");
79 return -EIO; 79 return -EIO;
@@ -140,14 +140,14 @@ static int pcm3730_attach(struct comedi_device *dev,
140 s->range_table = &range_digital; 140 s->range_table = &range_digital;
141 s->private = (void *)PCM3730_DIC; 141 s->private = (void *)PCM3730_DIC;
142 142
143 printk("\n"); 143 printk(KERN_INFO "\n");
144 144
145 return 0; 145 return 0;
146} 146}
147 147
148static int pcm3730_detach(struct comedi_device *dev) 148static int pcm3730_detach(struct comedi_device *dev)
149{ 149{
150 printk("comedi%d: pcm3730: remove\n", dev->minor); 150 printk(KERN_INFO "comedi%d: pcm3730: remove\n", dev->minor);
151 151
152 if (dev->iobase) 152 if (dev->iobase)
153 release_region(dev->iobase, PCM3730_SIZE); 153 release_region(dev->iobase, PCM3730_SIZE);
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index acac67090810..fab8092bd7aa 100644
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -34,11 +34,11 @@ Configuration options:
34 [0] - I/O port base 34 [0] - I/O port base
35 [1] - unused 35 [1] - unused
36 [2] - Analog input reference 36 [2] - Analog input reference
37 0 = single ended 37 0 = single ended
38 1 = differential 38 1 = differential
39 [3] - Analog input encoding (must match jumpers) 39 [3] - Analog input encoding (must match jumpers)
40 0 = straight binary 40 0 = straight binary
41 1 = two's complement 41 1 = two's complement
42*/ 42*/
43 43
44#include <linux/interrupt.h> 44#include <linux/interrupt.h>
@@ -113,9 +113,8 @@ static int pcmad_ai_insn_read(struct comedi_device *dev,
113 data[n] = inb(dev->iobase + PCMAD_LSB); 113 data[n] = inb(dev->iobase + PCMAD_LSB);
114 data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8); 114 data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8);
115 115
116 if (devpriv->twos_comp) { 116 if (devpriv->twos_comp)
117 data[n] ^= (1 << (this_board->n_ai_bits - 1)); 117 data[n] ^= (1 << (this_board->n_ai_bits - 1));
118 }
119 } 118 }
120 119
121 return n; 120 return n;
@@ -135,11 +134,12 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
135 unsigned long iobase; 134 unsigned long iobase;
136 135
137 iobase = it->options[0]; 136 iobase = it->options[0];
138 printk("comedi%d: pcmad: 0x%04lx ", dev->minor, iobase); 137 printk(KERN_INFO "comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
139 if (!request_region(iobase, PCMAD_SIZE, "pcmad")) { 138 if (!request_region(iobase, PCMAD_SIZE, "pcmad")) {
140 printk("I/O port conflict\n"); 139 printk(KERN_CONT "I/O port conflict\n");
141 return -EIO; 140 return -EIO;
142 } 141 }
142 printk(KERN_CONT "\n");
143 dev->iobase = iobase; 143 dev->iobase = iobase;
144 144
145 ret = alloc_subdevices(dev, 1); 145 ret = alloc_subdevices(dev, 1);
@@ -166,11 +166,11 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
166 166
167static int pcmad_detach(struct comedi_device *dev) 167static int pcmad_detach(struct comedi_device *dev)
168{ 168{
169 printk("comedi%d: pcmad: remove\n", dev->minor); 169 printk(KERN_INFO "comedi%d: pcmad: remove\n", dev->minor);
170 170
171 if (dev->irq) { 171 if (dev->irq)
172 free_irq(dev->irq, dev); 172 free_irq(dev->irq, dev);
173 } 173
174 if (dev->iobase) 174 if (dev->iobase)
175 release_region(dev->iobase, PCMAD_SIZE); 175 release_region(dev->iobase, PCMAD_SIZE);
176 176
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index 35ba93989a36..6ca4105610c1 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -550,7 +550,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
550 550
551 if (irq[0]) { 551 if (irq[0]) {
552 printk("irq: %u ", irq[0]); 552 printk("irq: %u ", irq[0]);
553 if (irq[1] && thisboard->dio_num_asics == 2) 553 if (thisboard->dio_num_asics == 2 && irq[1])
554 printk("second ASIC irq: %u ", irq[1]); 554 printk("second ASIC irq: %u ", irq[1]);
555 } else { 555 } else {
556 printk("(IRQ mode disabled) "); 556 printk("(IRQ mode disabled) ");
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
index d23e588d0632..1ebc356ce40e 100644
--- a/drivers/staging/comedi/drivers/poc.c
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -122,22 +122,21 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
122 unsigned int iosize; 122 unsigned int iosize;
123 123
124 iobase = it->options[0]; 124 iobase = it->options[0];
125 printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, 125 printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
126 this_board->name, iobase); 126 this_board->name, iobase);
127 127
128 dev->board_name = this_board->name; 128 dev->board_name = this_board->name;
129 129
130 if (iobase == 0) { 130 if (iobase == 0) {
131 printk("io base address required\n"); 131 printk(KERN_ERR "io base address required\n");
132 return -EINVAL; 132 return -EINVAL;
133 } 133 }
134 134
135 iosize = this_board->iosize; 135 iosize = this_board->iosize;
136 /* check if io addresses are available */ 136 /* check if io addresses are available */
137 if (!request_region(iobase, iosize, "dac02")) { 137 if (!request_region(iobase, iosize, "dac02")) {
138 printk 138 printk(KERN_ERR "I/O port conflict: failed to allocate ports "
139 ("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", 139 "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1);
140 iobase, iobase + iosize - 1);
141 return -EIO; 140 return -EIO;
142 } 141 }
143 dev->iobase = iobase; 142 dev->iobase = iobase;
@@ -156,9 +155,8 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
156 s->insn_write = this_board->winsn; 155 s->insn_write = this_board->winsn;
157 s->insn_read = this_board->rinsn; 156 s->insn_read = this_board->rinsn;
158 s->insn_bits = this_board->insnbits; 157 s->insn_bits = this_board->insnbits;
159 if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) { 158 if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO)
160 s->subdev_flags = SDF_WRITABLE; 159 s->subdev_flags = SDF_WRITABLE;
161 }
162 160
163 return 0; 161 return 0;
164} 162}
@@ -169,7 +167,7 @@ static int poc_detach(struct comedi_device *dev)
169 if (dev->iobase) 167 if (dev->iobase)
170 release_region(dev->iobase, this_board->iosize); 168 release_region(dev->iobase, this_board->iosize);
171 169
172 printk("comedi%d: dac02: remove\n", dev->minor); 170 printk(KERN_INFO "comedi%d: dac02: remove\n", dev->minor);
173 171
174 return 0; 172 return 0;
175} 173}
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index 2c9d05bd288c..028ed6f89c4c 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -32,22 +32,22 @@ Configuration options:
32 [0] - I/O port base address 32 [0] - I/O port base address
33 [1] - IRQ 33 [1] - IRQ
34 [2] - A/D reference 34 [2] - A/D reference
35 0 = differential 35 0 = differential
36 1 = pseudodifferential (common) 36 1 = pseudodifferential (common)
37 2 = single-ended 37 2 = single-ended
38 [3] - A/D range 38 [3] - A/D range
39 0 = [-10,10] 39 0 = [-10,10]
40 1 = [-5,5] 40 1 = [-5,5]
41 2 = [0,10] 41 2 = [0,10]
42 [4] - A/D encoding 42 [4] - A/D encoding
43 0 = two's complement 43 0 = two's complement
44 1 = straight binary 44 1 = straight binary
45 [5] - DAC 0 range 45 [5] - DAC 0 range
46 0 = [-10,10] 46 0 = [-10,10]
47 1 = [0,10] 47 1 = [0,10]
48 [6] - DAC 0 encoding 48 [6] - DAC 0 encoding
49 0 = two's complement 49 0 = two's complement
50 1 = straight binary 50 1 = straight binary
51 [7] - DAC 1 range (same as DAC 0) 51 [7] - DAC 1 range (same as DAC 0)
52 [8] - DAC 1 encoding (same as DAC 0) 52 [8] - DAC 1 encoding (same as DAC 0)
53*/ 53*/
@@ -225,7 +225,7 @@ static int rti800_ai_insn_read(struct comedi_device *dev,
225 for (t = RTI800_TIMEOUT; t; t--) { 225 for (t = RTI800_TIMEOUT; t; t--) {
226 status = inb(dev->iobase + RTI800_CSR); 226 status = inb(dev->iobase + RTI800_CSR);
227 if (status & RTI800_OVERRUN) { 227 if (status & RTI800_OVERRUN) {
228 printk("rti800: a/d overrun\n"); 228 printk(KERN_WARNING "rti800: a/d overrun\n");
229 outb(0, dev->iobase + RTI800_CLRFLAGS); 229 outb(0, dev->iobase + RTI800_CLRFLAGS);
230 return -EIO; 230 return -EIO;
231 } 231 }
@@ -234,15 +234,14 @@ static int rti800_ai_insn_read(struct comedi_device *dev,
234 udelay(1); 234 udelay(1);
235 } 235 }
236 if (t == 0) { 236 if (t == 0) {
237 printk("rti800: timeout\n"); 237 printk(KERN_WARNING "rti800: timeout\n");
238 return -ETIME; 238 return -ETIME;
239 } 239 }
240 data[i] = inb(dev->iobase + RTI800_ADCLO); 240 data[i] = inb(dev->iobase + RTI800_ADCLO);
241 data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8; 241 data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8;
242 242
243 if (devpriv->adc_coding == adc_2comp) { 243 if (devpriv->adc_coding == adc_2comp)
244 data[i] ^= 0x800; 244 data[i] ^= 0x800;
245 }
246 } 245 }
247 246
248 return i; 247 return i;
@@ -271,9 +270,9 @@ static int rti800_ao_insn_write(struct comedi_device *dev,
271 270
272 for (i = 0; i < insn->n; i++) { 271 for (i = 0; i < insn->n; i++) {
273 devpriv->ao_readback[chan] = d = data[i]; 272 devpriv->ao_readback[chan] = d = data[i];
274 if (devpriv->dac0_coding == dac_2comp) { 273 if (devpriv->dac0_coding == dac_2comp)
275 d ^= 0x800; 274 d ^= 0x800;
276 } 275
277 outb(d & 0xff, 276 outb(d & 0xff,
278 dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO)); 277 dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
279 outb(d >> 8, 278 outb(d >> 8,
@@ -315,15 +314,15 @@ static int rti800_do_insn_bits(struct comedi_device *dev,
315 options[0] - I/O port 314 options[0] - I/O port
316 options[1] - irq 315 options[1] - irq
317 options[2] - a/d mux 316 options[2] - a/d mux
318 0=differential, 1=pseudodiff, 2=single 317 0=differential, 1=pseudodiff, 2=single
319 options[3] - a/d range 318 options[3] - a/d range
320 0=bipolar10, 1=bipolar5, 2=unipolar10 319 0=bipolar10, 1=bipolar5, 2=unipolar10
321 options[4] - a/d coding 320 options[4] - a/d coding
322 0=2's comp, 1=straight binary 321 0=2's comp, 1=straight binary
323 options[5] - dac0 range 322 options[5] - dac0 range
324 0=bipolar10, 1=unipolar10 323 0=bipolar10, 1=unipolar10
325 options[6] - dac0 coding 324 options[6] - dac0 coding
326 0=2's comp, 1=straight binary 325 0=2's comp, 1=straight binary
327 options[7] - dac1 range 326 options[7] - dac1 range
328 options[8] - dac1 coding 327 options[8] - dac1 coding
329 */ 328 */
@@ -336,15 +335,15 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
336 struct comedi_subdevice *s; 335 struct comedi_subdevice *s;
337 336
338 iobase = it->options[0]; 337 iobase = it->options[0];
339 printk("comedi%d: rti800: 0x%04lx ", dev->minor, iobase); 338 printk(KERN_INFO "comedi%d: rti800: 0x%04lx\n", dev->minor, iobase);
340 if (!request_region(iobase, RTI800_SIZE, "rti800")) { 339 if (!request_region(iobase, RTI800_SIZE, "rti800")) {
341 printk("I/O port conflict\n"); 340 printk(KERN_WARNING "I/O port conflict\n");
342 return -EIO; 341 return -EIO;
343 } 342 }
344 dev->iobase = iobase; 343 dev->iobase = iobase;
345 344
346#ifdef DEBUG 345#ifdef DEBUG
347 printk("fingerprint=%x,%x,%x,%x,%x ", 346 printk(KERN_DEBUG "fingerprint=%x,%x,%x,%x,%x ",
348 inb(dev->iobase + 0), 347 inb(dev->iobase + 0),
349 inb(dev->iobase + 1), 348 inb(dev->iobase + 1),
350 inb(dev->iobase + 2), 349 inb(dev->iobase + 2),
@@ -357,15 +356,15 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
357 356
358 irq = it->options[1]; 357 irq = it->options[1];
359 if (irq) { 358 if (irq) {
360 printk("( irq = %u )", irq); 359 printk(KERN_INFO "( irq = %u )\n", irq);
361 ret = request_irq(irq, rti800_interrupt, 0, "rti800", dev); 360 ret = request_irq(irq, rti800_interrupt, 0, "rti800", dev);
362 if (ret < 0) { 361 if (ret < 0) {
363 printk(" Failed to allocate IRQ\n"); 362 printk(KERN_WARNING " Failed to allocate IRQ\n");
364 return ret; 363 return ret;
365 } 364 }
366 dev->irq = irq; 365 dev->irq = irq;
367 } else { 366 } else {
368 printk("( no irq )"); 367 printk(KERN_INFO "( no irq )\n");
369 } 368 }
370 369
371 dev->board_name = this_board->name; 370 dev->board_name = this_board->name;
@@ -461,14 +460,12 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
461 s->type = COMEDI_SUBD_TIMER; 460 s->type = COMEDI_SUBD_TIMER;
462#endif 461#endif
463 462
464 printk("\n");
465
466 return 0; 463 return 0;
467} 464}
468 465
469static int rti800_detach(struct comedi_device *dev) 466static int rti800_detach(struct comedi_device *dev)
470{ 467{
471 printk("comedi%d: rti800: remove\n", dev->minor); 468 printk(KERN_INFO "comedi%d: rti800: remove\n", dev->minor);
472 469
473 if (dev->iobase) 470 if (dev->iobase)
474 release_region(dev->iobase, RTI800_SIZE); 471 release_region(dev->iobase, RTI800_SIZE);
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
index 2f75c737ea15..2157edcf7997 100644
--- a/drivers/staging/comedi/drivers/rti802.c
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -106,9 +106,9 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
106 unsigned long iobase; 106 unsigned long iobase;
107 107
108 iobase = it->options[0]; 108 iobase = it->options[0];
109 printk("comedi%d: rti802: 0x%04lx ", dev->minor, iobase); 109 printk(KERN_INFO "comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
110 if (!request_region(iobase, RTI802_SIZE, "rti802")) { 110 if (!request_region(iobase, RTI802_SIZE, "rti802")) {
111 printk("I/O port conflict\n"); 111 printk(KERN_WARNING "I/O port conflict\n");
112 return -EIO; 112 return -EIO;
113 } 113 }
114 dev->iobase = iobase; 114 dev->iobase = iobase;
@@ -138,14 +138,12 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
138 ? &range_unipolar10 : &range_bipolar10; 138 ? &range_unipolar10 : &range_bipolar10;
139 } 139 }
140 140
141 printk("\n");
142
143 return 0; 141 return 0;
144} 142}
145 143
146static int rti802_detach(struct comedi_device *dev) 144static int rti802_detach(struct comedi_device *dev)
147{ 145{
148 printk("comedi%d: rti802: remove\n", dev->minor); 146 printk(KERN_INFO "comedi%d: rti802: remove\n", dev->minor);
149 147
150 if (dev->iobase) 148 if (dev->iobase)
151 release_region(dev->iobase, RTI802_SIZE); 149 release_region(dev->iobase, RTI802_SIZE);
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index fdd7ab954d8c..a3cc93362ec2 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -140,7 +140,7 @@ struct s626_private {
140 short allocatedBuf; 140 short allocatedBuf;
141 uint8_t ai_cmd_running; /* ai_cmd is running */ 141 uint8_t ai_cmd_running; /* ai_cmd is running */
142 uint8_t ai_continous; /* continous aquisition */ 142 uint8_t ai_continous; /* continous aquisition */
143 int ai_sample_count; /* number of samples to aquire */ 143 int ai_sample_count; /* number of samples to acquire */
144 unsigned int ai_sample_timer; 144 unsigned int ai_sample_timer;
145 /* time between samples in units of the timer */ 145 /* time between samples in units of the timer */
146 int ai_convert_count; /* conversion counter */ 146 int ai_convert_count; /* conversion counter */
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index db37dcdd98b6..dd2b90372794 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -397,7 +397,7 @@ static void serial_2002_open(struct comedi_device *dev)
397 char port[20]; 397 char port[20];
398 398
399 sprintf(port, "/dev/ttyS%d", devpriv->port); 399 sprintf(port, "/dev/ttyS%d", devpriv->port);
400 devpriv->tty = filp_open(port, 0, O_RDWR); 400 devpriv->tty = filp_open(port, O_RDWR, 0);
401 if (IS_ERR(devpriv->tty)) { 401 if (IS_ERR(devpriv->tty)) {
402 printk("serial_2002: file open error = %ld\n", 402 printk("serial_2002: file open error = %ld\n",
403 PTR_ERR(devpriv->tty)); 403 PTR_ERR(devpriv->tty));
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
index 4918fbfab5e8..17c92a57b0dd 100644
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -300,11 +300,11 @@ static int dnp_dio_insn_config(struct comedi_device *dev,
300 300
301 /* read 'old' direction of the port and set bits (out=1, in=0) */ 301 /* read 'old' direction of the port and set bits (out=1, in=0) */
302 register_buffer = inb(CSCDR); 302 register_buffer = inb(CSCDR);
303 if (data[0] == COMEDI_OUTPUT) { 303 if (data[0] == COMEDI_OUTPUT)
304 register_buffer |= (1 << chan); 304 register_buffer |= (1 << chan);
305 } else { 305 else
306 register_buffer &= ~(1 << chan); 306 register_buffer &= ~(1 << chan);
307 } 307
308 outb(register_buffer, CSCDR); 308 outb(register_buffer, CSCDR);
309 309
310 return 1; 310 return 1;
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 9a1b559c4b0d..8942ae45708d 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -95,7 +95,6 @@ sampling rate. If you sample two channels you get 4kHz and so on.
95#include <linux/slab.h> 95#include <linux/slab.h>
96#include <linux/input.h> 96#include <linux/input.h>
97#include <linux/usb.h> 97#include <linux/usb.h>
98#include <linux/smp_lock.h>
99#include <linux/fcntl.h> 98#include <linux/fcntl.h>
100#include <linux/compiler.h> 99#include <linux/compiler.h>
101#include <linux/firmware.h> 100#include <linux/firmware.h>
@@ -289,7 +288,7 @@ struct usbduxsub {
289 /* continous aquisition */ 288 /* continous aquisition */
290 short int ai_continous; 289 short int ai_continous;
291 short int ao_continous; 290 short int ao_continous;
292 /* number of samples to aquire */ 291 /* number of samples to acquire */
293 int ai_sample_count; 292 int ai_sample_count;
294 int ao_sample_count; 293 int ao_sample_count;
295 /* time between samples in units of the timer */ 294 /* time between samples in units of the timer */
@@ -2833,7 +2832,7 @@ static struct comedi_driver driver_usbdux = {
2833}; 2832};
2834 2833
2835/* Table with the USB-devices: just now only testing IDs */ 2834/* Table with the USB-devices: just now only testing IDs */
2836static struct usb_device_id usbduxsub_table[] = { 2835static const struct usb_device_id usbduxsub_table[] = {
2837 {USB_DEVICE(0x13d8, 0x0001)}, 2836 {USB_DEVICE(0x13d8, 0x0001)},
2838 {USB_DEVICE(0x13d8, 0x0002)}, 2837 {USB_DEVICE(0x13d8, 0x0002)},
2839 {} /* Terminating entry */ 2838 {} /* Terminating entry */
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 2e675cce7dbf..e89b81812538 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -44,7 +44,6 @@
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/input.h> 45#include <linux/input.h>
46#include <linux/usb.h> 46#include <linux/usb.h>
47#include <linux/smp_lock.h>
48#include <linux/fcntl.h> 47#include <linux/fcntl.h>
49#include <linux/compiler.h> 48#include <linux/compiler.h>
50#include "comedi_fc.h" 49#include "comedi_fc.h"
@@ -182,7 +181,7 @@ struct usbduxfastsub_s {
182 context */ 181 context */
183 short int ai_cmd_running; /* asynchronous command is running */ 182 short int ai_cmd_running; /* asynchronous command is running */
184 short int ai_continous; /* continous aquisition */ 183 short int ai_continous; /* continous aquisition */
185 long int ai_sample_count; /* number of samples to aquire */ 184 long int ai_sample_count; /* number of samples to acquire */
186 uint8_t *dux_commands; /* commands */ 185 uint8_t *dux_commands; /* commands */
187 int ignore; /* counter which ignores the first 186 int ignore; /* counter which ignores the first
188 buffers */ 187 buffers */
@@ -1769,7 +1768,7 @@ static struct comedi_driver driver_usbduxfast = {
1769/* 1768/*
1770 * Table with the USB-devices: just now only testing IDs 1769 * Table with the USB-devices: just now only testing IDs
1771 */ 1770 */
1772static struct usb_device_id usbduxfastsub_table[] = { 1771static const struct usb_device_id usbduxfastsub_table[] = {
1773 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */ 1772 /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
1774 {USB_DEVICE(0x13d8, 0x0010)}, /* real ID */ 1773 {USB_DEVICE(0x13d8, 0x0010)}, /* real ID */
1775 {USB_DEVICE(0x13d8, 0x0011)}, /* real ID */ 1774 {USB_DEVICE(0x13d8, 0x0011)}, /* real ID */
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index c34a0b9141e2..6479c38d0278 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -75,7 +75,7 @@ enum {
75 DEVICE_VMK8061 75 DEVICE_VMK8061
76}; 76};
77 77
78static struct usb_device_id vmk80xx_id_table[] = { 78static const struct usb_device_id vmk80xx_id_table[] = {
79 {USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055}, 79 {USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055},
80 {USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055}, 80 {USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055},
81 {USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055}, 81 {USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055},
diff --git a/drivers/staging/crystalhd/Kconfig b/drivers/staging/crystalhd/Kconfig
new file mode 100644
index 000000000000..56b414bca1a1
--- /dev/null
+++ b/drivers/staging/crystalhd/Kconfig
@@ -0,0 +1,6 @@
1config CRYSTALHD
2 tristate "Broadcom Crystal HD video decoder support"
3 depends on PCI
4 default n
5 help
6 Support for the Broadcom Crystal HD video decoder chipset
diff --git a/drivers/staging/crystalhd/Makefile b/drivers/staging/crystalhd/Makefile
new file mode 100644
index 000000000000..e2af0ce2e792
--- /dev/null
+++ b/drivers/staging/crystalhd/Makefile
@@ -0,0 +1,6 @@
1obj-$(CONFIG_CRYSTALHD) += crystalhd.o
2
3crystalhd-objs := crystalhd_cmds.o \
4 crystalhd_hw.o \
5 crystalhd_lnx.o \
6 crystalhd_misc.o
diff --git a/drivers/staging/crystalhd/TODO b/drivers/staging/crystalhd/TODO
new file mode 100644
index 000000000000..69be5d0cb80c
--- /dev/null
+++ b/drivers/staging/crystalhd/TODO
@@ -0,0 +1,16 @@
1- Testing
2- Cleanup return codes
3- Cleanup typedefs
4- Cleanup all WIN* references
5- Allocate an Accelerator device class specific Major number,
6 since we don't have any other open sourced accelerators, it is the only
7 one in that category for now.
8 A somewhat similar device is the DXR2/3
9
10Please send patches to:
11Greg Kroah-Hartman <greg@kroah.com>
12Naren Sankar <nsankar@broadcom.com>
13Jarod Wilson <jarod@wilsonet.com>
14Scott Davilla <davilla@4pi.com>
15Manu Abraham <abraham.manu@gmail.com>
16
diff --git a/drivers/staging/crystalhd/bc_dts_defs.h b/drivers/staging/crystalhd/bc_dts_defs.h
new file mode 100644
index 000000000000..c34cc07127b8
--- /dev/null
+++ b/drivers/staging/crystalhd/bc_dts_defs.h
@@ -0,0 +1,498 @@
1/********************************************************************
2 * Copyright(c) 2006-2009 Broadcom Corporation.
3 *
4 * Name: bc_dts_defs.h
5 *
6 * Description: Common definitions for all components. Only types
7 * is allowed to be included from this file.
8 *
9 * AU
10 *
11 * HISTORY:
12 *
13 ********************************************************************
14 * This header is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as published
16 * by the Free Software Foundation, either version 2.1 of the License.
17 *
18 * This header is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this header. If not, see <http://www.gnu.org/licenses/>.
24 *******************************************************************/
25
26#ifndef _BC_DTS_DEFS_H_
27#define _BC_DTS_DEFS_H_
28
29#include "bc_dts_types.h"
30
31/* BIT Mask */
32#define BC_BIT(_x) (1 << (_x))
33
34typedef enum _BC_STATUS {
35 BC_STS_SUCCESS = 0,
36 BC_STS_INV_ARG = 1,
37 BC_STS_BUSY = 2,
38 BC_STS_NOT_IMPL = 3,
39 BC_STS_PGM_QUIT = 4,
40 BC_STS_NO_ACCESS = 5,
41 BC_STS_INSUFF_RES = 6,
42 BC_STS_IO_ERROR = 7,
43 BC_STS_NO_DATA = 8,
44 BC_STS_VER_MISMATCH = 9,
45 BC_STS_TIMEOUT = 10,
46 BC_STS_FW_CMD_ERR = 11,
47 BC_STS_DEC_NOT_OPEN = 12,
48 BC_STS_ERR_USAGE = 13,
49 BC_STS_IO_USER_ABORT = 14,
50 BC_STS_IO_XFR_ERROR = 15,
51 BC_STS_DEC_NOT_STARTED = 16,
52 BC_STS_FWHEX_NOT_FOUND = 17,
53 BC_STS_FMT_CHANGE = 18,
54 BC_STS_HIF_ACCESS = 19,
55 BC_STS_CMD_CANCELLED = 20,
56 BC_STS_FW_AUTH_FAILED = 21,
57 BC_STS_BOOTLOADER_FAILED = 22,
58 BC_STS_CERT_VERIFY_ERROR = 23,
59 BC_STS_DEC_EXIST_OPEN = 24,
60 BC_STS_PENDING = 25,
61 BC_STS_CLK_NOCHG = 26,
62
63 /* Must be the last one.*/
64 BC_STS_ERROR = -1
65} BC_STATUS;
66
67/*------------------------------------------------------*
68 * Registry Key Definitions *
69 *------------------------------------------------------*/
70#define BC_REG_KEY_MAIN_PATH "Software\\Broadcom\\MediaPC\\70010"
71#define BC_REG_KEY_FWPATH "FirmwareFilePath"
72#define BC_REG_KEY_SEC_OPT "DbgOptions"
73
74/*
75 * Options:
76 *
77 * b[5] = Enable RSA KEY in EEPROM Support
78 * b[6] = Enable Old PIB scheme. (0 = Use PIB with video scheme)
79 *
80 * b[12] = Enable send message to NotifyIcon
81 *
82 */
83
84typedef enum _BC_SW_OPTIONS {
85 BC_OPT_DOSER_OUT_ENCRYPT = BC_BIT(3),
86 BC_OPT_LINK_OUT_ENCRYPT = BC_BIT(29),
87} BC_SW_OPTIONS;
88
89typedef struct _BC_REG_CONFIG{
90 uint32_t DbgOptions;
91} BC_REG_CONFIG;
92
93#if defined(__KERNEL__) || defined(__LINUX_USER__)
94#else
95/* Align data structures */
96#define ALIGN(x) __declspec(align(x))
97#endif
98
99/* mode
100 * b[0]..b[7] = _DtsDeviceOpenMode
101 * b[8] = Load new FW
102 * b[9] = Load file play back FW
103 * b[10] = Disk format (0 for HD DVD and 1 for BLU ray)
104 * b[11]-b[15] = default output resolution
105 * b[16] = Skip TX CPB Buffer Check
106 * b[17] = Adaptive Output Encrypt/Scramble Scheme
107 * b[18]-b[31] = reserved for future use
108 */
109
110/* To allow multiple apps to open the device. */
111enum _DtsDeviceOpenMode {
112 DTS_PLAYBACK_MODE = 0,
113 DTS_DIAG_MODE,
114 DTS_MONITOR_MODE,
115 DTS_HWINIT_MODE
116};
117
118/* To enable the filter to selectively enable/disable fixes or erratas */
119enum _DtsDeviceFixMode {
120 DTS_LOAD_NEW_FW = BC_BIT(8),
121 DTS_LOAD_FILE_PLAY_FW = BC_BIT(9),
122 DTS_DISK_FMT_BD = BC_BIT(10),
123 /* b[11]-b[15] : Default output resolution */
124 DTS_SKIP_TX_CHK_CPB = BC_BIT(16),
125 DTS_ADAPTIVE_OUTPUT_PER = BC_BIT(17),
126 DTS_INTELLIMAP = BC_BIT(18),
127 /* b[19]-b[21] : select clock frequency */
128 DTS_PLAYBACK_DROP_RPT_MODE = BC_BIT(22)
129};
130
131#define DTS_DFLT_RESOLUTION(x) (x<<11)
132
133#define DTS_DFLT_CLOCK(x) (x<<19)
134
135/* F/W File Version corresponding to S/W Releases */
136enum _FW_FILE_VER {
137 /* S/W release: 02.04.02 F/W release 2.12.2.0 */
138 BC_FW_VER_020402 = ((12<<16) | (2<<8) | (0))
139};
140
141/*------------------------------------------------------*
142 * Stream Types for DtsOpenDecoder() *
143 *------------------------------------------------------*/
144enum _DtsOpenDecStreamTypes {
145 BC_STREAM_TYPE_ES = 0,
146 BC_STREAM_TYPE_PES = 1,
147 BC_STREAM_TYPE_TS = 2,
148 BC_STREAM_TYPE_ES_TSTAMP = 6,
149};
150
151/*------------------------------------------------------*
152 * Video Algorithms for DtsSetVideoParams() *
153 *------------------------------------------------------*/
154enum _DtsSetVideoParamsAlgo {
155 BC_VID_ALGO_H264 = 0,
156 BC_VID_ALGO_MPEG2 = 1,
157 BC_VID_ALGO_VC1 = 4,
158 BC_VID_ALGO_VC1MP = 7,
159};
160
161/*------------------------------------------------------*
162 * MPEG Extension to the PPB *
163 *------------------------------------------------------*/
164#define BC_MPEG_VALID_PANSCAN (1)
165
166typedef struct _BC_PIB_EXT_MPEG {
167 uint32_t valid;
168 /* Always valid, defaults to picture size if no
169 * sequence display extension in the stream. */
170 uint32_t display_horizontal_size;
171 uint32_t display_vertical_size;
172
173 /* MPEG_VALID_PANSCAN
174 * Offsets are a copy values from the MPEG stream. */
175 uint32_t offset_count;
176 int32_t horizontal_offset[3];
177 int32_t vertical_offset[3];
178
179} BC_PIB_EXT_MPEG;
180
181/*------------------------------------------------------*
182 * H.264 Extension to the PPB *
183 *------------------------------------------------------*/
184/* Bit definitions for 'other.h264.valid' field */
185#define H264_VALID_PANSCAN (1)
186#define H264_VALID_SPS_CROP (2)
187#define H264_VALID_VUI (4)
188
189typedef struct _BC_PIB_EXT_H264 {
190 /* 'valid' specifies which fields (or sets of
191 * fields) below are valid. If the corresponding
192 * bit in 'valid' is NOT set then that field(s)
193 * is (are) not initialized. */
194 uint32_t valid;
195
196 /* H264_VALID_PANSCAN */
197 uint32_t pan_scan_count;
198 int32_t pan_scan_left[3];
199 int32_t pan_scan_right[3];
200 int32_t pan_scan_top[3];
201 int32_t pan_scan_bottom[3];
202
203 /* H264_VALID_SPS_CROP */
204 int32_t sps_crop_left;
205 int32_t sps_crop_right;
206 int32_t sps_crop_top;
207 int32_t sps_crop_bottom;
208
209 /* H264_VALID_VUI */
210 uint32_t chroma_top;
211 uint32_t chroma_bottom;
212
213} BC_PIB_EXT_H264;
214
215/*------------------------------------------------------*
216 * VC1 Extension to the PPB *
217 *------------------------------------------------------*/
218#define VC1_VALID_PANSCAN (1)
219
220typedef struct _BC_PIB_EXT_VC1 {
221 uint32_t valid;
222
223 /* Always valid, defaults to picture size if no
224 * sequence display extension in the stream. */
225 uint32_t display_horizontal_size;
226 uint32_t display_vertical_size;
227
228 /* VC1 pan scan windows */
229 uint32_t num_panscan_windows;
230 int32_t ps_horiz_offset[4];
231 int32_t ps_vert_offset[4];
232 int32_t ps_width[4];
233 int32_t ps_height[4];
234
235} BC_PIB_EXT_VC1;
236
237
238/*------------------------------------------------------*
239 * Picture Information Block *
240 *------------------------------------------------------*/
241#if defined(_WIN32) || defined(_WIN64) || defined(__LINUX_USER__)
242/* Values for 'pulldown' field. '0' means no pulldown information
243 * was present for this picture. */
244enum {
245 vdecNoPulldownInfo = 0,
246 vdecTop = 1,
247 vdecBottom = 2,
248 vdecTopBottom = 3,
249 vdecBottomTop = 4,
250 vdecTopBottomTop = 5,
251 vdecBottomTopBottom = 6,
252 vdecFrame_X2 = 7,
253 vdecFrame_X3 = 8,
254 vdecFrame_X1 = 9,
255 vdecFrame_X4 = 10,
256};
257
258/* Values for the 'frame_rate' field. */
259enum {
260 vdecFrameRateUnknown = 0,
261 vdecFrameRate23_97,
262 vdecFrameRate24,
263 vdecFrameRate25,
264 vdecFrameRate29_97,
265 vdecFrameRate30,
266 vdecFrameRate50,
267 vdecFrameRate59_94,
268 vdecFrameRate60,
269};
270
271/* Values for the 'aspect_ratio' field. */
272enum {
273 vdecAspectRatioUnknown = 0,
274 vdecAspectRatioSquare,
275 vdecAspectRatio12_11,
276 vdecAspectRatio10_11,
277 vdecAspectRatio16_11,
278 vdecAspectRatio40_33,
279 vdecAspectRatio24_11,
280 vdecAspectRatio20_11,
281 vdecAspectRatio32_11,
282 vdecAspectRatio80_33,
283 vdecAspectRatio18_11,
284 vdecAspectRatio15_11,
285 vdecAspectRatio64_33,
286 vdecAspectRatio160_99,
287 vdecAspectRatio4_3,
288 vdecAspectRatio16_9,
289 vdecAspectRatio221_1,
290 vdecAspectRatioOther = 255,
291};
292
293/* Values for the 'colour_primaries' field. */
294enum {
295 vdecColourPrimariesUnknown = 0,
296 vdecColourPrimariesBT709,
297 vdecColourPrimariesUnspecified,
298 vdecColourPrimariesReserved,
299 vdecColourPrimariesBT470_2M = 4,
300 vdecColourPrimariesBT470_2BG,
301 vdecColourPrimariesSMPTE170M,
302 vdecColourPrimariesSMPTE240M,
303 vdecColourPrimariesGenericFilm,
304};
305
306enum {
307 vdecRESOLUTION_CUSTOM = 0x00000000, /* custom */
308 vdecRESOLUTION_480i = 0x00000001, /* 480i */
309 vdecRESOLUTION_1080i = 0x00000002, /* 1080i (1920x1080, 60i) */
310 vdecRESOLUTION_NTSC = 0x00000003, /* NTSC (720x483, 60i) */
311 vdecRESOLUTION_480p = 0x00000004, /* 480p (720x480, 60p) */
312 vdecRESOLUTION_720p = 0x00000005, /* 720p (1280x720, 60p) */
313 vdecRESOLUTION_PAL1 = 0x00000006, /* PAL_1 (720x576, 50i) */
314 vdecRESOLUTION_1080i25 = 0x00000007, /* 1080i25 (1920x1080, 50i) */
315 vdecRESOLUTION_720p50 = 0x00000008, /* 720p50 (1280x720, 50p) */
316 vdecRESOLUTION_576p = 0x00000009, /* 576p (720x576, 50p) */
317 vdecRESOLUTION_1080i29_97 = 0x0000000A, /* 1080i (1920x1080, 59.94i) */
318 vdecRESOLUTION_720p59_94 = 0x0000000B, /* 720p (1280x720, 59.94p) */
319 vdecRESOLUTION_SD_DVD = 0x0000000C, /* SD DVD (720x483, 60i) */
320 vdecRESOLUTION_480p656 = 0x0000000D, /* 480p (720x480, 60p), output bus width 8 bit, clock 74.25MHz */
321 vdecRESOLUTION_1080p23_976 = 0x0000000E, /* 1080p23_976 (1920x1080, 23.976p) */
322 vdecRESOLUTION_720p23_976 = 0x0000000F, /* 720p23_976 (1280x720p, 23.976p) */
323 vdecRESOLUTION_240p29_97 = 0x00000010, /* 240p (1440x240, 29.97p ) */
324 vdecRESOLUTION_240p30 = 0x00000011, /* 240p (1440x240, 30p) */
325 vdecRESOLUTION_288p25 = 0x00000012, /* 288p (1440x288p, 25p) */
326 vdecRESOLUTION_1080p29_97 = 0x00000013, /* 1080p29_97 (1920x1080, 29.97p) */
327 vdecRESOLUTION_1080p30 = 0x00000014, /* 1080p30 (1920x1080, 30p) */
328 vdecRESOLUTION_1080p24 = 0x00000015, /* 1080p24 (1920x1080, 24p) */
329 vdecRESOLUTION_1080p25 = 0x00000016, /* 1080p25 (1920x1080, 25p) */
330 vdecRESOLUTION_720p24 = 0x00000017, /* 720p24 (1280x720, 25p) */
331 vdecRESOLUTION_720p29_97 = 0x00000018, /* 720p29.97 (1280x720, 29.97p) */
332 vdecRESOLUTION_480p23_976 = 0x00000019, /* 480p23.976 (720*480, 23.976) */
333 vdecRESOLUTION_480p29_97 = 0x0000001A, /* 480p29.976 (720*480, 29.97p) */
334 vdecRESOLUTION_576p25 = 0x0000001B, /* 576p25 (720*576, 25p) */
335 /* For Zero Frame Rate */
336 vdecRESOLUTION_480p0 = 0x0000001C, /* 480p (720x480, 0p) */
337 vdecRESOLUTION_480i0 = 0x0000001D, /* 480i (720x480, 0i) */
338 vdecRESOLUTION_576p0 = 0x0000001E, /* 576p (720x576, 0p) */
339 vdecRESOLUTION_720p0 = 0x0000001F, /* 720p (1280x720, 0p) */
340 vdecRESOLUTION_1080p0 = 0x00000020, /* 1080p (1920x1080, 0p) */
341 vdecRESOLUTION_1080i0 = 0x00000021, /* 1080i (1920x1080, 0i) */
342};
343
344/* Bit definitions for 'flags' field */
345#define VDEC_FLAG_EOS (0x0004)
346
347#define VDEC_FLAG_FRAME (0x0000)
348#define VDEC_FLAG_FIELDPAIR (0x0008)
349#define VDEC_FLAG_TOPFIELD (0x0010)
350#define VDEC_FLAG_BOTTOMFIELD (0x0018)
351
352#define VDEC_FLAG_PROGRESSIVE_SRC (0x0000)
353#define VDEC_FLAG_INTERLACED_SRC (0x0020)
354#define VDEC_FLAG_UNKNOWN_SRC (0x0040)
355
356#define VDEC_FLAG_BOTTOM_FIRST (0x0080)
357#define VDEC_FLAG_LAST_PICTURE (0x0100)
358
359#define VDEC_FLAG_PICTURE_META_DATA_PRESENT (0x40000)
360
361#endif /* _WIN32 || _WIN64 */
362
363enum _BC_OUTPUT_FORMAT {
364 MODE420 = 0x0,
365 MODE422_YUY2 = 0x1,
366 MODE422_UYVY = 0x2,
367};
368
369typedef struct _BC_PIC_INFO_BLOCK {
370 /* Common fields. */
371 uint64_t timeStamp; /* Timestamp */
372 uint32_t picture_number; /* Ordinal display number */
373 uint32_t width; /* pixels */
374 uint32_t height; /* pixels */
375 uint32_t chroma_format; /* 0x420, 0x422 or 0x444 */
376 uint32_t pulldown;
377 uint32_t flags;
378 uint32_t frame_rate;
379 uint32_t aspect_ratio;
380 uint32_t colour_primaries;
381 uint32_t picture_meta_payload;
382 uint32_t sess_num;
383 uint32_t ycom;
384 uint32_t custom_aspect_ratio_width_height;
385 uint32_t n_drop; /* number of non-reference frames remaining to be dropped */
386
387 /* Protocol-specific extensions. */
388 union {
389 BC_PIB_EXT_H264 h264;
390 BC_PIB_EXT_MPEG mpeg;
391 BC_PIB_EXT_VC1 vc1;
392 } other;
393
394} BC_PIC_INFO_BLOCK, *PBC_PIC_INFO_BLOCK;
395
396/*------------------------------------------------------*
397 * ProcOut Info *
398 *------------------------------------------------------*/
399/* Optional flags for ProcOut Interface.*/
400enum _POUT_OPTIONAL_IN_FLAGS_{
401 /* Flags from App to Device */
402 BC_POUT_FLAGS_YV12 = 0x01, /* Copy Data in YV12 format */
403 BC_POUT_FLAGS_STRIDE = 0x02, /* Stride size is valid. */
404 BC_POUT_FLAGS_SIZE = 0x04, /* Take size information from Application */
405 BC_POUT_FLAGS_INTERLACED = 0x08, /* copy only half the bytes */
406 BC_POUT_FLAGS_INTERLEAVED = 0x10, /* interleaved frame */
407
408 /* Flags from Device to APP */
409 BC_POUT_FLAGS_FMT_CHANGE = 0x10000, /* Data is not VALID when this flag is set */
410 BC_POUT_FLAGS_PIB_VALID = 0x20000, /* PIB Information valid */
411 BC_POUT_FLAGS_ENCRYPTED = 0x40000, /* Data is encrypted. */
412 BC_POUT_FLAGS_FLD_BOT = 0x80000, /* Bottom Field data */
413};
414
415#if defined(__KERNEL__) || defined(__LINUX_USER__)
416typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, void *pOut);
417#else
418typedef BC_STATUS(*dts_pout_callback)(void *shnd, uint32_t width, uint32_t height, uint32_t stride, struct _BC_DTS_PROC_OUT *pOut);
419#endif
420
421/* Line 21 Closed Caption */
422/* User Data */
423#define MAX_UD_SIZE 1792 /* 1920 - 128 */
424
425typedef struct _BC_DTS_PROC_OUT {
426 uint8_t *Ybuff; /* Caller Supplied buffer for Y data */
427 uint32_t YbuffSz; /* Caller Supplied Y buffer size */
428 uint32_t YBuffDoneSz; /* Transferred Y datasize */
429
430 uint8_t *UVbuff; /* Caller Supplied buffer for UV data */
431 uint32_t UVbuffSz; /* Caller Supplied UV buffer size */
432 uint32_t UVBuffDoneSz; /* Transferred UV data size */
433
434 uint32_t StrideSz; /* Caller supplied Stride Size */
435 uint32_t PoutFlags; /* Call IN Flags */
436
437 uint32_t discCnt; /* Picture discontinuity count */
438
439 BC_PIC_INFO_BLOCK PicInfo; /* Picture Information Block Data */
440
441 /* Line 21 Closed Caption */
442 /* User Data */
443 uint32_t UserDataSz;
444 uint8_t UserData[MAX_UD_SIZE];
445
446 void *hnd;
447 dts_pout_callback AppCallBack;
448 uint8_t DropFrames;
449 uint8_t b422Mode; /* Picture output Mode */
450 uint8_t bPibEnc; /* PIB encrypted */
451 uint8_t bRevertScramble;
452
453} BC_DTS_PROC_OUT;
454
455typedef struct _BC_DTS_STATUS {
456 uint8_t ReadyListCount; /* Number of frames in ready list (reported by driver) */
457 uint8_t FreeListCount; /* Number of frame buffers free. (reported by driver) */
458 uint8_t PowerStateChange; /* Number of active state power transitions (reported by driver) */
459 uint8_t reserved_[1];
460
461 uint32_t FramesDropped; /* Number of frames dropped. (reported by DIL) */
462 uint32_t FramesCaptured; /* Number of frames captured. (reported by DIL) */
463 uint32_t FramesRepeated; /* Number of frames repeated. (reported by DIL) */
464
465 uint32_t InputCount; /* Times compressed video has been sent to the HW.
466 * i.e. Successful DtsProcInput() calls (reported by DIL) */
467 uint64_t InputTotalSize; /* Amount of compressed video that has been sent to the HW.
468 * (reported by DIL) */
469 uint32_t InputBusyCount; /* Times compressed video has attempted to be sent to the HW
470 * but the input FIFO was full. (reported by DIL) */
471
472 uint32_t PIBMissCount; /* Amount of times a PIB is invalid. (reported by DIL) */
473
474 uint32_t cpbEmptySize; /* supported only for H.264, specifically changed for
475 * Adobe. Report size of CPB buffer available.
476 * Reported by DIL */
477 uint64_t NextTimeStamp; /* TimeStamp of the next picture that will be returned
478 * by a call to ProcOutput. Added for Adobe. Reported
479 * back from the driver */
480 uint8_t reserved__[16];
481
482} BC_DTS_STATUS;
483
484#define BC_SWAP32(_v) \
485 ((((_v) & 0xFF000000)>>24)| \
486 (((_v) & 0x00FF0000)>>8)| \
487 (((_v) & 0x0000FF00)<<8)| \
488 (((_v) & 0x000000FF)<<24))
489
490#define WM_AGENT_TRAYICON_DECODER_OPEN 10001
491#define WM_AGENT_TRAYICON_DECODER_CLOSE 10002
492#define WM_AGENT_TRAYICON_DECODER_START 10003
493#define WM_AGENT_TRAYICON_DECODER_STOP 10004
494#define WM_AGENT_TRAYICON_DECODER_RUN 10005
495#define WM_AGENT_TRAYICON_DECODER_PAUSE 10006
496
497
498#endif /* _BC_DTS_DEFS_H_ */
diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h
new file mode 100644
index 000000000000..b3125e3e0372
--- /dev/null
+++ b/drivers/staging/crystalhd/bc_dts_glob_lnx.h
@@ -0,0 +1,299 @@
1/********************************************************************
2 * Copyright(c) 2006-2009 Broadcom Corporation.
3 *
4 * Name: bc_dts_glob_lnx.h
5 *
6 * Description: Wrapper to Windows dts_glob.h for Link-Linux usage.
7 * The idea is to define additional Linux related defs
8 * in this file to avoid changes to existing Windows
9 * glob file.
10 *
11 * AU
12 *
13 * HISTORY:
14 *
15 ********************************************************************
16 * This header is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU Lesser General Public License as published
18 * by the Free Software Foundation, either version 2.1 of the License.
19 *
20 * This header is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU Lesser General Public License for more details.
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with this header. If not, see <http://www.gnu.org/licenses/>.
26 *******************************************************************/
27
28#ifndef _BC_DTS_GLOB_LNX_H_
29#define _BC_DTS_GLOB_LNX_H_
30
31#ifdef __LINUX_USER__
32#include <stdio.h>
33#include <stdlib.h>
34#include <unistd.h>
35#include <fcntl.h>
36#include <ctype.h>
37#include <string.h>
38#include <errno.h>
39#include <netdb.h>
40#include <sys/time.h>
41#include <time.h>
42#include <arpa/inet.h>
43#include <asm/param.h>
44#include <linux/ioctl.h>
45#include <sys/select.h>
46
47#define DRVIFLIB_INT_API
48
49#endif
50
51#include "bc_dts_defs.h"
52#include "bcm_70012_regs.h" /* Link Register defs */
53
54#define CRYSTALHD_API_NAME "crystalhd"
55#define CRYSTALHD_API_DEV_NAME "/dev/crystalhd"
56
57/*
58 * These are SW stack tunable parameters shared
59 * between the driver and the application.
60 */
61enum _BC_DTS_GLOBALS {
62 BC_MAX_FW_CMD_BUFF_SZ = 0x40, /* FW passthrough cmd/rsp buffer size */
63 PCI_CFG_SIZE = 256, /* PCI config size buffer */
64 BC_IOCTL_DATA_POOL_SIZE = 8, /* BC_IOCTL_DATA Pool size */
65 BC_LINK_MAX_OPENS = 3, /* Maximum simultaneous opens*/
66 BC_LINK_MAX_SGLS = 1024, /* Maximum SG elements 4M/4K */
67 BC_TX_LIST_CNT = 2, /* Max Tx DMA Rings */
68 BC_RX_LIST_CNT = 8, /* Max Rx DMA Rings*/
69 BC_PROC_OUTPUT_TIMEOUT = 3000, /* Milliseconds */
70 BC_INFIFO_THRESHOLD = 0x10000,
71};
72
73typedef struct _BC_CMD_REG_ACC {
74 uint32_t Offset;
75 uint32_t Value;
76} BC_CMD_REG_ACC;
77
78typedef struct _BC_CMD_DEV_MEM {
79 uint32_t StartOff;
80 uint32_t NumDwords;
81 uint32_t Rsrd;
82} BC_CMD_DEV_MEM;
83
84/* FW Passthrough command structure */
85enum _bc_fw_cmd_flags {
86 BC_FW_CMD_FLAGS_NONE = 0,
87 BC_FW_CMD_PIB_QS = 0x01,
88};
89
90typedef struct _BC_FW_CMD {
91 uint32_t cmd[BC_MAX_FW_CMD_BUFF_SZ];
92 uint32_t rsp[BC_MAX_FW_CMD_BUFF_SZ];
93 uint32_t flags;
94 uint32_t add_data;
95} BC_FW_CMD, *PBC_FW_CMD;
96
97typedef struct _BC_HW_TYPE {
98 uint16_t PciDevId;
99 uint16_t PciVenId;
100 uint8_t HwRev;
101 uint8_t Align[3];
102} BC_HW_TYPE;
103
104typedef struct _BC_PCI_CFG {
105 uint32_t Size;
106 uint32_t Offset;
107 uint8_t pci_cfg_space[PCI_CFG_SIZE];
108} BC_PCI_CFG;
109
110typedef struct _BC_VERSION_INFO_ {
111 uint8_t DriverMajor;
112 uint8_t DriverMinor;
113 uint16_t DriverRevision;
114} BC_VERSION_INFO;
115
116typedef struct _BC_START_RX_CAP_ {
117 uint32_t Rsrd;
118 uint32_t StartDeliveryThsh;
119 uint32_t PauseThsh;
120 uint32_t ResumeThsh;
121} BC_START_RX_CAP;
122
123typedef struct _BC_FLUSH_RX_CAP_ {
124 uint32_t Rsrd;
125 uint32_t bDiscardOnly;
126} BC_FLUSH_RX_CAP;
127
128typedef struct _BC_DTS_STATS {
129 uint8_t drvRLL;
130 uint8_t drvFLL;
131 uint8_t eosDetected;
132 uint8_t pwr_state_change;
133
134 /* Stats from App */
135 uint32_t opFrameDropped;
136 uint32_t opFrameCaptured;
137 uint32_t ipSampleCnt;
138 uint64_t ipTotalSize;
139 uint32_t reptdFrames;
140 uint32_t pauseCount;
141 uint32_t pibMisses;
142 uint32_t discCounter;
143
144 /* Stats from Driver */
145 uint32_t TxFifoBsyCnt;
146 uint32_t intCount;
147 uint32_t DrvIgnIntrCnt;
148 uint32_t DrvTotalFrmDropped;
149 uint32_t DrvTotalHWErrs;
150 uint32_t DrvTotalPIBFlushCnt;
151 uint32_t DrvTotalFrmCaptured;
152 uint32_t DrvPIBMisses;
153 uint32_t DrvPauseTime;
154 uint32_t DrvRepeatedFrms;
155 uint32_t res1[13];
156
157} BC_DTS_STATS;
158
159typedef struct _BC_PROC_INPUT_ {
160 uint8_t *pDmaBuff;
161 uint32_t BuffSz;
162 uint8_t Mapped;
163 uint8_t Encrypted;
164 uint8_t Rsrd[2];
165 uint32_t DramOffset; /* For debug use only */
166} BC_PROC_INPUT, *PBC_PROC_INPUT;
167
168typedef struct _BC_DEC_YUV_BUFFS {
169 uint32_t b422Mode;
170 uint8_t *YuvBuff;
171 uint32_t YuvBuffSz;
172 uint32_t UVbuffOffset;
173 uint32_t YBuffDoneSz;
174 uint32_t UVBuffDoneSz;
175 uint32_t RefCnt;
176} BC_DEC_YUV_BUFFS;
177
178enum _DECOUT_COMPLETION_FLAGS{
179 COMP_FLAG_NO_INFO = 0x00,
180 COMP_FLAG_FMT_CHANGE = 0x01,
181 COMP_FLAG_PIB_VALID = 0x02,
182 COMP_FLAG_DATA_VALID = 0x04,
183 COMP_FLAG_DATA_ENC = 0x08,
184 COMP_FLAG_DATA_BOT = 0x10,
185};
186
187typedef struct _BC_DEC_OUT_BUFF{
188 BC_DEC_YUV_BUFFS OutPutBuffs;
189 BC_PIC_INFO_BLOCK PibInfo;
190 uint32_t Flags;
191 uint32_t BadFrCnt;
192} BC_DEC_OUT_BUFF;
193
194typedef struct _BC_NOTIFY_MODE {
195 uint32_t Mode;
196 uint32_t Rsvr[3];
197} BC_NOTIFY_MODE;
198
199typedef struct _BC_CLOCK {
200 uint32_t clk;
201 uint32_t Rsvr[3];
202} BC_CLOCK;
203
204typedef struct _BC_IOCTL_DATA {
205 BC_STATUS RetSts;
206 uint32_t IoctlDataSz;
207 uint32_t Timeout;
208 union {
209 BC_CMD_REG_ACC regAcc;
210 BC_CMD_DEV_MEM devMem;
211 BC_FW_CMD fwCmd;
212 BC_HW_TYPE hwType;
213 BC_PCI_CFG pciCfg;
214 BC_VERSION_INFO VerInfo;
215 BC_PROC_INPUT ProcInput;
216 BC_DEC_YUV_BUFFS RxBuffs;
217 BC_DEC_OUT_BUFF DecOutData;
218 BC_START_RX_CAP RxCap;
219 BC_FLUSH_RX_CAP FlushRxCap;
220 BC_DTS_STATS drvStat;
221 BC_NOTIFY_MODE NotifyMode;
222 BC_CLOCK clockValue;
223 } u;
224 struct _BC_IOCTL_DATA *next;
225} BC_IOCTL_DATA;
226
227typedef enum _BC_DRV_CMD{
228 DRV_CMD_VERSION = 0, /* Get SW version */
229 DRV_CMD_GET_HWTYPE, /* Get HW version and type Dozer/Tank */
230 DRV_CMD_REG_RD, /* Read Device Register */
231 DRV_CMD_REG_WR, /* Write Device Register */
232 DRV_CMD_FPGA_RD, /* Read FPGA Register */
233 DRV_CMD_FPGA_WR, /* Wrtie FPGA Reister */
234 DRV_CMD_MEM_RD, /* Read Device Memory */
235 DRV_CMD_MEM_WR, /* Write Device Memory */
236 DRV_CMD_RD_PCI_CFG, /* Read PCI Config Space */
237 DRV_CMD_WR_PCI_CFG, /* Write the PCI Configuration Space*/
238 DRV_CMD_FW_DOWNLOAD, /* Download Firmware */
239 DRV_ISSUE_FW_CMD, /* Issue FW Cmd (pass through mode) */
240 DRV_CMD_PROC_INPUT, /* Process Input Sample */
241 DRV_CMD_ADD_RXBUFFS, /* Add Rx side buffers to driver pool */
242 DRV_CMD_FETCH_RXBUFF, /* Get Rx DMAed buffer */
243 DRV_CMD_START_RX_CAP, /* Start Rx Buffer Capture */
244 DRV_CMD_FLUSH_RX_CAP, /* Stop the capture for now...we will enhance this later*/
245 DRV_CMD_GET_DRV_STAT, /* Get Driver Internal Statistics */
246 DRV_CMD_RST_DRV_STAT, /* Reset Driver Internal Statistics */
247 DRV_CMD_NOTIFY_MODE, /* Notify the Mode to driver in which the application is Operating*/
248 DRV_CMD_CHANGE_CLOCK, /* Change the core clock to either save power or improve performance */
249
250 /* MUST be the last one.. */
251 DRV_CMD_END, /* End of the List.. */
252} BC_DRV_CMD;
253
254#define BC_IOC_BASE 'b'
255#define BC_IOC_VOID _IOC_NONE
256#define BC_IOC_IOWR(nr, type) _IOWR(BC_IOC_BASE, nr, type)
257#define BC_IOCTL_MB BC_IOCTL_DATA
258
259#define BCM_IOC_GET_VERSION BC_IOC_IOWR(DRV_CMD_VERSION, BC_IOCTL_MB)
260#define BCM_IOC_GET_HWTYPE BC_IOC_IOWR(DRV_CMD_GET_HWTYPE, BC_IOCTL_MB)
261#define BCM_IOC_REG_RD BC_IOC_IOWR(DRV_CMD_REG_RD, BC_IOCTL_MB)
262#define BCM_IOC_REG_WR BC_IOC_IOWR(DRV_CMD_REG_WR, BC_IOCTL_MB)
263#define BCM_IOC_MEM_RD BC_IOC_IOWR(DRV_CMD_MEM_RD, BC_IOCTL_MB)
264#define BCM_IOC_MEM_WR BC_IOC_IOWR(DRV_CMD_MEM_WR, BC_IOCTL_MB)
265#define BCM_IOC_FPGA_RD BC_IOC_IOWR(DRV_CMD_FPGA_RD, BC_IOCTL_MB)
266#define BCM_IOC_FPGA_WR BC_IOC_IOWR(DRV_CMD_FPGA_WR, BC_IOCTL_MB)
267#define BCM_IOC_RD_PCI_CFG BC_IOC_IOWR(DRV_CMD_RD_PCI_CFG, BC_IOCTL_MB)
268#define BCM_IOC_WR_PCI_CFG BC_IOC_IOWR(DRV_CMD_WR_PCI_CFG, BC_IOCTL_MB)
269#define BCM_IOC_PROC_INPUT BC_IOC_IOWR(DRV_CMD_PROC_INPUT, BC_IOCTL_MB)
270#define BCM_IOC_ADD_RXBUFFS BC_IOC_IOWR(DRV_CMD_ADD_RXBUFFS, BC_IOCTL_MB)
271#define BCM_IOC_FETCH_RXBUFF BC_IOC_IOWR(DRV_CMD_FETCH_RXBUFF, BC_IOCTL_MB)
272#define BCM_IOC_FW_CMD BC_IOC_IOWR(DRV_ISSUE_FW_CMD, BC_IOCTL_MB)
273#define BCM_IOC_START_RX_CAP BC_IOC_IOWR(DRV_CMD_START_RX_CAP, BC_IOCTL_MB)
274#define BCM_IOC_FLUSH_RX_CAP BC_IOC_IOWR(DRV_CMD_FLUSH_RX_CAP, BC_IOCTL_MB)
275#define BCM_IOC_GET_DRV_STAT BC_IOC_IOWR(DRV_CMD_GET_DRV_STAT, BC_IOCTL_MB)
276#define BCM_IOC_RST_DRV_STAT BC_IOC_IOWR(DRV_CMD_RST_DRV_STAT, BC_IOCTL_MB)
277#define BCM_IOC_NOTIFY_MODE BC_IOC_IOWR(DRV_CMD_NOTIFY_MODE, BC_IOCTL_MB)
278#define BCM_IOC_FW_DOWNLOAD BC_IOC_IOWR(DRV_CMD_FW_DOWNLOAD, BC_IOCTL_MB)
279#define BCM_IOC_CHG_CLK BC_IOC_IOWR(DRV_CMD_CHANGE_CLOCK, BC_IOCTL_MB)
280#define BCM_IOC_END BC_IOC_VOID
281
282/* Wrapper for main IOCTL data */
283typedef struct _crystalhd_ioctl_data {
284 BC_IOCTL_DATA udata; /* IOCTL from App..*/
285 uint32_t u_id; /* Driver specific user ID */
286 uint32_t cmd; /* Cmd ID for driver's use. */
287 void *add_cdata; /* Additional command specific data..*/
288 uint32_t add_cdata_sz; /* Additional command specific data size */
289 struct _crystalhd_ioctl_data *next; /* List/Fifo management */
290} crystalhd_ioctl_data;
291
292
293enum _crystalhd_kmod_ver{
294 crystalhd_kmod_major = 0,
295 crystalhd_kmod_minor = 9,
296 crystalhd_kmod_rev = 27,
297};
298
299#endif
diff --git a/drivers/staging/crystalhd/bc_dts_types.h b/drivers/staging/crystalhd/bc_dts_types.h
new file mode 100644
index 000000000000..ac0c81717385
--- /dev/null
+++ b/drivers/staging/crystalhd/bc_dts_types.h
@@ -0,0 +1,121 @@
1/********************************************************************
2 * Copyright(c) 2006-2009 Broadcom Corporation.
3 *
4 * Name: bc_dts_types.h
5 *
6 * Description: Data types
7 *
8 * AU
9 *
10 * HISTORY:
11 *
12 ********************************************************************
13 * This header is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License as published
15 * by the Free Software Foundation, either version 2.1 of the License.
16 *
17 * This header is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this header. If not, see <http://www.gnu.org/licenses/>.
23 *******************************************************************/
24
25#ifndef _BC_DTS_TYPES_H_
26#define _BC_DTS_TYPES_H_
27
28#ifdef __LINUX_USER__ // Don't include these for KERNEL..
29#include <stdint.h>
30#endif
31
32#if defined(_WIN64) || defined(_WIN32)
33typedef uint32_t U32;
34typedef int32_t S32;
35typedef uint16_t U16;
36typedef int16_t S16;
37typedef unsigned char U8;
38typedef char S8;
39#endif
40
41#ifndef PVOID
42typedef void *PVOID;
43#endif
44
45#ifndef BOOL
46typedef int BOOL;
47#endif
48
49#ifdef WIN32
50 typedef unsigned __int64 U64;
51#elif defined(_WIN64)
52 typedef uint64_t U64;
53#endif
54
55#ifdef _WIN64
56#if !(defined(POINTER_32))
57#define POINTER_32 __ptr32
58#endif
59#else /* _WIN32 */
60#define POINTER_32
61#endif
62
63#if defined(__KERNEL__) || defined(__LINUX_USER__)
64
65#ifdef __LINUX_USER__ /* Don't include these for KERNEL */
66typedef uint32_t ULONG;
67typedef int32_t LONG;
68typedef void *HANDLE;
69#ifndef VOID
70typedef void VOID;
71#endif
72typedef void *LPVOID;
73typedef uint32_t DWORD;
74typedef uint32_t UINT32;
75typedef uint32_t *LPDWORD;
76typedef unsigned char *PUCHAR;
77
78#ifndef TRUE
79 #define TRUE 1
80#endif
81
82#ifndef FALSE
83 #define FALSE 0
84#endif
85
86#define TEXT
87
88#else
89
90/* For Kernel usage.. */
91typedef bool bc_bool_t;
92#endif
93
94#else
95
96#ifndef uint64_t
97typedef struct _uint64_t {
98 uint32_t low_dw;
99 uint32_t hi_dw;
100} uint64_t;
101#endif
102
103#ifndef int32_t
104typedef signed long int32_t;
105#endif
106
107#ifndef uint32_t
108typedef unsigned long uint32_t;
109#endif
110
111#ifndef uint16_t
112typedef unsigned short uint16_t;
113#endif
114
115#ifndef uint8_t
116typedef unsigned char uint8_t;
117#endif
118#endif
119
120#endif
121
diff --git a/drivers/staging/crystalhd/bcm_70012_regs.h b/drivers/staging/crystalhd/bcm_70012_regs.h
new file mode 100644
index 000000000000..6922f54e432f
--- /dev/null
+++ b/drivers/staging/crystalhd/bcm_70012_regs.h
@@ -0,0 +1,757 @@
1/***************************************************************************
2 * Copyright (c) 1999-2009, Broadcom Corporation.
3 *
4 * Name: bcm_70012_regs.h
5 *
6 * Description: BCM70012 registers
7 *
8 ********************************************************************
9 * This header is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation, either version 2.1 of the License.
12 *
13 * This header is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this header. If not, see <http://www.gnu.org/licenses/>.
19 ***************************************************************************/
20
21#ifndef MACFILE_H__
22#define MACFILE_H__
23
24/**
25 * m = memory, c = core, r = register, f = field, d = data.
26 */
27#if !defined(GET_FIELD) && !defined(SET_FIELD)
28#define BRCM_ALIGN(c,r,f) c##_##r##_##f##_ALIGN
29#define BRCM_BITS(c,r,f) c##_##r##_##f##_BITS
30#define BRCM_MASK(c,r,f) c##_##r##_##f##_MASK
31#define BRCM_SHIFT(c,r,f) c##_##r##_##f##_SHIFT
32
33#define GET_FIELD(m,c,r,f) \
34 ((((m) & BRCM_MASK(c,r,f)) >> BRCM_SHIFT(c,r,f)) << BRCM_ALIGN(c,r,f))
35
36#define SET_FIELD(m,c,r,f,d) \
37 ((m) = (((m) & ~BRCM_MASK(c,r,f)) | ((((d) >> BRCM_ALIGN(c,r,f)) << \
38 BRCM_SHIFT(c,r,f)) & BRCM_MASK(c,r,f))) \
39 )
40
41#define SET_TYPE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##d)
42#define SET_NAME_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,c##_##r##_##f##_##d)
43#define SET_VALUE_FIELD(m,c,r,f,d) SET_FIELD(m,c,r,f,d)
44
45#endif /* GET & SET */
46
47/****************************************************************************
48 * Core Enums.
49 ***************************************************************************/
50/****************************************************************************
51 * Enums: AES_RGR_BRIDGE_RESET_CTRL
52 ***************************************************************************/
53#define AES_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
54#define AES_RGR_BRIDGE_RESET_CTRL_ASSERT 1
55
56/****************************************************************************
57 * Enums: CCE_RGR_BRIDGE_RESET_CTRL
58 ***************************************************************************/
59#define CCE_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
60#define CCE_RGR_BRIDGE_RESET_CTRL_ASSERT 1
61
62/****************************************************************************
63 * Enums: DBU_RGR_BRIDGE_RESET_CTRL
64 ***************************************************************************/
65#define DBU_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
66#define DBU_RGR_BRIDGE_RESET_CTRL_ASSERT 1
67
68/****************************************************************************
69 * Enums: DCI_RGR_BRIDGE_RESET_CTRL
70 ***************************************************************************/
71#define DCI_RGR_BRIDGE_RESET_CTRL_DEASSERT 0
72#define DCI_RGR_BRIDGE_RESET_CTRL_ASSERT 1
73
74/****************************************************************************
75 * Enums: GISB_ARBITER_DEASSERT_ASSERT
76 ***************************************************************************/
77#define GISB_ARBITER_DEASSERT_ASSERT_DEASSERT 0
78#define GISB_ARBITER_DEASSERT_ASSERT_ASSERT 1
79
80/****************************************************************************
81 * Enums: GISB_ARBITER_UNMASK_MASK
82 ***************************************************************************/
83#define GISB_ARBITER_UNMASK_MASK_UNMASK 0
84#define GISB_ARBITER_UNMASK_MASK_MASK 1
85
86/****************************************************************************
87 * Enums: GISB_ARBITER_DISABLE_ENABLE
88 ***************************************************************************/
89#define GISB_ARBITER_DISABLE_ENABLE_DISABLE 0
90#define GISB_ARBITER_DISABLE_ENABLE_ENABLE 1
91
92/****************************************************************************
93 * Enums: I2C_GR_BRIDGE_RESET_CTRL
94 ***************************************************************************/
95#define I2C_GR_BRIDGE_RESET_CTRL_DEASSERT 0
96#define I2C_GR_BRIDGE_RESET_CTRL_ASSERT 1
97
98/****************************************************************************
99 * Enums: MISC_GR_BRIDGE_RESET_CTRL
100 ***************************************************************************/
101#define MISC_GR_BRIDGE_RESET_CTRL_DEASSERT 0
102#define MISC_GR_BRIDGE_RESET_CTRL_ASSERT 1
103
104/****************************************************************************
105 * Enums: OTP_GR_BRIDGE_RESET_CTRL
106 ***************************************************************************/
107#define OTP_GR_BRIDGE_RESET_CTRL_DEASSERT 0
108#define OTP_GR_BRIDGE_RESET_CTRL_ASSERT 1
109
110/****************************************************************************
111 * BCM70012_TGT_TOP_PCIE_CFG
112 ***************************************************************************/
113#define PCIE_CFG_DEVICE_VENDOR_ID 0x00000000 /* DEVICE_VENDOR_ID Register */
114#define PCIE_CFG_STATUS_COMMAND 0x00000004 /* STATUS_COMMAND Register */
115#define PCIE_CFG_PCI_CLASSCODE_AND_REVISION_ID 0x00000008 /* PCI_CLASSCODE_AND_REVISION_ID Register */
116#define PCIE_CFG_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE 0x0000000c /* BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE_SIZE Register */
117#define PCIE_CFG_BASE_ADDRESS_1 0x00000010 /* BASE_ADDRESS_1 Register */
118#define PCIE_CFG_BASE_ADDRESS_2 0x00000014 /* BASE_ADDRESS_2 Register */
119#define PCIE_CFG_BASE_ADDRESS_3 0x00000018 /* BASE_ADDRESS_3 Register */
120#define PCIE_CFG_BASE_ADDRESS_4 0x0000001c /* BASE_ADDRESS_4 Register */
121#define PCIE_CFG_CARDBUS_CIS_POINTER 0x00000028 /* CARDBUS_CIS_POINTER Register */
122#define PCIE_CFG_SUBSYSTEM_DEVICE_VENDOR_ID 0x0000002c /* SUBSYSTEM_DEVICE_VENDOR_ID Register */
123#define PCIE_CFG_EXPANSION_ROM_BASE_ADDRESS 0x00000030 /* EXPANSION_ROM_BASE_ADDRESS Register */
124#define PCIE_CFG_CAPABILITIES_POINTER 0x00000034 /* CAPABILITIES_POINTER Register */
125#define PCIE_CFG_INTERRUPT 0x0000003c /* INTERRUPT Register */
126#define PCIE_CFG_VPD_CAPABILITIES 0x00000040 /* VPD_CAPABILITIES Register */
127#define PCIE_CFG_VPD_DATA 0x00000044 /* VPD_DATA Register */
128#define PCIE_CFG_POWER_MANAGEMENT_CAPABILITY 0x00000048 /* POWER_MANAGEMENT_CAPABILITY Register */
129#define PCIE_CFG_POWER_MANAGEMENT_CONTROL_STATUS 0x0000004c /* POWER_MANAGEMENT_CONTROL_STATUS Register */
130#define PCIE_CFG_MSI_CAPABILITY_HEADER 0x00000050 /* MSI_CAPABILITY_HEADER Register */
131#define PCIE_CFG_MSI_LOWER_ADDRESS 0x00000054 /* MSI_LOWER_ADDRESS Register */
132#define PCIE_CFG_MSI_UPPER_ADDRESS_REGISTER 0x00000058 /* MSI_UPPER_ADDRESS_REGISTER Register */
133#define PCIE_CFG_MSI_DATA 0x0000005c /* MSI_DATA Register */
134#define PCIE_CFG_BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER 0x00000060 /* BROADCOM_VENDOR_SPECIFIC_CAPABILITY_HEADER Register */
135#define PCIE_CFG_RESET_COUNTERS_INITIAL_VALUES 0x00000064 /* RESET_COUNTERS_INITIAL_VALUES Register */
136#define PCIE_CFG_MISCELLANEOUS_HOST_CONTROL 0x00000068 /* MISCELLANEOUS_HOST_CONTROL Register */
137#define PCIE_CFG_SPARE 0x0000006c /* SPARE Register */
138#define PCIE_CFG_PCI_STATE 0x00000070 /* PCI_STATE Register */
139#define PCIE_CFG_CLOCK_CONTROL 0x00000074 /* CLOCK_CONTROL Register */
140#define PCIE_CFG_REGISTER_BASE 0x00000078 /* REGISTER_BASE Register */
141#define PCIE_CFG_MEMORY_BASE 0x0000007c /* MEMORY_BASE Register */
142#define PCIE_CFG_REGISTER_DATA 0x00000080 /* REGISTER_DATA Register */
143#define PCIE_CFG_MEMORY_DATA 0x00000084 /* MEMORY_DATA Register */
144#define PCIE_CFG_EXPANSION_ROM_BAR_SIZE 0x00000088 /* EXPANSION_ROM_BAR_SIZE Register */
145#define PCIE_CFG_EXPANSION_ROM_ADDRESS 0x0000008c /* EXPANSION_ROM_ADDRESS Register */
146#define PCIE_CFG_EXPANSION_ROM_DATA 0x00000090 /* EXPANSION_ROM_DATA Register */
147#define PCIE_CFG_VPD_INTERFACE 0x00000094 /* VPD_INTERFACE Register */
148#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER 0x00000098 /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_UPPER Register */
149#define PCIE_CFG_UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER 0x0000009c /* UNDI_RECEIVE_BD_STANDARD_PRODUCER_RING_PRODUCER_INDEX_MAILBOX_LOWER Register */
150#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER 0x000000a0 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_UPPER Register */
151#define PCIE_CFG_UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER 0x000000a4 /* UNDI_RECEIVE_RETURN_RING_CONSUMER_INDEX_LOWER Register */
152#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER 0x000000a8 /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_UPPER Register */
153#define PCIE_CFG_UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER 0x000000ac /* UNDI_SEND_BD_PRODUCER_INDEX_MAILBOX_LOWER Register */
154#define PCIE_CFG_INT_MAILBOX_UPPER 0x000000b0 /* INT_MAILBOX_UPPER Register */
155#define PCIE_CFG_INT_MAILBOX_LOWER 0x000000b4 /* INT_MAILBOX_LOWER Register */
156#define PCIE_CFG_PRODUCT_ID_AND_ASIC_REVISION 0x000000bc /* PRODUCT_ID_AND_ASIC_REVISION Register */
157#define PCIE_CFG_FUNCTION_EVENT 0x000000c0 /* FUNCTION_EVENT Register */
158#define PCIE_CFG_FUNCTION_EVENT_MASK 0x000000c4 /* FUNCTION_EVENT_MASK Register */
159#define PCIE_CFG_FUNCTION_PRESENT 0x000000c8 /* FUNCTION_PRESENT Register */
160#define PCIE_CFG_PCIE_CAPABILITIES 0x000000cc /* PCIE_CAPABILITIES Register */
161#define PCIE_CFG_DEVICE_CAPABILITIES 0x000000d0 /* DEVICE_CAPABILITIES Register */
162#define PCIE_CFG_DEVICE_STATUS_CONTROL 0x000000d4 /* DEVICE_STATUS_CONTROL Register */
163#define PCIE_CFG_LINK_CAPABILITY 0x000000d8 /* LINK_CAPABILITY Register */
164#define PCIE_CFG_LINK_STATUS_CONTROL 0x000000dc /* LINK_STATUS_CONTROL Register */
165#define PCIE_CFG_DEVICE_CAPABILITIES_2 0x000000f0 /* DEVICE_CAPABILITIES_2 Register */
166#define PCIE_CFG_DEVICE_STATUS_CONTROL_2 0x000000f4 /* DEVICE_STATUS_CONTROL_2 Register */
167#define PCIE_CFG_LINK_CAPABILITIES_2 0x000000f8 /* LINK_CAPABILITIES_2 Register */
168#define PCIE_CFG_LINK_STATUS_CONTROL_2 0x000000fc /* LINK_STATUS_CONTROL_2 Register */
169#define PCIE_CFG_ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER 0x00000100 /* ADVANCED_ERROR_REPORTING_ENHANCED_CAPABILITY_HEADER Register */
170#define PCIE_CFG_UNCORRECTABLE_ERROR_STATUS 0x00000104 /* UNCORRECTABLE_ERROR_STATUS Register */
171#define PCIE_CFG_UNCORRECTABLE_ERROR_MASK 0x00000108 /* UNCORRECTABLE_ERROR_MASK Register */
172#define PCIE_CFG_UNCORRECTABLE_ERROR_SEVERITY 0x0000010c /* UNCORRECTABLE_ERROR_SEVERITY Register */
173#define PCIE_CFG_CORRECTABLE_ERROR_STATUS 0x00000110 /* CORRECTABLE_ERROR_STATUS Register */
174#define PCIE_CFG_CORRECTABLE_ERROR_MASK 0x00000114 /* CORRECTABLE_ERROR_MASK Register */
175#define PCIE_CFG_ADVANCED_ERROR_CAPABILITIES_AND_CONTROL 0x00000118 /* ADVANCED_ERROR_CAPABILITIES_AND_CONTROL Register */
176#define PCIE_CFG_HEADER_LOG_1 0x0000011c /* HEADER_LOG_1 Register */
177#define PCIE_CFG_HEADER_LOG_2 0x00000120 /* HEADER_LOG_2 Register */
178#define PCIE_CFG_HEADER_LOG_3 0x00000124 /* HEADER_LOG_3 Register */
179#define PCIE_CFG_HEADER_LOG_4 0x00000128 /* HEADER_LOG_4 Register */
180#define PCIE_CFG_VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER 0x0000013c /* VIRTUAL_CHANNEL_ENHANCED_CAPABILITY_HEADER Register */
181#define PCIE_CFG_PORT_VC_CAPABILITY 0x00000140 /* PORT_VC_CAPABILITY Register */
182#define PCIE_CFG_PORT_VC_CAPABILITY_2 0x00000144 /* PORT_VC_CAPABILITY_2 Register */
183#define PCIE_CFG_PORT_VC_STATUS_CONTROL 0x00000148 /* PORT_VC_STATUS_CONTROL Register */
184#define PCIE_CFG_VC_RESOURCE_CAPABILITY 0x0000014c /* VC_RESOURCE_CAPABILITY Register */
185#define PCIE_CFG_VC_RESOURCE_CONTROL 0x00000150 /* VC_RESOURCE_CONTROL Register */
186#define PCIE_CFG_VC_RESOURCE_STATUS 0x00000154 /* VC_RESOURCE_STATUS Register */
187#define PCIE_CFG_DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER 0x00000160 /* DEVICE_SERIAL_NO_ENHANCED_CAPABILITY_HEADER Register */
188#define PCIE_CFG_DEVICE_SERIAL_NO_LOWER_DW 0x00000164 /* DEVICE_SERIAL_NO_LOWER_DW Register */
189#define PCIE_CFG_DEVICE_SERIAL_NO_UPPER_DW 0x00000168 /* DEVICE_SERIAL_NO_UPPER_DW Register */
190#define PCIE_CFG_POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER 0x0000016c /* POWER_BUDGETING_ENHANCED_CAPABILITY_HEADER Register */
191#define PCIE_CFG_POWER_BUDGETING_DATA_SELECT 0x00000170 /* POWER_BUDGETING_DATA_SELECT Register */
192#define PCIE_CFG_POWER_BUDGETING_DATA 0x00000174 /* POWER_BUDGETING_DATA Register */
193#define PCIE_CFG_POWER_BUDGETING_CAPABILITY 0x00000178 /* POWER_BUDGETING_CAPABILITY Register */
194#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_2_1 0x0000017c /* FIRMWARE_POWER_BUDGETING_2_1 Register */
195#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_4_3 0x00000180 /* FIRMWARE_POWER_BUDGETING_4_3 Register */
196#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_6_5 0x00000184 /* FIRMWARE_POWER_BUDGETING_6_5 Register */
197#define PCIE_CFG_FIRMWARE_POWER_BUDGETING_8_7 0x00000188 /* FIRMWARE_POWER_BUDGETING_8_7 Register */
198#define PCIE_CFG_PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING 0x0000018c /* PCIE_1_1_ADVISORY_NON_FATAL_ERROR_MASKING Register */
199
200
201/****************************************************************************
202 * BCM70012_TGT_TOP_PCIE_TL
203 ***************************************************************************/
204#define PCIE_TL_TL_CONTROL 0x00000400 /* TL_CONTROL Register */
205#define PCIE_TL_TRANSACTION_CONFIGURATION 0x00000404 /* TRANSACTION_CONFIGURATION Register */
206
207
208/****************************************************************************
209 * BCM70012_TGT_TOP_PCIE_DLL
210 ***************************************************************************/
211#define PCIE_DLL_DATA_LINK_CONTROL 0x00000500 /* DATA_LINK_CONTROL Register */
212#define PCIE_DLL_DATA_LINK_STATUS 0x00000504 /* DATA_LINK_STATUS Register */
213
214
215/****************************************************************************
216 * BCM70012_TGT_TOP_INTR
217 ***************************************************************************/
218#define INTR_INTR_STATUS 0x00000700 /* Interrupt Status Register */
219#define INTR_INTR_SET 0x00000704 /* Interrupt Set Register */
220#define INTR_INTR_CLR_REG 0x00000708 /* Interrupt Clear Register */
221#define INTR_INTR_MSK_STS_REG 0x0000070c /* Interrupt Mask Status Register */
222#define INTR_INTR_MSK_SET_REG 0x00000710 /* Interrupt Mask Set Register */
223#define INTR_INTR_MSK_CLR_REG 0x00000714 /* Interrupt Mask Clear Register */
224#define INTR_EOI_CTRL 0x00000720 /* End of interrupt control register */
225
226
227/****************************************************************************
228 * BCM70012_MISC_TOP_MISC1
229 ***************************************************************************/
230#define MISC1_TX_FIRST_DESC_L_ADDR_LIST0 0x00000c00 /* Tx DMA Descriptor List0 First Descriptor lower Address */
231#define MISC1_TX_FIRST_DESC_U_ADDR_LIST0 0x00000c04 /* Tx DMA Descriptor List0 First Descriptor Upper Address */
232#define MISC1_TX_FIRST_DESC_L_ADDR_LIST1 0x00000c08 /* Tx DMA Descriptor List1 First Descriptor Lower Address */
233#define MISC1_TX_FIRST_DESC_U_ADDR_LIST1 0x00000c0c /* Tx DMA Descriptor List1 First Descriptor Upper Address */
234#define MISC1_TX_SW_DESC_LIST_CTRL_STS 0x00000c10 /* Tx DMA Software Descriptor List Control and Status */
235#define MISC1_TX_DMA_ERROR_STATUS 0x00000c18 /* Tx DMA Engine Error Status */
236#define MISC1_TX_DMA_LIST0_CUR_DESC_L_ADDR 0x00000c1c /* Tx DMA List0 Current Descriptor Lower Address */
237#define MISC1_TX_DMA_LIST0_CUR_DESC_U_ADDR 0x00000c20 /* Tx DMA List0 Current Descriptor Upper Address */
238#define MISC1_TX_DMA_LIST0_CUR_BYTE_CNT_REM 0x00000c24 /* Tx DMA List0 Current Descriptor Upper Address */
239#define MISC1_TX_DMA_LIST1_CUR_DESC_L_ADDR 0x00000c28 /* Tx DMA List1 Current Descriptor Lower Address */
240#define MISC1_TX_DMA_LIST1_CUR_DESC_U_ADDR 0x00000c2c /* Tx DMA List1 Current Descriptor Upper Address */
241#define MISC1_TX_DMA_LIST1_CUR_BYTE_CNT_REM 0x00000c30 /* Tx DMA List1 Current Descriptor Upper Address */
242#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c34 /* Y Rx Descriptor List0 First Descriptor Lower Address */
243#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c38 /* Y Rx Descriptor List0 First Descriptor Upper Address */
244#define MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c3c /* Y Rx Descriptor List1 First Descriptor Lower Address */
245#define MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c40 /* Y Rx Descriptor List1 First Descriptor Upper Address */
246#define MISC1_Y_RX_SW_DESC_LIST_CTRL_STS 0x00000c44 /* Y Rx Software Descriptor List Control and Status */
247#define MISC1_Y_RX_ERROR_STATUS 0x00000c4c /* Y Rx Engine Error Status */
248#define MISC1_Y_RX_LIST0_CUR_DESC_L_ADDR 0x00000c50 /* Y Rx List0 Current Descriptor Lower Address */
249#define MISC1_Y_RX_LIST0_CUR_DESC_U_ADDR 0x00000c54 /* Y Rx List0 Current Descriptor Upper Address */
250#define MISC1_Y_RX_LIST0_CUR_BYTE_CNT 0x00000c58 /* Y Rx List0 Current Descriptor Byte Count */
251#define MISC1_Y_RX_LIST1_CUR_DESC_L_ADDR 0x00000c5c /* Y Rx List1 Current Descriptor Lower address */
252#define MISC1_Y_RX_LIST1_CUR_DESC_U_ADDR 0x00000c60 /* Y Rx List1 Current Descriptor Upper address */
253#define MISC1_Y_RX_LIST1_CUR_BYTE_CNT 0x00000c64 /* Y Rx List1 Current Descriptor Byte Count */
254#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0 0x00000c68 /* UV Rx Descriptor List0 First Descriptor lower Address */
255#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0 0x00000c6c /* UV Rx Descriptor List0 First Descriptor Upper Address */
256#define MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1 0x00000c70 /* UV Rx Descriptor List1 First Descriptor Lower Address */
257#define MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1 0x00000c74 /* UV Rx Descriptor List1 First Descriptor Upper Address */
258#define MISC1_UV_RX_SW_DESC_LIST_CTRL_STS 0x00000c78 /* UV Rx Software Descriptor List Control and Status */
259#define MISC1_UV_RX_ERROR_STATUS 0x00000c7c /* UV Rx Engine Error Status */
260#define MISC1_UV_RX_LIST0_CUR_DESC_L_ADDR 0x00000c80 /* UV Rx List0 Current Descriptor Lower Address */
261#define MISC1_UV_RX_LIST0_CUR_DESC_U_ADDR 0x00000c84 /* UV Rx List0 Current Descriptor Upper Address */
262#define MISC1_UV_RX_LIST0_CUR_BYTE_CNT 0x00000c88 /* UV Rx List0 Current Descriptor Byte Count */
263#define MISC1_UV_RX_LIST1_CUR_DESC_L_ADDR 0x00000c8c /* UV Rx List1 Current Descriptor Lower Address */
264#define MISC1_UV_RX_LIST1_CUR_DESC_U_ADDR 0x00000c90 /* UV Rx List1 Current Descriptor Upper Address */
265#define MISC1_UV_RX_LIST1_CUR_BYTE_CNT 0x00000c94 /* UV Rx List1 Current Descriptor Byte Count */
266#define MISC1_DMA_DEBUG_OPTIONS_REG 0x00000c98 /* DMA Debug Options Register */
267#define MISC1_READ_CHANNEL_ERROR_STATUS 0x00000c9c /* Read Channel Error Status */
268#define MISC1_PCIE_DMA_CTRL 0x00000ca0 /* PCIE DMA Control Register */
269
270
271/****************************************************************************
272 * BCM70012_MISC_TOP_MISC2
273 ***************************************************************************/
274#define MISC2_GLOBAL_CTRL 0x00000d00 /* Global Control Register */
275#define MISC2_INTERNAL_STATUS 0x00000d04 /* Internal Status Register */
276#define MISC2_INTERNAL_STATUS_MUX_CTRL 0x00000d08 /* Internal Debug Mux Control */
277#define MISC2_DEBUG_FIFO_LENGTH 0x00000d0c /* Debug FIFO Length */
278
279
280/****************************************************************************
281 * BCM70012_MISC_TOP_MISC3
282 ***************************************************************************/
283#define MISC3_RESET_CTRL 0x00000e00 /* Reset Control Register */
284#define MISC3_BIST_CTRL 0x00000e04 /* BIST Control Register */
285#define MISC3_BIST_STATUS 0x00000e08 /* BIST Status Register */
286#define MISC3_RX_CHECKSUM 0x00000e0c /* Receive Checksum */
287#define MISC3_TX_CHECKSUM 0x00000e10 /* Transmit Checksum */
288#define MISC3_ECO_CTRL_CORE 0x00000e14 /* ECO Core Reset Control Register */
289#define MISC3_CSI_TEST_CTRL 0x00000e18 /* CSI Test Control Register */
290#define MISC3_HD_DVI_TEST_CTRL 0x00000e1c /* HD DVI Test Control Register */
291
292
293/****************************************************************************
294 * BCM70012_MISC_TOP_MISC_PERST
295 ***************************************************************************/
296#define MISC_PERST_ECO_CTRL_PERST 0x00000e80 /* ECO PCIE Reset Control Register */
297#define MISC_PERST_DECODER_CTRL 0x00000e84 /* Decoder Control Register */
298#define MISC_PERST_CCE_STATUS 0x00000e88 /* Config Copy Engine Status */
299#define MISC_PERST_PCIE_DEBUG 0x00000e8c /* PCIE Debug Control Register */
300#define MISC_PERST_PCIE_DEBUG_STATUS 0x00000e90 /* PCIE Debug Status Register */
301#define MISC_PERST_VREG_CTRL 0x00000e94 /* Voltage Regulator Control Register */
302#define MISC_PERST_MEM_CTRL 0x00000e98 /* Memory Control Register */
303#define MISC_PERST_CLOCK_CTRL 0x00000e9c /* Clock Control Register */
304
305
306/****************************************************************************
307 * BCM70012_MISC_TOP_GISB_ARBITER
308 ***************************************************************************/
309#define GISB_ARBITER_REVISION 0x00000f00 /* GISB ARBITER REVISION */
310#define GISB_ARBITER_SCRATCH 0x00000f04 /* GISB ARBITER Scratch Register */
311#define GISB_ARBITER_REQ_MASK 0x00000f08 /* GISB ARBITER Master Request Mask Register */
312#define GISB_ARBITER_TIMER 0x00000f0c /* GISB ARBITER Timer Value Register */
313
314
315/****************************************************************************
316 * BCM70012_OTP_TOP_OTP
317 ***************************************************************************/
318#define OTP_CONFIG_INFO 0x00001400 /* OTP Configuration Register */
319#define OTP_CMD 0x00001404 /* OTP Command Register */
320#define OTP_STATUS 0x00001408 /* OTP Status Register */
321#define OTP_CONTENT_MISC 0x0000140c /* Content : Miscellaneous Register */
322#define OTP_CONTENT_AES_0 0x00001410 /* Content : AES Key 0 Register */
323#define OTP_CONTENT_AES_1 0x00001414 /* Content : AES Key 1 Register */
324#define OTP_CONTENT_AES_2 0x00001418 /* Content : AES Key 2 Register */
325#define OTP_CONTENT_AES_3 0x0000141c /* Content : AES Key 3 Register */
326#define OTP_CONTENT_SHA_0 0x00001420 /* Content : SHA Key 0 Register */
327#define OTP_CONTENT_SHA_1 0x00001424 /* Content : SHA Key 1 Register */
328#define OTP_CONTENT_SHA_2 0x00001428 /* Content : SHA Key 2 Register */
329#define OTP_CONTENT_SHA_3 0x0000142c /* Content : SHA Key 3 Register */
330#define OTP_CONTENT_SHA_4 0x00001430 /* Content : SHA Key 4 Register */
331#define OTP_CONTENT_SHA_5 0x00001434 /* Content : SHA Key 5 Register */
332#define OTP_CONTENT_SHA_6 0x00001438 /* Content : SHA Key 6 Register */
333#define OTP_CONTENT_SHA_7 0x0000143c /* Content : SHA Key 7 Register */
334#define OTP_CONTENT_CHECKSUM 0x00001440 /* Content : Checksum Register */
335#define OTP_PROG_CTRL 0x00001444 /* Programming Control Register */
336#define OTP_PROG_STATUS 0x00001448 /* Programming Status Register */
337#define OTP_PROG_PULSE 0x0000144c /* Program Pulse Width Register */
338#define OTP_VERIFY_PULSE 0x00001450 /* Verify Pulse Width Register */
339#define OTP_PROG_MASK 0x00001454 /* Program Mask Register */
340#define OTP_DATA_INPUT 0x00001458 /* Data Input Register */
341#define OTP_DATA_OUTPUT 0x0000145c /* Data Output Register */
342
343
344/****************************************************************************
345 * BCM70012_AES_TOP_AES
346 ***************************************************************************/
347#define AES_CONFIG_INFO 0x00001800 /* AES Configuration Information Register */
348#define AES_CMD 0x00001804 /* AES Command Register */
349#define AES_STATUS 0x00001808 /* AES Status Register */
350#define AES_EEPROM_CONFIG 0x0000180c /* AES EEPROM Configuration Register */
351#define AES_EEPROM_DATA_0 0x00001810 /* AES EEPROM Data Register 0 */
352#define AES_EEPROM_DATA_1 0x00001814 /* AES EEPROM Data Register 1 */
353#define AES_EEPROM_DATA_2 0x00001818 /* AES EEPROM Data Register 2 */
354#define AES_EEPROM_DATA_3 0x0000181c /* AES EEPROM Data Register 3 */
355
356
357/****************************************************************************
358 * BCM70012_DCI_TOP_DCI
359 ***************************************************************************/
360#define DCI_CMD 0x00001c00 /* DCI Command Register */
361#define DCI_STATUS 0x00001c04 /* DCI Status Register */
362#define DCI_DRAM_BASE_ADDR 0x00001c08 /* DRAM Base Address Register */
363#define DCI_FIRMWARE_ADDR 0x00001c0c /* Firmware Address Register */
364#define DCI_FIRMWARE_DATA 0x00001c10 /* Firmware Data Register */
365#define DCI_SIGNATURE_DATA_0 0x00001c14 /* Signature Data Register 0 */
366#define DCI_SIGNATURE_DATA_1 0x00001c18 /* Signature Data Register 1 */
367#define DCI_SIGNATURE_DATA_2 0x00001c1c /* Signature Data Register 2 */
368#define DCI_SIGNATURE_DATA_3 0x00001c20 /* Signature Data Register 3 */
369#define DCI_SIGNATURE_DATA_4 0x00001c24 /* Signature Data Register 4 */
370#define DCI_SIGNATURE_DATA_5 0x00001c28 /* Signature Data Register 5 */
371#define DCI_SIGNATURE_DATA_6 0x00001c2c /* Signature Data Register 6 */
372#define DCI_SIGNATURE_DATA_7 0x00001c30 /* Signature Data Register 7 */
373
374
375/****************************************************************************
376 * BCM70012_TGT_TOP_INTR
377 ***************************************************************************/
378/****************************************************************************
379 * INTR :: INTR_STATUS
380 ***************************************************************************/
381/* INTR :: INTR_STATUS :: reserved0 [31:26] */
382#define INTR_INTR_STATUS_reserved0_MASK 0xfc000000
383#define INTR_INTR_STATUS_reserved0_ALIGN 0
384#define INTR_INTR_STATUS_reserved0_BITS 6
385#define INTR_INTR_STATUS_reserved0_SHIFT 26
386
387/* INTR :: INTR_STATUS :: PCIE_TGT_CA_ATTN [25:25] */
388#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_MASK 0x02000000
389#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_ALIGN 0
390#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_BITS 1
391#define INTR_INTR_STATUS_PCIE_TGT_CA_ATTN_SHIFT 25
392
393/* INTR :: INTR_STATUS :: PCIE_TGT_UR_ATTN [24:24] */
394#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_MASK 0x01000000
395#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_ALIGN 0
396#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_BITS 1
397#define INTR_INTR_STATUS_PCIE_TGT_UR_ATTN_SHIFT 24
398
399/* INTR :: INTR_STATUS :: reserved1 [23:14] */
400#define INTR_INTR_STATUS_reserved1_MASK 0x00ffc000
401#define INTR_INTR_STATUS_reserved1_ALIGN 0
402#define INTR_INTR_STATUS_reserved1_BITS 10
403#define INTR_INTR_STATUS_reserved1_SHIFT 14
404
405/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_ERR_INTR [13:13] */
406#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK 0x00002000
407#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_ALIGN 0
408#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_BITS 1
409#define INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_SHIFT 13
410
411/* INTR :: INTR_STATUS :: L1_UV_RX_DMA_DONE_INTR [12:12] */
412#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK 0x00001000
413#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_ALIGN 0
414#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_BITS 1
415#define INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_SHIFT 12
416
417/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_ERR_INTR [11:11] */
418#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK 0x00000800
419#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_ALIGN 0
420#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_BITS 1
421#define INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_SHIFT 11
422
423/* INTR :: INTR_STATUS :: L1_Y_RX_DMA_DONE_INTR [10:10] */
424#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK 0x00000400
425#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_ALIGN 0
426#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_BITS 1
427#define INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_SHIFT 10
428
429/* INTR :: INTR_STATUS :: L1_TX_DMA_ERR_INTR [09:09] */
430#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK 0x00000200
431#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_ALIGN 0
432#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_BITS 1
433#define INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_SHIFT 9
434
435/* INTR :: INTR_STATUS :: L1_TX_DMA_DONE_INTR [08:08] */
436#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK 0x00000100
437#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_ALIGN 0
438#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_BITS 1
439#define INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_SHIFT 8
440
441/* INTR :: INTR_STATUS :: reserved2 [07:06] */
442#define INTR_INTR_STATUS_reserved2_MASK 0x000000c0
443#define INTR_INTR_STATUS_reserved2_ALIGN 0
444#define INTR_INTR_STATUS_reserved2_BITS 2
445#define INTR_INTR_STATUS_reserved2_SHIFT 6
446
447/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_ERR_INTR [05:05] */
448#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK 0x00000020
449#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_ALIGN 0
450#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_BITS 1
451#define INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_SHIFT 5
452
453/* INTR :: INTR_STATUS :: L0_UV_RX_DMA_DONE_INTR [04:04] */
454#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK 0x00000010
455#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_ALIGN 0
456#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_BITS 1
457#define INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_SHIFT 4
458
459/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_ERR_INTR [03:03] */
460#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK 0x00000008
461#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_ALIGN 0
462#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_BITS 1
463#define INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_SHIFT 3
464
465/* INTR :: INTR_STATUS :: L0_Y_RX_DMA_DONE_INTR [02:02] */
466#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK 0x00000004
467#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_ALIGN 0
468#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_BITS 1
469#define INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_SHIFT 2
470
471/* INTR :: INTR_STATUS :: L0_TX_DMA_ERR_INTR [01:01] */
472#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK 0x00000002
473#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_ALIGN 0
474#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_BITS 1
475#define INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_SHIFT 1
476
477/* INTR :: INTR_STATUS :: L0_TX_DMA_DONE_INTR [00:00] */
478#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK 0x00000001
479#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_ALIGN 0
480#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_BITS 1
481#define INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_SHIFT 0
482
483
484/****************************************************************************
485 * MISC1 :: TX_SW_DESC_LIST_CTRL_STS
486 ***************************************************************************/
487/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: reserved0 [31:04] */
488#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_MASK 0xfffffff0
489#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_ALIGN 0
490#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_BITS 28
491#define MISC1_TX_SW_DESC_LIST_CTRL_STS_reserved0_SHIFT 4
492
493/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DMA_DATA_SERV_PTR [03:03] */
494#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_MASK 0x00000008
495#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_ALIGN 0
496#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_BITS 1
497#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DMA_DATA_SERV_PTR_SHIFT 3
498
499/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: DESC_SERV_PTR [02:02] */
500#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_MASK 0x00000004
501#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_ALIGN 0
502#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_BITS 1
503#define MISC1_TX_SW_DESC_LIST_CTRL_STS_DESC_SERV_PTR_SHIFT 2
504
505/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_HALT_ON_ERROR [01:01] */
506#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_MASK 0x00000002
507#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_ALIGN 0
508#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_BITS 1
509#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_HALT_ON_ERROR_SHIFT 1
510
511/* MISC1 :: TX_SW_DESC_LIST_CTRL_STS :: TX_DMA_RUN_STOP [00:00] */
512#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK 0x00000001
513#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_ALIGN 0
514#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_BITS 1
515#define MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_SHIFT 0
516
517
518/****************************************************************************
519 * MISC1 :: TX_DMA_ERROR_STATUS
520 ***************************************************************************/
521/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved0 [31:10] */
522#define MISC1_TX_DMA_ERROR_STATUS_reserved0_MASK 0xfffffc00
523#define MISC1_TX_DMA_ERROR_STATUS_reserved0_ALIGN 0
524#define MISC1_TX_DMA_ERROR_STATUS_reserved0_BITS 22
525#define MISC1_TX_DMA_ERROR_STATUS_reserved0_SHIFT 10
526
527/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DESC_TX_ABORT_ERRORS [09:09] */
528#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
529#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
530#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_BITS 1
531#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
532
533/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved1 [08:08] */
534#define MISC1_TX_DMA_ERROR_STATUS_reserved1_MASK 0x00000100
535#define MISC1_TX_DMA_ERROR_STATUS_reserved1_ALIGN 0
536#define MISC1_TX_DMA_ERROR_STATUS_reserved1_BITS 1
537#define MISC1_TX_DMA_ERROR_STATUS_reserved1_SHIFT 8
538
539/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DESC_TX_ABORT_ERRORS [07:07] */
540#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
541#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
542#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_BITS 1
543#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
544
545/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved2 [06:06] */
546#define MISC1_TX_DMA_ERROR_STATUS_reserved2_MASK 0x00000040
547#define MISC1_TX_DMA_ERROR_STATUS_reserved2_ALIGN 0
548#define MISC1_TX_DMA_ERROR_STATUS_reserved2_BITS 1
549#define MISC1_TX_DMA_ERROR_STATUS_reserved2_SHIFT 6
550
551/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_DMA_DATA_TX_ABORT_ERRORS [05:05] */
552#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000020
553#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
554#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_BITS 1
555#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_SHIFT 5
556
557/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L1_FIFO_FULL_ERRORS [04:04] */
558#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
559#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_ALIGN 0
560#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_BITS 1
561#define MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_SHIFT 4
562
563/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved3 [03:03] */
564#define MISC1_TX_DMA_ERROR_STATUS_reserved3_MASK 0x00000008
565#define MISC1_TX_DMA_ERROR_STATUS_reserved3_ALIGN 0
566#define MISC1_TX_DMA_ERROR_STATUS_reserved3_BITS 1
567#define MISC1_TX_DMA_ERROR_STATUS_reserved3_SHIFT 3
568
569/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_DMA_DATA_TX_ABORT_ERRORS [02:02] */
570#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK 0x00000004
571#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_ALIGN 0
572#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_BITS 1
573#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_SHIFT 2
574
575/* MISC1 :: TX_DMA_ERROR_STATUS :: TX_L0_FIFO_FULL_ERRORS [01:01] */
576#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
577#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_ALIGN 0
578#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_BITS 1
579#define MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_SHIFT 1
580
581/* MISC1 :: TX_DMA_ERROR_STATUS :: reserved4 [00:00] */
582#define MISC1_TX_DMA_ERROR_STATUS_reserved4_MASK 0x00000001
583#define MISC1_TX_DMA_ERROR_STATUS_reserved4_ALIGN 0
584#define MISC1_TX_DMA_ERROR_STATUS_reserved4_BITS 1
585#define MISC1_TX_DMA_ERROR_STATUS_reserved4_SHIFT 0
586
587
588/****************************************************************************
589 * MISC1 :: Y_RX_ERROR_STATUS
590 ***************************************************************************/
591/* MISC1 :: Y_RX_ERROR_STATUS :: reserved0 [31:14] */
592#define MISC1_Y_RX_ERROR_STATUS_reserved0_MASK 0xffffc000
593#define MISC1_Y_RX_ERROR_STATUS_reserved0_ALIGN 0
594#define MISC1_Y_RX_ERROR_STATUS_reserved0_BITS 18
595#define MISC1_Y_RX_ERROR_STATUS_reserved0_SHIFT 14
596
597/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
598#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000
599#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0
600#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1
601#define MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13
602
603/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
604#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000
605#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0
606#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1
607#define MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12
608
609/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
610#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800
611#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0
612#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1
613#define MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11
614
615/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
616#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400
617#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0
618#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1
619#define MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10
620
621/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
622#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
623#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
624#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1
625#define MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
626
627/* MISC1 :: Y_RX_ERROR_STATUS :: reserved1 [08:08] */
628#define MISC1_Y_RX_ERROR_STATUS_reserved1_MASK 0x00000100
629#define MISC1_Y_RX_ERROR_STATUS_reserved1_ALIGN 0
630#define MISC1_Y_RX_ERROR_STATUS_reserved1_BITS 1
631#define MISC1_Y_RX_ERROR_STATUS_reserved1_SHIFT 8
632
633/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
634#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
635#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
636#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1
637#define MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
638
639/* MISC1 :: Y_RX_ERROR_STATUS :: reserved2 [06:05] */
640#define MISC1_Y_RX_ERROR_STATUS_reserved2_MASK 0x00000060
641#define MISC1_Y_RX_ERROR_STATUS_reserved2_ALIGN 0
642#define MISC1_Y_RX_ERROR_STATUS_reserved2_BITS 2
643#define MISC1_Y_RX_ERROR_STATUS_reserved2_SHIFT 5
644
645/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
646#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
647#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0
648#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1
649#define MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4
650
651/* MISC1 :: Y_RX_ERROR_STATUS :: reserved3 [03:02] */
652#define MISC1_Y_RX_ERROR_STATUS_reserved3_MASK 0x0000000c
653#define MISC1_Y_RX_ERROR_STATUS_reserved3_ALIGN 0
654#define MISC1_Y_RX_ERROR_STATUS_reserved3_BITS 2
655#define MISC1_Y_RX_ERROR_STATUS_reserved3_SHIFT 2
656
657/* MISC1 :: Y_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
658#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
659#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0
660#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1
661#define MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1
662
663/* MISC1 :: Y_RX_ERROR_STATUS :: reserved4 [00:00] */
664#define MISC1_Y_RX_ERROR_STATUS_reserved4_MASK 0x00000001
665#define MISC1_Y_RX_ERROR_STATUS_reserved4_ALIGN 0
666#define MISC1_Y_RX_ERROR_STATUS_reserved4_BITS 1
667#define MISC1_Y_RX_ERROR_STATUS_reserved4_SHIFT 0
668
669
670/****************************************************************************
671 * MISC1 :: UV_RX_ERROR_STATUS
672 ***************************************************************************/
673/* MISC1 :: UV_RX_ERROR_STATUS :: reserved0 [31:14] */
674#define MISC1_UV_RX_ERROR_STATUS_reserved0_MASK 0xffffc000
675#define MISC1_UV_RX_ERROR_STATUS_reserved0_ALIGN 0
676#define MISC1_UV_RX_ERROR_STATUS_reserved0_BITS 18
677#define MISC1_UV_RX_ERROR_STATUS_reserved0_SHIFT 14
678
679/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_UNDERRUN_ERROR [13:13] */
680#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK 0x00002000
681#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_ALIGN 0
682#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_BITS 1
683#define MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_SHIFT 13
684
685/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_OVERRUN_ERROR [12:12] */
686#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK 0x00001000
687#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_ALIGN 0
688#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_BITS 1
689#define MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_SHIFT 12
690
691/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_UNDERRUN_ERROR [11:11] */
692#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK 0x00000800
693#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_ALIGN 0
694#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_BITS 1
695#define MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_SHIFT 11
696
697/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_OVERRUN_ERROR [10:10] */
698#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK 0x00000400
699#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_ALIGN 0
700#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_BITS 1
701#define MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_SHIFT 10
702
703/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_DESC_TX_ABORT_ERRORS [09:09] */
704#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK 0x00000200
705#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_ALIGN 0
706#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_BITS 1
707#define MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_SHIFT 9
708
709/* MISC1 :: UV_RX_ERROR_STATUS :: reserved1 [08:08] */
710#define MISC1_UV_RX_ERROR_STATUS_reserved1_MASK 0x00000100
711#define MISC1_UV_RX_ERROR_STATUS_reserved1_ALIGN 0
712#define MISC1_UV_RX_ERROR_STATUS_reserved1_BITS 1
713#define MISC1_UV_RX_ERROR_STATUS_reserved1_SHIFT 8
714
715/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_DESC_TX_ABORT_ERRORS [07:07] */
716#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK 0x00000080
717#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_ALIGN 0
718#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_BITS 1
719#define MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_SHIFT 7
720
721/* MISC1 :: UV_RX_ERROR_STATUS :: reserved2 [06:05] */
722#define MISC1_UV_RX_ERROR_STATUS_reserved2_MASK 0x00000060
723#define MISC1_UV_RX_ERROR_STATUS_reserved2_ALIGN 0
724#define MISC1_UV_RX_ERROR_STATUS_reserved2_BITS 2
725#define MISC1_UV_RX_ERROR_STATUS_reserved2_SHIFT 5
726
727/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L1_FIFO_FULL_ERRORS [04:04] */
728#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK 0x00000010
729#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_ALIGN 0
730#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_BITS 1
731#define MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_SHIFT 4
732
733/* MISC1 :: UV_RX_ERROR_STATUS :: reserved3 [03:02] */
734#define MISC1_UV_RX_ERROR_STATUS_reserved3_MASK 0x0000000c
735#define MISC1_UV_RX_ERROR_STATUS_reserved3_ALIGN 0
736#define MISC1_UV_RX_ERROR_STATUS_reserved3_BITS 2
737#define MISC1_UV_RX_ERROR_STATUS_reserved3_SHIFT 2
738
739/* MISC1 :: UV_RX_ERROR_STATUS :: RX_L0_FIFO_FULL_ERRORS [01:01] */
740#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK 0x00000002
741#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_ALIGN 0
742#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_BITS 1
743#define MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_SHIFT 1
744
745/* MISC1 :: UV_RX_ERROR_STATUS :: reserved4 [00:00] */
746#define MISC1_UV_RX_ERROR_STATUS_reserved4_MASK 0x00000001
747#define MISC1_UV_RX_ERROR_STATUS_reserved4_ALIGN 0
748#define MISC1_UV_RX_ERROR_STATUS_reserved4_BITS 1
749#define MISC1_UV_RX_ERROR_STATUS_reserved4_SHIFT 0
750
751/****************************************************************************
752 * Datatype Definitions.
753 ***************************************************************************/
754#endif /* #ifndef MACFILE_H__ */
755
756/* End of File */
757
diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c
new file mode 100644
index 000000000000..26145a8d0f78
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_cmds.c
@@ -0,0 +1,1058 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_cmds . c
5 *
6 * Description:
7 * BCM70010 Linux driver user command interfaces.
8 *
9 * HISTORY:
10 *
11 **********************************************************************
12 * This file is part of the crystalhd device driver.
13 *
14 * This driver is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * This driver is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
25 **********************************************************************/
26
27#include "crystalhd_cmds.h"
28#include "crystalhd_hw.h"
29
30static struct crystalhd_user *bc_cproc_get_uid(struct crystalhd_cmd *ctx)
31{
32 struct crystalhd_user *user = NULL;
33 int i;
34
35 for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
36 if (!ctx->user[i].in_use) {
37 user = &ctx->user[i];
38 break;
39 }
40 }
41
42 return user;
43}
44
45static int bc_cproc_get_user_count(struct crystalhd_cmd *ctx)
46{
47 int i, count = 0;
48
49 for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
50 if (ctx->user[i].in_use)
51 count++;
52 }
53
54 return count;
55}
56
57static void bc_cproc_mark_pwr_state(struct crystalhd_cmd *ctx)
58{
59 int i;
60
61 for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
62 if (!ctx->user[i].in_use)
63 continue;
64 if (ctx->user[i].mode == DTS_DIAG_MODE ||
65 ctx->user[i].mode == DTS_PLAYBACK_MODE) {
66 ctx->pwr_state_change = 1;
67 break;
68 }
69 }
70}
71
72static BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx,
73 crystalhd_ioctl_data *idata)
74{
75 int rc = 0, i = 0;
76
77 if (!ctx || !idata) {
78 BCMLOG_ERR("Invalid Arg!!\n");
79 return BC_STS_INV_ARG;
80 }
81
82 if (ctx->user[idata->u_id].mode != DTS_MODE_INV) {
83 BCMLOG_ERR("Close the handle first..\n");
84 return BC_STS_ERR_USAGE;
85 }
86 if (idata->udata.u.NotifyMode.Mode == DTS_MONITOR_MODE) {
87 ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
88 return BC_STS_SUCCESS;
89 }
90 if (ctx->state != BC_LINK_INVALID) {
91 BCMLOG_ERR("Link invalid state %d \n", ctx->state);
92 return BC_STS_ERR_USAGE;
93 }
94 /* Check for duplicate playback sessions..*/
95 for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
96 if (ctx->user[i].mode == DTS_DIAG_MODE ||
97 ctx->user[i].mode == DTS_PLAYBACK_MODE) {
98 BCMLOG_ERR("multiple playback sessions are not "
99 "supported..\n");
100 return BC_STS_ERR_USAGE;
101 }
102 }
103 ctx->cin_wait_exit = 0;
104 ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
105 /* Setup mmap pool for uaddr sgl mapping..*/
106 rc = crystalhd_create_dio_pool(ctx->adp, BC_LINK_MAX_SGLS);
107 if (rc)
108 return BC_STS_ERROR;
109
110 /* Setup Hardware DMA rings */
111 return crystalhd_hw_setup_dma_rings(&ctx->hw_ctx);
112}
113
114static BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx,
115 crystalhd_ioctl_data *idata)
116{
117
118 if (!ctx || !idata) {
119 BCMLOG_ERR("Invalid Arg!!\n");
120 return BC_STS_INV_ARG;
121 }
122 idata->udata.u.VerInfo.DriverMajor = crystalhd_kmod_major;
123 idata->udata.u.VerInfo.DriverMinor = crystalhd_kmod_minor;
124 idata->udata.u.VerInfo.DriverRevision = crystalhd_kmod_rev;
125 return BC_STS_SUCCESS;
126}
127
128
129static BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
130{
131 if (!ctx || !idata) {
132 BCMLOG_ERR("Invalid Arg!!\n");
133 return BC_STS_INV_ARG;
134 }
135
136 crystalhd_pci_cfg_rd(ctx->adp, 0, 2,
137 (uint32_t *)&idata->udata.u.hwType.PciVenId);
138 crystalhd_pci_cfg_rd(ctx->adp, 2, 2,
139 (uint32_t *)&idata->udata.u.hwType.PciDevId);
140 crystalhd_pci_cfg_rd(ctx->adp, 8, 1,
141 (uint32_t *)&idata->udata.u.hwType.HwRev);
142
143 return BC_STS_SUCCESS;
144}
145
146static BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx,
147 crystalhd_ioctl_data *idata)
148{
149 if (!ctx || !idata)
150 return BC_STS_INV_ARG;
151 idata->udata.u.regAcc.Value = bc_dec_reg_rd(ctx->adp,
152 idata->udata.u.regAcc.Offset);
153 return BC_STS_SUCCESS;
154}
155
156static BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx,
157 crystalhd_ioctl_data *idata)
158{
159 if (!ctx || !idata)
160 return BC_STS_INV_ARG;
161
162 bc_dec_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
163 idata->udata.u.regAcc.Value);
164
165 return BC_STS_SUCCESS;
166}
167
168static BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx,
169 crystalhd_ioctl_data *idata)
170{
171 if (!ctx || !idata)
172 return BC_STS_INV_ARG;
173
174 idata->udata.u.regAcc.Value = crystalhd_reg_rd(ctx->adp,
175 idata->udata.u.regAcc.Offset);
176 return BC_STS_SUCCESS;
177}
178
179static BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx,
180 crystalhd_ioctl_data *idata)
181{
182 if (!ctx || !idata)
183 return BC_STS_INV_ARG;
184
185 crystalhd_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
186 idata->udata.u.regAcc.Value);
187
188 return BC_STS_SUCCESS;
189}
190
191static BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx,
192 crystalhd_ioctl_data *idata)
193{
194 BC_STATUS sts = BC_STS_SUCCESS;
195
196 if (!ctx || !idata || !idata->add_cdata)
197 return BC_STS_INV_ARG;
198
199 if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
200 BCMLOG_ERR("insufficient buffer\n");
201 return BC_STS_INV_ARG;
202 }
203 sts = crystalhd_mem_rd(ctx->adp, idata->udata.u.devMem.StartOff,
204 idata->udata.u.devMem.NumDwords,
205 (uint32_t *)idata->add_cdata);
206 return sts;
207
208}
209
210static BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx,
211 crystalhd_ioctl_data *idata)
212{
213 BC_STATUS sts = BC_STS_SUCCESS;
214
215 if (!ctx || !idata || !idata->add_cdata)
216 return BC_STS_INV_ARG;
217
218 if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
219 BCMLOG_ERR("insufficient buffer\n");
220 return BC_STS_INV_ARG;
221 }
222
223 sts = crystalhd_mem_wr(ctx->adp, idata->udata.u.devMem.StartOff,
224 idata->udata.u.devMem.NumDwords,
225 (uint32_t *)idata->add_cdata);
226 return sts;
227}
228
229static BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx,
230 crystalhd_ioctl_data *idata)
231{
232 uint32_t ix, cnt, off, len;
233 BC_STATUS sts = BC_STS_SUCCESS;
234 uint32_t *temp;
235
236 if (!ctx || !idata)
237 return BC_STS_INV_ARG;
238
239 temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
240 off = idata->udata.u.pciCfg.Offset;
241 len = idata->udata.u.pciCfg.Size;
242
243 if (len <= 4)
244 return crystalhd_pci_cfg_rd(ctx->adp, off, len, temp);
245
246 /* Truncate to dword alignment..*/
247 len = 4;
248 cnt = idata->udata.u.pciCfg.Size / len;
249 for (ix = 0; ix < cnt; ix++) {
250 sts = crystalhd_pci_cfg_rd(ctx->adp, off, len, &temp[ix]);
251 if (sts != BC_STS_SUCCESS) {
252 BCMLOG_ERR("config read : %d\n", sts);
253 return sts;
254 }
255 off += len;
256 }
257
258 return sts;
259}
260
261static BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx,
262 crystalhd_ioctl_data *idata)
263{
264 uint32_t ix, cnt, off, len;
265 BC_STATUS sts = BC_STS_SUCCESS;
266 uint32_t *temp;
267
268 if (!ctx || !idata)
269 return BC_STS_INV_ARG;
270
271 temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
272 off = idata->udata.u.pciCfg.Offset;
273 len = idata->udata.u.pciCfg.Size;
274
275 if (len <= 4)
276 return crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[0]);
277
278 /* Truncate to dword alignment..*/
279 len = 4;
280 cnt = idata->udata.u.pciCfg.Size / len;
281 for (ix = 0; ix < cnt; ix++) {
282 sts = crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[ix]);
283 if (sts != BC_STS_SUCCESS) {
284 BCMLOG_ERR("config write : %d\n", sts);
285 return sts;
286 }
287 off += len;
288 }
289
290 return sts;
291}
292
293static BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx,
294 crystalhd_ioctl_data *idata)
295{
296 BC_STATUS sts = BC_STS_SUCCESS;
297
298 if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) {
299 BCMLOG_ERR("Invalid Arg!!\n");
300 return BC_STS_INV_ARG;
301 }
302
303 if (ctx->state != BC_LINK_INVALID) {
304 BCMLOG_ERR("Link invalid state %d \n", ctx->state);
305 return BC_STS_ERR_USAGE;
306 }
307
308 sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata,
309 idata->add_cdata_sz);
310
311 if (sts != BC_STS_SUCCESS) {
312 BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts);
313 } else
314 ctx->state |= BC_LINK_INIT;
315
316 return sts;
317}
318
319/*
320 * We use the FW_CMD interface to sync up playback state with application
321 * and firmware. This function will perform the required pre and post
322 * processing of the Firmware commands.
323 *
324 * Pause -
325 * Disable capture after decoder pause.
326 * Resume -
327 * First enable capture and issue decoder resume command.
328 * Flush -
329 * Abort pending input transfers and issue decoder flush command.
330 *
331 */
332static BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
333{
334 BC_STATUS sts;
335 uint32_t *cmd;
336
337 if (!(ctx->state & BC_LINK_INIT)) {
338 BCMLOG_ERR("Link invalid state %d \n", ctx->state);
339 return BC_STS_ERR_USAGE;
340 }
341
342 cmd = idata->udata.u.fwCmd.cmd;
343
344 /* Pre-Process */
345 if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
346 if (!cmd[3]) {
347 ctx->state &= ~BC_LINK_PAUSED;
348 crystalhd_hw_unpause(&ctx->hw_ctx);
349 }
350 } else if (cmd[0] == eCMD_C011_DEC_CHAN_FLUSH) {
351 BCMLOG(BCMLOG_INFO, "Flush issued\n");
352 if (cmd[3])
353 ctx->cin_wait_exit = 1;
354 }
355
356 sts = crystalhd_do_fw_cmd(&ctx->hw_ctx, &idata->udata.u.fwCmd);
357
358 if (sts != BC_STS_SUCCESS) {
359 BCMLOG(BCMLOG_INFO, "fw cmd %x failed\n", cmd[0]);
360 return sts;
361 }
362
363 /* Post-Process */
364 if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
365 if (cmd[3]) {
366 ctx->state |= BC_LINK_PAUSED;
367 crystalhd_hw_pause(&ctx->hw_ctx);
368 }
369 }
370
371 return sts;
372}
373
374static void bc_proc_in_completion(crystalhd_dio_req *dio_hnd,
375 wait_queue_head_t *event, BC_STATUS sts)
376{
377 if (!dio_hnd || !event) {
378 BCMLOG_ERR("Invalid Arg!!\n");
379 return;
380 }
381 if (sts == BC_STS_IO_USER_ABORT)
382 return;
383
384 dio_hnd->uinfo.comp_sts = sts;
385 dio_hnd->uinfo.ev_sts = 1;
386 crystalhd_set_event(event);
387}
388
389static BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx)
390{
391 wait_queue_head_t sleep_ev;
392 int rc = 0;
393
394 if (ctx->state & BC_LINK_SUSPEND)
395 return BC_STS_IO_USER_ABORT;
396
397 if (ctx->cin_wait_exit) {
398 ctx->cin_wait_exit = 0;
399 return BC_STS_CMD_CANCELLED;
400 }
401 crystalhd_create_event(&sleep_ev);
402 crystalhd_wait_on_event(&sleep_ev, 0, 100, rc, 0);
403 if (rc == -EINTR)
404 return BC_STS_IO_USER_ABORT;
405
406 return BC_STS_SUCCESS;
407}
408
409static BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx,
410 crystalhd_ioctl_data *idata,
411 crystalhd_dio_req *dio)
412{
413 uint32_t tx_listid = 0;
414 BC_STATUS sts = BC_STS_SUCCESS;
415 wait_queue_head_t event;
416 int rc = 0;
417
418 if (!ctx || !idata || !dio) {
419 BCMLOG_ERR("Invalid Arg!!\n");
420 return BC_STS_INV_ARG;
421 }
422
423 crystalhd_create_event(&event);
424
425 ctx->tx_list_id = 0;
426 /* msleep_interruptible(2000); */
427 sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio, bc_proc_in_completion,
428 &event, &tx_listid,
429 idata->udata.u.ProcInput.Encrypted);
430
431 while (sts == BC_STS_BUSY) {
432 sts = bc_cproc_codein_sleep(ctx);
433 if (sts != BC_STS_SUCCESS)
434 break;
435 sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio,
436 bc_proc_in_completion,
437 &event, &tx_listid,
438 idata->udata.u.ProcInput.Encrypted);
439 }
440 if (sts != BC_STS_SUCCESS) {
441 BCMLOG(BCMLOG_DBG, "_hw_txdma returning sts:%d\n", sts);
442 return sts;
443 }
444 if (ctx->cin_wait_exit)
445 ctx->cin_wait_exit = 0;
446
447 ctx->tx_list_id = tx_listid;
448
449 /* _post() succeeded.. wait for the completion. */
450 crystalhd_wait_on_event(&event, (dio->uinfo.ev_sts), 3000, rc, 0);
451 ctx->tx_list_id = 0;
452 if (!rc) {
453 return dio->uinfo.comp_sts;
454 } else if (rc == -EBUSY) {
455 BCMLOG(BCMLOG_DBG, "_tx_post() T/O \n");
456 sts = BC_STS_TIMEOUT;
457 } else if (rc == -EINTR) {
458 BCMLOG(BCMLOG_DBG, "Tx Wait Signal int.\n");
459 sts = BC_STS_IO_USER_ABORT;
460 } else {
461 sts = BC_STS_IO_ERROR;
462 }
463
464 /* We are cancelling the IO from the same context as the _post().
465 * so no need to wait on the event again.. the return itself
466 * ensures the release of our resources.
467 */
468 crystalhd_hw_cancel_tx(&ctx->hw_ctx, tx_listid);
469
470 return sts;
471}
472
473/* Helper function to check on user buffers */
474static BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz,
475 uint32_t uv_off, bool en_422)
476{
477 if (!ubuff || !ub_sz) {
478 BCMLOG_ERR("%s->Invalid Arg %p %x\n",
479 ((pin) ? "TX" : "RX"), ubuff, ub_sz);
480 return BC_STS_INV_ARG;
481 }
482
483 /* Check for alignment */
484 if (((uintptr_t)ubuff) & 0x03) {
485 BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p \n",
486 ((pin) ? "TX" : "RX"), ubuff);
487 return BC_STS_NOT_IMPL;
488 }
489 if (pin)
490 return BC_STS_SUCCESS;
491
492 if (!en_422 && !uv_off) {
493 BCMLOG_ERR("Need UV offset for 420 mode.\n");
494 return BC_STS_INV_ARG;
495 }
496
497 if (en_422 && uv_off) {
498 BCMLOG_ERR("UV offset in 422 mode ??\n");
499 return BC_STS_INV_ARG;
500 }
501
502 return BC_STS_SUCCESS;
503}
504
505static BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
506{
507 void *ubuff;
508 uint32_t ub_sz;
509 crystalhd_dio_req *dio_hnd = NULL;
510 BC_STATUS sts = BC_STS_SUCCESS;
511
512 if (!ctx || !idata) {
513 BCMLOG_ERR("Invalid Arg!!\n");
514 return BC_STS_INV_ARG;
515 }
516
517 ubuff = idata->udata.u.ProcInput.pDmaBuff;
518 ub_sz = idata->udata.u.ProcInput.BuffSz;
519
520 sts = bc_cproc_check_inbuffs(1, ubuff, ub_sz, 0, 0);
521 if (sts != BC_STS_SUCCESS)
522 return sts;
523
524 sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, 0, 0, 1, &dio_hnd);
525 if (sts != BC_STS_SUCCESS) {
526 BCMLOG_ERR("dio map - %d \n", sts);
527 return sts;
528 }
529
530 if (!dio_hnd)
531 return BC_STS_ERROR;
532
533 sts = bc_cproc_hw_txdma(ctx, idata, dio_hnd);
534
535 crystalhd_unmap_dio(ctx->adp, dio_hnd);
536
537 return sts;
538}
539
540static BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx,
541 crystalhd_ioctl_data *idata)
542{
543 void *ubuff;
544 uint32_t ub_sz, uv_off;
545 bool en_422;
546 crystalhd_dio_req *dio_hnd = NULL;
547 BC_STATUS sts = BC_STS_SUCCESS;
548
549 if (!ctx || !idata) {
550 BCMLOG_ERR("Invalid Arg!!\n");
551 return BC_STS_INV_ARG;
552 }
553
554 ubuff = idata->udata.u.RxBuffs.YuvBuff;
555 ub_sz = idata->udata.u.RxBuffs.YuvBuffSz;
556 uv_off = idata->udata.u.RxBuffs.UVbuffOffset;
557 en_422 = idata->udata.u.RxBuffs.b422Mode;
558
559 sts = bc_cproc_check_inbuffs(0, ubuff, ub_sz, uv_off, en_422);
560 if (sts != BC_STS_SUCCESS)
561 return sts;
562
563 sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, uv_off,
564 en_422, 0, &dio_hnd);
565 if (sts != BC_STS_SUCCESS) {
566 BCMLOG_ERR("dio map - %d \n", sts);
567 return sts;
568 }
569
570 if (!dio_hnd)
571 return BC_STS_ERROR;
572
573 sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd, (ctx->state == BC_LINK_READY));
574 if ((sts != BC_STS_SUCCESS) && (sts != BC_STS_BUSY)) {
575 crystalhd_unmap_dio(ctx->adp, dio_hnd);
576 return sts;
577 }
578
579 return BC_STS_SUCCESS;
580}
581
582static BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx,
583 crystalhd_dio_req *dio)
584{
585 BC_STATUS sts = BC_STS_SUCCESS;
586
587 sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio, 0);
588 if (sts != BC_STS_SUCCESS)
589 return sts;
590
591 ctx->state |= BC_LINK_FMT_CHG;
592 if (ctx->state == BC_LINK_READY)
593 sts = crystalhd_hw_start_capture(&ctx->hw_ctx);
594
595 return sts;
596}
597
598static BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx,
599 crystalhd_ioctl_data *idata)
600{
601 crystalhd_dio_req *dio = NULL;
602 BC_STATUS sts = BC_STS_SUCCESS;
603 BC_DEC_OUT_BUFF *frame;
604
605 if (!ctx || !idata) {
606 BCMLOG_ERR("Invalid Arg!!\n");
607 return BC_STS_INV_ARG;
608 }
609
610 if (!(ctx->state & BC_LINK_CAP_EN)) {
611 BCMLOG(BCMLOG_DBG, "Capture not enabled..%x\n", ctx->state);
612 return BC_STS_ERR_USAGE;
613 }
614
615 frame = &idata->udata.u.DecOutData;
616
617 sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
618 if (sts != BC_STS_SUCCESS)
619 return (ctx->state & BC_LINK_SUSPEND) ? BC_STS_IO_USER_ABORT : sts;
620
621 frame->Flags = dio->uinfo.comp_flags;
622
623 if (frame->Flags & COMP_FLAG_FMT_CHANGE)
624 return bc_cproc_fmt_change(ctx, dio);
625
626 frame->OutPutBuffs.YuvBuff = dio->uinfo.xfr_buff;
627 frame->OutPutBuffs.YuvBuffSz = dio->uinfo.xfr_len;
628 frame->OutPutBuffs.UVbuffOffset = dio->uinfo.uv_offset;
629 frame->OutPutBuffs.b422Mode = dio->uinfo.b422mode;
630
631 frame->OutPutBuffs.YBuffDoneSz = dio->uinfo.y_done_sz;
632 frame->OutPutBuffs.UVBuffDoneSz = dio->uinfo.uv_done_sz;
633
634 crystalhd_unmap_dio(ctx->adp, dio);
635
636 return BC_STS_SUCCESS;
637}
638
639static BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx,
640 crystalhd_ioctl_data *idata)
641{
642 ctx->state |= BC_LINK_CAP_EN;
643 if (ctx->state == BC_LINK_READY)
644 return crystalhd_hw_start_capture(&ctx->hw_ctx);
645
646 return BC_STS_SUCCESS;
647}
648
649static BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx,
650 crystalhd_ioctl_data *idata)
651{
652 crystalhd_dio_req *dio = NULL;
653 BC_STATUS sts = BC_STS_SUCCESS;
654 BC_DEC_OUT_BUFF *frame;
655 uint32_t count;
656
657 if (!ctx || !idata) {
658 BCMLOG_ERR("Invalid Arg!!\n");
659 return BC_STS_INV_ARG;
660 }
661
662 if (!(ctx->state & BC_LINK_CAP_EN))
663 return BC_STS_ERR_USAGE;
664
665 /* We should ack flush even when we are in paused/suspend state */
666 if (!(ctx->state & BC_LINK_READY))
667 return crystalhd_hw_stop_capture(&ctx->hw_ctx);
668
669 ctx->state &= ~(BC_LINK_CAP_EN|BC_LINK_FMT_CHG);
670
671 frame = &idata->udata.u.DecOutData;
672 for (count = 0; count < BC_RX_LIST_CNT; count++) {
673
674 sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
675 if (sts != BC_STS_SUCCESS)
676 break;
677
678 crystalhd_unmap_dio(ctx->adp, dio);
679 }
680
681 return crystalhd_hw_stop_capture(&ctx->hw_ctx);
682}
683
684static BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx,
685 crystalhd_ioctl_data *idata)
686{
687 BC_DTS_STATS *stats;
688 struct crystalhd_hw_stats hw_stats;
689
690 if (!ctx || !idata) {
691 BCMLOG_ERR("Invalid Arg!!\n");
692 return BC_STS_INV_ARG;
693 }
694
695 crystalhd_hw_stats(&ctx->hw_ctx, &hw_stats);
696
697 stats = &idata->udata.u.drvStat;
698 stats->drvRLL = hw_stats.rdyq_count;
699 stats->drvFLL = hw_stats.freeq_count;
700 stats->DrvTotalFrmDropped = hw_stats.rx_errors;
701 stats->DrvTotalHWErrs = hw_stats.rx_errors + hw_stats.tx_errors;
702 stats->intCount = hw_stats.num_interrupts;
703 stats->DrvIgnIntrCnt = hw_stats.num_interrupts -
704 hw_stats.dev_interrupts;
705 stats->TxFifoBsyCnt = hw_stats.cin_busy;
706 stats->pauseCount = hw_stats.pause_cnt;
707
708 if (ctx->pwr_state_change)
709 stats->pwr_state_change = 1;
710 if (ctx->state & BC_LINK_PAUSED)
711 stats->DrvPauseTime = 1;
712
713 return BC_STS_SUCCESS;
714}
715
716static BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx,
717 crystalhd_ioctl_data *idata)
718{
719 crystalhd_hw_stats(&ctx->hw_ctx, NULL);
720
721 return BC_STS_SUCCESS;
722}
723
724static BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx,
725 crystalhd_ioctl_data *idata)
726{
727 BC_CLOCK *clock;
728 uint32_t oldClk;
729 BC_STATUS sts = BC_STS_SUCCESS;
730
731 if (!ctx || !idata) {
732 BCMLOG_ERR("Invalid Arg!!\n");
733 return BC_STS_INV_ARG;
734 }
735
736 clock = &idata->udata.u.clockValue;
737 oldClk = ctx->hw_ctx.core_clock_mhz;
738 ctx->hw_ctx.core_clock_mhz = clock->clk;
739
740 if (ctx->state & BC_LINK_READY) {
741 sts = crystalhd_hw_set_core_clock(&ctx->hw_ctx);
742 if (sts == BC_STS_CLK_NOCHG)
743 ctx->hw_ctx.core_clock_mhz = oldClk;
744 }
745
746 clock->clk = ctx->hw_ctx.core_clock_mhz;
747
748 return sts;
749}
750
751/*=============== Cmd Proc Table.. ======================================*/
752static const crystalhd_cmd_tbl_t g_crystalhd_cproc_tbl[] = {
753 { BCM_IOC_GET_VERSION, bc_cproc_get_version, 0},
754 { BCM_IOC_GET_HWTYPE, bc_cproc_get_hwtype, 0},
755 { BCM_IOC_REG_RD, bc_cproc_reg_rd, 0},
756 { BCM_IOC_REG_WR, bc_cproc_reg_wr, 0},
757 { BCM_IOC_FPGA_RD, bc_cproc_link_reg_rd, 0},
758 { BCM_IOC_FPGA_WR, bc_cproc_link_reg_wr, 0},
759 { BCM_IOC_MEM_RD, bc_cproc_mem_rd, 0},
760 { BCM_IOC_MEM_WR, bc_cproc_mem_wr, 0},
761 { BCM_IOC_RD_PCI_CFG, bc_cproc_cfg_rd, 0},
762 { BCM_IOC_WR_PCI_CFG, bc_cproc_cfg_wr, 1},
763 { BCM_IOC_FW_DOWNLOAD, bc_cproc_download_fw, 1},
764 { BCM_IOC_FW_CMD, bc_cproc_do_fw_cmd, 1},
765 { BCM_IOC_PROC_INPUT, bc_cproc_proc_input, 1},
766 { BCM_IOC_ADD_RXBUFFS, bc_cproc_add_cap_buff, 1},
767 { BCM_IOC_FETCH_RXBUFF, bc_cproc_fetch_frame, 1},
768 { BCM_IOC_START_RX_CAP, bc_cproc_start_capture, 1},
769 { BCM_IOC_FLUSH_RX_CAP, bc_cproc_flush_cap_buffs, 1},
770 { BCM_IOC_GET_DRV_STAT, bc_cproc_get_stats, 0},
771 { BCM_IOC_RST_DRV_STAT, bc_cproc_reset_stats, 0},
772 { BCM_IOC_NOTIFY_MODE, bc_cproc_notify_mode, 0},
773 { BCM_IOC_CHG_CLK, bc_cproc_chg_clk, 0},
774 { BCM_IOC_END, NULL},
775};
776
777/*=============== Cmd Proc Functions.. ===================================*/
778
779/**
780 * crystalhd_suspend - Power management suspend request.
781 * @ctx: Command layer context.
782 * @idata: Iodata - required for internal use.
783 *
784 * Return:
785 * status
786 *
787 * 1. Set the state to Suspend.
788 * 2. Flush the Rx Buffers it will unmap all the buffers and
789 * stop the RxDMA engine.
790 * 3. Cancel The TX Io and Stop Dma Engine.
791 * 4. Put the DDR in to deep sleep.
792 * 5. Stop the hardware putting it in to Reset State.
793 *
794 * Current gstreamer frame work does not provide any power management
795 * related notification to user mode decoder plug-in. As a work-around
796 * we pass on the power mangement notification to our plug-in by completing
797 * all outstanding requests with BC_STS_IO_USER_ABORT return code.
798 */
799BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata)
800{
801 BC_STATUS sts = BC_STS_SUCCESS;
802
803 if (!ctx || !idata) {
804 BCMLOG_ERR("Invalid Parameters\n");
805 return BC_STS_ERROR;
806 }
807
808 if (ctx->state & BC_LINK_SUSPEND)
809 return BC_STS_SUCCESS;
810
811 if (ctx->state == BC_LINK_INVALID) {
812 BCMLOG(BCMLOG_DBG, "Nothing To Do Suspend Success\n");
813 return BC_STS_SUCCESS;
814 }
815
816 ctx->state |= BC_LINK_SUSPEND;
817
818 bc_cproc_mark_pwr_state(ctx);
819
820 if (ctx->state & BC_LINK_CAP_EN) {
821 sts = bc_cproc_flush_cap_buffs(ctx, idata);
822 if (sts != BC_STS_SUCCESS)
823 return sts;
824 }
825
826 if (ctx->tx_list_id) {
827 sts = crystalhd_hw_cancel_tx(&ctx->hw_ctx, ctx->tx_list_id);
828 if (sts != BC_STS_SUCCESS)
829 return sts;
830 }
831
832 sts = crystalhd_hw_suspend(&ctx->hw_ctx);
833 if (sts != BC_STS_SUCCESS)
834 return sts;
835
836 BCMLOG(BCMLOG_DBG, "BCM70012 suspend success\n");
837
838 return BC_STS_SUCCESS;
839}
840
841/**
842 * crystalhd_resume - Resume frame capture.
843 * @ctx: Command layer contextx.
844 *
845 * Return:
846 * status
847 *
848 *
849 * Resume frame capture.
850 *
851 * PM_Resume can't resume the playback state back to pre-suspend state
852 * because we don't keep video clip related information within driver.
853 * To get back to the pre-suspend state App will re-open the device and
854 * start a new playback session from the pre-suspend clip position.
855 *
856 */
857BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx)
858{
859 BCMLOG(BCMLOG_DBG, "crystalhd_resume Success %x\n", ctx->state);
860
861 bc_cproc_mark_pwr_state(ctx);
862
863 return BC_STS_SUCCESS;
864}
865
866/**
867 * crystalhd_user_open - Create application handle.
868 * @ctx: Command layer contextx.
869 * @user_ctx: User ID context.
870 *
871 * Return:
872 * status
873 *
874 * Creates an application specific UID and allocates
875 * application specific resources. HW layer initialization
876 * is done for the first open request.
877 */
878BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
879 struct crystalhd_user **user_ctx)
880{
881 struct crystalhd_user *uc;
882
883 if (!ctx || !user_ctx) {
884 BCMLOG_ERR("Invalid arg..\n");
885 return BC_STS_INV_ARG;
886 }
887
888 uc = bc_cproc_get_uid(ctx);
889 if (!uc) {
890 BCMLOG(BCMLOG_INFO, "No free user context...\n");
891 return BC_STS_BUSY;
892 }
893
894 BCMLOG(BCMLOG_INFO, "Opening new user[%x] handle\n", uc->uid);
895
896 crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
897
898 uc->in_use = 1;
899
900 *user_ctx = uc;
901
902 return BC_STS_SUCCESS;
903}
904
905/**
906 * crystalhd_user_close - Close application handle.
907 * @ctx: Command layer contextx.
908 * @uc: User ID context.
909 *
910 * Return:
911 * status
912 *
913 * Closer aplication handle and release app specific
914 * resources.
915 */
916BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc)
917{
918 uint32_t mode = uc->mode;
919
920 ctx->user[uc->uid].mode = DTS_MODE_INV;
921 ctx->user[uc->uid].in_use = 0;
922 ctx->cin_wait_exit = 1;
923 ctx->pwr_state_change = 0;
924
925 BCMLOG(BCMLOG_INFO, "Closing user[%x] handle\n", uc->uid);
926
927 if ((mode == DTS_DIAG_MODE) || (mode == DTS_PLAYBACK_MODE)) {
928 crystalhd_hw_free_dma_rings(&ctx->hw_ctx);
929 crystalhd_destroy_dio_pool(ctx->adp);
930 } else if (bc_cproc_get_user_count(ctx)) {
931 return BC_STS_SUCCESS;
932 }
933
934 crystalhd_hw_close(&ctx->hw_ctx);
935
936 ctx->state = BC_LINK_INVALID;
937
938 return BC_STS_SUCCESS;
939}
940
941/**
942 * crystalhd_setup_cmd_context - Setup Command layer resources.
943 * @ctx: Command layer contextx.
944 * @adp: Adapter context
945 *
946 * Return:
947 * status
948 *
949 * Called at the time of driver load.
950 */
951BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
952 struct crystalhd_adp *adp)
953{
954 int i = 0;
955
956 if (!ctx || !adp) {
957 BCMLOG_ERR("Invalid arg!!\n");
958 return BC_STS_INV_ARG;
959 }
960
961 if (ctx->adp)
962 BCMLOG(BCMLOG_DBG, "Resetting Cmd context delete missing..\n");
963
964 ctx->adp = adp;
965 for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
966 ctx->user[i].uid = i;
967 ctx->user[i].in_use = 0;
968 ctx->user[i].mode = DTS_MODE_INV;
969 }
970
971 /*Open and Close the Hardware to put it in to sleep state*/
972 crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
973 crystalhd_hw_close(&ctx->hw_ctx);
974 return BC_STS_SUCCESS;
975}
976
977/**
978 * crystalhd_delete_cmd_context - Release Command layer resources.
979 * @ctx: Command layer contextx.
980 *
981 * Return:
982 * status
983 *
984 * Called at the time of driver un-load.
985 */
986BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
987{
988 BCMLOG(BCMLOG_DBG, "Deleting Command context..\n");
989
990 ctx->adp = NULL;
991
992 return BC_STS_SUCCESS;
993}
994
995/**
996 * crystalhd_get_cmd_proc - Cproc table lookup.
997 * @ctx: Command layer contextx.
998 * @cmd: IOCTL command code.
999 * @uc: User ID context.
1000 *
1001 * Return:
1002 * command proc function pointer
1003 *
1004 * This function checks the process context, application's
1005 * mode of operation and returns the function pointer
1006 * from the cproc table.
1007 */
1008crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
1009 struct crystalhd_user *uc)
1010{
1011 crystalhd_cmd_proc cproc = NULL;
1012 unsigned int i, tbl_sz;
1013
1014 if (!ctx) {
1015 BCMLOG_ERR("Invalid arg.. Cmd[%d]\n", cmd);
1016 return NULL;
1017 }
1018
1019 if ((cmd != BCM_IOC_GET_DRV_STAT) && (ctx->state & BC_LINK_SUSPEND)) {
1020 BCMLOG_ERR("Invalid State [suspend Set].. Cmd[%d]\n", cmd);
1021 return NULL;
1022 }
1023
1024 tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(crystalhd_cmd_tbl_t);
1025 for (i = 0; i < tbl_sz; i++) {
1026 if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) {
1027 if ((uc->mode == DTS_MONITOR_MODE) &&
1028 (g_crystalhd_cproc_tbl[i].block_mon)) {
1029 BCMLOG(BCMLOG_INFO, "Blocking cmd %d \n", cmd);
1030 break;
1031 }
1032 cproc = g_crystalhd_cproc_tbl[i].cmd_proc;
1033 break;
1034 }
1035 }
1036
1037 return cproc;
1038}
1039
1040/**
1041 * crystalhd_cmd_interrupt - ISR entry point
1042 * @ctx: Command layer contextx.
1043 *
1044 * Return:
1045 * TRUE: If interrupt from bcm70012 device.
1046 *
1047 *
1048 * ISR entry point from OS layer.
1049 */
1050bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx)
1051{
1052 if (!ctx) {
1053 BCMLOG_ERR("Invalid arg..\n");
1054 return 0;
1055 }
1056
1057 return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx);
1058}
diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h
new file mode 100644
index 000000000000..6b290aed8e0b
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_cmds.h
@@ -0,0 +1,88 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_cmds . h
5 *
6 * Description:
7 * BCM70010 Linux driver user command interfaces.
8 *
9 * HISTORY:
10 *
11 **********************************************************************
12 * This file is part of the crystalhd device driver.
13 *
14 * This driver is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * This driver is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
25 **********************************************************************/
26
27#ifndef _CRYSTALHD_CMDS_H_
28#define _CRYSTALHD_CMDS_H_
29
30/*
31 * NOTE:: This is the main interface file between the Linux layer
32 * and the harware layer. This file will use the definitions
33 * from _dts_glob and dts_defs etc.. which are defined for
34 * windows.
35 */
36#include "crystalhd_misc.h"
37#include "crystalhd_hw.h"
38
39enum _crystalhd_state{
40 BC_LINK_INVALID = 0x00,
41 BC_LINK_INIT = 0x01,
42 BC_LINK_CAP_EN = 0x02,
43 BC_LINK_FMT_CHG = 0x04,
44 BC_LINK_SUSPEND = 0x10,
45 BC_LINK_PAUSED = 0x20,
46 BC_LINK_READY = (BC_LINK_INIT | BC_LINK_CAP_EN | BC_LINK_FMT_CHG),
47};
48
49struct crystalhd_user {
50 uint32_t uid;
51 uint32_t in_use;
52 uint32_t mode;
53};
54
55#define DTS_MODE_INV (-1)
56
57struct crystalhd_cmd {
58 uint32_t state;
59 struct crystalhd_adp *adp;
60 struct crystalhd_user user[BC_LINK_MAX_OPENS];
61
62 spinlock_t ctx_lock;
63 uint32_t tx_list_id;
64 uint32_t cin_wait_exit;
65 uint32_t pwr_state_change;
66 struct crystalhd_hw hw_ctx;
67};
68
69typedef BC_STATUS (*crystalhd_cmd_proc)(struct crystalhd_cmd *, crystalhd_ioctl_data *);
70
71typedef struct _crystalhd_cmd_tbl {
72 uint32_t cmd_id;
73 const crystalhd_cmd_proc cmd_proc;
74 uint32_t block_mon;
75} crystalhd_cmd_tbl_t;
76
77
78BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, crystalhd_ioctl_data *idata);
79BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx);
80crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
81 struct crystalhd_user *uc);
82BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx, struct crystalhd_user **user_ctx);
83BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc);
84BC_STATUS crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx, struct crystalhd_adp *adp);
85BC_STATUS crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx);
86bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx);
87
88#endif
diff --git a/drivers/staging/crystalhd/crystalhd_fw_if.h b/drivers/staging/crystalhd/crystalhd_fw_if.h
new file mode 100644
index 000000000000..261cd19a0ee7
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_fw_if.h
@@ -0,0 +1,369 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_fw_if . h
5 *
6 * Description:
7 * BCM70012 Firmware interface definitions.
8 *
9 * HISTORY:
10 *
11 **********************************************************************
12 * This file is part of the crystalhd device driver.
13 *
14 * This driver is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * This driver is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
25 **********************************************************************/
26
27#ifndef _CRYSTALHD_FW_IF_H_
28#define _CRYSTALHD_FW_IF_H_
29
30/* TBD: Pull in only required defs into this file.. */
31
32
33
34/* User Data Header */
35typedef struct user_data {
36 struct user_data *next;
37 uint32_t type;
38 uint32_t size;
39} UD_HDR;
40
41
42
43/*------------------------------------------------------*
44 * MPEG Extension to the PPB *
45 *------------------------------------------------------*/
46typedef struct {
47 uint32_t to_be_defined;
48 uint32_t valid;
49
50 /* Always valid, defaults to picture size if no
51 sequence display extension in the stream. */
52 uint32_t display_horizontal_size;
53 uint32_t display_vertical_size;
54
55 /* MPEG_VALID_PANSCAN
56 Offsets are a copy values from the MPEG stream. */
57 uint32_t offset_count;
58 int32_t horizontal_offset[3];
59 int32_t vertical_offset[3];
60
61 /* MPEG_VALID_USERDATA
62 User data is in the form of a linked list. */
63 int32_t userDataSize;
64 UD_HDR *userData;
65
66} PPB_MPEG;
67
68
69/*------------------------------------------------------*
70 * VC1 Extension to the PPB *
71 *------------------------------------------------------*/
72typedef struct {
73 uint32_t to_be_defined;
74 uint32_t valid;
75
76 /* Always valid, defaults to picture size if no
77 sequence display extension in the stream. */
78 uint32_t display_horizontal_size;
79 uint32_t display_vertical_size;
80
81 /* VC1 pan scan windows */
82 uint32_t num_panscan_windows;
83 int32_t ps_horiz_offset[4];
84 int32_t ps_vert_offset[4];
85 int32_t ps_width[4];
86 int32_t ps_height[4];
87
88 /* VC1_VALID_USERDATA
89 User data is in the form of a linked list. */
90 int32_t userDataSize;
91 UD_HDR *userData;
92
93} PPB_VC1;
94
95/*------------------------------------------------------*
96 * H.264 Extension to the PPB *
97 *------------------------------------------------------*/
98
99/**
100 * @brief Film grain SEI message.
101 *
102 * Content of the film grain SEI message.
103 */
104
105/* maximum number of model-values as for Thomson spec(standard says 5) */
106#define MAX_FGT_MODEL_VALUE (3)
107
108/* maximum number of intervals(as many as 256 intervals?) */
109#define MAX_FGT_VALUE_INTERVAL (256)
110
111typedef struct FGT_SEI {
112 struct FGT_SEI *next;
113 unsigned char model_values[3][MAX_FGT_VALUE_INTERVAL][MAX_FGT_MODEL_VALUE];
114 unsigned char upper_bound[3][MAX_FGT_VALUE_INTERVAL];
115 unsigned char lower_bound[3][MAX_FGT_VALUE_INTERVAL];
116
117 unsigned char cancel_flag; /* Cancel flag: 1 no film grain. */
118 unsigned char model_id; /* Model id. */
119
120 /* +unused SE based on Thomson spec */
121 unsigned char color_desc_flag; /* Separate color descrition flag. */
122 unsigned char bit_depth_luma; /* Bit depth luma minus 8. */
123 unsigned char bit_depth_chroma; /* Bit depth chroma minus 8. */
124 unsigned char full_range_flag; /* Full range flag. */
125 unsigned char color_primaries; /* Color primaries. */
126 unsigned char transfer_charact; /* Transfer characteristics. */
127 unsigned char matrix_coeff; /*< Matrix coefficients. */
128 /* -unused SE based on Thomson spec */
129
130 unsigned char blending_mode_id; /* Blending mode. */
131 unsigned char log2_scale_factor; /* Log2 scale factor (2-7). */
132 unsigned char comp_flag[3]; /* Components [0,2] parameters present flag. */
133 unsigned char num_intervals_minus1[3]; /* Number of intensity level intervals. */
134 unsigned char num_model_values[3]; /* Number of model values. */
135 uint16_t repetition_period; /* Repetition period (0-16384) */
136
137} FGT_SEI;
138
139typedef struct {
140 /* 'valid' specifies which fields (or sets of
141 * fields) below are valid. If the corresponding
142 * bit in 'valid' is NOT set then that field(s)
143 * is (are) not initialized. */
144 uint32_t valid;
145
146 int32_t poc_top; /* POC for Top Field/Frame */
147 int32_t poc_bottom; /* POC for Bottom Field */
148 uint32_t idr_pic_id;
149
150 /* H264_VALID_PANSCAN */
151 uint32_t pan_scan_count;
152 int32_t pan_scan_left[3];
153 int32_t pan_scan_right[3];
154 int32_t pan_scan_top[3];
155 int32_t pan_scan_bottom[3];
156
157 /* H264_VALID_CT_TYPE */
158 uint32_t ct_type_count;
159 uint32_t ct_type[3];
160
161 /* H264_VALID_SPS_CROP */
162 int32_t sps_crop_left;
163 int32_t sps_crop_right;
164 int32_t sps_crop_top;
165 int32_t sps_crop_bottom;
166
167 /* H264_VALID_VUI */
168 uint32_t chroma_top;
169 uint32_t chroma_bottom;
170
171 /* H264_VALID_USER */
172 uint32_t user_data_size;
173 UD_HDR *user_data;
174
175 /* H264 VALID FGT */
176 FGT_SEI *pfgt;
177
178} PPB_H264;
179
180typedef struct {
181 /* Common fields. */
182 uint32_t picture_number; /* Ordinal display number */
183 uint32_t video_buffer; /* Video (picbuf) number */
184 uint32_t video_address; /* Address of picbuf Y */
185 uint32_t video_address_uv; /* Address of picbuf UV */
186 uint32_t video_stripe; /* Picbuf stripe */
187 uint32_t video_width; /* Picbuf width */
188 uint32_t video_height; /* Picbuf height */
189
190 uint32_t channel_id; /* Decoder channel ID */
191 uint32_t status; /* reserved */
192 uint32_t width; /* pixels */
193 uint32_t height; /* pixels */
194 uint32_t chroma_format; /* see above */
195 uint32_t pulldown; /* see above */
196 uint32_t flags; /* see above */
197 uint32_t pts; /* 32 LSBs of PTS */
198 uint32_t protocol; /* protocolXXX (above) */
199
200 uint32_t frame_rate; /* see above */
201 uint32_t matrix_coeff; /* see above */
202 uint32_t aspect_ratio; /* see above */
203 uint32_t colour_primaries; /* see above */
204 uint32_t transfer_char; /* see above */
205 uint32_t pcr_offset; /* 45kHz if PCR type; else 27MHz */
206 uint32_t n_drop; /* Number of pictures to be dropped */
207
208 uint32_t custom_aspect_ratio_width_height;
209 /* upper 16-bits is Y and lower 16-bits is X */
210
211 uint32_t picture_tag; /* Indexing tag from BUD packets */
212 uint32_t picture_done_payload;
213 uint32_t picture_meta_payload;
214 uint32_t reserved[1];
215
216 /* Protocol-specific extensions. */
217 union {
218 PPB_H264 h264;
219 PPB_MPEG mpeg;
220 PPB_VC1 vc1;
221 } other;
222
223} PPB;
224
225typedef struct {
226 uint32_t bFormatChange;
227 uint32_t resolution;
228 uint32_t channelId;
229 uint32_t ppbPtr;
230 int32_t ptsStcOffset;
231 uint32_t zeroPanscanValid;
232 uint32_t dramOutBufAddr;
233 uint32_t yComponent;
234 PPB ppb;
235
236} C011_PIB;
237
238
239
240typedef struct {
241 uint32_t command;
242 uint32_t sequence;
243 uint32_t status;
244 uint32_t picBuf;
245 uint32_t picRelBuf;
246 uint32_t picInfoDeliveryQ;
247 uint32_t picInfoReleaseQ;
248 uint32_t channelStatus;
249 uint32_t userDataDeliveryQ;
250 uint32_t userDataReleaseQ;
251 uint32_t transportStreamCaptureAddr;
252 uint32_t asyncEventQ;
253
254} DecRspChannelStartVideo;
255
256#define eCMD_C011_CMD_BASE (0x73763000)
257
258/* host commands */
259typedef enum {
260 eCMD_TS_GET_NEXT_PIC = 0x7376F100, /* debug get next picture */
261 eCMD_TS_GET_LAST_PIC = 0x7376F102, /* debug get last pic status */
262 eCMD_TS_READ_WRITE_MEM = 0x7376F104, /* debug read write memory */
263
264 /* New API commands */
265 /* General commands */
266 eCMD_C011_INIT = eCMD_C011_CMD_BASE + 0x01,
267 eCMD_C011_RESET = eCMD_C011_CMD_BASE + 0x02,
268 eCMD_C011_SELF_TEST = eCMD_C011_CMD_BASE + 0x03,
269 eCMD_C011_GET_VERSION = eCMD_C011_CMD_BASE + 0x04,
270 eCMD_C011_GPIO = eCMD_C011_CMD_BASE + 0x05,
271 eCMD_C011_DEBUG_SETUP = eCMD_C011_CMD_BASE + 0x06,
272
273 /* Decoding commands */
274 eCMD_C011_DEC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x100,
275 eCMD_C011_DEC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x101,
276 eCMD_C011_DEC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x102,
277 eCMD_C011_DEC_CHAN_STATUS = eCMD_C011_CMD_BASE + 0x103,
278 eCMD_C011_DEC_CHAN_FLUSH = eCMD_C011_CMD_BASE + 0x104,
279 eCMD_C011_DEC_CHAN_TRICK_PLAY = eCMD_C011_CMD_BASE + 0x105,
280 eCMD_C011_DEC_CHAN_TS_PIDS = eCMD_C011_CMD_BASE + 0x106,
281 eCMD_C011_DEC_CHAN_PS_STREAM_ID = eCMD_C011_CMD_BASE + 0x107,
282 eCMD_C011_DEC_CHAN_INPUT_PARAMS = eCMD_C011_CMD_BASE + 0x108,
283 eCMD_C011_DEC_CHAN_VIDEO_OUTPUT = eCMD_C011_CMD_BASE + 0x109,
284 eCMD_C011_DEC_CHAN_OUTPUT_FORMAT = eCMD_C011_CMD_BASE + 0x10A,
285 eCMD_C011_DEC_CHAN_SCALING_FILTERS = eCMD_C011_CMD_BASE + 0x10B,
286 eCMD_C011_DEC_CHAN_OSD_MODE = eCMD_C011_CMD_BASE + 0x10D,
287 eCMD_C011_DEC_CHAN_DROP = eCMD_C011_CMD_BASE + 0x10E,
288 eCMD_C011_DEC_CHAN_RELEASE = eCMD_C011_CMD_BASE + 0x10F,
289 eCMD_C011_DEC_CHAN_STREAM_SETTINGS = eCMD_C011_CMD_BASE + 0x110,
290 eCMD_C011_DEC_CHAN_PAUSE_OUTPUT = eCMD_C011_CMD_BASE + 0x111,
291 eCMD_C011_DEC_CHAN_CHANGE = eCMD_C011_CMD_BASE + 0x112,
292 eCMD_C011_DEC_CHAN_SET_STC = eCMD_C011_CMD_BASE + 0x113,
293 eCMD_C011_DEC_CHAN_SET_PTS = eCMD_C011_CMD_BASE + 0x114,
294 eCMD_C011_DEC_CHAN_CC_MODE = eCMD_C011_CMD_BASE + 0x115,
295 eCMD_C011_DEC_CREATE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x116,
296 eCMD_C011_DEC_COPY_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x117,
297 eCMD_C011_DEC_DELETE_AUDIO_CONTEXT = eCMD_C011_CMD_BASE + 0x118,
298 eCMD_C011_DEC_CHAN_SET_DECYPTION = eCMD_C011_CMD_BASE + 0x119,
299 eCMD_C011_DEC_CHAN_START_VIDEO = eCMD_C011_CMD_BASE + 0x11A,
300 eCMD_C011_DEC_CHAN_STOP_VIDEO = eCMD_C011_CMD_BASE + 0x11B,
301 eCMD_C011_DEC_CHAN_PIC_CAPTURE = eCMD_C011_CMD_BASE + 0x11C,
302 eCMD_C011_DEC_CHAN_PAUSE = eCMD_C011_CMD_BASE + 0x11D,
303 eCMD_C011_DEC_CHAN_PAUSE_STATE = eCMD_C011_CMD_BASE + 0x11E,
304 eCMD_C011_DEC_CHAN_SET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x11F,
305 eCMD_C011_DEC_CHAN_GET_SLOWM_RATE = eCMD_C011_CMD_BASE + 0x120,
306 eCMD_C011_DEC_CHAN_SET_FF_RATE = eCMD_C011_CMD_BASE + 0x121,
307 eCMD_C011_DEC_CHAN_GET_FF_RATE = eCMD_C011_CMD_BASE + 0x122,
308 eCMD_C011_DEC_CHAN_FRAME_ADVANCE = eCMD_C011_CMD_BASE + 0x123,
309 eCMD_C011_DEC_CHAN_SET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x124,
310 eCMD_C011_DEC_CHAN_GET_SKIP_PIC_MODE = eCMD_C011_CMD_BASE + 0x125,
311 eCMD_C011_DEC_CHAN_FILL_PIC_BUF = eCMD_C011_CMD_BASE + 0x126,
312 eCMD_C011_DEC_CHAN_SET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x127,
313 eCMD_C011_DEC_CHAN_GET_CONTINUITY_CHECK = eCMD_C011_CMD_BASE + 0x128,
314 eCMD_C011_DEC_CHAN_SET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x129,
315 eCMD_C011_DEC_CHAN_GET_BRCM_TRICK_MODE = eCMD_C011_CMD_BASE + 0x12A,
316 eCMD_C011_DEC_CHAN_REVERSE_FIELD_STATUS = eCMD_C011_CMD_BASE + 0x12B,
317 eCMD_C011_DEC_CHAN_I_PICTURE_FOUND = eCMD_C011_CMD_BASE + 0x12C,
318 eCMD_C011_DEC_CHAN_SET_PARAMETER = eCMD_C011_CMD_BASE + 0x12D,
319 eCMD_C011_DEC_CHAN_SET_USER_DATA_MODE = eCMD_C011_CMD_BASE + 0x12E,
320 eCMD_C011_DEC_CHAN_SET_PAUSE_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x12F,
321 eCMD_C011_DEC_CHAN_SET_SLOW_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x130,
322 eCMD_C011_DEC_CHAN_SET_FF_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x131,
323 eCMD_C011_DEC_CHAN_SET_DISPLAY_TIMING_MODE = eCMD_C011_CMD_BASE + 0x132,
324 eCMD_C011_DEC_CHAN_SET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x133,
325 eCMD_C011_DEC_CHAN_GET_DISPLAY_MODE = eCMD_C011_CMD_BASE + 0x134,
326 eCMD_C011_DEC_CHAN_SET_REVERSE_FIELD = eCMD_C011_CMD_BASE + 0x135,
327 eCMD_C011_DEC_CHAN_STREAM_OPEN = eCMD_C011_CMD_BASE + 0x136,
328 eCMD_C011_DEC_CHAN_SET_PCR_PID = eCMD_C011_CMD_BASE + 0x137,
329 eCMD_C011_DEC_CHAN_SET_VID_PID = eCMD_C011_CMD_BASE + 0x138,
330 eCMD_C011_DEC_CHAN_SET_PAN_SCAN_MODE = eCMD_C011_CMD_BASE + 0x139,
331 eCMD_C011_DEC_CHAN_START_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x140,
332 eCMD_C011_DEC_CHAN_STOP_DISPLAY_AT_PTS = eCMD_C011_CMD_BASE + 0x141,
333 eCMD_C011_DEC_CHAN_SET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x142,
334 eCMD_C011_DEC_CHAN_GET_DISPLAY_ORDER = eCMD_C011_CMD_BASE + 0x143,
335 eCMD_C011_DEC_CHAN_SET_HOST_TRICK_MODE = eCMD_C011_CMD_BASE + 0x144,
336 eCMD_C011_DEC_CHAN_SET_OPERATION_MODE = eCMD_C011_CMD_BASE + 0x145,
337 eCMD_C011_DEC_CHAN_DISPLAY_PAUSE_UNTO_PTS = eCMD_C011_CMD_BASE + 0x146,
338 eCMD_C011_DEC_CHAN_SET_PTS_STC_DIFF_THRESHOLD = eCMD_C011_CMD_BASE + 0x147,
339 eCMD_C011_DEC_CHAN_SEND_COMPRESSED_BUF = eCMD_C011_CMD_BASE + 0x148,
340 eCMD_C011_DEC_CHAN_SET_CLIPPING = eCMD_C011_CMD_BASE + 0x149,
341 eCMD_C011_DEC_CHAN_SET_PARAMETERS_FOR_HARD_RESET_INTERRUPT_TO_HOST
342 = eCMD_C011_CMD_BASE + 0x150,
343
344 /* Decoder RevD commands */
345 eCMD_C011_DEC_CHAN_SET_CSC = eCMD_C011_CMD_BASE + 0x180, /* color space conversion */
346 eCMD_C011_DEC_CHAN_SET_RANGE_REMAP = eCMD_C011_CMD_BASE + 0x181,
347 eCMD_C011_DEC_CHAN_SET_FGT = eCMD_C011_CMD_BASE + 0x182,
348 /* Note: 0x183 not implemented yet in Rev D main */
349 eCMD_C011_DEC_CHAN_SET_LASTPICTURE_PADDING = eCMD_C011_CMD_BASE + 0x183,
350
351 /* Decoder 7412 commands (7412-only) */
352 eCMD_C011_DEC_CHAN_SET_CONTENT_KEY = eCMD_C011_CMD_BASE + 0x190,
353 eCMD_C011_DEC_CHAN_SET_SESSION_KEY = eCMD_C011_CMD_BASE + 0x191,
354 eCMD_C011_DEC_CHAN_FMT_CHANGE_ACK = eCMD_C011_CMD_BASE + 0x192,
355
356 eCMD_C011_DEC_CHAN_CUSTOM_VIDOUT = eCMD_C011_CMD_BASE + 0x1FF,
357
358 /* Encoding commands */
359 eCMD_C011_ENC_CHAN_OPEN = eCMD_C011_CMD_BASE + 0x200,
360 eCMD_C011_ENC_CHAN_CLOSE = eCMD_C011_CMD_BASE + 0x201,
361 eCMD_C011_ENC_CHAN_ACTIVATE = eCMD_C011_CMD_BASE + 0x202,
362 eCMD_C011_ENC_CHAN_CONTROL = eCMD_C011_CMD_BASE + 0x203,
363 eCMD_C011_ENC_CHAN_STATISTICS = eCMD_C011_CMD_BASE + 0x204,
364
365 eNOTIFY_C011_ENC_CHAN_EVENT = eCMD_C011_CMD_BASE + 0x210,
366
367} eC011_TS_CMD;
368
369#endif
diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c
new file mode 100644
index 000000000000..01819d34201a
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_hw.c
@@ -0,0 +1,2395 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_hw . c
5 *
6 * Description:
7 * BCM70010 Linux driver HW layer.
8 *
9 **********************************************************************
10 * This file is part of the crystalhd device driver.
11 *
12 * This driver is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, version 2 of the License.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
23 **********************************************************************/
24
25#include <linux/pci.h>
26#include <linux/delay.h>
27#include "crystalhd_hw.h"
28
29/* Functions internal to this file */
30
31static void crystalhd_enable_uarts(struct crystalhd_adp *adp)
32{
33 bc_dec_reg_wr(adp, UartSelectA, BSVS_UART_STREAM);
34 bc_dec_reg_wr(adp, UartSelectB, BSVS_UART_DEC_OUTER);
35}
36
37
38static void crystalhd_start_dram(struct crystalhd_adp *adp)
39{
40 bc_dec_reg_wr(adp, SDRAM_PARAM, ((40 / 5 - 1) << 0) |
41 /* tras (40ns tras)/(5ns period) -1 ((15/5 - 1) << 4) | // trcd */
42 ((15 / 5 - 1) << 7) | /* trp */
43 ((10 / 5 - 1) << 10) | /* trrd */
44 ((15 / 5 + 1) << 12) | /* twr */
45 ((2 + 1) << 16) | /* twtr */
46 ((70 / 5 - 2) << 19) | /* trfc */
47 (0 << 23));
48
49 bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
50 bc_dec_reg_wr(adp, SDRAM_EXT_MODE, 2);
51 bc_dec_reg_wr(adp, SDRAM_MODE, 0x132);
52 bc_dec_reg_wr(adp, SDRAM_PRECHARGE, 0);
53 bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
54 bc_dec_reg_wr(adp, SDRAM_REFRESH, 0);
55 bc_dec_reg_wr(adp, SDRAM_MODE, 0x32);
56 /* setting the refresh rate here */
57 bc_dec_reg_wr(adp, SDRAM_REF_PARAM, ((1 << 12) | 96));
58}
59
60
61static bool crystalhd_bring_out_of_rst(struct crystalhd_adp *adp)
62{
63 link_misc_perst_deco_ctrl rst_deco_cntrl;
64 link_misc_perst_clk_ctrl rst_clk_cntrl;
65 uint32_t temp;
66
67 /*
68 * Link clocks: MISC_PERST_CLOCK_CTRL Clear PLL power down bit,
69 * delay to allow PLL to lock Clear alternate clock, stop clock bits
70 */
71 rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
72 rst_clk_cntrl.pll_pwr_dn = 0;
73 crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
74 msleep_interruptible(50);
75
76 rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
77 rst_clk_cntrl.stop_core_clk = 0;
78 rst_clk_cntrl.sel_alt_clk = 0;
79
80 crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
81 msleep_interruptible(50);
82
83 /*
84 * Bus Arbiter Timeout: GISB_ARBITER_TIMER
85 * Set internal bus arbiter timeout to 40us based on core clock speed
86 * (63MHz * 40us = 0x9D8)
87 */
88 crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x9D8);
89
90 /*
91 * Decoder clocks: MISC_PERST_DECODER_CTRL
92 * Enable clocks while 7412 reset is asserted, delay
93 * De-assert 7412 reset
94 */
95 rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
96 rst_deco_cntrl.stop_bcm_7412_clk = 0;
97 rst_deco_cntrl.bcm7412_rst = 1;
98 crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
99 msleep_interruptible(10);
100
101 rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
102 rst_deco_cntrl.bcm7412_rst = 0;
103 crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
104 msleep_interruptible(50);
105
106 /* Disable OTP_CONTENT_MISC to 0 to disable all secure modes */
107 crystalhd_reg_wr(adp, OTP_CONTENT_MISC, 0);
108
109 /* Clear bit 29 of 0x404 */
110 temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
111 temp &= ~BC_BIT(29);
112 crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
113
114 /* 2.5V regulator must be set to 2.6 volts (+6%) */
115 /* FIXME: jarod: what's the point of this reg read? */
116 temp = crystalhd_reg_rd(adp, MISC_PERST_VREG_CTRL);
117 crystalhd_reg_wr(adp, MISC_PERST_VREG_CTRL, 0xF3);
118
119 return true;
120}
121
122static bool crystalhd_put_in_reset(struct crystalhd_adp *adp)
123{
124 link_misc_perst_deco_ctrl rst_deco_cntrl;
125 link_misc_perst_clk_ctrl rst_clk_cntrl;
126 uint32_t temp;
127
128 /*
129 * Decoder clocks: MISC_PERST_DECODER_CTRL
130 * Assert 7412 reset, delay
131 * Assert 7412 stop clock
132 */
133 rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_DECODER_CTRL);
134 rst_deco_cntrl.stop_bcm_7412_clk = 1;
135 crystalhd_reg_wr(adp, MISC_PERST_DECODER_CTRL, rst_deco_cntrl.whole_reg);
136 msleep_interruptible(50);
137
138 /* Bus Arbiter Timeout: GISB_ARBITER_TIMER
139 * Set internal bus arbiter timeout to 40us based on core clock speed
140 * (6.75MHZ * 40us = 0x10E)
141 */
142 crystalhd_reg_wr(adp, GISB_ARBITER_TIMER, 0x10E);
143
144 /* Link clocks: MISC_PERST_CLOCK_CTRL
145 * Stop core clk, delay
146 * Set alternate clk, delay, set PLL power down
147 */
148 rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
149 rst_clk_cntrl.stop_core_clk = 1;
150 rst_clk_cntrl.sel_alt_clk = 1;
151 crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
152 msleep_interruptible(50);
153
154 rst_clk_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC_PERST_CLOCK_CTRL);
155 rst_clk_cntrl.pll_pwr_dn = 1;
156 crystalhd_reg_wr(adp, MISC_PERST_CLOCK_CTRL, rst_clk_cntrl.whole_reg);
157
158 /*
159 * Read and restore the Transaction Configuration Register
160 * after core reset
161 */
162 temp = crystalhd_reg_rd(adp, PCIE_TL_TRANSACTION_CONFIGURATION);
163
164 /*
165 * Link core soft reset: MISC3_RESET_CTRL
166 * - Write BIT[0]=1 and read it back for core reset to take place
167 */
168 crystalhd_reg_wr(adp, MISC3_RESET_CTRL, 1);
169 rst_deco_cntrl.whole_reg = crystalhd_reg_rd(adp, MISC3_RESET_CTRL);
170 msleep_interruptible(50);
171
172 /* restore the transaction configuration register */
173 crystalhd_reg_wr(adp, PCIE_TL_TRANSACTION_CONFIGURATION, temp);
174
175 return true;
176}
177
178static void crystalhd_disable_interrupts(struct crystalhd_adp *adp)
179{
180 intr_mask_reg intr_mask;
181 intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
182 intr_mask.mask_pcie_err = 1;
183 intr_mask.mask_pcie_rbusmast_err = 1;
184 intr_mask.mask_pcie_rgr_bridge = 1;
185 intr_mask.mask_rx_done = 1;
186 intr_mask.mask_rx_err = 1;
187 intr_mask.mask_tx_done = 1;
188 intr_mask.mask_tx_err = 1;
189 crystalhd_reg_wr(adp, INTR_INTR_MSK_SET_REG, intr_mask.whole_reg);
190
191 return;
192}
193
194static void crystalhd_enable_interrupts(struct crystalhd_adp *adp)
195{
196 intr_mask_reg intr_mask;
197 intr_mask.whole_reg = crystalhd_reg_rd(adp, INTR_INTR_MSK_STS_REG);
198 intr_mask.mask_pcie_err = 1;
199 intr_mask.mask_pcie_rbusmast_err = 1;
200 intr_mask.mask_pcie_rgr_bridge = 1;
201 intr_mask.mask_rx_done = 1;
202 intr_mask.mask_rx_err = 1;
203 intr_mask.mask_tx_done = 1;
204 intr_mask.mask_tx_err = 1;
205 crystalhd_reg_wr(adp, INTR_INTR_MSK_CLR_REG, intr_mask.whole_reg);
206
207 return;
208}
209
210static void crystalhd_clear_errors(struct crystalhd_adp *adp)
211{
212 uint32_t reg;
213
214 /* FIXME: jarod: wouldn't we want to write a 0 to the reg? Or does the write clear the bits specified? */
215 reg = crystalhd_reg_rd(adp, MISC1_Y_RX_ERROR_STATUS);
216 if (reg)
217 crystalhd_reg_wr(adp, MISC1_Y_RX_ERROR_STATUS, reg);
218
219 reg = crystalhd_reg_rd(adp, MISC1_UV_RX_ERROR_STATUS);
220 if (reg)
221 crystalhd_reg_wr(adp, MISC1_UV_RX_ERROR_STATUS, reg);
222
223 reg = crystalhd_reg_rd(adp, MISC1_TX_DMA_ERROR_STATUS);
224 if (reg)
225 crystalhd_reg_wr(adp, MISC1_TX_DMA_ERROR_STATUS, reg);
226}
227
228static void crystalhd_clear_interrupts(struct crystalhd_adp *adp)
229{
230 uint32_t intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
231
232 if (intr_sts) {
233 crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
234
235 /* Write End Of Interrupt for PCIE */
236 crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
237 }
238}
239
240static void crystalhd_soft_rst(struct crystalhd_adp *adp)
241{
242 uint32_t val;
243
244 /* Assert c011 soft reset*/
245 bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000001);
246 msleep_interruptible(50);
247
248 /* Release c011 soft reset*/
249 bc_dec_reg_wr(adp, DecHt_HostSwReset, 0x00000000);
250
251 /* Disable Stuffing..*/
252 val = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
253 val |= BC_BIT(8);
254 crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, val);
255}
256
257static bool crystalhd_load_firmware_config(struct crystalhd_adp *adp)
258{
259 uint32_t i = 0, reg;
260
261 crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (BC_DRAM_FW_CFG_ADDR >> 19));
262
263 crystalhd_reg_wr(adp, AES_CMD, 0);
264 crystalhd_reg_wr(adp, AES_CONFIG_INFO, (BC_DRAM_FW_CFG_ADDR & 0x7FFFF));
265 crystalhd_reg_wr(adp, AES_CMD, 0x1);
266
267 /* FIXME: jarod: I've seen this fail, and introducing extra delays helps... */
268 for (i = 0; i < 100; ++i) {
269 reg = crystalhd_reg_rd(adp, AES_STATUS);
270 if (reg & 0x1)
271 return true;
272 msleep_interruptible(10);
273 }
274
275 return false;
276}
277
278
279static bool crystalhd_start_device(struct crystalhd_adp *adp)
280{
281 uint32_t dbg_options, glb_cntrl = 0, reg_pwrmgmt = 0;
282
283 BCMLOG(BCMLOG_INFO, "Starting BCM70012 Device\n");
284
285 reg_pwrmgmt = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
286 reg_pwrmgmt &= ~ASPM_L1_ENABLE;
287
288 crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg_pwrmgmt);
289
290 if (!crystalhd_bring_out_of_rst(adp)) {
291 BCMLOG_ERR("Failed To Bring Link Out Of Reset\n");
292 return false;
293 }
294
295 crystalhd_disable_interrupts(adp);
296
297 crystalhd_clear_errors(adp);
298
299 crystalhd_clear_interrupts(adp);
300
301 crystalhd_enable_interrupts(adp);
302
303 /* Enable the option for getting the total no. of DWORDS
304 * that have been transfered by the RXDMA engine
305 */
306 dbg_options = crystalhd_reg_rd(adp, MISC1_DMA_DEBUG_OPTIONS_REG);
307 dbg_options |= 0x10;
308 crystalhd_reg_wr(adp, MISC1_DMA_DEBUG_OPTIONS_REG, dbg_options);
309
310 /* Enable PCI Global Control options */
311 glb_cntrl = crystalhd_reg_rd(adp, MISC2_GLOBAL_CTRL);
312 glb_cntrl |= 0x100;
313 glb_cntrl |= 0x8000;
314 crystalhd_reg_wr(adp, MISC2_GLOBAL_CTRL, glb_cntrl);
315
316 crystalhd_enable_interrupts(adp);
317
318 crystalhd_soft_rst(adp);
319 crystalhd_start_dram(adp);
320 crystalhd_enable_uarts(adp);
321
322 return true;
323}
324
325static bool crystalhd_stop_device(struct crystalhd_adp *adp)
326{
327 uint32_t reg;
328
329 BCMLOG(BCMLOG_INFO, "Stopping BCM70012 Device\n");
330 /* Clear and disable interrupts */
331 crystalhd_disable_interrupts(adp);
332 crystalhd_clear_errors(adp);
333 crystalhd_clear_interrupts(adp);
334
335 if (!crystalhd_put_in_reset(adp))
336 BCMLOG_ERR("Failed to Put Link To Reset State\n");
337
338 reg = crystalhd_reg_rd(adp, PCIE_DLL_DATA_LINK_CONTROL);
339 reg |= ASPM_L1_ENABLE;
340 crystalhd_reg_wr(adp, PCIE_DLL_DATA_LINK_CONTROL, reg);
341
342 /* Set PCI Clk Req */
343 reg = crystalhd_reg_rd(adp, PCIE_CLK_REQ_REG);
344 reg |= PCI_CLK_REQ_ENABLE;
345 crystalhd_reg_wr(adp, PCIE_CLK_REQ_REG, reg);
346
347 return true;
348}
349
350static crystalhd_rx_dma_pkt *crystalhd_hw_alloc_rx_pkt(struct crystalhd_hw *hw)
351{
352 unsigned long flags = 0;
353 crystalhd_rx_dma_pkt *temp = NULL;
354
355 if (!hw)
356 return NULL;
357
358 spin_lock_irqsave(&hw->lock, flags);
359 temp = hw->rx_pkt_pool_head;
360 if (temp) {
361 hw->rx_pkt_pool_head = hw->rx_pkt_pool_head->next;
362 temp->dio_req = NULL;
363 temp->pkt_tag = 0;
364 temp->flags = 0;
365 }
366 spin_unlock_irqrestore(&hw->lock, flags);
367
368 return temp;
369}
370
371static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw,
372 crystalhd_rx_dma_pkt *pkt)
373{
374 unsigned long flags = 0;
375
376 if (!hw || !pkt)
377 return;
378
379 spin_lock_irqsave(&hw->lock, flags);
380 pkt->next = hw->rx_pkt_pool_head;
381 hw->rx_pkt_pool_head = pkt;
382 spin_unlock_irqrestore(&hw->lock, flags);
383}
384
385/*
386 * Call back from TX - IOQ deletion.
387 *
388 * This routine will release the TX DMA rings allocated
389 * druing setup_dma rings interface.
390 *
391 * Memory is allocated per DMA ring basis. This is just
392 * a place holder to be able to create the dio queues.
393 */
394static void crystalhd_tx_desc_rel_call_back(void *context, void *data)
395{
396}
397
398/*
399 * Rx Packet release callback..
400 *
401 * Release All user mapped capture buffers and Our DMA packets
402 * back to our free pool. The actual cleanup of the DMA
403 * ring descriptors happen during dma ring release.
404 */
405static void crystalhd_rx_pkt_rel_call_back(void *context, void *data)
406{
407 struct crystalhd_hw *hw = (struct crystalhd_hw *)context;
408 crystalhd_rx_dma_pkt *pkt = (crystalhd_rx_dma_pkt *)data;
409
410 if (!pkt || !hw) {
411 BCMLOG_ERR("Invalid arg - %p %p\n", hw, pkt);
412 return;
413 }
414
415 if (pkt->dio_req)
416 crystalhd_unmap_dio(hw->adp, pkt->dio_req);
417 else
418 BCMLOG_ERR("Missing dio_req: 0x%x\n", pkt->pkt_tag);
419
420 crystalhd_hw_free_rx_pkt(hw, pkt);
421}
422
423#define crystalhd_hw_delete_ioq(adp, q) \
424 if (q) { \
425 crystalhd_delete_dioq(adp, q); \
426 q = NULL; \
427 }
428
429static void crystalhd_hw_delete_ioqs(struct crystalhd_hw *hw)
430{
431 if (!hw)
432 return;
433
434 BCMLOG(BCMLOG_DBG, "Deleting IOQs \n");
435 crystalhd_hw_delete_ioq(hw->adp, hw->tx_actq);
436 crystalhd_hw_delete_ioq(hw->adp, hw->tx_freeq);
437 crystalhd_hw_delete_ioq(hw->adp, hw->rx_actq);
438 crystalhd_hw_delete_ioq(hw->adp, hw->rx_freeq);
439 crystalhd_hw_delete_ioq(hw->adp, hw->rx_rdyq);
440}
441
442#define crystalhd_hw_create_ioq(sts, hw, q, cb) \
443do { \
444 sts = crystalhd_create_dioq(hw->adp, &q, cb, hw); \
445 if (sts != BC_STS_SUCCESS) \
446 goto hw_create_ioq_err; \
447} while (0)
448
449/*
450 * Create IOQs..
451 *
452 * TX - Active & Free
453 * RX - Active, Ready and Free.
454 */
455static BC_STATUS crystalhd_hw_create_ioqs(struct crystalhd_hw *hw)
456{
457 BC_STATUS sts = BC_STS_SUCCESS;
458
459 if (!hw) {
460 BCMLOG_ERR("Invalid Arg!!\n");
461 return BC_STS_INV_ARG;
462 }
463
464 crystalhd_hw_create_ioq(sts, hw, hw->tx_freeq,
465 crystalhd_tx_desc_rel_call_back);
466 crystalhd_hw_create_ioq(sts, hw, hw->tx_actq,
467 crystalhd_tx_desc_rel_call_back);
468
469 crystalhd_hw_create_ioq(sts, hw, hw->rx_freeq,
470 crystalhd_rx_pkt_rel_call_back);
471 crystalhd_hw_create_ioq(sts, hw, hw->rx_rdyq,
472 crystalhd_rx_pkt_rel_call_back);
473 crystalhd_hw_create_ioq(sts, hw, hw->rx_actq,
474 crystalhd_rx_pkt_rel_call_back);
475
476 return sts;
477
478hw_create_ioq_err:
479 crystalhd_hw_delete_ioqs(hw);
480
481 return sts;
482}
483
484
485static bool crystalhd_code_in_full(struct crystalhd_adp *adp, uint32_t needed_sz,
486 bool b_188_byte_pkts, uint8_t flags)
487{
488 uint32_t base, end, writep, readp;
489 uint32_t cpbSize, cpbFullness, fifoSize;
490
491 if (flags & 0x02) { /* ASF Bit is set */
492 base = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Base);
493 end = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2End);
494 writep = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Wrptr);
495 readp = bc_dec_reg_rd(adp, REG_Dec_TsAudCDB2Rdptr);
496 } else if (b_188_byte_pkts) { /*Encrypted 188 byte packets*/
497 base = bc_dec_reg_rd(adp, REG_Dec_TsUser0Base);
498 end = bc_dec_reg_rd(adp, REG_Dec_TsUser0End);
499 writep = bc_dec_reg_rd(adp, REG_Dec_TsUser0Wrptr);
500 readp = bc_dec_reg_rd(adp, REG_Dec_TsUser0Rdptr);
501 } else {
502 base = bc_dec_reg_rd(adp, REG_DecCA_RegCinBase);
503 end = bc_dec_reg_rd(adp, REG_DecCA_RegCinEnd);
504 writep = bc_dec_reg_rd(adp, REG_DecCA_RegCinWrPtr);
505 readp = bc_dec_reg_rd(adp, REG_DecCA_RegCinRdPtr);
506 }
507
508 cpbSize = end - base;
509 if (writep >= readp)
510 cpbFullness = writep - readp;
511 else
512 cpbFullness = (end - base) - (readp - writep);
513
514 fifoSize = cpbSize - cpbFullness;
515
516 if (fifoSize < BC_INFIFO_THRESHOLD)
517 return true;
518
519 if (needed_sz > (fifoSize - BC_INFIFO_THRESHOLD))
520 return true;
521
522 return false;
523}
524
525static BC_STATUS crystalhd_hw_tx_req_complete(struct crystalhd_hw *hw,
526 uint32_t list_id, BC_STATUS cs)
527{
528 tx_dma_pkt *tx_req;
529
530 if (!hw || !list_id) {
531 BCMLOG_ERR("Invalid Arg..\n");
532 return BC_STS_INV_ARG;
533 }
534
535 hw->pwr_lock--;
536
537 tx_req = (tx_dma_pkt *)crystalhd_dioq_find_and_fetch(hw->tx_actq, list_id);
538 if (!tx_req) {
539 if (cs != BC_STS_IO_USER_ABORT)
540 BCMLOG_ERR("Find and Fetch Did not find req\n");
541 return BC_STS_NO_DATA;
542 }
543
544 if (tx_req->call_back) {
545 tx_req->call_back(tx_req->dio_req, tx_req->cb_event, cs);
546 tx_req->dio_req = NULL;
547 tx_req->cb_event = NULL;
548 tx_req->call_back = NULL;
549 } else {
550 BCMLOG(BCMLOG_DBG, "Missing Tx Callback - %X\n",
551 tx_req->list_tag);
552 }
553
554 /* Now put back the tx_list back in FreeQ */
555 tx_req->list_tag = 0;
556
557 return crystalhd_dioq_add(hw->tx_freeq, tx_req, false, 0);
558}
559
560static bool crystalhd_tx_list0_handler(struct crystalhd_hw *hw, uint32_t err_sts)
561{
562 uint32_t err_mask, tmp;
563 unsigned long flags = 0;
564
565 err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L0_DESC_TX_ABORT_ERRORS_MASK |
566 MISC1_TX_DMA_ERROR_STATUS_TX_L0_DMA_DATA_TX_ABORT_ERRORS_MASK |
567 MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
568
569 if (!(err_sts & err_mask))
570 return false;
571
572 BCMLOG_ERR("Error on Tx-L0 %x \n", err_sts);
573
574 tmp = err_mask;
575
576 if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK)
577 tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L0_FIFO_FULL_ERRORS_MASK;
578
579 if (tmp) {
580 spin_lock_irqsave(&hw->lock, flags);
581 /* reset list index.*/
582 hw->tx_list_post_index = 0;
583 spin_unlock_irqrestore(&hw->lock, flags);
584 }
585
586 tmp = err_sts & err_mask;
587 crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
588
589 return true;
590}
591
592static bool crystalhd_tx_list1_handler(struct crystalhd_hw *hw, uint32_t err_sts)
593{
594 uint32_t err_mask, tmp;
595 unsigned long flags = 0;
596
597 err_mask = MISC1_TX_DMA_ERROR_STATUS_TX_L1_DESC_TX_ABORT_ERRORS_MASK |
598 MISC1_TX_DMA_ERROR_STATUS_TX_L1_DMA_DATA_TX_ABORT_ERRORS_MASK |
599 MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
600
601 if (!(err_sts & err_mask))
602 return false;
603
604 BCMLOG_ERR("Error on Tx-L1 %x \n", err_sts);
605
606 tmp = err_mask;
607
608 if (err_sts & MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK)
609 tmp &= ~MISC1_TX_DMA_ERROR_STATUS_TX_L1_FIFO_FULL_ERRORS_MASK;
610
611 if (tmp) {
612 spin_lock_irqsave(&hw->lock, flags);
613 /* reset list index.*/
614 hw->tx_list_post_index = 0;
615 spin_unlock_irqrestore(&hw->lock, flags);
616 }
617
618 tmp = err_sts & err_mask;
619 crystalhd_reg_wr(hw->adp, MISC1_TX_DMA_ERROR_STATUS, tmp);
620
621 return true;
622}
623
624static void crystalhd_tx_isr(struct crystalhd_hw *hw, uint32_t int_sts)
625{
626 uint32_t err_sts;
627
628 if (int_sts & INTR_INTR_STATUS_L0_TX_DMA_DONE_INTR_MASK)
629 crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
630 BC_STS_SUCCESS);
631
632 if (int_sts & INTR_INTR_STATUS_L1_TX_DMA_DONE_INTR_MASK)
633 crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
634 BC_STS_SUCCESS);
635
636 if (!(int_sts & (INTR_INTR_STATUS_L0_TX_DMA_ERR_INTR_MASK |
637 INTR_INTR_STATUS_L1_TX_DMA_ERR_INTR_MASK))) {
638 /* No error mask set.. */
639 return;
640 }
641
642 /* Handle Tx errors. */
643 err_sts = crystalhd_reg_rd(hw->adp, MISC1_TX_DMA_ERROR_STATUS);
644
645 if (crystalhd_tx_list0_handler(hw, err_sts))
646 crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 0,
647 BC_STS_ERROR);
648
649 if (crystalhd_tx_list1_handler(hw, err_sts))
650 crystalhd_hw_tx_req_complete(hw, hw->tx_ioq_tag_seed + 1,
651 BC_STS_ERROR);
652
653 hw->stats.tx_errors++;
654}
655
656static void crystalhd_hw_dump_desc(pdma_descriptor p_dma_desc,
657 uint32_t ul_desc_index, uint32_t cnt)
658{
659 uint32_t ix, ll = 0;
660
661 if (!p_dma_desc || !cnt)
662 return;
663
664 /* FIXME: jarod: perhaps a modparam desc_debug to enable this, rather than
665 * setting ll (log level, I presume) to non-zero? */
666 if (!ll)
667 return;
668
669 for (ix = ul_desc_index; ix < (ul_desc_index + cnt); ix++) {
670 BCMLOG(ll, "%s[%d] Buff[%x:%x] Next:[%x:%x] XferSz:%x Intr:%x,Last:%x\n",
671 ((p_dma_desc[ul_desc_index].dma_dir) ? "TDesc" : "RDesc"),
672 ul_desc_index,
673 p_dma_desc[ul_desc_index].buff_addr_high,
674 p_dma_desc[ul_desc_index].buff_addr_low,
675 p_dma_desc[ul_desc_index].next_desc_addr_high,
676 p_dma_desc[ul_desc_index].next_desc_addr_low,
677 p_dma_desc[ul_desc_index].xfer_size,
678 p_dma_desc[ul_desc_index].intr_enable,
679 p_dma_desc[ul_desc_index].last_rec_indicator);
680 }
681
682}
683
684static BC_STATUS crystalhd_hw_fill_desc(crystalhd_dio_req *ioreq,
685 dma_descriptor *desc,
686 dma_addr_t desc_paddr_base,
687 uint32_t sg_cnt, uint32_t sg_st_ix,
688 uint32_t sg_st_off, uint32_t xfr_sz)
689{
690 uint32_t count = 0, ix = 0, sg_ix = 0, len = 0, last_desc_ix = 0;
691 dma_addr_t desc_phy_addr = desc_paddr_base;
692 addr_64 addr_temp;
693
694 if (!ioreq || !desc || !desc_paddr_base || !xfr_sz ||
695 (!sg_cnt && !ioreq->uinfo.dir_tx)) {
696 BCMLOG_ERR("Invalid Args\n");
697 return BC_STS_INV_ARG;
698 }
699
700 for (ix = 0; ix < sg_cnt; ix++) {
701
702 /* Setup SGLE index. */
703 sg_ix = ix + sg_st_ix;
704
705 /* Get SGLE length */
706 len = crystalhd_get_sgle_len(ioreq, sg_ix);
707 if (len % 4) {
708 BCMLOG_ERR(" len in sg %d %d %d\n", len, sg_ix, sg_cnt);
709 return BC_STS_NOT_IMPL;
710 }
711 /* Setup DMA desc with Phy addr & Length at current index. */
712 addr_temp.full_addr = crystalhd_get_sgle_paddr(ioreq, sg_ix);
713 if (sg_ix == sg_st_ix) {
714 addr_temp.full_addr += sg_st_off;
715 len -= sg_st_off;
716 }
717 memset(&desc[ix], 0, sizeof(desc[ix]));
718 desc[ix].buff_addr_low = addr_temp.low_part;
719 desc[ix].buff_addr_high = addr_temp.high_part;
720 desc[ix].dma_dir = ioreq->uinfo.dir_tx;
721
722 /* Chain DMA descriptor. */
723 addr_temp.full_addr = desc_phy_addr + sizeof(dma_descriptor);
724 desc[ix].next_desc_addr_low = addr_temp.low_part;
725 desc[ix].next_desc_addr_high = addr_temp.high_part;
726
727 if ((count + len) > xfr_sz)
728 len = xfr_sz - count;
729
730 /* Debug.. */
731 if ((!len) || (len > crystalhd_get_sgle_len(ioreq, sg_ix))) {
732 BCMLOG_ERR("inv-len(%x) Ix(%d) count:%x xfr_sz:%x sg_cnt:%d\n",
733 len, ix, count, xfr_sz, sg_cnt);
734 return BC_STS_ERROR;
735 }
736 /* Length expects Multiple of 4 */
737 desc[ix].xfer_size = (len / 4);
738
739 crystalhd_hw_dump_desc(desc, ix, 1);
740
741 count += len;
742 desc_phy_addr += sizeof(dma_descriptor);
743 }
744
745 last_desc_ix = ix - 1;
746
747 if (ioreq->fb_size) {
748 memset(&desc[ix], 0, sizeof(desc[ix]));
749 addr_temp.full_addr = ioreq->fb_pa;
750 desc[ix].buff_addr_low = addr_temp.low_part;
751 desc[ix].buff_addr_high = addr_temp.high_part;
752 desc[ix].dma_dir = ioreq->uinfo.dir_tx;
753 desc[ix].xfer_size = 1;
754 desc[ix].fill_bytes = 4 - ioreq->fb_size;
755 count += ioreq->fb_size;
756 last_desc_ix++;
757 }
758
759 /* setup last descriptor..*/
760 desc[last_desc_ix].last_rec_indicator = 1;
761 desc[last_desc_ix].next_desc_addr_low = 0;
762 desc[last_desc_ix].next_desc_addr_high = 0;
763 desc[last_desc_ix].intr_enable = 1;
764
765 crystalhd_hw_dump_desc(desc, last_desc_ix, 1);
766
767 if (count != xfr_sz) {
768 BCMLOG_ERR("interal error sz curr:%x exp:%x\n", count, xfr_sz);
769 return BC_STS_ERROR;
770 }
771
772 return BC_STS_SUCCESS;
773}
774
775static BC_STATUS crystalhd_xlat_sgl_to_dma_desc(crystalhd_dio_req *ioreq,
776 pdma_desc_mem pdesc_mem,
777 uint32_t *uv_desc_index)
778{
779 dma_descriptor *desc = NULL;
780 dma_addr_t desc_paddr_base = 0;
781 uint32_t sg_cnt = 0, sg_st_ix = 0, sg_st_off = 0;
782 uint32_t xfr_sz = 0;
783 BC_STATUS sts = BC_STS_SUCCESS;
784
785 /* Check params.. */
786 if (!ioreq || !pdesc_mem || !uv_desc_index) {
787 BCMLOG_ERR("Invalid Args\n");
788 return BC_STS_INV_ARG;
789 }
790
791 if (!pdesc_mem->sz || !pdesc_mem->pdma_desc_start ||
792 !ioreq->sg || (!ioreq->sg_cnt && !ioreq->uinfo.dir_tx)) {
793 BCMLOG_ERR("Invalid Args\n");
794 return BC_STS_INV_ARG;
795 }
796
797 if ((ioreq->uinfo.dir_tx) && (ioreq->uinfo.uv_offset)) {
798 BCMLOG_ERR("UV offset for TX??\n");
799 return BC_STS_INV_ARG;
800
801 }
802
803 desc = pdesc_mem->pdma_desc_start;
804 desc_paddr_base = pdesc_mem->phy_addr;
805
806 if (ioreq->uinfo.dir_tx || (ioreq->uinfo.uv_offset == 0)) {
807 sg_cnt = ioreq->sg_cnt;
808 xfr_sz = ioreq->uinfo.xfr_len;
809 } else {
810 sg_cnt = ioreq->uinfo.uv_sg_ix + 1;
811 xfr_sz = ioreq->uinfo.uv_offset;
812 }
813
814 sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
815 sg_st_ix, sg_st_off, xfr_sz);
816
817 if ((sts != BC_STS_SUCCESS) || !ioreq->uinfo.uv_offset)
818 return sts;
819
820 /* Prepare for UV mapping.. */
821 desc = &pdesc_mem->pdma_desc_start[sg_cnt];
822 desc_paddr_base = pdesc_mem->phy_addr +
823 (sg_cnt * sizeof(dma_descriptor));
824
825 /* Done with desc addr.. now update sg stuff.*/
826 sg_cnt = ioreq->sg_cnt - ioreq->uinfo.uv_sg_ix;
827 xfr_sz = ioreq->uinfo.xfr_len - ioreq->uinfo.uv_offset;
828 sg_st_ix = ioreq->uinfo.uv_sg_ix;
829 sg_st_off = ioreq->uinfo.uv_sg_off;
830
831 sts = crystalhd_hw_fill_desc(ioreq, desc, desc_paddr_base, sg_cnt,
832 sg_st_ix, sg_st_off, xfr_sz);
833 if (sts != BC_STS_SUCCESS)
834 return sts;
835
836 *uv_desc_index = sg_st_ix;
837
838 return sts;
839}
840
841static void crystalhd_start_tx_dma_engine(struct crystalhd_hw *hw)
842{
843 uint32_t dma_cntrl;
844
845 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
846 if (!(dma_cntrl & DMA_START_BIT)) {
847 dma_cntrl |= DMA_START_BIT;
848 crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS,
849 dma_cntrl);
850 }
851
852 return;
853}
854
855/* _CHECK_THIS_
856 *
857 * Verify if the Stop generates a completion interrupt or not.
858 * if it does not generate an interrupt, then add polling here.
859 */
860static BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw)
861{
862 uint32_t dma_cntrl, cnt = 30;
863 uint32_t l1 = 1, l2 = 1;
864 unsigned long flags = 0;
865
866 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS);
867
868 BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n");
869
870 /* FIXME: jarod: invert dma_ctrl and check bit? or are there missing parens? */
871 if (!dma_cntrl & DMA_START_BIT) {
872 BCMLOG(BCMLOG_DBG, "Already Stopped\n");
873 return BC_STS_SUCCESS;
874 }
875
876 crystalhd_disable_interrupts(hw->adp);
877
878 /* Issue stop to HW */
879 /* This bit when set gave problems. Please check*/
880 dma_cntrl &= ~DMA_START_BIT;
881 crystalhd_reg_wr(hw->adp, MISC1_TX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
882
883 BCMLOG(BCMLOG_DBG, "Cleared the DMA Start bit\n");
884
885 /* Poll for 3seconds (30 * 100ms) on both the lists..*/
886 while ((l1 || l2) && cnt) {
887
888 if (l1) {
889 l1 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST0);
890 l1 &= DMA_START_BIT;
891 }
892
893 if (l2) {
894 l2 = crystalhd_reg_rd(hw->adp, MISC1_TX_FIRST_DESC_L_ADDR_LIST1);
895 l2 &= DMA_START_BIT;
896 }
897
898 msleep_interruptible(100);
899
900 cnt--;
901 }
902
903 if (!cnt) {
904 BCMLOG_ERR("Failed to stop TX DMA.. l1 %d, l2 %d\n", l1, l2);
905 crystalhd_enable_interrupts(hw->adp);
906 return BC_STS_ERROR;
907 }
908
909 spin_lock_irqsave(&hw->lock, flags);
910 hw->tx_list_post_index = 0;
911 spin_unlock_irqrestore(&hw->lock, flags);
912 BCMLOG(BCMLOG_DBG, "stopped TX DMA..\n");
913 crystalhd_enable_interrupts(hw->adp);
914
915 return BC_STS_SUCCESS;
916}
917
918static uint32_t crystalhd_get_pib_avail_cnt(struct crystalhd_hw *hw)
919{
920 /*
921 * Position of the PIB Entries can be found at
922 * 0th and the 1st location of the Circular list.
923 */
924 uint32_t Q_addr;
925 uint32_t pib_cnt, r_offset, w_offset;
926
927 Q_addr = hw->pib_del_Q_addr;
928
929 /* Get the Read Pointer */
930 crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
931
932 /* Get the Write Pointer */
933 crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
934
935 if (r_offset == w_offset)
936 return 0; /* Queue is empty */
937
938 if (w_offset > r_offset)
939 pib_cnt = w_offset - r_offset;
940 else
941 pib_cnt = (w_offset + MAX_PIB_Q_DEPTH) -
942 (r_offset + MIN_PIB_Q_DEPTH);
943
944 if (pib_cnt > MAX_PIB_Q_DEPTH) {
945 BCMLOG_ERR("Invalid PIB Count (%u)\n", pib_cnt);
946 return 0;
947 }
948
949 return pib_cnt;
950}
951
952static uint32_t crystalhd_get_addr_from_pib_Q(struct crystalhd_hw *hw)
953{
954 uint32_t Q_addr;
955 uint32_t addr_entry, r_offset, w_offset;
956
957 Q_addr = hw->pib_del_Q_addr;
958
959 /* Get the Read Pointer 0Th Location is Read Pointer */
960 crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
961
962 /* Get the Write Pointer 1st Location is Write pointer */
963 crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
964
965 /* Queue is empty */
966 if (r_offset == w_offset)
967 return 0;
968
969 if ((r_offset < MIN_PIB_Q_DEPTH) || (r_offset >= MAX_PIB_Q_DEPTH))
970 return 0;
971
972 /* Get the Actual Address of the PIB */
973 crystalhd_mem_rd(hw->adp, Q_addr + (r_offset * sizeof(uint32_t)),
974 1, &addr_entry);
975
976 /* Increment the Read Pointer */
977 r_offset++;
978
979 if (MAX_PIB_Q_DEPTH == r_offset)
980 r_offset = MIN_PIB_Q_DEPTH;
981
982 /* Write back the read pointer to It's Location */
983 crystalhd_mem_wr(hw->adp, Q_addr, 1, &r_offset);
984
985 return addr_entry;
986}
987
988static bool crystalhd_rel_addr_to_pib_Q(struct crystalhd_hw *hw, uint32_t addr_to_rel)
989{
990 uint32_t Q_addr;
991 uint32_t r_offset, w_offset, n_offset;
992
993 Q_addr = hw->pib_rel_Q_addr;
994
995 /* Get the Read Pointer */
996 crystalhd_mem_rd(hw->adp, Q_addr, 1, &r_offset);
997
998 /* Get the Write Pointer */
999 crystalhd_mem_rd(hw->adp, Q_addr + sizeof(uint32_t), 1, &w_offset);
1000
1001 if ((r_offset < MIN_PIB_Q_DEPTH) ||
1002 (r_offset >= MAX_PIB_Q_DEPTH))
1003 return false;
1004
1005 n_offset = w_offset + 1;
1006
1007 if (MAX_PIB_Q_DEPTH == n_offset)
1008 n_offset = MIN_PIB_Q_DEPTH;
1009
1010 if (r_offset == n_offset)
1011 return false; /* should never happen */
1012
1013 /* Write the DRAM ADDR to the Queue at Next Offset */
1014 crystalhd_mem_wr(hw->adp, Q_addr + (w_offset * sizeof(uint32_t)),
1015 1, &addr_to_rel);
1016
1017 /* Put the New value of the write pointer in Queue */
1018 crystalhd_mem_wr(hw->adp, Q_addr + sizeof(uint32_t), 1, &n_offset);
1019
1020 return true;
1021}
1022
1023static void cpy_pib_to_app(C011_PIB *src_pib, BC_PIC_INFO_BLOCK *dst_pib)
1024{
1025 if (!src_pib || !dst_pib) {
1026 BCMLOG_ERR("Invalid Arguments\n");
1027 return;
1028 }
1029
1030 dst_pib->timeStamp = 0;
1031 dst_pib->picture_number = src_pib->ppb.picture_number;
1032 dst_pib->width = src_pib->ppb.width;
1033 dst_pib->height = src_pib->ppb.height;
1034 dst_pib->chroma_format = src_pib->ppb.chroma_format;
1035 dst_pib->pulldown = src_pib->ppb.pulldown;
1036 dst_pib->flags = src_pib->ppb.flags;
1037 dst_pib->sess_num = src_pib->ptsStcOffset;
1038 dst_pib->aspect_ratio = src_pib->ppb.aspect_ratio;
1039 dst_pib->colour_primaries = src_pib->ppb.colour_primaries;
1040 dst_pib->picture_meta_payload = src_pib->ppb.picture_meta_payload;
1041 dst_pib->frame_rate = src_pib->resolution ;
1042 return;
1043}
1044
1045static void crystalhd_hw_proc_pib(struct crystalhd_hw *hw)
1046{
1047 unsigned int cnt;
1048 C011_PIB src_pib;
1049 uint32_t pib_addr, pib_cnt;
1050 BC_PIC_INFO_BLOCK *AppPib;
1051 crystalhd_rx_dma_pkt *rx_pkt = NULL;
1052
1053 pib_cnt = crystalhd_get_pib_avail_cnt(hw);
1054
1055 if (!pib_cnt)
1056 return;
1057
1058 for (cnt = 0; cnt < pib_cnt; cnt++) {
1059
1060 pib_addr = crystalhd_get_addr_from_pib_Q(hw);
1061 crystalhd_mem_rd(hw->adp, pib_addr, sizeof(C011_PIB) / 4,
1062 (uint32_t *)&src_pib);
1063
1064 if (src_pib.bFormatChange) {
1065 rx_pkt = (crystalhd_rx_dma_pkt *)crystalhd_dioq_fetch(hw->rx_freeq);
1066 if (!rx_pkt)
1067 return;
1068 rx_pkt->flags = 0;
1069 rx_pkt->flags |= COMP_FLAG_PIB_VALID | COMP_FLAG_FMT_CHANGE;
1070 AppPib = &rx_pkt->pib;
1071 cpy_pib_to_app(&src_pib, AppPib);
1072
1073 BCMLOG(BCMLOG_DBG,
1074 "App PIB:%x %x %x %x %x %x %x %x %x %x\n",
1075 rx_pkt->pib.picture_number,
1076 rx_pkt->pib.aspect_ratio,
1077 rx_pkt->pib.chroma_format,
1078 rx_pkt->pib.colour_primaries,
1079 rx_pkt->pib.frame_rate,
1080 rx_pkt->pib.height,
1081 rx_pkt->pib.height,
1082 rx_pkt->pib.n_drop,
1083 rx_pkt->pib.pulldown,
1084 rx_pkt->pib.ycom);
1085
1086 crystalhd_dioq_add(hw->rx_rdyq, (void *)rx_pkt, true, rx_pkt->pkt_tag);
1087
1088 }
1089
1090 crystalhd_rel_addr_to_pib_Q(hw, pib_addr);
1091 }
1092}
1093
1094static void crystalhd_start_rx_dma_engine(struct crystalhd_hw *hw)
1095{
1096 uint32_t dma_cntrl;
1097
1098 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
1099 if (!(dma_cntrl & DMA_START_BIT)) {
1100 dma_cntrl |= DMA_START_BIT;
1101 crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
1102 }
1103
1104 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
1105 if (!(dma_cntrl & DMA_START_BIT)) {
1106 dma_cntrl |= DMA_START_BIT;
1107 crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
1108 }
1109
1110 return;
1111}
1112
1113static void crystalhd_stop_rx_dma_engine(struct crystalhd_hw *hw)
1114{
1115 uint32_t dma_cntrl = 0, count = 30;
1116 uint32_t l0y = 1, l0uv = 1, l1y = 1, l1uv = 1;
1117
1118 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
1119 if ((dma_cntrl & DMA_START_BIT)) {
1120 dma_cntrl &= ~DMA_START_BIT;
1121 crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
1122 }
1123
1124 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
1125 if ((dma_cntrl & DMA_START_BIT)) {
1126 dma_cntrl &= ~DMA_START_BIT;
1127 crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
1128 }
1129
1130 /* Poll for 3seconds (30 * 100ms) on both the lists..*/
1131 while ((l0y || l0uv || l1y || l1uv) && count) {
1132
1133 if (l0y) {
1134 l0y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0);
1135 l0y &= DMA_START_BIT;
1136 if (!l0y) {
1137 hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
1138 }
1139 }
1140
1141 if (l1y) {
1142 l1y = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1);
1143 l1y &= DMA_START_BIT;
1144 if (!l1y) {
1145 hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
1146 }
1147 }
1148
1149 if (l0uv) {
1150 l0uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0);
1151 l0uv &= DMA_START_BIT;
1152 if (!l0uv) {
1153 hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
1154 }
1155 }
1156
1157 if (l1uv) {
1158 l1uv = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1);
1159 l1uv &= DMA_START_BIT;
1160 if (!l1uv) {
1161 hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
1162 }
1163 }
1164 msleep_interruptible(100);
1165 count--;
1166 }
1167
1168 hw->rx_list_post_index = 0;
1169
1170 BCMLOG(BCMLOG_SSTEP, "Capture Stop: %d List0:Sts:%x List1:Sts:%x\n",
1171 count, hw->rx_list_sts[0], hw->rx_list_sts[1]);
1172}
1173
1174static BC_STATUS crystalhd_hw_prog_rxdma(struct crystalhd_hw *hw, crystalhd_rx_dma_pkt *rx_pkt)
1175{
1176 uint32_t y_low_addr_reg, y_high_addr_reg;
1177 uint32_t uv_low_addr_reg, uv_high_addr_reg;
1178 addr_64 desc_addr;
1179 unsigned long flags;
1180
1181 if (!hw || !rx_pkt) {
1182 BCMLOG_ERR("Invalid Arguments\n");
1183 return BC_STS_INV_ARG;
1184 }
1185
1186 if (hw->rx_list_post_index >= DMA_ENGINE_CNT) {
1187 BCMLOG_ERR("List Out Of bounds %x\n", hw->rx_list_post_index);
1188 return BC_STS_INV_ARG;
1189 }
1190
1191 spin_lock_irqsave(&hw->rx_lock, flags);
1192 /* FIXME: jarod: sts_free is an enum for 0, in crystalhd_hw.h... yuk... */
1193 if (sts_free != hw->rx_list_sts[hw->rx_list_post_index]) {
1194 spin_unlock_irqrestore(&hw->rx_lock, flags);
1195 return BC_STS_BUSY;
1196 }
1197
1198 if (!hw->rx_list_post_index) {
1199 y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST0;
1200 y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST0;
1201 uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST0;
1202 uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST0;
1203 } else {
1204 y_low_addr_reg = MISC1_Y_RX_FIRST_DESC_L_ADDR_LIST1;
1205 y_high_addr_reg = MISC1_Y_RX_FIRST_DESC_U_ADDR_LIST1;
1206 uv_low_addr_reg = MISC1_UV_RX_FIRST_DESC_L_ADDR_LIST1;
1207 uv_high_addr_reg = MISC1_UV_RX_FIRST_DESC_U_ADDR_LIST1;
1208 }
1209 rx_pkt->pkt_tag = hw->rx_pkt_tag_seed + hw->rx_list_post_index;
1210 hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_y_intr;
1211 if (rx_pkt->uv_phy_addr)
1212 hw->rx_list_sts[hw->rx_list_post_index] |= rx_waiting_uv_intr;
1213 hw->rx_list_post_index = (hw->rx_list_post_index + 1) % DMA_ENGINE_CNT;
1214 spin_unlock_irqrestore(&hw->rx_lock, flags);
1215
1216 crystalhd_dioq_add(hw->rx_actq, (void *)rx_pkt, false, rx_pkt->pkt_tag);
1217
1218 crystalhd_start_rx_dma_engine(hw);
1219 /* Program the Y descriptor */
1220 desc_addr.full_addr = rx_pkt->desc_mem.phy_addr;
1221 crystalhd_reg_wr(hw->adp, y_high_addr_reg, desc_addr.high_part);
1222 crystalhd_reg_wr(hw->adp, y_low_addr_reg, desc_addr.low_part | 0x01);
1223
1224 if (rx_pkt->uv_phy_addr) {
1225 /* Program the UV descriptor */
1226 desc_addr.full_addr = rx_pkt->uv_phy_addr;
1227 crystalhd_reg_wr(hw->adp, uv_high_addr_reg, desc_addr.high_part);
1228 crystalhd_reg_wr(hw->adp, uv_low_addr_reg, desc_addr.low_part | 0x01);
1229 }
1230
1231 return BC_STS_SUCCESS;
1232}
1233
1234static BC_STATUS crystalhd_hw_post_cap_buff(struct crystalhd_hw *hw,
1235 crystalhd_rx_dma_pkt *rx_pkt)
1236{
1237 BC_STATUS sts = crystalhd_hw_prog_rxdma(hw, rx_pkt);
1238
1239 if (sts == BC_STS_BUSY)
1240 crystalhd_dioq_add(hw->rx_freeq, (void *)rx_pkt,
1241 false, rx_pkt->pkt_tag);
1242
1243 return sts;
1244}
1245
1246static void crystalhd_get_dnsz(struct crystalhd_hw *hw, uint32_t list_index,
1247 uint32_t *y_dw_dnsz, uint32_t *uv_dw_dnsz)
1248{
1249 uint32_t y_dn_sz_reg, uv_dn_sz_reg;
1250
1251 if (!list_index) {
1252 y_dn_sz_reg = MISC1_Y_RX_LIST0_CUR_BYTE_CNT;
1253 uv_dn_sz_reg = MISC1_UV_RX_LIST0_CUR_BYTE_CNT;
1254 } else {
1255 y_dn_sz_reg = MISC1_Y_RX_LIST1_CUR_BYTE_CNT;
1256 uv_dn_sz_reg = MISC1_UV_RX_LIST1_CUR_BYTE_CNT;
1257 }
1258
1259 *y_dw_dnsz = crystalhd_reg_rd(hw->adp, y_dn_sz_reg);
1260 *uv_dw_dnsz = crystalhd_reg_rd(hw->adp, uv_dn_sz_reg);
1261}
1262
1263/*
1264 * This function should be called only after making sure that the two DMA
1265 * lists are free. This function does not check if DMA's are active, before
1266 * turning off the DMA.
1267 */
1268static void crystalhd_hw_finalize_pause(struct crystalhd_hw *hw)
1269{
1270 uint32_t dma_cntrl, aspm;
1271
1272 hw->stop_pending = 0;
1273
1274 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS);
1275 if (dma_cntrl & DMA_START_BIT) {
1276 dma_cntrl &= ~DMA_START_BIT;
1277 crystalhd_reg_wr(hw->adp, MISC1_Y_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
1278 }
1279
1280 dma_cntrl = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS);
1281 if (dma_cntrl & DMA_START_BIT) {
1282 dma_cntrl &= ~DMA_START_BIT;
1283 crystalhd_reg_wr(hw->adp, MISC1_UV_RX_SW_DESC_LIST_CTRL_STS, dma_cntrl);
1284 }
1285 hw->rx_list_post_index = 0;
1286
1287 aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
1288 aspm |= ASPM_L1_ENABLE;
1289 /* NAREN BCMLOG(BCMLOG_INFO, "aspm on\n"); */
1290 crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
1291}
1292
1293static BC_STATUS crystalhd_rx_pkt_done(struct crystalhd_hw *hw, uint32_t list_index,
1294 BC_STATUS comp_sts)
1295{
1296 crystalhd_rx_dma_pkt *rx_pkt = NULL;
1297 uint32_t y_dw_dnsz, uv_dw_dnsz;
1298 BC_STATUS sts = BC_STS_SUCCESS;
1299
1300 if (!hw || list_index >= DMA_ENGINE_CNT) {
1301 BCMLOG_ERR("Invalid Arguments\n");
1302 return BC_STS_INV_ARG;
1303 }
1304
1305 rx_pkt = crystalhd_dioq_find_and_fetch(hw->rx_actq,
1306 hw->rx_pkt_tag_seed + list_index);
1307 if (!rx_pkt) {
1308 BCMLOG_ERR("Act-Q:PostIx:%x L0Sts:%x L1Sts:%x current L:%x tag:%x comp:%x\n",
1309 hw->rx_list_post_index, hw->rx_list_sts[0],
1310 hw->rx_list_sts[1], list_index,
1311 hw->rx_pkt_tag_seed + list_index, comp_sts);
1312 return BC_STS_INV_ARG;
1313 }
1314
1315 if (comp_sts == BC_STS_SUCCESS) {
1316 crystalhd_get_dnsz(hw, list_index, &y_dw_dnsz, &uv_dw_dnsz);
1317 rx_pkt->dio_req->uinfo.y_done_sz = y_dw_dnsz;
1318 rx_pkt->flags = COMP_FLAG_DATA_VALID;
1319 if (rx_pkt->uv_phy_addr)
1320 rx_pkt->dio_req->uinfo.uv_done_sz = uv_dw_dnsz;
1321 crystalhd_dioq_add(hw->rx_rdyq, rx_pkt, true,
1322 hw->rx_pkt_tag_seed + list_index);
1323 return sts;
1324 }
1325
1326 /* Check if we can post this DIO again. */
1327 return crystalhd_hw_post_cap_buff(hw, rx_pkt);
1328}
1329
1330static bool crystalhd_rx_list0_handler(struct crystalhd_hw *hw, uint32_t int_sts,
1331 uint32_t y_err_sts, uint32_t uv_err_sts)
1332{
1333 uint32_t tmp;
1334 list_sts tmp_lsts;
1335
1336 if (!(y_err_sts & GET_Y0_ERR_MSK) && !(uv_err_sts & GET_UV0_ERR_MSK))
1337 return false;
1338
1339 tmp_lsts = hw->rx_list_sts[0];
1340
1341 /* Y0 - DMA */
1342 tmp = y_err_sts & GET_Y0_ERR_MSK;
1343 if (int_sts & INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
1344 hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
1345
1346 if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
1347 hw->rx_list_sts[0] &= ~rx_waiting_y_intr;
1348 tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
1349 }
1350
1351 if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
1352 hw->rx_list_sts[0] &= ~rx_y_mask;
1353 hw->rx_list_sts[0] |= rx_y_error;
1354 tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
1355 }
1356
1357 if (tmp) {
1358 hw->rx_list_sts[0] &= ~rx_y_mask;
1359 hw->rx_list_sts[0] |= rx_y_error;
1360 hw->rx_list_post_index = 0;
1361 }
1362
1363 /* UV0 - DMA */
1364 tmp = uv_err_sts & GET_UV0_ERR_MSK;
1365 if (int_sts & INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK)
1366 hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
1367
1368 if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK) {
1369 hw->rx_list_sts[0] &= ~rx_waiting_uv_intr;
1370 tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK;
1371 }
1372
1373 if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK) {
1374 hw->rx_list_sts[0] &= ~rx_uv_mask;
1375 hw->rx_list_sts[0] |= rx_uv_error;
1376 tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK;
1377 }
1378
1379 if (tmp) {
1380 hw->rx_list_sts[0] &= ~rx_uv_mask;
1381 hw->rx_list_sts[0] |= rx_uv_error;
1382 hw->rx_list_post_index = 0;
1383 }
1384
1385 if (y_err_sts & GET_Y0_ERR_MSK) {
1386 tmp = y_err_sts & GET_Y0_ERR_MSK;
1387 crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
1388 }
1389
1390 if (uv_err_sts & GET_UV0_ERR_MSK) {
1391 tmp = uv_err_sts & GET_UV0_ERR_MSK;
1392 crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
1393 }
1394
1395 return (tmp_lsts != hw->rx_list_sts[0]);
1396}
1397
1398static bool crystalhd_rx_list1_handler(struct crystalhd_hw *hw, uint32_t int_sts,
1399 uint32_t y_err_sts, uint32_t uv_err_sts)
1400{
1401 uint32_t tmp;
1402 list_sts tmp_lsts;
1403
1404 if (!(y_err_sts & GET_Y1_ERR_MSK) && !(uv_err_sts & GET_UV1_ERR_MSK))
1405 return false;
1406
1407 tmp_lsts = hw->rx_list_sts[1];
1408
1409 /* Y1 - DMA */
1410 tmp = y_err_sts & GET_Y1_ERR_MSK;
1411 if (int_sts & INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK)
1412 hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
1413
1414 if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
1415 hw->rx_list_sts[1] &= ~rx_waiting_y_intr;
1416 tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
1417 }
1418
1419 if (y_err_sts & MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
1420 /* Add retry-support..*/
1421 hw->rx_list_sts[1] &= ~rx_y_mask;
1422 hw->rx_list_sts[1] |= rx_y_error;
1423 tmp &= ~MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
1424 }
1425
1426 if (tmp) {
1427 hw->rx_list_sts[1] &= ~rx_y_mask;
1428 hw->rx_list_sts[1] |= rx_y_error;
1429 hw->rx_list_post_index = 0;
1430 }
1431
1432 /* UV1 - DMA */
1433 tmp = uv_err_sts & GET_UV1_ERR_MSK;
1434 if (int_sts & INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK) {
1435 hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
1436 }
1437
1438 if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK) {
1439 hw->rx_list_sts[1] &= ~rx_waiting_uv_intr;
1440 tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK;
1441 }
1442
1443 if (uv_err_sts & MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK) {
1444 /* Add retry-support*/
1445 hw->rx_list_sts[1] &= ~rx_uv_mask;
1446 hw->rx_list_sts[1] |= rx_uv_error;
1447 tmp &= ~MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK;
1448 }
1449
1450 if (tmp) {
1451 hw->rx_list_sts[1] &= ~rx_uv_mask;
1452 hw->rx_list_sts[1] |= rx_uv_error;
1453 hw->rx_list_post_index = 0;
1454 }
1455
1456 if (y_err_sts & GET_Y1_ERR_MSK) {
1457 tmp = y_err_sts & GET_Y1_ERR_MSK;
1458 crystalhd_reg_wr(hw->adp, MISC1_Y_RX_ERROR_STATUS, tmp);
1459 }
1460
1461 if (uv_err_sts & GET_UV1_ERR_MSK) {
1462 tmp = uv_err_sts & GET_UV1_ERR_MSK;
1463 crystalhd_reg_wr(hw->adp, MISC1_UV_RX_ERROR_STATUS, tmp);
1464 }
1465
1466 return (tmp_lsts != hw->rx_list_sts[1]);
1467}
1468
1469
1470static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts)
1471{
1472 unsigned long flags;
1473 uint32_t i, list_avail = 0;
1474 BC_STATUS comp_sts = BC_STS_NO_DATA;
1475 uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0;
1476 bool ret = 0;
1477
1478 if (!hw) {
1479 BCMLOG_ERR("Invalid Arguments\n");
1480 return;
1481 }
1482
1483 if (!(intr_sts & GET_RX_INTR_MASK))
1484 return;
1485
1486 y_err_sts = crystalhd_reg_rd(hw->adp, MISC1_Y_RX_ERROR_STATUS);
1487 uv_err_sts = crystalhd_reg_rd(hw->adp, MISC1_UV_RX_ERROR_STATUS);
1488
1489 for (i = 0; i < DMA_ENGINE_CNT; i++) {
1490 /* Update States..*/
1491 spin_lock_irqsave(&hw->rx_lock, flags);
1492 if (i == 0)
1493 ret = crystalhd_rx_list0_handler(hw, intr_sts, y_err_sts, uv_err_sts);
1494 else
1495 ret = crystalhd_rx_list1_handler(hw, intr_sts, y_err_sts, uv_err_sts);
1496 if (ret) {
1497 switch (hw->rx_list_sts[i]) {
1498 case sts_free:
1499 comp_sts = BC_STS_SUCCESS;
1500 list_avail = 1;
1501 break;
1502 case rx_y_error:
1503 case rx_uv_error:
1504 case rx_sts_error:
1505 /* We got error on both or Y or uv. */
1506 hw->stats.rx_errors++;
1507 crystalhd_get_dnsz(hw, i, &y_dn_sz, &uv_dn_sz);
1508 /* FIXME: jarod: this is where my mini pci-e card is tripping up */
1509 BCMLOG(BCMLOG_DBG, "list_index:%x rx[%d] Y:%x "
1510 "UV:%x Int:%x YDnSz:%x UVDnSz:%x\n",
1511 i, hw->stats.rx_errors, y_err_sts,
1512 uv_err_sts, intr_sts, y_dn_sz, uv_dn_sz);
1513 hw->rx_list_sts[i] = sts_free;
1514 comp_sts = BC_STS_ERROR;
1515 break;
1516 default:
1517 /* Wait for completion..*/
1518 comp_sts = BC_STS_NO_DATA;
1519 break;
1520 }
1521 }
1522 spin_unlock_irqrestore(&hw->rx_lock, flags);
1523
1524 /* handle completion...*/
1525 if (comp_sts != BC_STS_NO_DATA) {
1526 crystalhd_rx_pkt_done(hw, i, comp_sts);
1527 comp_sts = BC_STS_NO_DATA;
1528 }
1529 }
1530
1531 if (list_avail) {
1532 if (hw->stop_pending) {
1533 if ((hw->rx_list_sts[0] == sts_free) &&
1534 (hw->rx_list_sts[1] == sts_free))
1535 crystalhd_hw_finalize_pause(hw);
1536 } else {
1537 crystalhd_hw_start_capture(hw);
1538 }
1539 }
1540}
1541
1542static BC_STATUS crystalhd_fw_cmd_post_proc(struct crystalhd_hw *hw,
1543 BC_FW_CMD *fw_cmd)
1544{
1545 BC_STATUS sts = BC_STS_SUCCESS;
1546 DecRspChannelStartVideo *st_rsp = NULL;
1547
1548 switch (fw_cmd->cmd[0]) {
1549 case eCMD_C011_DEC_CHAN_START_VIDEO:
1550 st_rsp = (DecRspChannelStartVideo *)fw_cmd->rsp;
1551 hw->pib_del_Q_addr = st_rsp->picInfoDeliveryQ;
1552 hw->pib_rel_Q_addr = st_rsp->picInfoReleaseQ;
1553 BCMLOG(BCMLOG_DBG, "DelQAddr:%x RelQAddr:%x\n",
1554 hw->pib_del_Q_addr, hw->pib_rel_Q_addr);
1555 break;
1556 case eCMD_C011_INIT:
1557 if (!(crystalhd_load_firmware_config(hw->adp))) {
1558 BCMLOG_ERR("Invalid Params.\n");
1559 sts = BC_STS_FW_AUTH_FAILED;
1560 }
1561 break;
1562 default:
1563 break;
1564 }
1565 return sts;
1566}
1567
1568static BC_STATUS crystalhd_put_ddr2sleep(struct crystalhd_hw *hw)
1569{
1570 uint32_t reg;
1571 link_misc_perst_decoder_ctrl rst_cntrl_reg;
1572
1573 /* Pulse reset pin of 7412 (MISC_PERST_DECODER_CTRL) */
1574 rst_cntrl_reg.whole_reg = crystalhd_reg_rd(hw->adp, MISC_PERST_DECODER_CTRL);
1575
1576 rst_cntrl_reg.bcm_7412_rst = 1;
1577 crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
1578 msleep_interruptible(50);
1579
1580 rst_cntrl_reg.bcm_7412_rst = 0;
1581 crystalhd_reg_wr(hw->adp, MISC_PERST_DECODER_CTRL, rst_cntrl_reg.whole_reg);
1582
1583 /* Close all banks, put DDR in idle */
1584 bc_dec_reg_wr(hw->adp, SDRAM_PRECHARGE, 0);
1585
1586 /* Set bit 25 (drop CKE pin of DDR) */
1587 reg = bc_dec_reg_rd(hw->adp, SDRAM_PARAM);
1588 reg |= 0x02000000;
1589 bc_dec_reg_wr(hw->adp, SDRAM_PARAM, reg);
1590
1591 /* Reset the audio block */
1592 bc_dec_reg_wr(hw->adp, AUD_DSP_MISC_SOFT_RESET, 0x1);
1593
1594 /* Power down Raptor PLL */
1595 reg = bc_dec_reg_rd(hw->adp, DecHt_PllCCtl);
1596 reg |= 0x00008000;
1597 bc_dec_reg_wr(hw->adp, DecHt_PllCCtl, reg);
1598
1599 /* Power down all Audio PLL */
1600 bc_dec_reg_wr(hw->adp, AIO_MISC_PLL_RESET, 0x1);
1601
1602 /* Power down video clock (75MHz) */
1603 reg = bc_dec_reg_rd(hw->adp, DecHt_PllECtl);
1604 reg |= 0x00008000;
1605 bc_dec_reg_wr(hw->adp, DecHt_PllECtl, reg);
1606
1607 /* Power down video clock (75MHz) */
1608 reg = bc_dec_reg_rd(hw->adp, DecHt_PllDCtl);
1609 reg |= 0x00008000;
1610 bc_dec_reg_wr(hw->adp, DecHt_PllDCtl, reg);
1611
1612 /* Power down core clock (200MHz) */
1613 reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
1614 reg |= 0x00008000;
1615 bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
1616
1617 /* Power down core clock (200MHz) */
1618 reg = bc_dec_reg_rd(hw->adp, DecHt_PllBCtl);
1619 reg |= 0x00008000;
1620 bc_dec_reg_wr(hw->adp, DecHt_PllBCtl, reg);
1621
1622 return BC_STS_SUCCESS;
1623}
1624
1625/************************************************
1626**
1627*************************************************/
1628
1629BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, uint32_t sz)
1630{
1631 uint32_t reg_data, cnt, *temp_buff;
1632 uint32_t fw_sig_len = 36;
1633 uint32_t dram_offset = BC_FWIMG_ST_ADDR, sig_reg;
1634
1635 BCMLOG_ENTER;
1636
1637 if (!adp || !buffer || !sz) {
1638 BCMLOG_ERR("Invalid Params.\n");
1639 return BC_STS_INV_ARG;
1640 }
1641
1642 reg_data = crystalhd_reg_rd(adp, OTP_CMD);
1643 if (!(reg_data & 0x02)) {
1644 BCMLOG_ERR("Invalid hw config.. otp not programmed\n");
1645 return BC_STS_ERROR;
1646 }
1647
1648 reg_data = 0;
1649 crystalhd_reg_wr(adp, DCI_CMD, 0);
1650 reg_data |= BC_BIT(0);
1651 crystalhd_reg_wr(adp, DCI_CMD, reg_data);
1652
1653 reg_data = 0;
1654 cnt = 1000;
1655 msleep_interruptible(10);
1656
1657 while (reg_data != BC_BIT(4)) {
1658 reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
1659 reg_data &= BC_BIT(4);
1660 if (--cnt == 0) {
1661 BCMLOG_ERR("Firmware Download RDY Timeout.\n");
1662 return BC_STS_TIMEOUT;
1663 }
1664 }
1665
1666 msleep_interruptible(10);
1667 /* Load the FW to the FW_ADDR field in the DCI_FIRMWARE_ADDR */
1668 crystalhd_reg_wr(adp, DCI_FIRMWARE_ADDR, dram_offset);
1669 temp_buff = (uint32_t *)buffer;
1670 for (cnt = 0; cnt < (sz - fw_sig_len); cnt += 4) {
1671 crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (dram_offset >> 19));
1672 crystalhd_reg_wr(adp, DCI_FIRMWARE_DATA, *temp_buff);
1673 dram_offset += 4;
1674 temp_buff++;
1675 }
1676 msleep_interruptible(10);
1677
1678 temp_buff++;
1679
1680 sig_reg = (uint32_t)DCI_SIGNATURE_DATA_7;
1681 for (cnt = 0; cnt < 8; cnt++) {
1682 uint32_t swapped_data = *temp_buff;
1683 swapped_data = bswap_32_1(swapped_data);
1684 crystalhd_reg_wr(adp, sig_reg, swapped_data);
1685 sig_reg -= 4;
1686 temp_buff++;
1687 }
1688 msleep_interruptible(10);
1689
1690 reg_data = 0;
1691 reg_data |= BC_BIT(1);
1692 crystalhd_reg_wr(adp, DCI_CMD, reg_data);
1693 msleep_interruptible(10);
1694
1695 reg_data = 0;
1696 reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
1697
1698 if ((reg_data & BC_BIT(9)) == BC_BIT(9)) {
1699 cnt = 1000;
1700 while ((reg_data & BC_BIT(0)) != BC_BIT(0)) {
1701 reg_data = crystalhd_reg_rd(adp, DCI_STATUS);
1702 reg_data &= BC_BIT(0);
1703 if (!(--cnt))
1704 break;
1705 msleep_interruptible(10);
1706 }
1707 reg_data = 0;
1708 reg_data = crystalhd_reg_rd(adp, DCI_CMD);
1709 reg_data |= BC_BIT(4);
1710 crystalhd_reg_wr(adp, DCI_CMD, reg_data);
1711
1712 } else {
1713 BCMLOG_ERR("F/w Signature mismatch\n");
1714 return BC_STS_FW_AUTH_FAILED;
1715 }
1716
1717 BCMLOG(BCMLOG_INFO, "Firmware Downloaded Successfully\n");
1718 return BC_STS_SUCCESS;;
1719}
1720
1721BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd)
1722{
1723 uint32_t cnt = 0, cmd_res_addr;
1724 uint32_t *cmd_buff, *res_buff;
1725 wait_queue_head_t fw_cmd_event;
1726 int rc = 0;
1727 BC_STATUS sts;
1728
1729 crystalhd_create_event(&fw_cmd_event);
1730
1731 BCMLOG_ENTER;
1732
1733 if (!hw || !fw_cmd) {
1734 BCMLOG_ERR("Invalid Arguments\n");
1735 return BC_STS_INV_ARG;
1736 }
1737
1738 cmd_buff = fw_cmd->cmd;
1739 res_buff = fw_cmd->rsp;
1740
1741 if (!cmd_buff || !res_buff) {
1742 BCMLOG_ERR("Invalid Parameters for F/W Command \n");
1743 return BC_STS_INV_ARG;
1744 }
1745
1746 hw->pwr_lock++;
1747
1748 hw->fwcmd_evt_sts = 0;
1749 hw->pfw_cmd_event = &fw_cmd_event;
1750
1751 /*Write the command to the memory*/
1752 crystalhd_mem_wr(hw->adp, TS_Host2CpuSnd, FW_CMD_BUFF_SZ, cmd_buff);
1753
1754 /*Memory Read for memory arbitrator flush*/
1755 crystalhd_mem_rd(hw->adp, TS_Host2CpuSnd, 1, &cnt);
1756
1757 /* Write the command address to mailbox */
1758 bc_dec_reg_wr(hw->adp, Hst2CpuMbx1, TS_Host2CpuSnd);
1759 msleep_interruptible(50);
1760
1761 crystalhd_wait_on_event(&fw_cmd_event, hw->fwcmd_evt_sts, 20000, rc, 0);
1762
1763 if (!rc) {
1764 sts = BC_STS_SUCCESS;
1765 } else if (rc == -EBUSY) {
1766 BCMLOG_ERR("Firmware command T/O\n");
1767 sts = BC_STS_TIMEOUT;
1768 } else if (rc == -EINTR) {
1769 BCMLOG(BCMLOG_DBG, "FwCmd Wait Signal int.\n");
1770 sts = BC_STS_IO_USER_ABORT;
1771 } else {
1772 BCMLOG_ERR("FwCmd IO Error.\n");
1773 sts = BC_STS_IO_ERROR;
1774 }
1775
1776 if (sts != BC_STS_SUCCESS) {
1777 BCMLOG_ERR("FwCmd Failed.\n");
1778 hw->pwr_lock--;
1779 return sts;
1780 }
1781
1782 /*Get the Responce Address*/
1783 cmd_res_addr = bc_dec_reg_rd(hw->adp, Cpu2HstMbx1);
1784
1785 /*Read the Response*/
1786 crystalhd_mem_rd(hw->adp, cmd_res_addr, FW_CMD_BUFF_SZ, res_buff);
1787
1788 hw->pwr_lock--;
1789
1790 if (res_buff[2] != C011_RET_SUCCESS) {
1791 BCMLOG_ERR("res_buff[2] != C011_RET_SUCCESS\n");
1792 return BC_STS_FW_CMD_ERR;
1793 }
1794
1795 sts = crystalhd_fw_cmd_post_proc(hw, fw_cmd);
1796 if (sts != BC_STS_SUCCESS)
1797 BCMLOG_ERR("crystalhd_fw_cmd_post_proc Failed.\n");
1798
1799 return sts;
1800}
1801
1802bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
1803{
1804 uint32_t intr_sts = 0;
1805 uint32_t deco_intr = 0;
1806 bool rc = 0;
1807
1808 if (!adp || !hw->dev_started)
1809 return rc;
1810
1811 hw->stats.num_interrupts++;
1812 hw->pwr_lock++;
1813
1814 deco_intr = bc_dec_reg_rd(adp, Stream2Host_Intr_Sts);
1815 intr_sts = crystalhd_reg_rd(adp, INTR_INTR_STATUS);
1816
1817 if (intr_sts) {
1818 /* let system know we processed interrupt..*/
1819 rc = 1;
1820 hw->stats.dev_interrupts++;
1821 }
1822
1823 if (deco_intr && (deco_intr != 0xdeaddead)) {
1824
1825 if (deco_intr & 0x80000000) {
1826 /*Set the Event and the status flag*/
1827 if (hw->pfw_cmd_event) {
1828 hw->fwcmd_evt_sts = 1;
1829 crystalhd_set_event(hw->pfw_cmd_event);
1830 }
1831 }
1832
1833 if (deco_intr & BC_BIT(1))
1834 crystalhd_hw_proc_pib(hw);
1835
1836 bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, deco_intr);
1837 /* FIXME: jarod: No udelay? might this be the real reason mini pci-e cards were stalling out? */
1838 bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0);
1839 rc = 1;
1840 }
1841
1842 /* Rx interrupts */
1843 crystalhd_rx_isr(hw, intr_sts);
1844
1845 /* Tx interrupts*/
1846 crystalhd_tx_isr(hw, intr_sts);
1847
1848 /* Clear interrupts */
1849 if (rc) {
1850 if (intr_sts)
1851 crystalhd_reg_wr(adp, INTR_INTR_CLR_REG, intr_sts);
1852
1853 crystalhd_reg_wr(adp, INTR_EOI_CTRL, 1);
1854 }
1855
1856 hw->pwr_lock--;
1857
1858 return rc;
1859}
1860
1861BC_STATUS crystalhd_hw_open(struct crystalhd_hw *hw, struct crystalhd_adp *adp)
1862{
1863 if (!hw || !adp) {
1864 BCMLOG_ERR("Invalid Arguments\n");
1865 return BC_STS_INV_ARG;
1866 }
1867
1868 if (hw->dev_started)
1869 return BC_STS_SUCCESS;
1870
1871 memset(hw, 0, sizeof(struct crystalhd_hw));
1872
1873 hw->adp = adp;
1874 spin_lock_init(&hw->lock);
1875 spin_lock_init(&hw->rx_lock);
1876 /* FIXME: jarod: what are these magic numbers?!? */
1877 hw->tx_ioq_tag_seed = 0x70023070;
1878 hw->rx_pkt_tag_seed = 0x70029070;
1879
1880 hw->stop_pending = 0;
1881 crystalhd_start_device(hw->adp);
1882 hw->dev_started = true;
1883
1884 /* set initial core clock */
1885 hw->core_clock_mhz = CLOCK_PRESET;
1886 hw->prev_n = 0;
1887 hw->pwr_lock = 0;
1888 crystalhd_hw_set_core_clock(hw);
1889
1890 return BC_STS_SUCCESS;
1891}
1892
1893BC_STATUS crystalhd_hw_close(struct crystalhd_hw *hw)
1894{
1895 if (!hw) {
1896 BCMLOG_ERR("Invalid Arguments\n");
1897 return BC_STS_INV_ARG;
1898 }
1899
1900 if (!hw->dev_started)
1901 return BC_STS_SUCCESS;
1902
1903 /* Stop and DDR sleep will happen in here */
1904 crystalhd_hw_suspend(hw);
1905 hw->dev_started = false;
1906
1907 return BC_STS_SUCCESS;
1908}
1909
1910BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *hw)
1911{
1912 unsigned int i;
1913 void *mem;
1914 size_t mem_len;
1915 dma_addr_t phy_addr;
1916 BC_STATUS sts = BC_STS_SUCCESS;
1917 crystalhd_rx_dma_pkt *rpkt;
1918
1919 if (!hw || !hw->adp) {
1920 BCMLOG_ERR("Invalid Arguments\n");
1921 return BC_STS_INV_ARG;
1922 }
1923
1924 sts = crystalhd_hw_create_ioqs(hw);
1925 if (sts != BC_STS_SUCCESS) {
1926 BCMLOG_ERR("Failed to create IOQs..\n");
1927 return sts;
1928 }
1929
1930 mem_len = BC_LINK_MAX_SGLS * sizeof(dma_descriptor);
1931
1932 for (i = 0; i < BC_TX_LIST_CNT; i++) {
1933 mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
1934 if (mem) {
1935 memset(mem, 0, mem_len);
1936 } else {
1937 BCMLOG_ERR("Insufficient Memory For TX\n");
1938 crystalhd_hw_free_dma_rings(hw);
1939 return BC_STS_INSUFF_RES;
1940 }
1941 /* rx_pkt_pool -- static memory allocation */
1942 hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = mem;
1943 hw->tx_pkt_pool[i].desc_mem.phy_addr = phy_addr;
1944 hw->tx_pkt_pool[i].desc_mem.sz = BC_LINK_MAX_SGLS *
1945 sizeof(dma_descriptor);
1946 hw->tx_pkt_pool[i].list_tag = 0;
1947
1948 /* Add TX dma requests to Free Queue..*/
1949 sts = crystalhd_dioq_add(hw->tx_freeq,
1950 &hw->tx_pkt_pool[i], false, 0);
1951 if (sts != BC_STS_SUCCESS) {
1952 crystalhd_hw_free_dma_rings(hw);
1953 return sts;
1954 }
1955 }
1956
1957 for (i = 0; i < BC_RX_LIST_CNT; i++) {
1958 rpkt = kzalloc(sizeof(*rpkt), GFP_KERNEL);
1959 if (!rpkt) {
1960 BCMLOG_ERR("Insufficient Memory For RX\n");
1961 crystalhd_hw_free_dma_rings(hw);
1962 return BC_STS_INSUFF_RES;
1963 }
1964
1965 mem = bc_kern_dma_alloc(hw->adp, mem_len, &phy_addr);
1966 if (mem) {
1967 memset(mem, 0, mem_len);
1968 } else {
1969 BCMLOG_ERR("Insufficient Memory For RX\n");
1970 crystalhd_hw_free_dma_rings(hw);
1971 return BC_STS_INSUFF_RES;
1972 }
1973 rpkt->desc_mem.pdma_desc_start = mem;
1974 rpkt->desc_mem.phy_addr = phy_addr;
1975 rpkt->desc_mem.sz = BC_LINK_MAX_SGLS * sizeof(dma_descriptor);
1976 rpkt->pkt_tag = hw->rx_pkt_tag_seed + i;
1977 crystalhd_hw_free_rx_pkt(hw, rpkt);
1978 }
1979
1980 return BC_STS_SUCCESS;
1981}
1982
1983BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *hw)
1984{
1985 unsigned int i;
1986 crystalhd_rx_dma_pkt *rpkt = NULL;
1987
1988 if (!hw || !hw->adp) {
1989 BCMLOG_ERR("Invalid Arguments\n");
1990 return BC_STS_INV_ARG;
1991 }
1992
1993 /* Delete all IOQs.. */
1994 crystalhd_hw_delete_ioqs(hw);
1995
1996 for (i = 0; i < BC_TX_LIST_CNT; i++) {
1997 if (hw->tx_pkt_pool[i].desc_mem.pdma_desc_start) {
1998 bc_kern_dma_free(hw->adp,
1999 hw->tx_pkt_pool[i].desc_mem.sz,
2000 hw->tx_pkt_pool[i].desc_mem.pdma_desc_start,
2001 hw->tx_pkt_pool[i].desc_mem.phy_addr);
2002
2003 hw->tx_pkt_pool[i].desc_mem.pdma_desc_start = NULL;
2004 }
2005 }
2006
2007 BCMLOG(BCMLOG_DBG, "Releasing RX Pkt pool\n");
2008 do {
2009 rpkt = crystalhd_hw_alloc_rx_pkt(hw);
2010 if (!rpkt)
2011 break;
2012 bc_kern_dma_free(hw->adp, rpkt->desc_mem.sz,
2013 rpkt->desc_mem.pdma_desc_start,
2014 rpkt->desc_mem.phy_addr);
2015 kfree(rpkt);
2016 } while (rpkt);
2017
2018 return BC_STS_SUCCESS;
2019}
2020
2021BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq,
2022 hw_comp_callback call_back,
2023 wait_queue_head_t *cb_event, uint32_t *list_id,
2024 uint8_t data_flags)
2025{
2026 tx_dma_pkt *tx_dma_packet = NULL;
2027 uint32_t first_desc_u_addr, first_desc_l_addr;
2028 uint32_t low_addr, high_addr;
2029 addr_64 desc_addr;
2030 BC_STATUS sts, add_sts;
2031 uint32_t dummy_index = 0;
2032 unsigned long flags;
2033 bool rc;
2034
2035 if (!hw || !ioreq || !call_back || !cb_event || !list_id) {
2036 BCMLOG_ERR("Invalid Arguments\n");
2037 return BC_STS_INV_ARG;
2038 }
2039
2040 /*
2041 * Since we hit code in busy condition very frequently,
2042 * we will check the code in status first before
2043 * checking the availability of free elem.
2044 *
2045 * This will avoid the Q fetch/add in normal condition.
2046 */
2047 rc = crystalhd_code_in_full(hw->adp, ioreq->uinfo.xfr_len,
2048 false, data_flags);
2049 if (rc) {
2050 hw->stats.cin_busy++;
2051 return BC_STS_BUSY;
2052 }
2053
2054 /* Get a list from TxFreeQ */
2055 tx_dma_packet = (tx_dma_pkt *)crystalhd_dioq_fetch(hw->tx_freeq);
2056 if (!tx_dma_packet) {
2057 BCMLOG_ERR("No empty elements..\n");
2058 return BC_STS_ERR_USAGE;
2059 }
2060
2061 sts = crystalhd_xlat_sgl_to_dma_desc(ioreq,
2062 &tx_dma_packet->desc_mem,
2063 &dummy_index);
2064 if (sts != BC_STS_SUCCESS) {
2065 add_sts = crystalhd_dioq_add(hw->tx_freeq, tx_dma_packet,
2066 false, 0);
2067 if (add_sts != BC_STS_SUCCESS)
2068 BCMLOG_ERR("double fault..\n");
2069
2070 return sts;
2071 }
2072
2073 hw->pwr_lock++;
2074
2075 desc_addr.full_addr = tx_dma_packet->desc_mem.phy_addr;
2076 low_addr = desc_addr.low_part;
2077 high_addr = desc_addr.high_part;
2078
2079 tx_dma_packet->call_back = call_back;
2080 tx_dma_packet->cb_event = cb_event;
2081 tx_dma_packet->dio_req = ioreq;
2082
2083 spin_lock_irqsave(&hw->lock, flags);
2084
2085 if (hw->tx_list_post_index == 0) {
2086 first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST0;
2087 first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST0;
2088 } else {
2089 first_desc_u_addr = MISC1_TX_FIRST_DESC_U_ADDR_LIST1;
2090 first_desc_l_addr = MISC1_TX_FIRST_DESC_L_ADDR_LIST1;
2091 }
2092
2093 *list_id = tx_dma_packet->list_tag = hw->tx_ioq_tag_seed +
2094 hw->tx_list_post_index;
2095
2096 hw->tx_list_post_index = (hw->tx_list_post_index + 1) % DMA_ENGINE_CNT;
2097
2098 spin_unlock_irqrestore(&hw->lock, flags);
2099
2100
2101 /* Insert in Active Q..*/
2102 crystalhd_dioq_add(hw->tx_actq, tx_dma_packet, false,
2103 tx_dma_packet->list_tag);
2104
2105 /*
2106 * Interrupt will come as soon as you write
2107 * the valid bit. So be ready for that. All
2108 * the initialization should happen before that.
2109 */
2110 crystalhd_start_tx_dma_engine(hw);
2111 crystalhd_reg_wr(hw->adp, first_desc_u_addr, desc_addr.high_part);
2112
2113 crystalhd_reg_wr(hw->adp, first_desc_l_addr, desc_addr.low_part | 0x01);
2114 /* Be sure we set the valid bit ^^^^ */
2115
2116 return BC_STS_SUCCESS;
2117}
2118
2119/*
2120 * This is a force cancel and we are racing with ISR.
2121 *
2122 * Will try to remove the req from ActQ before ISR gets it.
2123 * If ISR gets it first then the completion happens in the
2124 * normal path and we will return _STS_NO_DATA from here.
2125 *
2126 * FIX_ME: Not Tested the actual condition..
2127 */
2128BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id)
2129{
2130 if (!hw || !list_id) {
2131 BCMLOG_ERR("Invalid Arguments\n");
2132 return BC_STS_INV_ARG;
2133 }
2134
2135 crystalhd_stop_tx_dma_engine(hw);
2136 crystalhd_hw_tx_req_complete(hw, list_id, BC_STS_IO_USER_ABORT);
2137
2138 return BC_STS_SUCCESS;
2139}
2140
2141BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
2142 crystalhd_dio_req *ioreq, bool en_post)
2143{
2144 crystalhd_rx_dma_pkt *rpkt;
2145 uint32_t tag, uv_desc_ix = 0;
2146 BC_STATUS sts;
2147
2148 if (!hw || !ioreq) {
2149 BCMLOG_ERR("Invalid Arguments\n");
2150 return BC_STS_INV_ARG;
2151 }
2152
2153 rpkt = crystalhd_hw_alloc_rx_pkt(hw);
2154 if (!rpkt) {
2155 BCMLOG_ERR("Insufficient resources\n");
2156 return BC_STS_INSUFF_RES;
2157 }
2158
2159 rpkt->dio_req = ioreq;
2160 tag = rpkt->pkt_tag;
2161
2162 sts = crystalhd_xlat_sgl_to_dma_desc(ioreq, &rpkt->desc_mem, &uv_desc_ix);
2163 if (sts != BC_STS_SUCCESS)
2164 return sts;
2165
2166 rpkt->uv_phy_addr = 0;
2167
2168 /* Store the address of UV in the rx packet for post*/
2169 if (uv_desc_ix)
2170 rpkt->uv_phy_addr = rpkt->desc_mem.phy_addr +
2171 (sizeof(dma_descriptor) * (uv_desc_ix + 1));
2172
2173 if (en_post)
2174 sts = crystalhd_hw_post_cap_buff(hw, rpkt);
2175 else
2176 sts = crystalhd_dioq_add(hw->rx_freeq, rpkt, false, tag);
2177
2178 return sts;
2179}
2180
2181BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
2182 BC_PIC_INFO_BLOCK *pib,
2183 crystalhd_dio_req **ioreq)
2184{
2185 crystalhd_rx_dma_pkt *rpkt;
2186 uint32_t timeout = BC_PROC_OUTPUT_TIMEOUT / 1000;
2187 uint32_t sig_pending = 0;
2188
2189
2190 if (!hw || !ioreq || !pib) {
2191 BCMLOG_ERR("Invalid Arguments\n");
2192 return BC_STS_INV_ARG;
2193 }
2194
2195 rpkt = crystalhd_dioq_fetch_wait(hw->rx_rdyq, timeout, &sig_pending);
2196 if (!rpkt) {
2197 if (sig_pending) {
2198 BCMLOG(BCMLOG_INFO, "wait on frame time out %d\n", sig_pending);
2199 return BC_STS_IO_USER_ABORT;
2200 } else {
2201 return BC_STS_TIMEOUT;
2202 }
2203 }
2204
2205 rpkt->dio_req->uinfo.comp_flags = rpkt->flags;
2206
2207 if (rpkt->flags & COMP_FLAG_PIB_VALID)
2208 memcpy(pib, &rpkt->pib, sizeof(*pib));
2209
2210 *ioreq = rpkt->dio_req;
2211
2212 crystalhd_hw_free_rx_pkt(hw, rpkt);
2213
2214 return BC_STS_SUCCESS;
2215}
2216
2217BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw)
2218{
2219 crystalhd_rx_dma_pkt *rx_pkt;
2220 BC_STATUS sts;
2221 uint32_t i;
2222
2223 if (!hw) {
2224 BCMLOG_ERR("Invalid Arguments\n");
2225 return BC_STS_INV_ARG;
2226 }
2227
2228 /* This is start of capture.. Post to both the lists.. */
2229 for (i = 0; i < DMA_ENGINE_CNT; i++) {
2230 rx_pkt = crystalhd_dioq_fetch(hw->rx_freeq);
2231 if (!rx_pkt)
2232 return BC_STS_NO_DATA;
2233 sts = crystalhd_hw_post_cap_buff(hw, rx_pkt);
2234 if (BC_STS_SUCCESS != sts)
2235 break;
2236
2237 }
2238
2239 return BC_STS_SUCCESS;
2240}
2241
2242BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw)
2243{
2244 void *temp = NULL;
2245
2246 if (!hw) {
2247 BCMLOG_ERR("Invalid Arguments\n");
2248 return BC_STS_INV_ARG;
2249 }
2250
2251 crystalhd_stop_rx_dma_engine(hw);
2252
2253 do {
2254 temp = crystalhd_dioq_fetch(hw->rx_freeq);
2255 if (temp)
2256 crystalhd_rx_pkt_rel_call_back(hw, temp);
2257 } while (temp);
2258
2259 return BC_STS_SUCCESS;
2260}
2261
2262BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw)
2263{
2264 hw->stats.pause_cnt++;
2265 hw->stop_pending = 1;
2266
2267 if ((hw->rx_list_sts[0] == sts_free) &&
2268 (hw->rx_list_sts[1] == sts_free))
2269 crystalhd_hw_finalize_pause(hw);
2270
2271 return BC_STS_SUCCESS;
2272}
2273
2274BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw)
2275{
2276 BC_STATUS sts;
2277 uint32_t aspm;
2278
2279 hw->stop_pending = 0;
2280
2281 aspm = crystalhd_reg_rd(hw->adp, PCIE_DLL_DATA_LINK_CONTROL);
2282 aspm &= ~ASPM_L1_ENABLE;
2283/* NAREN BCMLOG(BCMLOG_INFO, "aspm off\n"); */
2284 crystalhd_reg_wr(hw->adp, PCIE_DLL_DATA_LINK_CONTROL, aspm);
2285
2286 sts = crystalhd_hw_start_capture(hw);
2287 return sts;
2288}
2289
2290BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw)
2291{
2292 BC_STATUS sts;
2293
2294 if (!hw) {
2295 BCMLOG_ERR("Invalid Arguments\n");
2296 return BC_STS_INV_ARG;
2297 }
2298
2299 sts = crystalhd_put_ddr2sleep(hw);
2300 if (sts != BC_STS_SUCCESS) {
2301 BCMLOG_ERR("Failed to Put DDR To Sleep!!\n");
2302 return BC_STS_ERROR;
2303 }
2304
2305 if (!crystalhd_stop_device(hw->adp)) {
2306 BCMLOG_ERR("Failed to Stop Device!!\n");
2307 return BC_STS_ERROR;
2308 }
2309
2310 return BC_STS_SUCCESS;
2311}
2312
2313void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats)
2314{
2315 if (!hw) {
2316 BCMLOG_ERR("Invalid Arguments\n");
2317 return;
2318 }
2319
2320 /* if called w/NULL stats, its a req to zero out the stats */
2321 if (!stats) {
2322 memset(&hw->stats, 0, sizeof(hw->stats));
2323 return;
2324 }
2325
2326 hw->stats.freeq_count = crystalhd_dioq_count(hw->rx_freeq);
2327 hw->stats.rdyq_count = crystalhd_dioq_count(hw->rx_rdyq);
2328 memcpy(stats, &hw->stats, sizeof(*stats));
2329}
2330
2331BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *hw)
2332{
2333 uint32_t reg, n, i;
2334 uint32_t vco_mg, refresh_reg;
2335
2336 if (!hw) {
2337 BCMLOG_ERR("Invalid Arguments\n");
2338 return BC_STS_INV_ARG;
2339 }
2340
2341 /* FIXME: jarod: wha? */
2342 /*n = (hw->core_clock_mhz * 3) / 20 + 1; */
2343 n = hw->core_clock_mhz/5;
2344
2345 if (n == hw->prev_n)
2346 return BC_STS_CLK_NOCHG;
2347
2348 if (hw->pwr_lock > 0) {
2349 /* BCMLOG(BCMLOG_INFO,"pwr_lock is %u\n", hw->pwr_lock) */
2350 return BC_STS_CLK_NOCHG;
2351 }
2352
2353 i = n * 27;
2354 if (i < 560)
2355 vco_mg = 0;
2356 else if (i < 900)
2357 vco_mg = 1;
2358 else if (i < 1030)
2359 vco_mg = 2;
2360 else
2361 vco_mg = 3;
2362
2363 reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
2364
2365 reg &= 0xFFFFCFC0;
2366 reg |= n;
2367 reg |= vco_mg << 12;
2368
2369 BCMLOG(BCMLOG_INFO, "clock is moving to %d with n %d with vco_mg %d\n",
2370 hw->core_clock_mhz, n, vco_mg);
2371
2372 /* Change the DRAM refresh rate to accomodate the new frequency */
2373 /* refresh reg = ((refresh_rate * clock_rate)/16) - 1; rounding up*/
2374 refresh_reg = (7 * hw->core_clock_mhz / 16);
2375 bc_dec_reg_wr(hw->adp, SDRAM_REF_PARAM, ((1 << 12) | refresh_reg));
2376
2377 bc_dec_reg_wr(hw->adp, DecHt_PllACtl, reg);
2378
2379 i = 0;
2380
2381 for (i = 0; i < 10; i++) {
2382 reg = bc_dec_reg_rd(hw->adp, DecHt_PllACtl);
2383
2384 if (reg & 0x00020000) {
2385 hw->prev_n = n;
2386 /* FIXME: jarod: outputting a random "C" is... confusing... */
2387 BCMLOG(BCMLOG_INFO, "C");
2388 return BC_STS_SUCCESS;
2389 } else {
2390 msleep_interruptible(10);
2391 }
2392 }
2393 BCMLOG(BCMLOG_INFO, "clk change failed\n");
2394 return BC_STS_CLK_NOCHG;
2395}
diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h
new file mode 100644
index 000000000000..1c6318e912ac
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_hw.h
@@ -0,0 +1,398 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_hw . h
5 *
6 * Description:
7 * BCM70012 Linux driver hardware layer.
8 *
9 * HISTORY:
10 *
11 **********************************************************************
12 * This file is part of the crystalhd device driver.
13 *
14 * This driver is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * This driver is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
25 **********************************************************************/
26
27#ifndef _CRYSTALHD_HW_H_
28#define _CRYSTALHD_HW_H_
29
30#include "crystalhd_misc.h"
31#include "crystalhd_fw_if.h"
32
33/* HW constants..*/
34#define DMA_ENGINE_CNT 2
35#define MAX_PIB_Q_DEPTH 64
36#define MIN_PIB_Q_DEPTH 2
37#define WR_POINTER_OFF 4
38
39#define ASPM_L1_ENABLE (BC_BIT(27))
40
41/*************************************************
42 7412 Decoder Registers.
43**************************************************/
44#define FW_CMD_BUFF_SZ 64
45#define TS_Host2CpuSnd 0x00000100
46#define Hst2CpuMbx1 0x00100F00
47#define Cpu2HstMbx1 0x00100F04
48#define MbxStat1 0x00100F08
49#define Stream2Host_Intr_Sts 0x00100F24
50#define C011_RET_SUCCESS 0x0 /* Reutrn status of firmware command. */
51
52/* TS input status register */
53#define TS_StreamAFIFOStatus 0x0010044C
54#define TS_StreamBFIFOStatus 0x0010084C
55
56/*UART Selection definitions*/
57#define UartSelectA 0x00100300
58#define UartSelectB 0x00100304
59
60#define BSVS_UART_DEC_NONE 0x00
61#define BSVS_UART_DEC_OUTER 0x01
62#define BSVS_UART_DEC_INNER 0x02
63#define BSVS_UART_STREAM 0x03
64
65/* Code-In fifo */
66#define REG_DecCA_RegCinCTL 0xa00
67#define REG_DecCA_RegCinBase 0xa0c
68#define REG_DecCA_RegCinEnd 0xa10
69#define REG_DecCA_RegCinWrPtr 0xa04
70#define REG_DecCA_RegCinRdPtr 0xa08
71
72#define REG_Dec_TsUser0Base 0x100864
73#define REG_Dec_TsUser0Rdptr 0x100868
74#define REG_Dec_TsUser0Wrptr 0x10086C
75#define REG_Dec_TsUser0End 0x100874
76
77/* ASF Case ...*/
78#define REG_Dec_TsAudCDB2Base 0x10036c
79#define REG_Dec_TsAudCDB2Rdptr 0x100378
80#define REG_Dec_TsAudCDB2Wrptr 0x100374
81#define REG_Dec_TsAudCDB2End 0x100370
82
83/* DRAM bringup Registers */
84#define SDRAM_PARAM 0x00040804
85#define SDRAM_PRECHARGE 0x000408B0
86#define SDRAM_EXT_MODE 0x000408A4
87#define SDRAM_MODE 0x000408A0
88#define SDRAM_REFRESH 0x00040890
89#define SDRAM_REF_PARAM 0x00040808
90
91#define DecHt_PllACtl 0x34000C
92#define DecHt_PllBCtl 0x340010
93#define DecHt_PllCCtl 0x340014
94#define DecHt_PllDCtl 0x340034
95#define DecHt_PllECtl 0x340038
96#define AUD_DSP_MISC_SOFT_RESET 0x00240104
97#define AIO_MISC_PLL_RESET 0x0026000C
98#define PCIE_CLK_REQ_REG 0xDC
99#define PCI_CLK_REQ_ENABLE (BC_BIT(8))
100
101/*************************************************
102 F/W Copy engine definitions..
103**************************************************/
104#define BC_FWIMG_ST_ADDR 0x00000000
105/* FIXME: jarod: there's a kernel function that'll do this for us... */
106#define rotr32_1(x, n) (((x) >> n) | ((x) << (32 - n)))
107#define bswap_32_1(x) ((rotr32_1((x), 24) & 0x00ff00ff) | (rotr32_1((x), 8) & 0xff00ff00))
108
109#define DecHt_HostSwReset 0x340000
110#define BC_DRAM_FW_CFG_ADDR 0x001c2000
111
112typedef union _addr_64_ {
113 struct {
114 uint32_t low_part;
115 uint32_t high_part;
116 };
117
118 uint64_t full_addr;
119
120} addr_64;
121
122typedef union _intr_mask_reg_ {
123 struct {
124 uint32_t mask_tx_done:1;
125 uint32_t mask_tx_err:1;
126 uint32_t mask_rx_done:1;
127 uint32_t mask_rx_err:1;
128 uint32_t mask_pcie_err:1;
129 uint32_t mask_pcie_rbusmast_err:1;
130 uint32_t mask_pcie_rgr_bridge:1;
131 uint32_t reserved:25;
132 };
133
134 uint32_t whole_reg;
135
136} intr_mask_reg;
137
138typedef union _link_misc_perst_deco_ctrl_ {
139 struct {
140 uint32_t bcm7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
141 uint32_t reserved0:3; /* Reserved.No Effect*/
142 uint32_t stop_bcm_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
143 uint32_t reserved1:27; /* Reseved. No Effect*/
144 };
145
146 uint32_t whole_reg;
147
148} link_misc_perst_deco_ctrl;
149
150typedef union _link_misc_perst_clk_ctrl_ {
151 struct {
152 uint32_t sel_alt_clk:1; /* When set, selects a 6.75MHz clock as the source of core_clk */
153 uint32_t stop_core_clk:1; /* When set, stops the branch of core_clk that is not needed for low power operation */
154 uint32_t pll_pwr_dn:1; /* When set, powers down the main PLL. The alternate clock bit should be set
155 to select an alternate clock before setting this bit.*/
156 uint32_t reserved0:5; /* Reserved */
157 uint32_t pll_mult:8; /* This setting controls the multiplier for the PLL. */
158 uint32_t pll_div:4; /* This setting controls the divider for the PLL. */
159 uint32_t reserved1:12; /* Reserved */
160 };
161
162 uint32_t whole_reg;
163
164} link_misc_perst_clk_ctrl;
165
166
167typedef union _link_misc_perst_decoder_ctrl_ {
168 struct {
169 uint32_t bcm_7412_rst:1; /* 1 -> BCM7412 is held in reset. Reset value 1.*/
170 uint32_t res0:3; /* Reserved.No Effect*/
171 uint32_t stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/
172 uint32_t res1:27; /* Reseved. No Effect */
173 };
174
175 uint32_t whole_reg;
176
177} link_misc_perst_decoder_ctrl;
178
179
180typedef union _desc_low_addr_reg_ {
181 struct {
182 uint32_t list_valid:1;
183 uint32_t reserved:4;
184 uint32_t low_addr:27;
185 };
186
187 uint32_t whole_reg;
188
189} desc_low_addr_reg;
190
191typedef struct _dma_descriptor_ { /* 8 32-bit values */
192 /* 0th u32 */
193 uint32_t sdram_buff_addr:28; /* bits 0-27: SDRAM Address */
194 uint32_t res0:4; /* bits 28-31: Reserved */
195
196 /* 1st u32 */
197 uint32_t buff_addr_low; /* 1 buffer address low */
198 uint32_t buff_addr_high; /* 2 buffer address high */
199
200 /* 3rd u32 */
201 uint32_t res2:2; /* 0-1 - Reserved */
202 uint32_t xfer_size:23; /* 2-24 = Xfer size in words */
203 uint32_t res3:6; /* 25-30 reserved */
204 uint32_t intr_enable:1; /* 31 - Interrupt After this desc */
205
206 /* 4th u32 */
207 uint32_t endian_xlat_align:2; /* 0-1 Endian Translation */
208 uint32_t next_desc_cont:1; /* 2 - Next desc is in contig memory */
209 uint32_t res4:25; /* 3 - 27 Reserved bits */
210 uint32_t fill_bytes:2; /* 28-29 Bits Fill Bytes */
211 uint32_t dma_dir:1; /* 30 bit DMA Direction */
212 uint32_t last_rec_indicator:1; /* 31 bit Last Record Indicator */
213
214 /* 5th u32 */
215 uint32_t next_desc_addr_low; /* 32-bits Next Desc Addr lower */
216
217 /* 6th u32 */
218 uint32_t next_desc_addr_high; /* 32-bits Next Desc Addr Higher */
219
220 /* 7th u32 */
221 uint32_t res8; /* Last 32bits reserved */
222
223} dma_descriptor, *pdma_descriptor;
224
225/*
226 * We will allocate the memory in 4K pages
227 * the linked list will be a list of 32 byte descriptors.
228 * The virtual address will determine what should be freed.
229 */
230typedef struct _dma_desc_mem_ {
231 pdma_descriptor pdma_desc_start; /* 32-bytes for dma descriptor. should be first element */
232 dma_addr_t phy_addr; /* physical address of each DMA desc */
233 uint32_t sz;
234 struct _dma_desc_mem_ *Next; /* points to Next Descriptor in chain */
235
236} dma_desc_mem, *pdma_desc_mem;
237
238
239
240typedef enum _list_sts_ {
241 sts_free = 0,
242
243 /* RX-Y Bits 0:7 */
244 rx_waiting_y_intr = 0x00000001,
245 rx_y_error = 0x00000004,
246
247 /* RX-UV Bits 8:16 */
248 rx_waiting_uv_intr = 0x0000100,
249 rx_uv_error = 0x0000400,
250
251 rx_sts_waiting = (rx_waiting_y_intr|rx_waiting_uv_intr),
252 rx_sts_error = (rx_y_error|rx_uv_error),
253
254 rx_y_mask = 0x000000FF,
255 rx_uv_mask = 0x0000FF00,
256
257} list_sts;
258
259typedef struct _tx_dma_pkt_ {
260 dma_desc_mem desc_mem;
261 hw_comp_callback call_back;
262 crystalhd_dio_req *dio_req;
263 wait_queue_head_t *cb_event;
264 uint32_t list_tag;
265
266} tx_dma_pkt;
267
268typedef struct _crystalhd_rx_dma_pkt {
269 dma_desc_mem desc_mem;
270 crystalhd_dio_req *dio_req;
271 uint32_t pkt_tag;
272 uint32_t flags;
273 BC_PIC_INFO_BLOCK pib;
274 dma_addr_t uv_phy_addr;
275 struct _crystalhd_rx_dma_pkt *next;
276
277} crystalhd_rx_dma_pkt;
278
279struct crystalhd_hw_stats{
280 uint32_t rx_errors;
281 uint32_t tx_errors;
282 uint32_t freeq_count;
283 uint32_t rdyq_count;
284 uint32_t num_interrupts;
285 uint32_t dev_interrupts;
286 uint32_t cin_busy;
287 uint32_t pause_cnt;
288};
289
290struct crystalhd_hw {
291 tx_dma_pkt tx_pkt_pool[DMA_ENGINE_CNT];
292 spinlock_t lock;
293
294 uint32_t tx_ioq_tag_seed;
295 uint32_t tx_list_post_index;
296
297 crystalhd_rx_dma_pkt *rx_pkt_pool_head;
298 uint32_t rx_pkt_tag_seed;
299
300 bool dev_started;
301 void *adp;
302
303 wait_queue_head_t *pfw_cmd_event;
304 int fwcmd_evt_sts;
305
306 uint32_t pib_del_Q_addr;
307 uint32_t pib_rel_Q_addr;
308
309 crystalhd_dioq_t *tx_freeq;
310 crystalhd_dioq_t *tx_actq;
311
312 /* Rx DMA Engine Specific Locks */
313 spinlock_t rx_lock;
314 uint32_t rx_list_post_index;
315 list_sts rx_list_sts[DMA_ENGINE_CNT];
316 crystalhd_dioq_t *rx_rdyq;
317 crystalhd_dioq_t *rx_freeq;
318 crystalhd_dioq_t *rx_actq;
319 uint32_t stop_pending;
320
321 /* HW counters.. */
322 struct crystalhd_hw_stats stats;
323
324 /* Core clock in MHz */
325 uint32_t core_clock_mhz;
326 uint32_t prev_n;
327 uint32_t pwr_lock;
328};
329
330/* Clock defines for power control */
331#define CLOCK_PRESET 175
332
333/* DMA engine register BIT mask wrappers.. */
334#define DMA_START_BIT MISC1_TX_SW_DESC_LIST_CTRL_STS_TX_DMA_RUN_STOP_MASK
335
336#define GET_RX_INTR_MASK (INTR_INTR_STATUS_L1_UV_RX_DMA_ERR_INTR_MASK | \
337 INTR_INTR_STATUS_L1_UV_RX_DMA_DONE_INTR_MASK | \
338 INTR_INTR_STATUS_L1_Y_RX_DMA_ERR_INTR_MASK | \
339 INTR_INTR_STATUS_L1_Y_RX_DMA_DONE_INTR_MASK | \
340 INTR_INTR_STATUS_L0_UV_RX_DMA_ERR_INTR_MASK | \
341 INTR_INTR_STATUS_L0_UV_RX_DMA_DONE_INTR_MASK | \
342 INTR_INTR_STATUS_L0_Y_RX_DMA_ERR_INTR_MASK | \
343 INTR_INTR_STATUS_L0_Y_RX_DMA_DONE_INTR_MASK)
344
345#define GET_Y0_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
346 MISC1_Y_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
347 MISC1_Y_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
348 MISC1_Y_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
349
350#define GET_UV0_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L0_OVERRUN_ERROR_MASK | \
351 MISC1_UV_RX_ERROR_STATUS_RX_L0_UNDERRUN_ERROR_MASK | \
352 MISC1_UV_RX_ERROR_STATUS_RX_L0_DESC_TX_ABORT_ERRORS_MASK | \
353 MISC1_UV_RX_ERROR_STATUS_RX_L0_FIFO_FULL_ERRORS_MASK)
354
355#define GET_Y1_ERR_MSK (MISC1_Y_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
356 MISC1_Y_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
357 MISC1_Y_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
358 MISC1_Y_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
359
360#define GET_UV1_ERR_MSK (MISC1_UV_RX_ERROR_STATUS_RX_L1_OVERRUN_ERROR_MASK | \
361 MISC1_UV_RX_ERROR_STATUS_RX_L1_UNDERRUN_ERROR_MASK | \
362 MISC1_UV_RX_ERROR_STATUS_RX_L1_DESC_TX_ABORT_ERRORS_MASK | \
363 MISC1_UV_RX_ERROR_STATUS_RX_L1_FIFO_FULL_ERRORS_MASK)
364
365
366/**** API Exposed to the other layers ****/
367BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp,
368 void *buffer, uint32_t sz);
369BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, BC_FW_CMD *fw_cmd);
370bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw);
371BC_STATUS crystalhd_hw_open(struct crystalhd_hw *, struct crystalhd_adp *);
372BC_STATUS crystalhd_hw_close(struct crystalhd_hw *);
373BC_STATUS crystalhd_hw_setup_dma_rings(struct crystalhd_hw *);
374BC_STATUS crystalhd_hw_free_dma_rings(struct crystalhd_hw *);
375
376
377BC_STATUS crystalhd_hw_post_tx(struct crystalhd_hw *hw, crystalhd_dio_req *ioreq,
378 hw_comp_callback call_back,
379 wait_queue_head_t *cb_event,
380 uint32_t *list_id, uint8_t data_flags);
381
382BC_STATUS crystalhd_hw_pause(struct crystalhd_hw *hw);
383BC_STATUS crystalhd_hw_unpause(struct crystalhd_hw *hw);
384BC_STATUS crystalhd_hw_suspend(struct crystalhd_hw *hw);
385BC_STATUS crystalhd_hw_cancel_tx(struct crystalhd_hw *hw, uint32_t list_id);
386BC_STATUS crystalhd_hw_add_cap_buffer(struct crystalhd_hw *hw,
387 crystalhd_dio_req *ioreq, bool en_post);
388BC_STATUS crystalhd_hw_get_cap_buffer(struct crystalhd_hw *hw,
389 BC_PIC_INFO_BLOCK *pib,
390 crystalhd_dio_req **ioreq);
391BC_STATUS crystalhd_hw_stop_capture(struct crystalhd_hw *hw);
392BC_STATUS crystalhd_hw_start_capture(struct crystalhd_hw *hw);
393void crystalhd_hw_stats(struct crystalhd_hw *hw, struct crystalhd_hw_stats *stats);
394
395/* API to program the core clock on the decoder */
396BC_STATUS crystalhd_hw_set_core_clock(struct crystalhd_hw *);
397
398#endif
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c
new file mode 100644
index 000000000000..3eac70aa213c
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_lnx.c
@@ -0,0 +1,765 @@
1/***************************************************************************
2 BCM70010 Linux driver
3 Copyright (c) 2005-2009, Broadcom Corporation.
4
5 This driver is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 2 of the License.
8
9 This driver is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this driver. If not, see <http://www.gnu.org/licenses/>.
16***************************************************************************/
17
18#include <linux/version.h>
19
20#include "crystalhd_lnx.h"
21
22static struct class *crystalhd_class;
23
24static struct crystalhd_adp *g_adp_info;
25
26static irqreturn_t chd_dec_isr(int irq, void *arg)
27{
28 struct crystalhd_adp *adp = (struct crystalhd_adp *) arg;
29 int rc = 0;
30 if (adp)
31 rc = crystalhd_cmd_interrupt(&adp->cmds);
32
33 return IRQ_RETVAL(rc);
34}
35
36static int chd_dec_enable_int(struct crystalhd_adp *adp)
37{
38 int rc = 0;
39
40 if (!adp || !adp->pdev) {
41 BCMLOG_ERR("Invalid arg!!\n");
42 return -EINVAL;
43 }
44
45 if (adp->pdev->msi_enabled)
46 adp->msi = 1;
47 else
48 adp->msi = pci_enable_msi(adp->pdev);
49
50 rc = request_irq(adp->pdev->irq, chd_dec_isr, IRQF_SHARED,
51 adp->name, (void *)adp);
52 if (rc) {
53 BCMLOG_ERR("Interrupt request failed.. \n");
54 pci_disable_msi(adp->pdev);
55 }
56
57 return rc;
58}
59
60static int chd_dec_disable_int(struct crystalhd_adp *adp)
61{
62 if (!adp || !adp->pdev) {
63 BCMLOG_ERR("Invalid arg!!\n");
64 return -EINVAL;
65 }
66
67 free_irq(adp->pdev->irq, adp);
68
69 if (adp->msi)
70 pci_disable_msi(adp->pdev);
71
72 return 0;
73}
74
75crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr)
76{
77 unsigned long flags = 0;
78 crystalhd_ioctl_data *temp;
79
80 if (!adp)
81 return NULL;
82
83 spin_lock_irqsave(&adp->lock, flags);
84
85 temp = adp->idata_free_head;
86 if (temp) {
87 adp->idata_free_head = adp->idata_free_head->next;
88 memset(temp, 0, sizeof(*temp));
89 }
90
91 spin_unlock_irqrestore(&adp->lock, flags);
92 return temp;
93}
94
95void chd_dec_free_iodata(struct crystalhd_adp *adp, crystalhd_ioctl_data *iodata,
96 bool isr)
97{
98 unsigned long flags = 0;
99
100 if (!adp || !iodata)
101 return;
102
103 spin_lock_irqsave(&adp->lock, flags);
104 iodata->next = adp->idata_free_head;
105 adp->idata_free_head = iodata;
106 spin_unlock_irqrestore(&adp->lock, flags);
107}
108
109static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int set)
110{
111 int rc;
112
113 if (!ud || !dr) {
114 BCMLOG_ERR("Invalid arg \n");
115 return -EINVAL;
116 }
117
118 if (set)
119 rc = copy_to_user((void *)ud, dr, size);
120 else
121 rc = copy_from_user(dr, (void *)ud, size);
122
123 if (rc) {
124 BCMLOG_ERR("Invalid args for command \n");
125 rc = -EFAULT;
126 }
127
128 return rc;
129}
130
131static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, crystalhd_ioctl_data *io,
132 uint32_t m_sz, unsigned long ua)
133{
134 unsigned long ua_off;
135 int rc = 0;
136
137 if (!adp || !io || !ua || !m_sz) {
138 BCMLOG_ERR("Invalid Arg!!\n");
139 return -EINVAL;
140 }
141
142 io->add_cdata = vmalloc(m_sz);
143 if (!io->add_cdata) {
144 BCMLOG_ERR("kalloc fail for sz:%x\n", m_sz);
145 return -ENOMEM;
146 }
147
148 io->add_cdata_sz = m_sz;
149 ua_off = ua + sizeof(io->udata);
150 rc = crystalhd_user_data(ua_off, io->add_cdata, io->add_cdata_sz, 0);
151 if (rc) {
152 BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
153 io->add_cdata_sz, (unsigned int)ua_off);
154 if (io->add_cdata) {
155 kfree(io->add_cdata);
156 io->add_cdata = NULL;
157 }
158 return -ENODATA;
159 }
160
161 return rc;
162}
163
164static int chd_dec_release_cdata(struct crystalhd_adp *adp,
165 crystalhd_ioctl_data *io, unsigned long ua)
166{
167 unsigned long ua_off;
168 int rc;
169
170 if (!adp || !io || !ua) {
171 BCMLOG_ERR("Invalid Arg!!\n");
172 return -EINVAL;
173 }
174
175 if (io->cmd != BCM_IOC_FW_DOWNLOAD) {
176 ua_off = ua + sizeof(io->udata);
177 rc = crystalhd_user_data(ua_off, io->add_cdata,
178 io->add_cdata_sz, 1);
179 if (rc) {
180 BCMLOG_ERR("failed to push add_cdata sz:%x ua_off:%x\n",
181 io->add_cdata_sz, (unsigned int)ua_off);
182 return -ENODATA;
183 }
184 }
185
186 if (io->add_cdata) {
187 vfree(io->add_cdata);
188 io->add_cdata = NULL;
189 }
190
191 return 0;
192}
193
194static int chd_dec_proc_user_data(struct crystalhd_adp *adp,
195 crystalhd_ioctl_data *io,
196 unsigned long ua, int set)
197{
198 int rc;
199 uint32_t m_sz = 0;
200
201 if (!adp || !io || !ua) {
202 BCMLOG_ERR("Invalid Arg!!\n");
203 return -EINVAL;
204 }
205
206 rc = crystalhd_user_data(ua, &io->udata, sizeof(io->udata), set);
207 if (rc) {
208 BCMLOG_ERR("failed to %s iodata \n", (set ? "set" : "get"));
209 return rc;
210 }
211
212 switch (io->cmd) {
213 case BCM_IOC_MEM_RD:
214 case BCM_IOC_MEM_WR:
215 case BCM_IOC_FW_DOWNLOAD:
216 m_sz = io->udata.u.devMem.NumDwords * 4;
217 if (set)
218 rc = chd_dec_release_cdata(adp, io, ua);
219 else
220 rc = chd_dec_fetch_cdata(adp, io, m_sz, ua);
221 break;
222 default:
223 break;
224 }
225
226 return rc;
227}
228
229static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua,
230 uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func)
231{
232 int rc;
233 crystalhd_ioctl_data *temp;
234 BC_STATUS sts = BC_STS_SUCCESS;
235
236 temp = chd_dec_alloc_iodata(adp, 0);
237 if (!temp) {
238 BCMLOG_ERR("Failed to get iodata..\n");
239 return -EINVAL;
240 }
241
242 temp->u_id = uid;
243 temp->cmd = cmd;
244
245 rc = chd_dec_proc_user_data(adp, temp, ua, 0);
246 if (!rc) {
247 sts = func(&adp->cmds, temp);
248 if (sts == BC_STS_PENDING)
249 sts = BC_STS_NOT_IMPL;
250 temp->udata.RetSts = sts;
251 rc = chd_dec_proc_user_data(adp, temp, ua, 1);
252 }
253
254 if (temp) {
255 chd_dec_free_iodata(adp, temp, 0);
256 temp = NULL;
257 }
258
259 return rc;
260}
261
262/* API interfaces */
263static int chd_dec_ioctl(struct inode *in, struct file *fd,
264 unsigned int cmd, unsigned long ua)
265{
266 struct crystalhd_adp *adp = chd_get_adp();
267 crystalhd_cmd_proc cproc;
268 struct crystalhd_user *uc;
269
270 if (!adp || !fd) {
271 BCMLOG_ERR("Invalid adp\n");
272 return -EINVAL;
273 }
274
275 uc = (struct crystalhd_user *)fd->private_data;
276 if (!uc) {
277 BCMLOG_ERR("Failed to get uc\n");
278 return -ENODATA;
279 }
280
281 cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc);
282 if (!cproc) {
283 BCMLOG_ERR("Unhandled command: %d\n", cmd);
284 return -EINVAL;
285 }
286
287 return chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc);
288}
289
290static int chd_dec_open(struct inode *in, struct file *fd)
291{
292 struct crystalhd_adp *adp = chd_get_adp();
293 int rc = 0;
294 BC_STATUS sts = BC_STS_SUCCESS;
295 struct crystalhd_user *uc = NULL;
296
297 BCMLOG_ENTER;
298 if (!adp) {
299 BCMLOG_ERR("Invalid adp\n");
300 return -EINVAL;
301 }
302
303 if (adp->cfg_users >= BC_LINK_MAX_OPENS) {
304 BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users);
305 return -EBUSY;
306 }
307
308 sts = crystalhd_user_open(&adp->cmds, &uc);
309 if (sts != BC_STS_SUCCESS) {
310 BCMLOG_ERR("cmd_user_open - %d \n", sts);
311 rc = -EBUSY;
312 }
313
314 adp->cfg_users++;
315
316 fd->private_data = uc;
317
318 return rc;
319}
320
321static int chd_dec_close(struct inode *in, struct file *fd)
322{
323 struct crystalhd_adp *adp = chd_get_adp();
324 struct crystalhd_user *uc;
325
326 BCMLOG_ENTER;
327 if (!adp) {
328 BCMLOG_ERR("Invalid adp \n");
329 return -EINVAL;
330 }
331
332 uc = (struct crystalhd_user *)fd->private_data;
333 if (!uc) {
334 BCMLOG_ERR("Failed to get uc\n");
335 return -ENODATA;
336 }
337
338 crystalhd_user_close(&adp->cmds, uc);
339
340 adp->cfg_users--;
341
342 return 0;
343}
344
345static const struct file_operations chd_dec_fops = {
346 .owner = THIS_MODULE,
347 .ioctl = chd_dec_ioctl,
348 .open = chd_dec_open,
349 .release = chd_dec_close,
350};
351
352static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
353{
354 crystalhd_ioctl_data *temp;
355 struct device *dev;
356 int rc = -ENODEV, i = 0;
357
358 if (!adp)
359 goto fail;
360
361 adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME,
362 &chd_dec_fops);
363 if (adp->chd_dec_major < 0) {
364 BCMLOG_ERR("Failed to create config dev\n");
365 rc = adp->chd_dec_major;
366 goto fail;
367 }
368
369 /* register crystalhd class */
370 crystalhd_class = class_create(THIS_MODULE, "crystalhd");
371 if (IS_ERR(crystalhd_class)) {
372 BCMLOG_ERR("failed to create class\n");
373 goto fail;
374 }
375
376 dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0),
377 NULL, "crystalhd");
378 if (!dev) {
379 BCMLOG_ERR("failed to create device\n");
380 goto device_create_fail;
381 }
382
383 rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ);
384 if (rc) {
385 BCMLOG_ERR("failed to create device\n");
386 goto elem_pool_fail;
387 }
388
389 /* Allocate general purpose ioctl pool. */
390 for (i = 0; i < CHD_IODATA_POOL_SZ; i++) {
391 /* FIXME: jarod: why atomic? */
392 temp = kzalloc(sizeof(crystalhd_ioctl_data), GFP_ATOMIC);
393 if (!temp) {
394 BCMLOG_ERR("ioctl data pool kzalloc failed\n");
395 rc = -ENOMEM;
396 goto kzalloc_fail;
397 }
398 /* Add to global pool.. */
399 chd_dec_free_iodata(adp, temp, 0);
400 }
401
402 return 0;
403
404kzalloc_fail:
405 crystalhd_delete_elem_pool(adp);
406elem_pool_fail:
407 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
408device_create_fail:
409 class_destroy(crystalhd_class);
410fail:
411 return rc;
412}
413
414static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp)
415{
416 crystalhd_ioctl_data *temp = NULL;
417 if (!adp)
418 return;
419
420 if (adp->chd_dec_major > 0) {
421 /* unregister crystalhd class */
422 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
423 unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME);
424 BCMLOG(BCMLOG_INFO, "released api device - %d\n",
425 adp->chd_dec_major);
426 class_destroy(crystalhd_class);
427 }
428 adp->chd_dec_major = 0;
429
430 /* Clear iodata pool.. */
431 do {
432 temp = chd_dec_alloc_iodata(adp, 0);
433 if (temp)
434 kfree(temp);
435 } while (temp);
436
437 crystalhd_delete_elem_pool(adp);
438}
439
440static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo)
441{
442 int rc;
443 unsigned long bar2 = pci_resource_start(pinfo->pdev, 2);
444 uint32_t mem_len = pci_resource_len(pinfo->pdev, 2);
445 unsigned long bar0 = pci_resource_start(pinfo->pdev, 0);
446 uint32_t i2o_len = pci_resource_len(pinfo->pdev, 0);
447
448 BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x bar0:0x%lx-0x%08x\n",
449 bar2, mem_len, bar0, i2o_len);
450
451 rc = check_mem_region(bar2, mem_len);
452 if (rc) {
453 BCMLOG_ERR("No valid mem region...\n");
454 return -ENOMEM;
455 }
456
457 pinfo->addr = ioremap_nocache(bar2, mem_len);
458 if (!pinfo->addr) {
459 BCMLOG_ERR("Failed to remap mem region...\n");
460 return -ENOMEM;
461 }
462
463 pinfo->pci_mem_start = bar2;
464 pinfo->pci_mem_len = mem_len;
465
466 rc = check_mem_region(bar0, i2o_len);
467 if (rc) {
468 BCMLOG_ERR("No valid mem region...\n");
469 return -ENOMEM;
470 }
471
472 pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len);
473 if (!pinfo->i2o_addr) {
474 BCMLOG_ERR("Failed to remap mem region...\n");
475 return -ENOMEM;
476 }
477
478 pinfo->pci_i2o_start = bar0;
479 pinfo->pci_i2o_len = i2o_len;
480
481 rc = pci_request_regions(pinfo->pdev, pinfo->name);
482 if (rc < 0) {
483 BCMLOG_ERR("Region request failed: %d\n", rc);
484 return rc;
485 }
486
487 BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx i2o_addr:0x%08lx\n",
488 (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr);
489
490 return 0;
491}
492
493static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo)
494{
495 if (!pinfo)
496 return;
497
498 if (pinfo->addr)
499 iounmap(pinfo->addr);
500
501 if (pinfo->i2o_addr)
502 iounmap(pinfo->i2o_addr);
503
504 pci_release_regions(pinfo->pdev);
505}
506
507
508static void __devexit chd_dec_pci_remove(struct pci_dev *pdev)
509{
510 struct crystalhd_adp *pinfo;
511 BC_STATUS sts = BC_STS_SUCCESS;
512
513 BCMLOG_ENTER;
514
515 pinfo = (struct crystalhd_adp *) pci_get_drvdata(pdev);
516 if (!pinfo) {
517 BCMLOG_ERR("could not get adp\n");
518 return;
519 }
520
521 sts = crystalhd_delete_cmd_context(&pinfo->cmds);
522 if (sts != BC_STS_SUCCESS)
523 BCMLOG_ERR("cmd delete :%d \n", sts);
524
525 chd_dec_release_chdev(pinfo);
526
527 chd_dec_disable_int(pinfo);
528
529 chd_pci_release_mem(pinfo);
530 pci_disable_device(pinfo->pdev);
531
532 kfree(pinfo);
533 g_adp_info = NULL;
534}
535
536static int __devinit chd_dec_pci_probe(struct pci_dev *pdev,
537 const struct pci_device_id *entry)
538{
539 struct crystalhd_adp *pinfo;
540 int rc;
541 BC_STATUS sts = BC_STS_SUCCESS;
542
543 BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x "
544 "s_vendor:0x%04x s_device: 0x%04x\n",
545 pdev->vendor, pdev->device, pdev->subsystem_vendor,
546 pdev->subsystem_device);
547
548 /* FIXME: jarod: why atomic? */
549 pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_ATOMIC);
550 if (!pinfo) {
551 BCMLOG_ERR("Failed to allocate memory\n");
552 return -ENOMEM;
553 }
554
555 pinfo->pdev = pdev;
556
557 rc = pci_enable_device(pdev);
558 if (rc) {
559 BCMLOG_ERR("Failed to enable PCI device\n");
560 return rc;
561 }
562
563 snprintf(pinfo->name, 31, "crystalhd_pci_e:%d:%d:%d",
564 pdev->bus->number, PCI_SLOT(pdev->devfn),
565 PCI_FUNC(pdev->devfn));
566
567 rc = chd_pci_reserve_mem(pinfo);
568 if (rc) {
569 BCMLOG_ERR("Failed to setup memory regions.\n");
570 return -ENOMEM;
571 }
572
573 pinfo->present = 1;
574 pinfo->drv_data = entry->driver_data;
575
576 /* Setup adapter level lock.. */
577 spin_lock_init(&pinfo->lock);
578
579 /* setup api stuff.. */
580 chd_dec_init_chdev(pinfo);
581 rc = chd_dec_enable_int(pinfo);
582 if (rc) {
583 BCMLOG_ERR("_enable_int err:%d \n", rc);
584 pci_disable_device(pdev);
585 return -ENODEV;
586 }
587
588 /* Set dma mask... */
589 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
590 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
591 pinfo->dmabits = 64;
592 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
593 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
594 pinfo->dmabits = 32;
595 } else {
596 BCMLOG_ERR("Unabled to setup DMA %d\n", rc);
597 pci_disable_device(pdev);
598 return -ENODEV;
599 }
600
601 sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo);
602 if (sts != BC_STS_SUCCESS) {
603 BCMLOG_ERR("cmd setup :%d \n", sts);
604 pci_disable_device(pdev);
605 return -ENODEV;
606 }
607
608 pci_set_master(pdev);
609
610 pci_set_drvdata(pdev, pinfo);
611
612 g_adp_info = pinfo;
613
614 return 0;
615}
616
617#ifdef CONFIG_PM
618int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
619{
620 struct crystalhd_adp *adp;
621 crystalhd_ioctl_data *temp;
622 BC_STATUS sts = BC_STS_SUCCESS;
623
624 adp = (struct crystalhd_adp *)pci_get_drvdata(pdev);
625 if (!adp) {
626 BCMLOG_ERR("could not get adp\n");
627 return -ENODEV;
628 }
629
630 temp = chd_dec_alloc_iodata(adp, false);
631 if (!temp) {
632 BCMLOG_ERR("could not get ioctl data\n");
633 return -ENODEV;
634 }
635
636 sts = crystalhd_suspend(&adp->cmds, temp);
637 if (sts != BC_STS_SUCCESS) {
638 BCMLOG_ERR("BCM70012 Suspend %d\n", sts);
639 return -ENODEV;
640 }
641
642 chd_dec_free_iodata(adp, temp, false);
643 chd_dec_disable_int(adp);
644 pci_save_state(pdev);
645
646 /* Disable IO/bus master/irq router */
647 pci_disable_device(pdev);
648 pci_set_power_state(pdev, pci_choose_state(pdev, state));
649 return 0;
650}
651
652int chd_dec_pci_resume(struct pci_dev *pdev)
653{
654 struct crystalhd_adp *adp;
655 BC_STATUS sts = BC_STS_SUCCESS;
656 int rc;
657
658 adp = (struct crystalhd_adp *)pci_get_drvdata(pdev);
659 if (!adp) {
660 BCMLOG_ERR("could not get adp\n");
661 return -ENODEV;
662 }
663
664 pci_set_power_state(pdev, PCI_D0);
665 pci_restore_state(pdev);
666
667 /* device's irq possibly is changed, driver should take care */
668 if (pci_enable_device(pdev)) {
669 BCMLOG_ERR("Failed to enable PCI device\n");
670 return 1;
671 }
672
673 pci_set_master(pdev);
674
675 rc = chd_dec_enable_int(adp);
676 if (rc) {
677 BCMLOG_ERR("_enable_int err:%d \n", rc);
678 pci_disable_device(pdev);
679 return -ENODEV;
680 }
681
682 sts = crystalhd_resume(&adp->cmds);
683 if (sts != BC_STS_SUCCESS) {
684 BCMLOG_ERR("BCM70012 Resume %d\n", sts);
685 pci_disable_device(pdev);
686 return -ENODEV;
687 }
688
689 return 0;
690}
691#endif
692
693static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = {
694 { PCI_VDEVICE(BROADCOM, 0x1612), 8 },
695 { 0, },
696};
697MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table);
698
699static struct pci_driver bc_chd_70012_driver = {
700 .name = "Broadcom 70012 Decoder",
701 .probe = chd_dec_pci_probe,
702 .remove = __devexit_p(chd_dec_pci_remove),
703 .id_table = chd_dec_pci_id_table,
704#ifdef CONFIG_PM
705 .suspend = chd_dec_pci_suspend,
706 .resume = chd_dec_pci_resume
707#endif
708};
709
710void chd_set_log_level(struct crystalhd_adp *adp, char *arg)
711{
712 if ((!arg) || (strlen(arg) < 3))
713 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA;
714 else if (!strncmp(arg, "sstep", 5))
715 g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG |
716 BCMLOG_SSTEP | BCMLOG_ERROR;
717 else if (!strncmp(arg, "info", 4))
718 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO;
719 else if (!strncmp(arg, "debug", 5))
720 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO |
721 BCMLOG_DBG;
722 else if (!strncmp(arg, "pball", 5))
723 g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK);
724 else if (!strncmp(arg, "silent", 6))
725 g_linklog_level = 0;
726 else
727 g_linklog_level = 0;
728}
729
730struct crystalhd_adp *chd_get_adp(void)
731{
732 return g_adp_info;
733}
734
735static int __init chd_dec_module_init(void)
736{
737 int rc;
738
739 chd_set_log_level(NULL, "debug");
740 BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d \n",
741 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
742
743 rc = pci_register_driver(&bc_chd_70012_driver);
744
745 if (rc < 0)
746 BCMLOG_ERR("Could not find any devices. err:%d \n", rc);
747
748 return rc;
749}
750module_init(chd_dec_module_init);
751
752static void __exit chd_dec_module_cleanup(void)
753{
754 BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d \n",
755 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev);
756
757 pci_unregister_driver(&bc_chd_70012_driver);
758}
759module_exit(chd_dec_module_cleanup);
760
761MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>");
762MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>");
763MODULE_DESCRIPTION(CRYSTAL_HD_NAME);
764MODULE_LICENSE("GPL");
765MODULE_ALIAS("bcm70012");
diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h
new file mode 100644
index 000000000000..d338ae97a4cf
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_lnx.h
@@ -0,0 +1,96 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_lnx . c
5 *
6 * Description:
7 * BCM70012 Linux driver
8 *
9 * HISTORY:
10 *
11 **********************************************************************
12 * This file is part of the crystalhd device driver.
13 *
14 * This driver is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * This driver is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
25 **********************************************************************/
26
27#ifndef _CRYSTALHD_LNX_H_
28#define _CRYSTALHD_LNX_H_
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/errno.h>
33#include <linux/string.h>
34#include <linux/mm.h>
35#include <linux/tty.h>
36#include <linux/slab.h>
37#include <linux/delay.h>
38#include <linux/fb.h>
39#include <linux/pci.h>
40#include <linux/init.h>
41#include <linux/interrupt.h>
42#include <linux/pagemap.h>
43#include <linux/vmalloc.h>
44
45#include <asm/io.h>
46#include <asm/irq.h>
47#include <asm/pgtable.h>
48#include <asm/system.h>
49#include <asm/uaccess.h>
50
51#include "crystalhd_cmds.h"
52
53#define CRYSTAL_HD_NAME "Broadcom Crystal HD Decoder (BCM70012) Driver"
54
55
56/* OS specific PCI information structure and adapter information. */
57struct crystalhd_adp {
58 /* Hardware borad/PCI specifics */
59 char name[32];
60 struct pci_dev *pdev;
61
62 unsigned long pci_mem_start;
63 uint32_t pci_mem_len;
64 void *addr;
65
66 unsigned long pci_i2o_start;
67 uint32_t pci_i2o_len;
68 void *i2o_addr;
69
70 unsigned int drv_data;
71 unsigned int dmabits; /* 32 | 64 */
72 unsigned int registered;
73 unsigned int present;
74 unsigned int msi;
75
76 spinlock_t lock;
77
78 /* API Related */
79 unsigned int chd_dec_major;
80 unsigned int cfg_users;
81
82 crystalhd_ioctl_data *idata_free_head; /* ioctl data pool */
83 crystalhd_elem_t *elem_pool_head; /* Queue element pool */
84
85 struct crystalhd_cmd cmds;
86
87 crystalhd_dio_req *ua_map_free_head;
88 struct pci_pool *fill_byte_pool;
89};
90
91
92struct crystalhd_adp *chd_get_adp(void);
93void chd_set_log_level(struct crystalhd_adp *adp, char *arg);
94
95#endif
96
diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c
new file mode 100644
index 000000000000..587dcc477865
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_misc.c
@@ -0,0 +1,1030 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_misc . c
5 *
6 * Description:
7 * BCM70012 Linux driver misc routines.
8 *
9 * HISTORY:
10 *
11 **********************************************************************
12 * This file is part of the crystalhd device driver.
13 *
14 * This driver is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, version 2 of the License.
17 *
18 * This driver is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
25 **********************************************************************/
26
27#include "crystalhd_misc.h"
28#include "crystalhd_lnx.h"
29
30uint32_t g_linklog_level;
31
32static inline uint32_t crystalhd_dram_rd(struct crystalhd_adp *adp, uint32_t mem_off)
33{
34 crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
35 return bc_dec_reg_rd(adp, (0x00380000 | (mem_off & 0x0007FFFF)));
36}
37
38static inline void crystalhd_dram_wr(struct crystalhd_adp *adp, uint32_t mem_off, uint32_t val)
39{
40 crystalhd_reg_wr(adp, DCI_DRAM_BASE_ADDR, (mem_off >> 19));
41 bc_dec_reg_wr(adp, (0x00380000 | (mem_off & 0x0007FFFF)), val);
42}
43
44static inline BC_STATUS bc_chk_dram_range(struct crystalhd_adp *adp, uint32_t start_off, uint32_t cnt)
45{
46 return BC_STS_SUCCESS;
47}
48
49static crystalhd_dio_req *crystalhd_alloc_dio(struct crystalhd_adp *adp)
50{
51 unsigned long flags = 0;
52 crystalhd_dio_req *temp = NULL;
53
54 if (!adp) {
55 BCMLOG_ERR("Invalid Arg!!\n");
56 return temp;
57 }
58
59 spin_lock_irqsave(&adp->lock, flags);
60 temp = adp->ua_map_free_head;
61 if (temp)
62 adp->ua_map_free_head = adp->ua_map_free_head->next;
63 spin_unlock_irqrestore(&adp->lock, flags);
64
65 return temp;
66}
67
68static void crystalhd_free_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio)
69{
70 unsigned long flags = 0;
71
72 if (!adp || !dio)
73 return;
74 spin_lock_irqsave(&adp->lock, flags);
75 dio->sig = crystalhd_dio_inv;
76 dio->page_cnt = 0;
77 dio->fb_size = 0;
78 memset(&dio->uinfo, 0, sizeof(dio->uinfo));
79 dio->next = adp->ua_map_free_head;
80 adp->ua_map_free_head = dio;
81 spin_unlock_irqrestore(&adp->lock, flags);
82}
83
84static crystalhd_elem_t *crystalhd_alloc_elem(struct crystalhd_adp *adp)
85{
86 unsigned long flags = 0;
87 crystalhd_elem_t *temp = NULL;
88
89 if (!adp)
90 return temp;
91 spin_lock_irqsave(&adp->lock, flags);
92 temp = adp->elem_pool_head;
93 if (temp) {
94 adp->elem_pool_head = adp->elem_pool_head->flink;
95 memset(temp, 0, sizeof(*temp));
96 }
97 spin_unlock_irqrestore(&adp->lock, flags);
98
99 return temp;
100}
101static void crystalhd_free_elem(struct crystalhd_adp *adp, crystalhd_elem_t *elem)
102{
103 unsigned long flags = 0;
104
105 if (!adp || !elem)
106 return;
107 spin_lock_irqsave(&adp->lock, flags);
108 elem->flink = adp->elem_pool_head;
109 adp->elem_pool_head = elem;
110 spin_unlock_irqrestore(&adp->lock, flags);
111}
112
113static inline void crystalhd_set_sg(struct scatterlist *sg, struct page *page,
114 unsigned int len, unsigned int offset)
115{
116 sg_set_page(sg, page, len, offset);
117#ifdef CONFIG_X86_64
118 sg->dma_length = len;
119#endif
120}
121
122static inline void crystalhd_init_sg(struct scatterlist *sg, unsigned int entries)
123{
124 /* http://lkml.org/lkml/2007/11/27/68 */
125 sg_init_table(sg, entries);
126}
127
128/*========================== Extern ========================================*/
129/**
130 * bc_dec_reg_rd - Read 7412's device register.
131 * @adp: Adapter instance
132 * @reg_off: Register offset.
133 *
134 * Return:
135 * 32bit value read
136 *
137 * 7412's device register read routine. This interface use
138 * 7412's device access range mapped from BAR-2 (4M) of PCIe
139 * configuration space.
140 */
141uint32_t bc_dec_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
142{
143 if (!adp || (reg_off > adp->pci_mem_len)) {
144 BCMLOG_ERR("dec_rd_reg_off outof range: 0x%08x\n", reg_off);
145 return 0;
146 }
147
148 return readl(adp->addr + reg_off);
149}
150
151/**
152 * bc_dec_reg_wr - Write 7412's device register
153 * @adp: Adapter instance
154 * @reg_off: Register offset.
155 * @val: Dword value to be written.
156 *
157 * Return:
158 * none.
159 *
160 * 7412's device register write routine. This interface use
161 * 7412's device access range mapped from BAR-2 (4M) of PCIe
162 * configuration space.
163 */
164void bc_dec_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
165{
166 if (!adp || (reg_off > adp->pci_mem_len)) {
167 BCMLOG_ERR("dec_wr_reg_off outof range: 0x%08x\n", reg_off);
168 return;
169 }
170 writel(val, adp->addr + reg_off);
171 udelay(8);
172}
173
174/**
175 * crystalhd_reg_rd - Read Link's device register.
176 * @adp: Adapter instance
177 * @reg_off: Register offset.
178 *
179 * Return:
180 * 32bit value read
181 *
182 * Link device register read routine. This interface use
183 * Link's device access range mapped from BAR-1 (64K) of PCIe
184 * configuration space.
185 *
186 */
187uint32_t crystalhd_reg_rd(struct crystalhd_adp *adp, uint32_t reg_off)
188{
189 if (!adp || (reg_off > adp->pci_i2o_len)) {
190 BCMLOG_ERR("link_rd_reg_off outof range: 0x%08x\n", reg_off);
191 return 0;
192 }
193 return readl(adp->i2o_addr + reg_off);
194}
195
196/**
197 * crystalhd_reg_wr - Write Link's device register
198 * @adp: Adapter instance
199 * @reg_off: Register offset.
200 * @val: Dword value to be written.
201 *
202 * Return:
203 * none.
204 *
205 * Link device register write routine. This interface use
206 * Link's device access range mapped from BAR-1 (64K) of PCIe
207 * configuration space.
208 *
209 */
210void crystalhd_reg_wr(struct crystalhd_adp *adp, uint32_t reg_off, uint32_t val)
211{
212 if (!adp || (reg_off > adp->pci_i2o_len)) {
213 BCMLOG_ERR("link_wr_reg_off outof range: 0x%08x\n", reg_off);
214 return;
215 }
216 writel(val, adp->i2o_addr + reg_off);
217}
218
219/**
220 * crystalhd_mem_rd - Read data from 7412's DRAM area.
221 * @adp: Adapter instance
222 * @start_off: Start offset.
223 * @dw_cnt: Count in dwords.
224 * @rd_buff: Buffer to copy the data from dram.
225 *
226 * Return:
227 * Status.
228 *
229 * 7412's Dram read routine.
230 */
231BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *adp, uint32_t start_off,
232 uint32_t dw_cnt, uint32_t *rd_buff)
233{
234 uint32_t ix = 0;
235
236 if (!adp || !rd_buff ||
237 (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
238 BCMLOG_ERR("Invalid arg \n");
239 return BC_STS_INV_ARG;
240 }
241 for (ix = 0; ix < dw_cnt; ix++)
242 rd_buff[ix] = crystalhd_dram_rd(adp, (start_off + (ix * 4)));
243
244 return BC_STS_SUCCESS;
245}
246
247/**
248 * crystalhd_mem_wr - Write data to 7412's DRAM area.
249 * @adp: Adapter instance
250 * @start_off: Start offset.
251 * @dw_cnt: Count in dwords.
252 * @wr_buff: Data Buffer to be written.
253 *
254 * Return:
255 * Status.
256 *
257 * 7412's Dram write routine.
258 */
259BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *adp, uint32_t start_off,
260 uint32_t dw_cnt, uint32_t *wr_buff)
261{
262 uint32_t ix = 0;
263
264 if (!adp || !wr_buff ||
265 (bc_chk_dram_range(adp, start_off, dw_cnt) != BC_STS_SUCCESS)) {
266 BCMLOG_ERR("Invalid arg \n");
267 return BC_STS_INV_ARG;
268 }
269
270 for (ix = 0; ix < dw_cnt; ix++)
271 crystalhd_dram_wr(adp, (start_off + (ix * 4)), wr_buff[ix]);
272
273 return BC_STS_SUCCESS;
274}
275/**
276 * crystalhd_pci_cfg_rd - PCIe config read
277 * @adp: Adapter instance
278 * @off: PCI config space offset.
279 * @len: Size -- Byte, Word & dword.
280 * @val: Value read
281 *
282 * Return:
283 * Status.
284 *
285 * Get value from Link's PCIe config space.
286 */
287BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *adp, uint32_t off,
288 uint32_t len, uint32_t *val)
289{
290 BC_STATUS sts = BC_STS_SUCCESS;
291 int rc = 0;
292
293 if (!adp || !val) {
294 BCMLOG_ERR("Invalid arg \n");
295 return BC_STS_INV_ARG;
296 }
297
298 switch (len) {
299 case 1:
300 rc = pci_read_config_byte(adp->pdev, off, (u8 *)val);
301 break;
302 case 2:
303 rc = pci_read_config_word(adp->pdev, off, (u16 *)val);
304 break;
305 case 4:
306 rc = pci_read_config_dword(adp->pdev, off, (u32 *)val);
307 break;
308 default:
309 rc = -EINVAL;
310 sts = BC_STS_INV_ARG;
311 BCMLOG_ERR("Invalid len:%d\n", len);
312 };
313
314 if (rc && (sts == BC_STS_SUCCESS))
315 sts = BC_STS_ERROR;
316
317 return sts;
318}
319
320/**
321 * crystalhd_pci_cfg_wr - PCIe config write
322 * @adp: Adapter instance
323 * @off: PCI config space offset.
324 * @len: Size -- Byte, Word & dword.
325 * @val: Value to be written
326 *
327 * Return:
328 * Status.
329 *
330 * Set value to Link's PCIe config space.
331 */
332BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *adp, uint32_t off,
333 uint32_t len, uint32_t val)
334{
335 BC_STATUS sts = BC_STS_SUCCESS;
336 int rc = 0;
337
338 if (!adp || !val) {
339 BCMLOG_ERR("Invalid arg \n");
340 return BC_STS_INV_ARG;
341 }
342
343 switch (len) {
344 case 1:
345 rc = pci_write_config_byte(adp->pdev, off, (u8)val);
346 break;
347 case 2:
348 rc = pci_write_config_word(adp->pdev, off, (u16)val);
349 break;
350 case 4:
351 rc = pci_write_config_dword(adp->pdev, off, val);
352 break;
353 default:
354 rc = -EINVAL;
355 sts = BC_STS_INV_ARG;
356 BCMLOG_ERR("Invalid len:%d\n", len);
357 };
358
359 if (rc && (sts == BC_STS_SUCCESS))
360 sts = BC_STS_ERROR;
361
362 return sts;
363}
364
365/**
366 * bc_kern_dma_alloc - Allocate memory for Dma rings
367 * @adp: Adapter instance
368 * @sz: Size of the memory to allocate.
369 * @phy_addr: Physical address of the memory allocated.
370 * Typedef to system's dma_addr_t (u64)
371 *
372 * Return:
373 * Pointer to allocated memory..
374 *
375 * Wrapper to Linux kernel interface.
376 *
377 */
378void *bc_kern_dma_alloc(struct crystalhd_adp *adp, uint32_t sz,
379 dma_addr_t *phy_addr)
380{
381 void *temp = NULL;
382
383 if (!adp || !sz || !phy_addr) {
384 BCMLOG_ERR("Invalide Arg..\n");
385 return temp;
386 }
387
388 temp = pci_alloc_consistent(adp->pdev, sz, phy_addr);
389 if (temp)
390 memset(temp, 0, sz);
391
392 return temp;
393}
394
395/**
396 * bc_kern_dma_free - Release Dma ring memory.
397 * @adp: Adapter instance
398 * @sz: Size of the memory to allocate.
399 * @ka: Kernel virtual address returned during _dio_alloc()
400 * @phy_addr: Physical address of the memory allocated.
401 * Typedef to system's dma_addr_t (u64)
402 *
403 * Return:
404 * none.
405 */
406void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka,
407 dma_addr_t phy_addr)
408{
409 if (!adp || !ka || !sz || !phy_addr) {
410 BCMLOG_ERR("Invalide Arg..\n");
411 return;
412 }
413
414 pci_free_consistent(adp->pdev, sz, ka, phy_addr);
415}
416
417/**
418 * crystalhd_create_dioq - Create Generic DIO queue
419 * @adp: Adapter instance
420 * @dioq_hnd: Handle to the dio queue created
421 * @cb : Optional - Call back To free the element.
422 * @cbctx: Context to pass to callback.
423 *
424 * Return:
425 * status
426 *
427 * Initialize Generic DIO queue to hold any data. Callback
428 * will be used to free elements while deleting the queue.
429 */
430BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *adp,
431 crystalhd_dioq_t **dioq_hnd,
432 crystalhd_data_free_cb cb, void *cbctx)
433{
434 crystalhd_dioq_t *dioq = NULL;
435
436 if (!adp || !dioq_hnd) {
437 BCMLOG_ERR("Invalid arg!!\n");
438 return BC_STS_INV_ARG;
439 }
440
441 dioq = kzalloc(sizeof(*dioq), GFP_KERNEL);
442 if (!dioq)
443 return BC_STS_INSUFF_RES;
444
445 spin_lock_init(&dioq->lock);
446 dioq->sig = BC_LINK_DIOQ_SIG;
447 dioq->head = (crystalhd_elem_t *)&dioq->head;
448 dioq->tail = (crystalhd_elem_t *)&dioq->head;
449 crystalhd_create_event(&dioq->event);
450 dioq->adp = adp;
451 dioq->data_rel_cb = cb;
452 dioq->cb_context = cbctx;
453 *dioq_hnd = dioq;
454
455 return BC_STS_SUCCESS;
456}
457
458/**
459 * crystalhd_delete_dioq - Delete Generic DIO queue
460 * @adp: Adapter instance
461 * @dioq: DIOQ instance..
462 *
463 * Return:
464 * None.
465 *
466 * Release Generic DIO queue. This function will remove
467 * all the entries from the Queue and will release data
468 * by calling the call back provided during creation.
469 *
470 */
471void crystalhd_delete_dioq(struct crystalhd_adp *adp, crystalhd_dioq_t *dioq)
472{
473 void *temp;
474
475 if (!dioq || (dioq->sig != BC_LINK_DIOQ_SIG))
476 return;
477
478 do {
479 temp = crystalhd_dioq_fetch(dioq);
480 if (temp && dioq->data_rel_cb)
481 dioq->data_rel_cb(dioq->cb_context, temp);
482 } while (temp);
483 dioq->sig = 0;
484 kfree(dioq);
485}
486
487/**
488 * crystalhd_dioq_add - Add new DIO request element.
489 * @ioq: DIO queue instance
490 * @t: DIO request to be added.
491 * @wake: True - Wake up suspended process.
492 * @tag: Special tag to assign - For search and get.
493 *
494 * Return:
495 * Status.
496 *
497 * Insert new element to Q tail.
498 */
499BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data,
500 bool wake, uint32_t tag)
501{
502 unsigned long flags = 0;
503 crystalhd_elem_t *tmp;
504
505 if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !data) {
506 BCMLOG_ERR("Invalid arg!!\n");
507 return BC_STS_INV_ARG;
508 }
509
510 tmp = crystalhd_alloc_elem(ioq->adp);
511 if (!tmp) {
512 BCMLOG_ERR("No free elements.\n");
513 return BC_STS_INSUFF_RES;
514 }
515
516 tmp->data = data;
517 tmp->tag = tag;
518 spin_lock_irqsave(&ioq->lock, flags);
519 tmp->flink = (crystalhd_elem_t *)&ioq->head;
520 tmp->blink = ioq->tail;
521 tmp->flink->blink = tmp;
522 tmp->blink->flink = tmp;
523 ioq->count++;
524 spin_unlock_irqrestore(&ioq->lock, flags);
525
526 if (wake)
527 crystalhd_set_event(&ioq->event);
528
529 return BC_STS_SUCCESS;
530}
531
532/**
533 * crystalhd_dioq_fetch - Fetch element from head.
534 * @ioq: DIO queue instance
535 *
536 * Return:
537 * data element from the head..
538 *
539 * Remove an element from Queue.
540 */
541void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq)
542{
543 unsigned long flags = 0;
544 crystalhd_elem_t *tmp;
545 crystalhd_elem_t *ret = NULL;
546 void *data = NULL;
547
548 if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
549 BCMLOG_ERR("Invalid arg!!\n");
550 return data;
551 }
552
553 spin_lock_irqsave(&ioq->lock, flags);
554 tmp = ioq->head;
555 if (tmp != (crystalhd_elem_t *)&ioq->head) {
556 ret = tmp;
557 tmp->flink->blink = tmp->blink;
558 tmp->blink->flink = tmp->flink;
559 ioq->count--;
560 }
561 spin_unlock_irqrestore(&ioq->lock, flags);
562 if (ret) {
563 data = ret->data;
564 crystalhd_free_elem(ioq->adp, ret);
565 }
566
567 return data;
568}
569/**
570 * crystalhd_dioq_find_and_fetch - Search the tag and Fetch element
571 * @ioq: DIO queue instance
572 * @tag: Tag to search for.
573 *
574 * Return:
575 * element from the head..
576 *
577 * Search TAG and remove the element.
578 */
579void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag)
580{
581 unsigned long flags = 0;
582 crystalhd_elem_t *tmp;
583 crystalhd_elem_t *ret = NULL;
584 void *data = NULL;
585
586 if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG)) {
587 BCMLOG_ERR("Invalid arg!!\n");
588 return data;
589 }
590
591 spin_lock_irqsave(&ioq->lock, flags);
592 tmp = ioq->head;
593 while (tmp != (crystalhd_elem_t *)&ioq->head) {
594 if (tmp->tag == tag) {
595 ret = tmp;
596 tmp->flink->blink = tmp->blink;
597 tmp->blink->flink = tmp->flink;
598 ioq->count--;
599 break;
600 }
601 tmp = tmp->flink;
602 }
603 spin_unlock_irqrestore(&ioq->lock, flags);
604
605 if (ret) {
606 data = ret->data;
607 crystalhd_free_elem(ioq->adp, ret);
608 }
609
610 return data;
611}
612
613/**
614 * crystalhd_dioq_fetch_wait - Fetch element from Head.
615 * @ioq: DIO queue instance
616 * @to_secs: Wait timeout in seconds..
617 *
618 * Return:
619 * element from the head..
620 *
621 * Return element from head if Q is not empty. Wait for new element
622 * if Q is empty for Timeout seconds.
623 */
624void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs,
625 uint32_t *sig_pend)
626{
627 unsigned long flags = 0;
628 int rc = 0, count;
629 void *tmp = NULL;
630
631 if (!ioq || (ioq->sig != BC_LINK_DIOQ_SIG) || !to_secs || !sig_pend) {
632 BCMLOG_ERR("Invalid arg!!\n");
633 return tmp;
634 }
635
636 count = to_secs;
637 spin_lock_irqsave(&ioq->lock, flags);
638 while ((ioq->count == 0) && count) {
639 spin_unlock_irqrestore(&ioq->lock, flags);
640
641 crystalhd_wait_on_event(&ioq->event, (ioq->count > 0), 1000, rc, 0);
642 if (rc == 0) {
643 goto out;
644 } else if (rc == -EINTR) {
645 BCMLOG(BCMLOG_INFO, "Cancelling fetch wait\n");
646 *sig_pend = 1;
647 return tmp;
648 }
649 spin_lock_irqsave(&ioq->lock, flags);
650 count--;
651 }
652 spin_unlock_irqrestore(&ioq->lock, flags);
653
654out:
655 return crystalhd_dioq_fetch(ioq);
656}
657
658/**
659 * crystalhd_map_dio - Map user address for DMA
660 * @adp: Adapter instance
661 * @ubuff: User buffer to map.
662 * @ubuff_sz: User buffer size.
663 * @uv_offset: UV buffer offset.
664 * @en_422mode: TRUE:422 FALSE:420 Capture mode.
665 * @dir_tx: TRUE for Tx (To device from host)
666 * @dio_hnd: Handle to mapped DIO request.
667 *
668 * Return:
669 * Status.
670 *
671 * This routine maps user address and lock pages for DMA.
672 *
673 */
674BC_STATUS crystalhd_map_dio(struct crystalhd_adp *adp, void *ubuff,
675 uint32_t ubuff_sz, uint32_t uv_offset,
676 bool en_422mode, bool dir_tx,
677 crystalhd_dio_req **dio_hnd)
678{
679 crystalhd_dio_req *dio;
680 /* FIXME: jarod: should some of these unsigned longs be uint32_t or uintptr_t? */
681 unsigned long start = 0, end = 0, uaddr = 0, count = 0;
682 unsigned long spsz = 0, uv_start = 0;
683 int i = 0, rw = 0, res = 0, nr_pages = 0, skip_fb_sg = 0;
684
685 if (!adp || !ubuff || !ubuff_sz || !dio_hnd) {
686 BCMLOG_ERR("Invalid arg \n");
687 return BC_STS_INV_ARG;
688 }
689 /* Compute pages */
690 uaddr = (unsigned long)ubuff;
691 count = (unsigned long)ubuff_sz;
692 end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
693 start = uaddr >> PAGE_SHIFT;
694 nr_pages = end - start;
695
696 if (!count || ((uaddr + count) < uaddr)) {
697 BCMLOG_ERR("User addr overflow!!\n");
698 return BC_STS_INV_ARG;
699 }
700
701 dio = crystalhd_alloc_dio(adp);
702 if (!dio) {
703 BCMLOG_ERR("dio pool empty..\n");
704 return BC_STS_INSUFF_RES;
705 }
706
707 if (dir_tx) {
708 rw = WRITE;
709 dio->direction = DMA_TO_DEVICE;
710 } else {
711 rw = READ;
712 dio->direction = DMA_FROM_DEVICE;
713 }
714
715 if (nr_pages > dio->max_pages) {
716 BCMLOG_ERR("max_pages(%d) exceeded(%d)!!\n",
717 dio->max_pages, nr_pages);
718 crystalhd_unmap_dio(adp, dio);
719 return BC_STS_INSUFF_RES;
720 }
721
722 if (uv_offset) {
723 uv_start = (uaddr + (unsigned long)uv_offset) >> PAGE_SHIFT;
724 dio->uinfo.uv_sg_ix = uv_start - start;
725 dio->uinfo.uv_sg_off = ((uaddr + (unsigned long)uv_offset) & ~PAGE_MASK);
726 }
727
728 dio->fb_size = ubuff_sz & 0x03;
729 if (dio->fb_size) {
730 res = copy_from_user(dio->fb_va,
731 (void *)(uaddr + count - dio->fb_size),
732 dio->fb_size);
733 if (res) {
734 BCMLOG_ERR("failed %d to copy %u fill bytes from %p\n",
735 res, dio->fb_size,
736 (void *)(uaddr + count-dio->fb_size));
737 crystalhd_unmap_dio(adp, dio);
738 return BC_STS_INSUFF_RES;
739 }
740 }
741
742 down_read(&current->mm->mmap_sem);
743 res = get_user_pages(current, current->mm, uaddr, nr_pages, rw == READ,
744 0, dio->pages, NULL);
745 up_read(&current->mm->mmap_sem);
746
747 /* Save for release..*/
748 dio->sig = crystalhd_dio_locked;
749 if (res < nr_pages) {
750 BCMLOG_ERR("get pages failed: %d-%d\n", nr_pages, res);
751 dio->page_cnt = res;
752 crystalhd_unmap_dio(adp, dio);
753 return BC_STS_ERROR;
754 }
755
756 dio->page_cnt = nr_pages;
757 /* Get scatter/gather */
758 crystalhd_init_sg(dio->sg, dio->page_cnt);
759 crystalhd_set_sg(&dio->sg[0], dio->pages[0], 0, uaddr & ~PAGE_MASK);
760 if (nr_pages > 1) {
761 dio->sg[0].length = PAGE_SIZE - dio->sg[0].offset;
762
763#ifdef CONFIG_X86_64
764 dio->sg[0].dma_length = dio->sg[0].length;
765#endif
766 count -= dio->sg[0].length;
767 for (i = 1; i < nr_pages; i++) {
768 if (count < 4) {
769 spsz = count;
770 skip_fb_sg = 1;
771 } else {
772 spsz = (count < PAGE_SIZE) ?
773 (count & ~0x03) : PAGE_SIZE;
774 }
775 crystalhd_set_sg(&dio->sg[i], dio->pages[i], spsz, 0);
776 count -= spsz;
777 }
778 } else {
779 if (count < 4) {
780 dio->sg[0].length = count;
781 skip_fb_sg = 1;
782 } else {
783 dio->sg[0].length = count - dio->fb_size;
784 }
785#ifdef CONFIG_X86_64
786 dio->sg[0].dma_length = dio->sg[0].length;
787#endif
788 }
789 dio->sg_cnt = pci_map_sg(adp->pdev, dio->sg,
790 dio->page_cnt, dio->direction);
791 if (dio->sg_cnt <= 0) {
792 BCMLOG_ERR("sg map %d-%d \n", dio->sg_cnt, dio->page_cnt);
793 crystalhd_unmap_dio(adp, dio);
794 return BC_STS_ERROR;
795 }
796 if (dio->sg_cnt && skip_fb_sg)
797 dio->sg_cnt -= 1;
798 dio->sig = crystalhd_dio_sg_mapped;
799 /* Fill in User info.. */
800 dio->uinfo.xfr_len = ubuff_sz;
801 dio->uinfo.xfr_buff = ubuff;
802 dio->uinfo.uv_offset = uv_offset;
803 dio->uinfo.b422mode = en_422mode;
804 dio->uinfo.dir_tx = dir_tx;
805
806 *dio_hnd = dio;
807
808 return BC_STS_SUCCESS;
809}
810
811/**
812 * crystalhd_unmap_sgl - Release mapped resources
813 * @adp: Adapter instance
814 * @dio: DIO request instance
815 *
816 * Return:
817 * Status.
818 *
819 * This routine is to unmap the user buffer pages.
820 */
821BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *adp, crystalhd_dio_req *dio)
822{
823 struct page *page = NULL;
824 int j = 0;
825
826 if (!adp || !dio) {
827 BCMLOG_ERR("Invalid arg \n");
828 return BC_STS_INV_ARG;
829 }
830
831 if ((dio->page_cnt > 0) && (dio->sig != crystalhd_dio_inv)) {
832 for (j = 0; j < dio->page_cnt; j++) {
833 page = dio->pages[j];
834 if (page) {
835 if (!PageReserved(page) &&
836 (dio->direction == DMA_FROM_DEVICE))
837 SetPageDirty(page);
838 page_cache_release(page);
839 }
840 }
841 }
842 if (dio->sig == crystalhd_dio_sg_mapped)
843 pci_unmap_sg(adp->pdev, dio->sg, dio->page_cnt, dio->direction);
844
845 crystalhd_free_dio(adp, dio);
846
847 return BC_STS_SUCCESS;
848}
849
850/**
851 * crystalhd_create_dio_pool - Allocate mem pool for DIO management.
852 * @adp: Adapter instance
853 * @max_pages: Max pages for size calculation.
854 *
855 * Return:
856 * system error.
857 *
858 * This routine creates a memory pool to hold dio context for
859 * for HW Direct IO operation.
860 */
861int crystalhd_create_dio_pool(struct crystalhd_adp *adp, uint32_t max_pages)
862{
863 uint32_t asz = 0, i = 0;
864 uint8_t *temp;
865 crystalhd_dio_req *dio;
866
867 if (!adp || !max_pages) {
868 BCMLOG_ERR("Invalid Arg!!\n");
869 return -EINVAL;
870 }
871
872 /* Get dma memory for fill byte handling..*/
873 adp->fill_byte_pool = pci_pool_create("crystalhd_fbyte",
874 adp->pdev, 8, 8, 0);
875 if (!adp->fill_byte_pool) {
876 BCMLOG_ERR("failed to create fill byte pool\n");
877 return -ENOMEM;
878 }
879
880 /* Get the max size from user based on 420/422 modes */
881 asz = (sizeof(*dio->pages) * max_pages) +
882 (sizeof(*dio->sg) * max_pages) + sizeof(*dio);
883
884 BCMLOG(BCMLOG_DBG, "Initializing Dio pool %d %d %x %p\n",
885 BC_LINK_SG_POOL_SZ, max_pages, asz, adp->fill_byte_pool);
886
887 for (i = 0; i < BC_LINK_SG_POOL_SZ; i++) {
888 temp = (uint8_t *)kzalloc(asz, GFP_KERNEL);
889 if ((temp) == NULL) {
890 BCMLOG_ERR("Failed to alloc %d mem\n", asz);
891 return -ENOMEM;
892 }
893
894 dio = (crystalhd_dio_req *)temp;
895 temp += sizeof(*dio);
896 dio->pages = (struct page **)temp;
897 temp += (sizeof(*dio->pages) * max_pages);
898 dio->sg = (struct scatterlist *)temp;
899 dio->max_pages = max_pages;
900 dio->fb_va = pci_pool_alloc(adp->fill_byte_pool, GFP_KERNEL,
901 &dio->fb_pa);
902 if (!dio->fb_va) {
903 BCMLOG_ERR("fill byte alloc failed.\n");
904 return -ENOMEM;
905 }
906
907 crystalhd_free_dio(adp, dio);
908 }
909
910 return 0;
911}
912
913/**
914 * crystalhd_destroy_dio_pool - Release DIO mem pool.
915 * @adp: Adapter instance
916 *
917 * Return:
918 * none.
919 *
920 * This routine releases dio memory pool during close.
921 */
922void crystalhd_destroy_dio_pool(struct crystalhd_adp *adp)
923{
924 crystalhd_dio_req *dio;
925 int count = 0;
926
927 if (!adp) {
928 BCMLOG_ERR("Invalid Arg!!\n");
929 return;
930 }
931
932 do {
933 dio = crystalhd_alloc_dio(adp);
934 if (dio) {
935 if (dio->fb_va)
936 pci_pool_free(adp->fill_byte_pool,
937 dio->fb_va, dio->fb_pa);
938 count++;
939 kfree(dio);
940 }
941 } while (dio);
942
943 if (adp->fill_byte_pool) {
944 pci_pool_destroy(adp->fill_byte_pool);
945 adp->fill_byte_pool = NULL;
946 }
947
948 BCMLOG(BCMLOG_DBG, "Released dio pool %d \n", count);
949}
950
951/**
952 * crystalhd_create_elem_pool - List element pool creation.
953 * @adp: Adapter instance
954 * @pool_size: Number of elements in the pool.
955 *
956 * Return:
957 * 0 - success, <0 error
958 *
959 * Create general purpose list element pool to hold pending,
960 * and active requests.
961 */
962int __devinit crystalhd_create_elem_pool(struct crystalhd_adp *adp,
963 uint32_t pool_size)
964{
965 uint32_t i;
966 crystalhd_elem_t *temp;
967
968 if (!adp || !pool_size)
969 return -EINVAL;
970
971 for (i = 0; i < pool_size; i++) {
972 temp = kzalloc(sizeof(*temp), GFP_KERNEL);
973 if (!temp) {
974 BCMLOG_ERR("kalloc failed \n");
975 return -ENOMEM;
976 }
977 crystalhd_free_elem(adp, temp);
978 }
979 BCMLOG(BCMLOG_DBG, "allocated %d elem\n", pool_size);
980 return 0;
981}
982
983/**
984 * crystalhd_delete_elem_pool - List element pool deletion.
985 * @adp: Adapter instance
986 *
987 * Return:
988 * none
989 *
990 * Delete general purpose list element pool.
991 */
992void crystalhd_delete_elem_pool(struct crystalhd_adp *adp)
993{
994 crystalhd_elem_t *temp;
995 int dbg_cnt = 0;
996
997 if (!adp)
998 return;
999
1000 do {
1001 temp = crystalhd_alloc_elem(adp);
1002 if (temp) {
1003 kfree(temp);
1004 dbg_cnt++;
1005 }
1006 } while (temp);
1007
1008 BCMLOG(BCMLOG_DBG, "released %d elem\n", dbg_cnt);
1009}
1010
1011/*================ Debug support routines.. ================================*/
1012void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount)
1013{
1014 uint32_t i, k = 1;
1015
1016 for (i = 0; i < dwcount; i++) {
1017 if (k == 1)
1018 BCMLOG(BCMLOG_DATA, "0x%08X : ", off);
1019
1020 BCMLOG(BCMLOG_DATA, " 0x%08X ", *((uint32_t *)buff));
1021
1022 buff += sizeof(uint32_t);
1023 off += sizeof(uint32_t);
1024 k++;
1025 if ((i == dwcount - 1) || (k > 4)) {
1026 BCMLOG(BCMLOG_DATA, "\n");
1027 k = 1;
1028 }
1029 }
1030}
diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h
new file mode 100644
index 000000000000..a2aa6ad7fc81
--- /dev/null
+++ b/drivers/staging/crystalhd/crystalhd_misc.h
@@ -0,0 +1,229 @@
1/***************************************************************************
2 * Copyright (c) 2005-2009, Broadcom Corporation.
3 *
4 * Name: crystalhd_misc . h
5 *
6 * Description:
7 * BCM70012 Linux driver general purpose routines.
8 * Includes reg/mem read and write routines.
9 *
10 * HISTORY:
11 *
12 **********************************************************************
13 * This file is part of the crystalhd device driver.
14 *
15 * This driver is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, version 2 of the License.
18 *
19 * This driver is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this driver. If not, see <http://www.gnu.org/licenses/>.
26 **********************************************************************/
27
28#ifndef _CRYSTALHD_MISC_H_
29#define _CRYSTALHD_MISC_H_
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/string.h>
35#include <linux/ioctl.h>
36#include <linux/dma-mapping.h>
37#include <linux/version.h>
38#include <linux/sched.h>
39#include <asm/system.h>
40#include "bc_dts_glob_lnx.h"
41
42/* Global log level variable defined in crystal_misc.c file */
43extern uint32_t g_linklog_level;
44
45/* Global element pool for all Queue management.
46 * TX: Active = BC_TX_LIST_CNT, Free = BC_TX_LIST_CNT.
47 * RX: Free = BC_RX_LIST_CNT, Active = 2
48 * FW-CMD: 4
49 */
50#define BC_LINK_ELEM_POOL_SZ ((BC_TX_LIST_CNT * 2) + BC_RX_LIST_CNT + 2 + 4)
51
52/* Driver's IODATA pool count */
53#define CHD_IODATA_POOL_SZ (BC_IOCTL_DATA_POOL_SIZE * BC_LINK_MAX_OPENS)
54
55/* Scatter Gather memory pool size for Tx and Rx */
56#define BC_LINK_SG_POOL_SZ (BC_TX_LIST_CNT + BC_RX_LIST_CNT)
57
58enum _crystalhd_dio_sig {
59 crystalhd_dio_inv = 0,
60 crystalhd_dio_locked,
61 crystalhd_dio_sg_mapped,
62};
63
64struct crystalhd_dio_user_info {
65 void *xfr_buff;
66 uint32_t xfr_len;
67 uint32_t uv_offset;
68 bool dir_tx;
69
70 uint32_t uv_sg_ix;
71 uint32_t uv_sg_off;
72 int comp_sts;
73 int ev_sts;
74 uint32_t y_done_sz;
75 uint32_t uv_done_sz;
76 uint32_t comp_flags;
77 bool b422mode;
78};
79
80typedef struct _crystalhd_dio_req {
81 uint32_t sig;
82 uint32_t max_pages;
83 struct page **pages;
84 struct scatterlist *sg;
85 int sg_cnt;
86 int page_cnt;
87 int direction;
88 struct crystalhd_dio_user_info uinfo;
89 void *fb_va;
90 uint32_t fb_size;
91 dma_addr_t fb_pa;
92 struct _crystalhd_dio_req *next;
93} crystalhd_dio_req;
94
95#define BC_LINK_DIOQ_SIG (0x09223280)
96
97typedef struct _crystalhd_elem_s {
98 struct _crystalhd_elem_s *flink;
99 struct _crystalhd_elem_s *blink;
100 void *data;
101 uint32_t tag;
102} crystalhd_elem_t;
103
104typedef void (*crystalhd_data_free_cb)(void *context, void *data);
105
106typedef struct _crystalhd_dioq_s {
107 uint32_t sig;
108 struct crystalhd_adp *adp;
109 crystalhd_elem_t *head;
110 crystalhd_elem_t *tail;
111 uint32_t count;
112 spinlock_t lock;
113 wait_queue_head_t event;
114 crystalhd_data_free_cb data_rel_cb;
115 void *cb_context;
116} crystalhd_dioq_t;
117
118typedef void (*hw_comp_callback)(crystalhd_dio_req *,
119 wait_queue_head_t *event, BC_STATUS sts);
120
121/*========= Decoder (7412) register access routines.================= */
122uint32_t bc_dec_reg_rd(struct crystalhd_adp *, uint32_t);
123void bc_dec_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
124
125/*========= Link (70012) register access routines.. =================*/
126uint32_t crystalhd_reg_rd(struct crystalhd_adp *, uint32_t);
127void crystalhd_reg_wr(struct crystalhd_adp *, uint32_t, uint32_t);
128
129/*========= Decoder (7412) memory access routines..=================*/
130BC_STATUS crystalhd_mem_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
131BC_STATUS crystalhd_mem_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
132
133/*==========Link (70012) PCIe Config access routines.================*/
134BC_STATUS crystalhd_pci_cfg_rd(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t *);
135BC_STATUS crystalhd_pci_cfg_wr(struct crystalhd_adp *, uint32_t, uint32_t, uint32_t);
136
137/*========= Linux Kernel Interface routines. ======================= */
138void *bc_kern_dma_alloc(struct crystalhd_adp *, uint32_t, dma_addr_t *);
139void bc_kern_dma_free(struct crystalhd_adp *, uint32_t,
140 void *, dma_addr_t);
141#define crystalhd_create_event(_ev) init_waitqueue_head(_ev)
142#define crystalhd_set_event(_ev) wake_up_interruptible(_ev)
143#define crystalhd_wait_on_event(ev, condition, timeout, ret, nosig) \
144do { \
145 DECLARE_WAITQUEUE(entry, current); \
146 unsigned long end = jiffies + ((timeout * HZ) / 1000); \
147 ret = 0; \
148 add_wait_queue(ev, &entry); \
149 for (;;) { \
150 __set_current_state(TASK_INTERRUPTIBLE); \
151 if (condition) { \
152 break; \
153 } \
154 if (time_after_eq(jiffies, end)) { \
155 ret = -EBUSY; \
156 break; \
157 } \
158 schedule_timeout((HZ / 100 > 1) ? HZ / 100 : 1); \
159 if (!nosig && signal_pending(current)) { \
160 ret = -EINTR; \
161 break; \
162 } \
163 } \
164 __set_current_state(TASK_RUNNING); \
165 remove_wait_queue(ev, &entry); \
166} while (0)
167
168/*================ Direct IO mapping routines ==================*/
169extern int crystalhd_create_dio_pool(struct crystalhd_adp *, uint32_t);
170extern void crystalhd_destroy_dio_pool(struct crystalhd_adp *);
171extern BC_STATUS crystalhd_map_dio(struct crystalhd_adp *, void *, uint32_t,
172 uint32_t, bool, bool, crystalhd_dio_req**);
173
174extern BC_STATUS crystalhd_unmap_dio(struct crystalhd_adp *, crystalhd_dio_req*);
175#define crystalhd_get_sgle_paddr(_dio, _ix) (cpu_to_le64(sg_dma_address(&_dio->sg[_ix])))
176#define crystalhd_get_sgle_len(_dio, _ix) (cpu_to_le32(sg_dma_len(&_dio->sg[_ix])))
177
178/*================ General Purpose Queues ==================*/
179extern BC_STATUS crystalhd_create_dioq(struct crystalhd_adp *, crystalhd_dioq_t **, crystalhd_data_free_cb , void *);
180extern void crystalhd_delete_dioq(struct crystalhd_adp *, crystalhd_dioq_t *);
181extern BC_STATUS crystalhd_dioq_add(crystalhd_dioq_t *ioq, void *data, bool wake, uint32_t tag);
182extern void *crystalhd_dioq_fetch(crystalhd_dioq_t *ioq);
183extern void *crystalhd_dioq_find_and_fetch(crystalhd_dioq_t *ioq, uint32_t tag);
184extern void *crystalhd_dioq_fetch_wait(crystalhd_dioq_t *ioq, uint32_t to_secs, uint32_t *sig_pend);
185
186#define crystalhd_dioq_count(_ioq) ((_ioq) ? _ioq->count : 0)
187
188extern int crystalhd_create_elem_pool(struct crystalhd_adp *, uint32_t);
189extern void crystalhd_delete_elem_pool(struct crystalhd_adp *);
190
191
192/*================ Debug routines/macros .. ================================*/
193extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff, uint32_t dwcount);
194
195enum _chd_log_levels {
196 BCMLOG_ERROR = 0x80000000, /* Don't disable this option */
197 BCMLOG_DATA = 0x40000000, /* Data, enable by default */
198 BCMLOG_SPINLOCK = 0x20000000, /* Spcial case for Spin locks*/
199
200 /* Following are allowed only in debug mode */
201 BCMLOG_INFO = 0x00000001, /* Generic informational */
202 BCMLOG_DBG = 0x00000002, /* First level Debug info */
203 BCMLOG_SSTEP = 0x00000004, /* Stepping information */
204 BCMLOG_ENTER_LEAVE = 0x00000008, /* stack tracking */
205};
206
207#define BCMLOG_ENTER \
208if (g_linklog_level & BCMLOG_ENTER_LEAVE) { \
209 printk("Entered %s\n", __func__); \
210}
211
212#define BCMLOG_LEAVE \
213if (g_linklog_level & BCMLOG_ENTER_LEAVE) { \
214 printk("Leaving %s\n", __func__); \
215}
216
217#define BCMLOG(trace, fmt, args...) \
218if (g_linklog_level & trace) { \
219 printk(fmt, ##args); \
220}
221
222#define BCMLOG_ERR(fmt, args...) \
223do { \
224 if (g_linklog_level & BCMLOG_ERROR) { \
225 printk("*ERR*:%s:%d: "fmt, __FILE__, __LINE__, ##args); \
226 } \
227} while (0);
228
229#endif
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
index 89c8fe2997fa..46c7f78bb972 100644
--- a/drivers/staging/cx25821/cx25821-audups11.c
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -343,10 +343,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
343 struct v4l2_control *ctl) 343 struct v4l2_control *ctl)
344{ 344{
345 struct cx25821_fh *fh = priv; 345 struct cx25821_fh *fh = priv;
346 struct cx25821_dev *dev = fh->dev; 346 struct cx25821_dev *dev;
347 int err; 347 int err;
348 348
349 if (fh) { 349 if (fh) {
350 dev = fh->dev;
350 err = v4l2_prio_check(&dev->prio, &fh->prio); 351 err = v4l2_prio_check(&dev->prio, &fh->prio);
351 if (0 != err) 352 if (0 != err)
352 return err; 353 return err;
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
index 1eb079b3d429..d6016200d699 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -795,10 +795,8 @@ int medusa_video_init(struct cx25821_dev *dev)
795 value &= 0xFFFFFFDF; 795 value &= 0xFFFFFFDF;
796 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); 796 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
797 797
798 if (ret_val < 0) { 798 if (ret_val < 0)
799 mutex_unlock(&dev->lock);
800 return -EINVAL; 799 return -EINVAL;
801 }
802 800
803 mutex_unlock(&dev->lock); 801 mutex_unlock(&dev->lock);
804 802
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index c7c14c7698a7..8cd3986d2e5c 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -876,7 +876,7 @@ int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
876 dprintk(1, "%s()\n", __func__); 876 dprintk(1, "%s()\n", __func__);
877 877
878 n = i->index; 878 n = i->index;
879 if (n > 2) 879 if (n >= 2)
880 return -EINVAL; 880 return -EINVAL;
881 881
882 if (0 == INPUT(n)->type) 882 if (0 == INPUT(n)->type)
@@ -963,10 +963,11 @@ int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
963int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f) 963int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
964{ 964{
965 struct cx25821_fh *fh = priv; 965 struct cx25821_fh *fh = priv;
966 struct cx25821_dev *dev = fh->dev; 966 struct cx25821_dev *dev;
967 int err; 967 int err;
968 968
969 if (fh) { 969 if (fh) {
970 dev = fh->dev;
970 err = v4l2_prio_check(&dev->prio, &fh->prio); 971 err = v4l2_prio_check(&dev->prio, &fh->prio);
971 if (0 != err) 972 if (0 != err)
972 return err; 973 return err;
diff --git a/drivers/staging/dream/camera/Kconfig b/drivers/staging/dream/camera/Kconfig
index 0a3e903b3363..bfb6d241d807 100644
--- a/drivers/staging/dream/camera/Kconfig
+++ b/drivers/staging/dream/camera/Kconfig
@@ -15,7 +15,7 @@ config MSM_CAMERA_DEBUG
15 15
16config MSM_CAMERA_FLASH 16config MSM_CAMERA_FLASH
17 bool "Qualcomm MSM camera flash support" 17 bool "Qualcomm MSM camera flash support"
18 depends on MSM_CAMERA 18 depends on MSM_CAMERA && BROKEN
19 ---help--- 19 ---help---
20 Enable support for LED flash for msm camera 20 Enable support for LED flash for msm camera
21 21
diff --git a/drivers/staging/dream/camera/Makefile b/drivers/staging/dream/camera/Makefile
index 4429ae5fcafd..db228d7d1136 100644
--- a/drivers/staging/dream/camera/Makefile
+++ b/drivers/staging/dream/camera/Makefile
@@ -1,3 +1,4 @@
1EXTRA_CFLAGS=-Idrivers/staging/dream/include
1obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o 2obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
2obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o 3obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
3obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o 4obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c
index 7d938772eacc..dc7c603625c7 100644
--- a/drivers/staging/dream/camera/msm_camera.c
+++ b/drivers/staging/dream/camera/msm_camera.c
@@ -2,7 +2,7 @@
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated. 2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */ 3 */
4 4
5//FIXME: most allocations need not be GFP_ATOMIC 5/* FIXME: most allocations need not be GFP_ATOMIC */
6/* FIXME: management of mutexes */ 6/* FIXME: management of mutexes */
7/* FIXME: msm_pmem_region_lookup return values */ 7/* FIXME: msm_pmem_region_lookup return values */
8/* FIXME: way too many copy to/from user */ 8/* FIXME: way too many copy to/from user */
@@ -76,14 +76,14 @@ static LIST_HEAD(msm_sensors);
76 list_del_init(&qcmd->list); \ 76 list_del_init(&qcmd->list); \
77 kfree(qcmd); \ 77 kfree(qcmd); \
78 }; \ 78 }; \
79} while(0) 79} while (0)
80 80
81#define MSM_DRAIN_QUEUE(sync, name) do { \ 81#define MSM_DRAIN_QUEUE(sync, name) do { \
82 unsigned long flags; \ 82 unsigned long flags; \
83 spin_lock_irqsave(&(sync)->name##_lock, flags); \ 83 spin_lock_irqsave(&(sync)->name##_lock, flags); \
84 MSM_DRAIN_QUEUE_NOSYNC(sync, name); \ 84 MSM_DRAIN_QUEUE_NOSYNC(sync, name); \
85 spin_unlock_irqrestore(&(sync)->name##_lock, flags); \ 85 spin_unlock_irqrestore(&(sync)->name##_lock, flags); \
86} while(0) 86} while (0)
87 87
88static int check_overlap(struct hlist_head *ptype, 88static int check_overlap(struct hlist_head *ptype,
89 unsigned long paddr, 89 unsigned long paddr,
@@ -361,7 +361,7 @@ static int __msm_get_frame(struct msm_sync *sync,
361 if (!frame->buffer) { 361 if (!frame->buffer) {
362 pr_err("%s: cannot get frame, invalid lookup address " 362 pr_err("%s: cannot get frame, invalid lookup address "
363 "y=%x cbcr=%x offset=%d\n", 363 "y=%x cbcr=%x offset=%d\n",
364 __FUNCTION__, 364 __func__,
365 pphy->y_phy, 365 pphy->y_phy,
366 pphy->cbcr_phy, 366 pphy->cbcr_phy,
367 frame->y_off); 367 frame->y_off);
@@ -455,7 +455,7 @@ static int msm_disable_vfe(struct msm_sync *sync, void __user *arg)
455 return rc; 455 return rc;
456} 456}
457 457
458static struct msm_queue_cmd* __msm_control(struct msm_sync *sync, 458static struct msm_queue_cmd *__msm_control(struct msm_sync *sync,
459 struct msm_control_device_queue *queue, 459 struct msm_control_device_queue *queue,
460 struct msm_queue_cmd *qcmd, 460 struct msm_queue_cmd *qcmd,
461 int timeout) 461 int timeout)
@@ -592,8 +592,7 @@ end:
592 * a result of a successful completion, we are freeing the qcmd that 592 * a result of a successful completion, we are freeing the qcmd that
593 * we dequeued from queue->ctrl_status_q. 593 * we dequeued from queue->ctrl_status_q.
594 */ 594 */
595 if (qcmd) 595 kfree(qcmd);
596 kfree(qcmd);
597 596
598 CDBG("msm_control: end rc = %d\n", rc); 597 CDBG("msm_control: end rc = %d\n", rc);
599 return rc; 598 return rc;
@@ -670,7 +669,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg)
670 &(stats.fd)); 669 &(stats.fd));
671 if (!stats.buffer) { 670 if (!stats.buffer) {
672 pr_err("%s: msm_pmem_stats_ptov_lookup error\n", 671 pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
673 __FUNCTION__); 672 __func__);
674 rc = -EINVAL; 673 rc = -EINVAL;
675 goto failure; 674 goto failure;
676 } 675 }
@@ -718,8 +717,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg)
718 buf.fmain.buffer = 717 buf.fmain.buffer =
719 (unsigned long)region.vaddr; 718 (unsigned long)region.vaddr;
720 buf.fmain.fd = region.fd; 719 buf.fmain.fd = region.fd;
721 } 720 } else {
722 else {
723 pr_err("%s: pmem lookup failed\n", 721 pr_err("%s: pmem lookup failed\n",
724 __func__); 722 __func__);
725 rc = -EINVAL; 723 rc = -EINVAL;
@@ -796,8 +794,7 @@ static int msm_get_stats(struct msm_sync *sync, void __user *arg)
796 } 794 }
797 795
798failure: 796failure:
799 if (qcmd) 797 kfree(qcmd);
800 kfree(qcmd);
801 798
802 CDBG("msm_get_stats: %d\n", rc); 799 CDBG("msm_get_stats: %d\n", rc);
803 return rc; 800 return rc;
@@ -838,8 +835,8 @@ static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm,
838 kfree(qcmd); 835 kfree(qcmd);
839 goto end; 836 goto end;
840 } 837 }
841 } 838 } else
842 else ctrlcmd->value = NULL; 839 ctrlcmd->value = NULL;
843 840
844end: 841end:
845 CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc); 842 CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc);
@@ -869,14 +866,14 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
869 return -EFAULT; 866 return -EFAULT;
870 } 867 }
871 868
872 switch(cfgcmd.cmd_type) { 869 switch (cfgcmd.cmd_type) {
873 case CMD_STATS_ENABLE: 870 case CMD_STATS_ENABLE:
874 axi_data.bufnum1 = 871 axi_data.bufnum1 =
875 msm_pmem_region_lookup(&sync->stats, 872 msm_pmem_region_lookup(&sync->stats,
876 MSM_PMEM_AEC_AWB, &region[0], 873 MSM_PMEM_AEC_AWB, &region[0],
877 NUM_WB_EXP_STAT_OUTPUT_BUFFERS); 874 NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
878 if (!axi_data.bufnum1) { 875 if (!axi_data.bufnum1) {
879 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 876 pr_err("%s: pmem region lookup error\n", __func__);
880 return -EINVAL; 877 return -EINVAL;
881 } 878 }
882 axi_data.region = &region[0]; 879 axi_data.region = &region[0];
@@ -888,7 +885,7 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
888 MSM_PMEM_AF, &region[0], 885 MSM_PMEM_AF, &region[0],
889 NUM_AF_STAT_OUTPUT_BUFFERS); 886 NUM_AF_STAT_OUTPUT_BUFFERS);
890 if (!axi_data.bufnum1) { 887 if (!axi_data.bufnum1) {
891 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 888 pr_err("%s: pmem region lookup error\n", __func__);
892 return -EINVAL; 889 return -EINVAL;
893 } 890 }
894 axi_data.region = &region[0]; 891 axi_data.region = &region[0];
@@ -899,7 +896,7 @@ static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
899 break; 896 break;
900 default: 897 default:
901 pr_err("%s: unknown command type %d\n", 898 pr_err("%s: unknown command type %d\n",
902 __FUNCTION__, cfgcmd.cmd_type); 899 __func__, cfgcmd.cmd_type);
903 return -EINVAL; 900 return -EINVAL;
904 } 901 }
905 902
@@ -928,7 +925,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
928 msm_pmem_region_lookup(&sync->frame, pmem_type, 925 msm_pmem_region_lookup(&sync->frame, pmem_type,
929 &region[0], 8); 926 &region[0], 8);
930 if (!axi_data.bufnum1) { 927 if (!axi_data.bufnum1) {
931 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 928 pr_err("%s: pmem region lookup error\n", __func__);
932 return -EINVAL; 929 return -EINVAL;
933 } 930 }
934 break; 931 break;
@@ -939,7 +936,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
939 msm_pmem_region_lookup(&sync->frame, pmem_type, 936 msm_pmem_region_lookup(&sync->frame, pmem_type,
940 &region[0], 8); 937 &region[0], 8);
941 if (!axi_data.bufnum2) { 938 if (!axi_data.bufnum2) {
942 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 939 pr_err("%s: pmem region lookup error\n", __func__);
943 return -EINVAL; 940 return -EINVAL;
944 } 941 }
945 break; 942 break;
@@ -950,7 +947,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
950 msm_pmem_region_lookup(&sync->frame, pmem_type, 947 msm_pmem_region_lookup(&sync->frame, pmem_type,
951 &region[0], 8); 948 &region[0], 8);
952 if (!axi_data.bufnum1) { 949 if (!axi_data.bufnum1) {
953 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 950 pr_err("%s: pmem region lookup error\n", __func__);
954 return -EINVAL; 951 return -EINVAL;
955 } 952 }
956 953
@@ -959,7 +956,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
959 msm_pmem_region_lookup(&sync->frame, pmem_type, 956 msm_pmem_region_lookup(&sync->frame, pmem_type,
960 &region[axi_data.bufnum1], 8); 957 &region[axi_data.bufnum1], 8);
961 if (!axi_data.bufnum2) { 958 if (!axi_data.bufnum2) {
962 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 959 pr_err("%s: pmem region lookup error\n", __func__);
963 return -EINVAL; 960 return -EINVAL;
964 } 961 }
965 break; 962 break;
@@ -970,7 +967,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
970 msm_pmem_region_lookup(&sync->frame, pmem_type, 967 msm_pmem_region_lookup(&sync->frame, pmem_type,
971 &region[0], 8); 968 &region[0], 8);
972 if (!axi_data.bufnum2) { 969 if (!axi_data.bufnum2) {
973 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 970 pr_err("%s: pmem region lookup error\n", __func__);
974 return -EINVAL; 971 return -EINVAL;
975 } 972 }
976 break; 973 break;
@@ -981,7 +978,7 @@ static int msm_frame_axi_cfg(struct msm_sync *sync,
981 978
982 default: 979 default:
983 pr_err("%s: unknown command type %d\n", 980 pr_err("%s: unknown command type %d\n",
984 __FUNCTION__, cfgcmd->cmd_type); 981 __func__, cfgcmd->cmd_type);
985 return -EINVAL; 982 return -EINVAL;
986 } 983 }
987 984
@@ -1047,7 +1044,7 @@ static int __msm_put_frame_buf(struct msm_sync *sync,
1047 rc = sync->vfefn.vfe_config(&cfgcmd, &pphy); 1044 rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
1048 } else { 1045 } else {
1049 pr_err("%s: msm_pmem_frame_vtop_lookup failed\n", 1046 pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
1050 __FUNCTION__); 1047 __func__);
1051 rc = -EINVAL; 1048 rc = -EINVAL;
1052 } 1049 }
1053 1050
@@ -1131,7 +1128,7 @@ static int msm_stats_axi_cfg(struct msm_sync *sync,
1131 break; 1128 break;
1132 default: 1129 default:
1133 pr_err("%s: unknown command type %d\n", 1130 pr_err("%s: unknown command type %d\n",
1134 __FUNCTION__, cfgcmd->cmd_type); 1131 __func__, cfgcmd->cmd_type);
1135 return -EINVAL; 1132 return -EINVAL;
1136 } 1133 }
1137 1134
@@ -1140,7 +1137,7 @@ static int msm_stats_axi_cfg(struct msm_sync *sync,
1140 msm_pmem_region_lookup(&sync->stats, pmem_type, 1137 msm_pmem_region_lookup(&sync->stats, pmem_type,
1141 &region[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS); 1138 &region[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
1142 if (!axi_data.bufnum1) { 1139 if (!axi_data.bufnum1) {
1143 pr_err("%s: pmem region lookup error\n", __FUNCTION__); 1140 pr_err("%s: pmem region lookup error\n", __func__);
1144 return -EINVAL; 1141 return -EINVAL;
1145 } 1142 }
1146 axi_data.region = &region[0]; 1143 axi_data.region = &region[0];
@@ -1177,7 +1174,7 @@ static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg)
1177 cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE; 1174 cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
1178 else { 1175 else {
1179 pr_err("%s: invalid buf type %d\n", 1176 pr_err("%s: invalid buf type %d\n",
1180 __FUNCTION__, 1177 __func__,
1181 buf.type); 1178 buf.type);
1182 rc = -EINVAL; 1179 rc = -EINVAL;
1183 goto put_done; 1180 goto put_done;
@@ -1223,7 +1220,7 @@ static int msm_axi_config(struct msm_sync *sync, void __user *arg)
1223 1220
1224 default: 1221 default:
1225 pr_err("%s: unknown command type %d\n", 1222 pr_err("%s: unknown command type %d\n",
1226 __FUNCTION__, 1223 __func__,
1227 cfgcmd.cmd_type); 1224 cfgcmd.cmd_type);
1228 return -EINVAL; 1225 return -EINVAL;
1229 } 1226 }
@@ -1622,7 +1619,8 @@ static int msm_release_control(struct inode *node, struct file *filep)
1622 int rc; 1619 int rc;
1623 struct msm_control_device *ctrl_pmsm = filep->private_data; 1620 struct msm_control_device *ctrl_pmsm = filep->private_data;
1624 struct msm_device *pmsm = ctrl_pmsm->pmsm; 1621 struct msm_device *pmsm = ctrl_pmsm->pmsm;
1625 printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); 1622 printk(KERN_INFO "msm_camera: RELEASE %s\n",
1623 filep->f_path.dentry->d_name.name);
1626 rc = __msm_release(pmsm->sync); 1624 rc = __msm_release(pmsm->sync);
1627 if (!rc) { 1625 if (!rc) {
1628 MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q); 1626 MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q);
@@ -1636,7 +1634,8 @@ static int msm_release_frame(struct inode *node, struct file *filep)
1636{ 1634{
1637 int rc; 1635 int rc;
1638 struct msm_device *pmsm = filep->private_data; 1636 struct msm_device *pmsm = filep->private_data;
1639 printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name); 1637 printk(KERN_INFO "msm_camera: RELEASE %s\n",
1638 filep->f_path.dentry->d_name.name);
1640 rc = __msm_release(pmsm->sync); 1639 rc = __msm_release(pmsm->sync);
1641 if (!rc) { 1640 if (!rc) {
1642 MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q); 1641 MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q);
@@ -1720,7 +1719,7 @@ static void msm_vfe_sync(struct msm_vfe_resp *vdata,
1720 qcmd->type = qtype; 1719 qcmd->type = qtype;
1721 1720
1722 if (qtype == MSM_CAM_Q_VFE_MSG) { 1721 if (qtype == MSM_CAM_Q_VFE_MSG) {
1723 switch(vdata->type) { 1722 switch (vdata->type) {
1724 case VFE_MSG_OUTPUT1: 1723 case VFE_MSG_OUTPUT1:
1725 case VFE_MSG_OUTPUT2: 1724 case VFE_MSG_OUTPUT2:
1726 qcmd_frame = 1725 qcmd_frame =
@@ -1885,8 +1884,10 @@ static int msm_open_control(struct inode *inode, struct file *filep)
1885 return -ENOMEM; 1884 return -ENOMEM;
1886 1885
1887 rc = msm_open_common(inode, filep, 0); 1886 rc = msm_open_common(inode, filep, 0);
1888 if (rc < 0) 1887 if (rc < 0) {
1888 kfree(ctrl_pmsm);
1889 return rc; 1889 return rc;
1890 }
1890 1891
1891 ctrl_pmsm->pmsm = filep->private_data; 1892 ctrl_pmsm->pmsm = filep->private_data;
1892 filep->private_data = ctrl_pmsm; 1893 filep->private_data = ctrl_pmsm;
@@ -1929,7 +1930,7 @@ static int __msm_v4l2_control(struct msm_sync *sync,
1929 memcpy(out->value, ctrl->value, ctrl->length); 1930 memcpy(out->value, ctrl->value, ctrl->length);
1930 1931
1931end: 1932end:
1932 if (rcmd) kfree(rcmd); 1933 kfree(rcmd);
1933 CDBG("__msm_v4l2_control: end rc = %d\n", rc); 1934 CDBG("__msm_v4l2_control: end rc = %d\n", rc);
1934 return rc; 1935 return rc;
1935} 1936}
diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c
index 33ab3ac6ac57..62fd24d632d5 100644
--- a/drivers/staging/dream/camera/msm_vfe7x.c
+++ b/drivers/staging/dream/camera/msm_vfe7x.c
@@ -255,8 +255,7 @@ static int vfe_7x_init(struct msm_vfe_callback *presp,
255 255
256 extlen = sizeof(struct vfe_frame_extra); 256 extlen = sizeof(struct vfe_frame_extra);
257 257
258 extdata = 258 extdata = kmalloc(extlen, GFP_ATOMIC);
259 kmalloc(sizeof(extlen), GFP_ATOMIC);
260 if (!extdata) { 259 if (!extdata) {
261 rc = -ENOMEM; 260 rc = -ENOMEM;
262 goto init_fail; 261 goto init_fail;
diff --git a/drivers/staging/dream/camera/s5k3e2fx.c b/drivers/staging/dream/camera/s5k3e2fx.c
index edba19889b0f..841792e2624b 100644
--- a/drivers/staging/dream/camera/s5k3e2fx.c
+++ b/drivers/staging/dream/camera/s5k3e2fx.c
@@ -743,12 +743,12 @@ static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data)
743 } 743 }
744 744
745 /* initialize AF */ 745 /* initialize AF */
746 if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 746 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3146, 0x3A);
747 0x3146, 0x3A)) < 0) 747 if (rc < 0)
748 goto init_fail1; 748 goto init_fail1;
749 749
750 if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 750 rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3130, 0x03);
751 0x3130, 0x03)) < 0) 751 if (rc < 0)
752 goto init_fail1; 752 goto init_fail1;
753 753
754 goto init_done; 754 goto init_done;
@@ -814,20 +814,20 @@ static uint16_t s5k3e2fx_get_prev_lines_pf(void)
814 814
815static uint16_t s5k3e2fx_get_prev_pixels_pl(void) 815static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
816{ 816{
817 return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w + 817 return s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
818 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p); 818 s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p;
819} 819}
820 820
821static uint16_t s5k3e2fx_get_pict_lines_pf(void) 821static uint16_t s5k3e2fx_get_pict_lines_pf(void)
822{ 822{
823 return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h + 823 return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
824 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l); 824 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
825} 825}
826 826
827static uint16_t s5k3e2fx_get_pict_pixels_pl(void) 827static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
828{ 828{
829 return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w + 829 return s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
830 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p); 830 s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
831} 831}
832 832
833static uint32_t s5k3e2fx_get_pict_max_exp_lc(void) 833static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
@@ -1093,14 +1093,10 @@ static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps)
1093 1093
1094 actual_step = step_direction * (int16_t)num_steps; 1094 actual_step = step_direction * (int16_t)num_steps;
1095 pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos; 1095 pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
1096 gain = actual_step * 0x400 / 5; 1096 gain = ((actual_step << 10) / 5) >> 10;
1097 1097
1098 for (i = 0; i <= 4; i++) { 1098 for (i = 0; i <= 4; i++)
1099 if (actual_step >= 0) 1099 s_move[i] = gain;
1100 s_move[i] = ((((i+1)*gain+0x200) - (i*gain+0x200))/0x400);
1101 else
1102 s_move[i] = ((((i+1)*gain-0x200) - (i*gain-0x200))/0x400);
1103 }
1104 1100
1105 /* Ring Damping Code */ 1101 /* Ring Damping Code */
1106 for (i = 0; i <= 4; i++) { 1102 for (i = 0; i <= 4; i++) {
diff --git a/drivers/staging/dream/include/linux/android_pmem.h b/drivers/staging/dream/include/linux/android_pmem.h
new file mode 100644
index 000000000000..2fc05d7d335b
--- /dev/null
+++ b/drivers/staging/dream/include/linux/android_pmem.h
@@ -0,0 +1,80 @@
1/* drivers/staging/dream/include/linux/android_pmem.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _ANDROID_PMEM_H_
17#define _ANDROID_PMEM_H_
18
19#define PMEM_IOCTL_MAGIC 'p'
20#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int)
21#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int)
22#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int)
23#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int)
24/* This ioctl will allocate pmem space, backing the file, it will fail
25 * if the file already has an allocation, pass it the len as the argument
26 * to the ioctl */
27#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
28/* This will connect a one pmem file to another, pass the file that is already
29 * backed in memory as the argument to the ioctl
30 */
31#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
32/* Returns the total size of the pmem region it is sent to as a pmem_region
33 * struct (with offset set to 0).
34 */
35#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int)
36/* Revokes gpu registers and resets the gpu. Pass a pointer to the
37 * start of the mapped gpu regs (the vaddr returned by mmap) as the argument.
38 */
39#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
40#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
41#define HW3D_WAIT_FOR_INTERRUPT _IOW(PMEM_IOCTL_MAGIC, 10, unsigned int)
42
43int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart,
44 unsigned long *end, struct file **filp);
45int get_pmem_user_addr(struct file *file, unsigned long *start,
46 unsigned long *end);
47void put_pmem_file(struct file* file);
48void flush_pmem_file(struct file *file, unsigned long start, unsigned long len);
49
50struct android_pmem_platform_data
51{
52 const char* name;
53 /* starting physical address of memory region */
54 unsigned long start;
55 /* size of memory region */
56 unsigned long size;
57 /* set to indicate the region should not be managed with an allocator */
58 unsigned no_allocator;
59 /* set to indicate maps of this region should be cached, if a mix of
60 * cached and uncached is desired, set this and open the device with
61 * O_SYNC to get an uncached region */
62 unsigned cached;
63 /* The MSM7k has bits to enable a write buffer in the bus controller*/
64 unsigned buffered;
65};
66
67struct pmem_region {
68 unsigned long offset;
69 unsigned long len;
70};
71
72int pmem_setup(struct android_pmem_platform_data *pdata,
73 long (*ioctl)(struct file *, unsigned int, unsigned long),
74 int (*release)(struct inode *, struct file *));
75
76int pmem_remap(struct pmem_region *region, struct file *file,
77 unsigned operation);
78
79#endif //_ANDROID_PPP_H_
80
diff --git a/drivers/staging/dream/include/linux/gpio_event.h b/drivers/staging/dream/include/linux/gpio_event.h
new file mode 100644
index 000000000000..ffc5da392ad7
--- /dev/null
+++ b/drivers/staging/dream/include/linux/gpio_event.h
@@ -0,0 +1,154 @@
1/* drivers/staging/dream/include/linux/gpio_event.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _LINUX_GPIO_EVENT_H
17#define _LINUX_GPIO_EVENT_H
18
19#include <linux/input.h>
20
21enum {
22 GPIO_EVENT_FUNC_UNINIT = 0x0,
23 GPIO_EVENT_FUNC_INIT = 0x1,
24 GPIO_EVENT_FUNC_SUSPEND = 0x2,
25 GPIO_EVENT_FUNC_RESUME = 0x3,
26};
27struct gpio_event_info {
28 int (*func)(struct input_dev *input_dev,
29 struct gpio_event_info *info,
30 void **data, int func);
31 int (*event)(struct input_dev *input_dev,
32 struct gpio_event_info *info,
33 void **data, unsigned int type,
34 unsigned int code, int value); /* out events */
35};
36
37struct gpio_event_platform_data {
38 const char *name;
39 struct gpio_event_info **info;
40 size_t info_count;
41 int (*power)(const struct gpio_event_platform_data *pdata, bool on);
42};
43
44#define GPIO_EVENT_DEV_NAME "gpio-event"
45
46/* Key matrix */
47
48enum gpio_event_matrix_flags {
49 /* unset: drive active output low, set: drive active output high */
50 GPIOKPF_ACTIVE_HIGH = 1U << 0,
51 GPIOKPF_DEBOUNCE = 1U << 1,
52 GPIOKPF_REMOVE_SOME_PHANTOM_KEYS = 1U << 2,
53 GPIOKPF_REMOVE_PHANTOM_KEYS = GPIOKPF_REMOVE_SOME_PHANTOM_KEYS |
54 GPIOKPF_DEBOUNCE,
55 GPIOKPF_DRIVE_INACTIVE = 1U << 3,
56 GPIOKPF_LEVEL_TRIGGERED_IRQ = 1U << 4,
57 GPIOKPF_PRINT_UNMAPPED_KEYS = 1U << 16,
58 GPIOKPF_PRINT_MAPPED_KEYS = 1U << 17,
59 GPIOKPF_PRINT_PHANTOM_KEYS = 1U << 18,
60};
61
62extern int gpio_event_matrix_func(struct input_dev *input_dev,
63 struct gpio_event_info *info, void **data, int func);
64struct gpio_event_matrix_info {
65 /* initialize to gpio_event_matrix_func */
66 struct gpio_event_info info;
67 /* size must be ninputs * noutputs */
68 const unsigned short *keymap;
69 unsigned int *input_gpios;
70 unsigned int *output_gpios;
71 unsigned int ninputs;
72 unsigned int noutputs;
73 /* time to wait before reading inputs after driving each output */
74 ktime_t settle_time;
75 /* time to wait before scanning the keypad a second time */
76 ktime_t debounce_delay;
77 ktime_t poll_time;
78 unsigned flags;
79};
80
81/* Directly connected inputs and outputs */
82
83enum gpio_event_direct_flags {
84 GPIOEDF_ACTIVE_HIGH = 1U << 0,
85/* GPIOEDF_USE_DOWN_IRQ = 1U << 1, */
86/* GPIOEDF_USE_IRQ = (1U << 2) | GPIOIDF_USE_DOWN_IRQ, */
87 GPIOEDF_PRINT_KEYS = 1U << 8,
88 GPIOEDF_PRINT_KEY_DEBOUNCE = 1U << 9,
89};
90
91struct gpio_event_direct_entry {
92 uint32_t gpio:23;
93 uint32_t code:9;
94};
95
96/* inputs */
97extern int gpio_event_input_func(struct input_dev *input_dev,
98 struct gpio_event_info *info, void **data, int func);
99struct gpio_event_input_info {
100 /* initialize to gpio_event_input_func */
101 struct gpio_event_info info;
102 ktime_t debounce_time;
103 ktime_t poll_time;
104 uint16_t flags;
105 uint16_t type;
106 const struct gpio_event_direct_entry *keymap;
107 size_t keymap_size;
108};
109
110/* outputs */
111extern int gpio_event_output_func(struct input_dev *input_dev,
112 struct gpio_event_info *info, void **data, int func);
113extern int gpio_event_output_event(struct input_dev *input_dev,
114 struct gpio_event_info *info, void **data,
115 unsigned int type, unsigned int code, int value);
116struct gpio_event_output_info {
117 /* initialize to gpio_event_output_func and gpio_event_output_event */
118 struct gpio_event_info info;
119 uint16_t flags;
120 uint16_t type;
121 const struct gpio_event_direct_entry *keymap;
122 size_t keymap_size;
123};
124
125
126/* axes */
127
128enum gpio_event_axis_flags {
129 GPIOEAF_PRINT_UNKNOWN_DIRECTION = 1U << 16,
130 GPIOEAF_PRINT_RAW = 1U << 17,
131 GPIOEAF_PRINT_EVENT = 1U << 18,
132};
133
134extern int gpio_event_axis_func(struct input_dev *input_dev,
135 struct gpio_event_info *info, void **data, int func);
136struct gpio_event_axis_info {
137 /* initialize to gpio_event_axis_func */
138 struct gpio_event_info info;
139 uint8_t count;
140 uint8_t type; /* EV_REL or EV_ABS */
141 uint16_t code;
142 uint16_t decoded_size;
143 uint16_t (*map)(struct gpio_event_axis_info *info, uint16_t in);
144 uint32_t *gpio;
145 uint32_t flags;
146};
147#define gpio_axis_2bit_gray_map gpio_axis_4bit_gray_map
148#define gpio_axis_3bit_gray_map gpio_axis_4bit_gray_map
149uint16_t gpio_axis_4bit_gray_map(
150 struct gpio_event_axis_info *info, uint16_t in);
151uint16_t gpio_axis_5bit_singletrack_map(
152 struct gpio_event_axis_info *info, uint16_t in);
153
154#endif
diff --git a/drivers/staging/dream/include/linux/msm_adsp.h b/drivers/staging/dream/include/linux/msm_adsp.h
new file mode 100644
index 000000000000..e775f3e94f1d
--- /dev/null
+++ b/drivers/staging/dream/include/linux/msm_adsp.h
@@ -0,0 +1,84 @@
1/* drivers/staging/dream/include/linux/msm_adsp.h
2 *
3 * Copyright (c) QUALCOMM Incorporated
4 * Copyright (C) 2007 Google, Inc.
5 * Author: Iliyan Malchev <ibm@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17#ifndef __LINUX_MSM_ADSP_H
18#define __LINUX_MSM_ADSP_H
19
20#include <linux/types.h>
21#include <linux/ioctl.h>
22
23#define ADSP_IOCTL_MAGIC 'q'
24
25/* ADSP_IOCTL_WRITE_COMMAND */
26struct adsp_command_t {
27 uint16_t queue;
28 uint32_t len; /* bytes */
29 uint8_t *data;
30};
31
32/* ADSP_IOCTL_GET_EVENT */
33struct adsp_event_t {
34 uint16_t type; /* 1 == event (RPC), 0 == message (adsp) */
35 uint32_t timeout_ms; /* -1 for infinite, 0 for immediate return */
36 uint16_t msg_id;
37 uint16_t flags; /* 1 == 16--bit event, 0 == 32-bit event */
38 uint32_t len; /* size in, number of bytes out */
39 uint8_t *data;
40};
41
42#define ADSP_IOCTL_ENABLE \
43 _IOR(ADSP_IOCTL_MAGIC, 1, unsigned)
44
45#define ADSP_IOCTL_DISABLE \
46 _IOR(ADSP_IOCTL_MAGIC, 2, unsigned)
47
48#define ADSP_IOCTL_DISABLE_ACK \
49 _IOR(ADSP_IOCTL_MAGIC, 3, unsigned)
50
51#define ADSP_IOCTL_WRITE_COMMAND \
52 _IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *)
53
54#define ADSP_IOCTL_GET_EVENT \
55 _IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *)
56
57#define ADSP_IOCTL_SET_CLKRATE \
58 _IOR(ADSP_IOCTL_MAGIC, 6, unsigned)
59
60#define ADSP_IOCTL_DISABLE_EVENT_RSP \
61 _IOR(ADSP_IOCTL_MAGIC, 10, unsigned)
62
63struct adsp_pmem_info {
64 int fd;
65 void *vaddr;
66};
67
68#define ADSP_IOCTL_REGISTER_PMEM \
69 _IOW(ADSP_IOCTL_MAGIC, 13, unsigned)
70
71#define ADSP_IOCTL_UNREGISTER_PMEM \
72 _IOW(ADSP_IOCTL_MAGIC, 14, unsigned)
73
74/* Cause any further GET_EVENT ioctls to fail (-ENODEV)
75 * until the device is closed and reopened. Useful for
76 * terminating event dispatch threads
77 */
78#define ADSP_IOCTL_ABORT_EVENT_READ \
79 _IOW(ADSP_IOCTL_MAGIC, 15, unsigned)
80
81#define ADSP_IOCTL_LINK_TASK \
82 _IOW(ADSP_IOCTL_MAGIC, 16, unsigned)
83
84#endif
diff --git a/drivers/staging/dream/include/linux/msm_audio.h b/drivers/staging/dream/include/linux/msm_audio.h
new file mode 100644
index 000000000000..cfbdaa0d98b2
--- /dev/null
+++ b/drivers/staging/dream/include/linux/msm_audio.h
@@ -0,0 +1,115 @@
1/* drivers/staging/dream/include/linux/msm_audio.h
2 *
3 * Copyright (C) 2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __LINUX_MSM_AUDIO_H
17#define __LINUX_MSM_AUDIO_H
18
19#include <linux/types.h>
20#include <linux/ioctl.h>
21#include <asm/sizes.h>
22
23/* PCM Audio */
24
25#define AUDIO_IOCTL_MAGIC 'a'
26
27#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
28#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
29#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
30#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
31#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
32#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
33#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
34#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
35#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
36#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
37#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
38#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
39#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
40#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
41#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
42#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
43#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
44#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
45#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
46
47#define AUDIO_MAX_COMMON_IOCTL_NUM 100
48
49#define AUDIO_MAX_COMMON_IOCTL_NUM 100
50
51struct msm_audio_config {
52 uint32_t buffer_size;
53 uint32_t buffer_count;
54 uint32_t channel_count;
55 uint32_t sample_rate;
56 uint32_t type;
57 uint32_t unused[3];
58};
59
60struct msm_audio_stats {
61 uint32_t byte_count;
62 uint32_t sample_count;
63 uint32_t unused[2];
64};
65
66/* Audio routing */
67
68#define SND_IOCTL_MAGIC 's'
69
70#define SND_MUTE_UNMUTED 0
71#define SND_MUTE_MUTED 1
72
73struct msm_snd_device_config {
74 uint32_t device;
75 uint32_t ear_mute;
76 uint32_t mic_mute;
77};
78
79#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
80
81#define SND_METHOD_VOICE 0
82
83struct msm_snd_volume_config {
84 uint32_t device;
85 uint32_t method;
86 uint32_t volume;
87};
88
89#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
90
91/* Returns the number of SND endpoints supported. */
92
93#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
94
95struct msm_snd_endpoint {
96 int id; /* input and output */
97 char name[64]; /* output only */
98};
99
100/* Takes an index between 0 and one less than the number returned by
101 * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
102 * SND endpoint. On input, the .id field contains the number of the
103 * endpoint, and on exit it contains the SND index, while .name contains
104 * the description of the endpoint.
105 */
106
107#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
108
109struct msm_audio_pcm_config {
110 uint32_t pcm_feedback; /* 0 - disable > 0 - enable */
111 uint32_t buffer_count; /* Number of buffers to allocate */
112 uint32_t buffer_size; /* Size of buffer for capturing of
113 PCM samples */
114};
115#endif
diff --git a/drivers/staging/dream/include/linux/msm_rpcrouter.h b/drivers/staging/dream/include/linux/msm_rpcrouter.h
new file mode 100644
index 000000000000..64845fb481f1
--- /dev/null
+++ b/drivers/staging/dream/include/linux/msm_rpcrouter.h
@@ -0,0 +1,47 @@
1/* drivers/staging/dream/include/linux/msm_rpcrouter.h
2 *
3 * Copyright (c) QUALCOMM Incorporated
4 * Copyright (C) 2007 Google, Inc.
5 * Author: San Mehat <san@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17#ifndef __LINUX_MSM_RPCROUTER_H
18#define __LINUX_MSM_RPCROUTER_H
19
20#include <linux/types.h>
21#include <linux/ioctl.h>
22
23#define RPC_ROUTER_VERSION_V1 0x00010000
24
25struct rpcrouter_ioctl_server_args {
26 uint32_t prog;
27 uint32_t vers;
28};
29
30#define RPC_ROUTER_IOCTL_MAGIC (0xC1)
31
32#define RPC_ROUTER_IOCTL_GET_VERSION \
33 _IOR(RPC_ROUTER_IOCTL_MAGIC, 0, unsigned int)
34
35#define RPC_ROUTER_IOCTL_GET_MTU \
36 _IOR(RPC_ROUTER_IOCTL_MAGIC, 1, unsigned int)
37
38#define RPC_ROUTER_IOCTL_REGISTER_SERVER \
39 _IOWR(RPC_ROUTER_IOCTL_MAGIC, 2, unsigned int)
40
41#define RPC_ROUTER_IOCTL_UNREGISTER_SERVER \
42 _IOWR(RPC_ROUTER_IOCTL_MAGIC, 3, unsigned int)
43
44#define RPC_ROUTER_IOCTL_GET_MINOR_VERSION \
45 _IOW(RPC_ROUTER_IOCTL_MAGIC, 4, unsigned int)
46
47#endif
diff --git a/drivers/staging/dream/include/linux/wakelock.h b/drivers/staging/dream/include/linux/wakelock.h
new file mode 100644
index 000000000000..93c31a4d1ca7
--- /dev/null
+++ b/drivers/staging/dream/include/linux/wakelock.h
@@ -0,0 +1,91 @@
1/* drivers/staging/dream/include/linux/wakelock.h
2 *
3 * Copyright (C) 2007-2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef _LINUX_WAKELOCK_H
17#define _LINUX_WAKELOCK_H
18
19#include <linux/list.h>
20#include <linux/ktime.h>
21
22/* A wake_lock prevents the system from entering suspend or other low power
23 * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
24 * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
25 * states that cause large interrupt latencies or that disable a set of
26 * interrupts will not entered from idle until the wake_locks are released.
27 */
28
29enum {
30 WAKE_LOCK_SUSPEND, /* Prevent suspend */
31 WAKE_LOCK_IDLE, /* Prevent low power idle */
32 WAKE_LOCK_TYPE_COUNT
33};
34
35struct wake_lock {
36#ifdef CONFIG_HAS_WAKELOCK
37 struct list_head link;
38 int flags;
39 const char *name;
40 unsigned long expires;
41#ifdef CONFIG_WAKELOCK_STAT
42 struct {
43 int count;
44 int expire_count;
45 int wakeup_count;
46 ktime_t total_time;
47 ktime_t prevent_suspend_time;
48 ktime_t max_time;
49 ktime_t last_time;
50 } stat;
51#endif
52#endif
53};
54
55#ifdef CONFIG_HAS_WAKELOCK
56
57void wake_lock_init(struct wake_lock *lock, int type, const char *name);
58void wake_lock_destroy(struct wake_lock *lock);
59void wake_lock(struct wake_lock *lock);
60void wake_lock_timeout(struct wake_lock *lock, long timeout);
61void wake_unlock(struct wake_lock *lock);
62
63/* wake_lock_active returns a non-zero value if the wake_lock is currently
64 * locked. If the wake_lock has a timeout, it does not check the timeout
65 * but if the timeout had aready been checked it will return 0.
66 */
67int wake_lock_active(struct wake_lock *lock);
68
69/* has_wake_lock returns 0 if no wake locks of the specified type are active,
70 * and non-zero if one or more wake locks are held. Specifically it returns
71 * -1 if one or more wake locks with no timeout are active or the
72 * number of jiffies until all active wake locks time out.
73 */
74long has_wake_lock(int type);
75
76#else
77
78static inline void wake_lock_init(struct wake_lock *lock, int type,
79 const char *name) {}
80static inline void wake_lock_destroy(struct wake_lock *lock) {}
81static inline void wake_lock(struct wake_lock *lock) {}
82static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
83static inline void wake_unlock(struct wake_lock *lock) {}
84
85static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
86static inline long has_wake_lock(int type) { return 0; }
87
88#endif
89
90#endif
91
diff --git a/drivers/staging/dream/include/mach/camera.h b/drivers/staging/dream/include/mach/camera.h
new file mode 100644
index 000000000000..c20f0423abd4
--- /dev/null
+++ b/drivers/staging/dream/include/mach/camera.h
@@ -0,0 +1,279 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#ifndef __ASM__ARCH_CAMERA_H
6#define __ASM__ARCH_CAMERA_H
7
8#include <linux/list.h>
9#include <linux/poll.h>
10#include <linux/cdev.h>
11#include <linux/platform_device.h>
12#include "linux/types.h"
13
14#include <mach/board.h>
15#include <media/msm_camera.h>
16
17#ifdef CONFIG_MSM_CAMERA_DEBUG
18#define CDBG(fmt, args...) printk(KERN_INFO "msm_camera: " fmt, ##args)
19#else
20#define CDBG(fmt, args...) do { } while (0)
21#endif
22
23#define MSM_CAMERA_MSG 0
24#define MSM_CAMERA_EVT 1
25#define NUM_WB_EXP_NEUTRAL_REGION_LINES 4
26#define NUM_WB_EXP_STAT_OUTPUT_BUFFERS 3
27#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
28#define NUM_AF_STAT_OUTPUT_BUFFERS 3
29
30enum msm_queue {
31 MSM_CAM_Q_CTRL, /* control command or control command status */
32 MSM_CAM_Q_VFE_EVT, /* adsp event */
33 MSM_CAM_Q_VFE_MSG, /* adsp message */
34 MSM_CAM_Q_V4L2_REQ, /* v4l2 request */
35};
36
37enum vfe_resp_msg {
38 VFE_EVENT,
39 VFE_MSG_GENERAL,
40 VFE_MSG_SNAPSHOT,
41 VFE_MSG_OUTPUT1,
42 VFE_MSG_OUTPUT2,
43 VFE_MSG_STATS_AF,
44 VFE_MSG_STATS_WE,
45};
46
47struct msm_vfe_phy_info {
48 uint32_t sbuf_phy;
49 uint32_t y_phy;
50 uint32_t cbcr_phy;
51};
52
53struct msm_vfe_resp {
54 enum vfe_resp_msg type;
55 struct msm_vfe_evt_msg evt_msg;
56 struct msm_vfe_phy_info phy;
57 void *extdata;
58 int32_t extlen;
59};
60
61struct msm_vfe_callback {
62 void (*vfe_resp)(struct msm_vfe_resp *,
63 enum msm_queue, void *syncdata);
64 void* (*vfe_alloc)(int, void *syncdata);
65};
66
67struct msm_camvfe_fn {
68 int (*vfe_init)(struct msm_vfe_callback *, struct platform_device *);
69 int (*vfe_enable)(struct camera_enable_cmd *);
70 int (*vfe_config)(struct msm_vfe_cfg_cmd *, void *);
71 int (*vfe_disable)(struct camera_enable_cmd *,
72 struct platform_device *dev);
73 void (*vfe_release)(struct platform_device *);
74};
75
76struct msm_sensor_ctrl {
77 int (*s_init)(const struct msm_camera_sensor_info *);
78 int (*s_release)(void);
79 int (*s_config)(void __user *);
80};
81
82struct msm_sync {
83 /* These two queues are accessed from a process context only. */
84 struct hlist_head frame; /* most-frequently accessed */
85 struct hlist_head stats;
86
87 /* The message queue is used by the control thread to send commands
88 * to the config thread, and also by the DSP to send messages to the
89 * config thread. Thus it is the only queue that is accessed from
90 * both interrupt and process context.
91 */
92 spinlock_t msg_event_q_lock;
93 struct list_head msg_event_q;
94 wait_queue_head_t msg_event_wait;
95
96 /* This queue contains preview frames. It is accessed by the DSP (in
97 * in interrupt context, and by the frame thread.
98 */
99 spinlock_t prev_frame_q_lock;
100 struct list_head prev_frame_q;
101 wait_queue_head_t prev_frame_wait;
102 int unblock_poll_frame;
103
104 /* This queue contains snapshot frames. It is accessed by the DSP (in
105 * interrupt context, and by the control thread.
106 */
107 spinlock_t pict_frame_q_lock;
108 struct list_head pict_frame_q;
109 wait_queue_head_t pict_frame_wait;
110
111 struct msm_camera_sensor_info *sdata;
112 struct msm_camvfe_fn vfefn;
113 struct msm_sensor_ctrl sctrl;
114 struct platform_device *pdev;
115 uint8_t opencnt;
116 void *cropinfo;
117 int croplen;
118 unsigned pict_pp;
119
120 const char *apps_id;
121
122 struct mutex lock;
123 struct list_head list;
124};
125
126#define MSM_APPS_ID_V4L2 "msm_v4l2"
127#define MSM_APPS_ID_PROP "msm_qct"
128
129struct msm_device {
130 struct msm_sync *sync; /* most-frequently accessed */
131 struct device *device;
132 struct cdev cdev;
133 /* opened is meaningful only for the config and frame nodes,
134 * which may be opened only once.
135 */
136 atomic_t opened;
137};
138
139struct msm_control_device_queue {
140 spinlock_t ctrl_status_q_lock;
141 struct list_head ctrl_status_q;
142 wait_queue_head_t ctrl_status_wait;
143};
144
145struct msm_control_device {
146 struct msm_device *pmsm;
147
148 /* This queue used by the config thread to send responses back to the
149 * control thread. It is accessed only from a process context.
150 */
151 struct msm_control_device_queue ctrl_q;
152};
153
154/* this structure is used in kernel */
155struct msm_queue_cmd {
156 struct list_head list;
157 enum msm_queue type;
158 void *command;
159};
160
161struct register_address_value_pair {
162 uint16_t register_address;
163 uint16_t register_value;
164};
165
166struct msm_pmem_region {
167 struct hlist_node list;
168 int type;
169 void *vaddr;
170 unsigned long paddr;
171 unsigned long len;
172 struct file *file;
173 uint32_t y_off;
174 uint32_t cbcr_off;
175 int fd;
176 uint8_t active;
177};
178
179struct axidata {
180 uint32_t bufnum1;
181 uint32_t bufnum2;
182 struct msm_pmem_region *region;
183};
184
185#ifdef CONFIG_MSM_CAMERA_FLASH
186int msm_camera_flash_set_led_state(unsigned led_state);
187#else
188static inline int msm_camera_flash_set_led_state(unsigned led_state)
189{
190 return -ENOTSUPP;
191}
192#endif
193
194/* Below functions are added for V4L2 kernel APIs */
195struct msm_v4l2_driver {
196 struct msm_sync *sync;
197 int (*open)(struct msm_sync *, const char *apps_id);
198 int (*release)(struct msm_sync *);
199 int (*ctrl)(struct msm_sync *, struct msm_ctrl_cmd *);
200 int (*reg_pmem)(struct msm_sync *, struct msm_pmem_info *);
201 int (*get_frame) (struct msm_sync *, struct msm_frame *);
202 int (*put_frame) (struct msm_sync *, struct msm_frame *);
203 int (*get_pict) (struct msm_sync *, struct msm_ctrl_cmd *);
204 unsigned int (*drv_poll) (struct msm_sync *, struct file *,
205 struct poll_table_struct *);
206};
207
208int msm_v4l2_register(struct msm_v4l2_driver *);
209int msm_v4l2_unregister(struct msm_v4l2_driver *);
210
211void msm_camvfe_init(void);
212int msm_camvfe_check(void *);
213void msm_camvfe_fn_init(struct msm_camvfe_fn *, void *);
214int msm_camera_drv_start(struct platform_device *dev,
215 int (*sensor_probe)(const struct msm_camera_sensor_info *,
216 struct msm_sensor_ctrl *));
217
218enum msm_camio_clk_type {
219 CAMIO_VFE_MDC_CLK,
220 CAMIO_MDC_CLK,
221 CAMIO_VFE_CLK,
222 CAMIO_VFE_AXI_CLK,
223
224 CAMIO_MAX_CLK
225};
226
227enum msm_camio_clk_src_type {
228 MSM_CAMIO_CLK_SRC_INTERNAL,
229 MSM_CAMIO_CLK_SRC_EXTERNAL,
230 MSM_CAMIO_CLK_SRC_MAX
231};
232
233enum msm_s_test_mode {
234 S_TEST_OFF,
235 S_TEST_1,
236 S_TEST_2,
237 S_TEST_3
238};
239
240enum msm_s_resolution {
241 S_QTR_SIZE,
242 S_FULL_SIZE,
243 S_INVALID_SIZE
244};
245
246enum msm_s_reg_update {
247 /* Sensor egisters that need to be updated during initialization */
248 S_REG_INIT,
249 /* Sensor egisters that needs periodic I2C writes */
250 S_UPDATE_PERIODIC,
251 /* All the sensor Registers will be updated */
252 S_UPDATE_ALL,
253 /* Not valid update */
254 S_UPDATE_INVALID
255};
256
257enum msm_s_setting {
258 S_RES_PREVIEW,
259 S_RES_CAPTURE
260};
261
262int msm_camio_enable(struct platform_device *dev);
263
264int msm_camio_clk_enable(enum msm_camio_clk_type clk);
265int msm_camio_clk_disable(enum msm_camio_clk_type clk);
266int msm_camio_clk_config(uint32_t freq);
267void msm_camio_clk_rate_set(int rate);
268void msm_camio_clk_axi_rate_set(int rate);
269
270void msm_camio_camif_pad_reg_reset(void);
271void msm_camio_camif_pad_reg_reset_2(void);
272
273void msm_camio_vfe_blk_reset(void);
274
275void msm_camio_clk_sel(enum msm_camio_clk_src_type);
276void msm_camio_disable(struct platform_device *);
277int msm_camio_probe_on(struct platform_device *);
278int msm_camio_probe_off(struct platform_device *);
279#endif
diff --git a/drivers/staging/dream/include/mach/msm_adsp.h b/drivers/staging/dream/include/mach/msm_adsp.h
new file mode 100644
index 000000000000..a081683328a3
--- /dev/null
+++ b/drivers/staging/dream/include/mach/msm_adsp.h
@@ -0,0 +1,112 @@
1/* include/asm-arm/arch-msm/msm_adsp.h
2 *
3 * Copyright (C) 2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __ASM__ARCH_MSM_ADSP_H
17#define __ASM__ARCH_MSM_ADSP_H
18
19struct msm_adsp_module;
20
21struct msm_adsp_ops {
22 /* event is called from interrupt context when a message
23 * arrives from the DSP. Use the provided function pointer
24 * to copy the message into a local buffer. Do NOT call
25 * it multiple times.
26 */
27 void (*event)(void *driver_data, unsigned id, size_t len,
28 void (*getevent)(void *ptr, size_t len));
29};
30
31/* Get, Put, Enable, and Disable are synchronous and must only
32 * be called from thread context. Enable and Disable will block
33 * up to one second in the event of a fatal DSP error but are
34 * much faster otherwise.
35 */
36int msm_adsp_get(const char *name, struct msm_adsp_module **module,
37 struct msm_adsp_ops *ops, void *driver_data);
38void msm_adsp_put(struct msm_adsp_module *module);
39int msm_adsp_enable(struct msm_adsp_module *module);
40int msm_adsp_disable(struct msm_adsp_module *module);
41int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
42
43/* Write is safe to call from interrupt context.
44 */
45int msm_adsp_write(struct msm_adsp_module *module,
46 unsigned queue_id,
47 void *data, size_t len);
48
49#if CONFIG_MSM_AMSS_VERSION >= 6350
50/* Command Queue Indexes */
51#define QDSP_lpmCommandQueue 0
52#define QDSP_mpuAfeQueue 1
53#define QDSP_mpuGraphicsCmdQueue 2
54#define QDSP_mpuModmathCmdQueue 3
55#define QDSP_mpuVDecCmdQueue 4
56#define QDSP_mpuVDecPktQueue 5
57#define QDSP_mpuVEncCmdQueue 6
58#define QDSP_rxMpuDecCmdQueue 7
59#define QDSP_rxMpuDecPktQueue 8
60#define QDSP_txMpuEncQueue 9
61#define QDSP_uPAudPPCmd1Queue 10
62#define QDSP_uPAudPPCmd2Queue 11
63#define QDSP_uPAudPPCmd3Queue 12
64#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
65#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
66#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
67#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
68#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
69#define QDSP_uPAudPreProcCmdQueue 18
70#define QDSP_uPAudRecBitStreamQueue 19
71#define QDSP_uPAudRecCmdQueue 20
72#define QDSP_uPDiagQueue 21
73#define QDSP_uPJpegActionCmdQueue 22
74#define QDSP_uPJpegCfgCmdQueue 23
75#define QDSP_uPVocProcQueue 24
76#define QDSP_vfeCommandQueue 25
77#define QDSP_vfeCommandScaleQueue 26
78#define QDSP_vfeCommandTableQueue 27
79#define QDSP_MAX_NUM_QUEUES 28
80#else
81/* Command Queue Indexes */
82#define QDSP_lpmCommandQueue 0
83#define QDSP_mpuAfeQueue 1
84#define QDSP_mpuGraphicsCmdQueue 2
85#define QDSP_mpuModmathCmdQueue 3
86#define QDSP_mpuVDecCmdQueue 4
87#define QDSP_mpuVDecPktQueue 5
88#define QDSP_mpuVEncCmdQueue 6
89#define QDSP_rxMpuDecCmdQueue 7
90#define QDSP_rxMpuDecPktQueue 8
91#define QDSP_txMpuEncQueue 9
92#define QDSP_uPAudPPCmd1Queue 10
93#define QDSP_uPAudPPCmd2Queue 11
94#define QDSP_uPAudPPCmd3Queue 12
95#define QDSP_uPAudPlay0BitStreamCtrlQueue 13
96#define QDSP_uPAudPlay1BitStreamCtrlQueue 14
97#define QDSP_uPAudPlay2BitStreamCtrlQueue 15
98#define QDSP_uPAudPlay3BitStreamCtrlQueue 16
99#define QDSP_uPAudPlay4BitStreamCtrlQueue 17
100#define QDSP_uPAudPreProcCmdQueue 18
101#define QDSP_uPAudRecBitStreamQueue 19
102#define QDSP_uPAudRecCmdQueue 20
103#define QDSP_uPJpegActionCmdQueue 21
104#define QDSP_uPJpegCfgCmdQueue 22
105#define QDSP_uPVocProcQueue 23
106#define QDSP_vfeCommandQueue 24
107#define QDSP_vfeCommandScaleQueue 25
108#define QDSP_vfeCommandTableQueue 26
109#define QDSP_QUEUE_MAX 26
110#endif
111
112#endif
diff --git a/drivers/staging/dream/include/mach/msm_rpcrouter.h b/drivers/staging/dream/include/mach/msm_rpcrouter.h
new file mode 100644
index 000000000000..9724ece1c97c
--- /dev/null
+++ b/drivers/staging/dream/include/mach/msm_rpcrouter.h
@@ -0,0 +1,179 @@
1/** include/asm-arm/arch-msm/msm_rpcrouter.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2007-2009 QUALCOMM Incorporated
5 * Author: San Mehat <san@android.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef __ASM__ARCH_MSM_RPCROUTER_H
19#define __ASM__ARCH_MSM_RPCROUTER_H
20
21#include <linux/types.h>
22#include <linux/list.h>
23#include <linux/platform_device.h>
24
25#if CONFIG_MSM_AMSS_VERSION >= 6350
26/* RPC API version structure
27 * Version bit 31 : 1->hashkey versioning,
28 * 0->major-minor (backward compatible) versioning
29 * hashkey versioning:
30 * Version bits 31-0 hashkey
31 * major-minor (backward compatible) versioning
32 * Version bits 30-28 reserved (no match)
33 * Version bits 27-16 major (must match)
34 * Version bits 15-0 minor (greater or equal)
35 */
36#define RPC_VERSION_MODE_MASK 0x80000000
37#define RPC_VERSION_MAJOR_MASK 0x0fff0000
38#define RPC_VERSION_MAJOR_OFFSET 16
39#define RPC_VERSION_MINOR_MASK 0x0000ffff
40
41#define MSM_RPC_VERS(major, minor) \
42 ((uint32_t)((((major) << RPC_VERSION_MAJOR_OFFSET) & \
43 RPC_VERSION_MAJOR_MASK) | \
44 ((minor) & RPC_VERSION_MINOR_MASK)))
45#define MSM_RPC_GET_MAJOR(vers) (((vers) & RPC_VERSION_MAJOR_MASK) >> \
46 RPC_VERSION_MAJOR_OFFSET)
47#define MSM_RPC_GET_MINOR(vers) ((vers) & RPC_VERSION_MINOR_MASK)
48#else
49#define MSM_RPC_VERS(major, minor) (major)
50#define MSM_RPC_GET_MAJOR(vers) (vers)
51#define MSM_RPC_GET_MINOR(vers) 0
52#endif
53
54struct msm_rpc_endpoint;
55
56struct rpcsvr_platform_device
57{
58 struct platform_device base;
59 uint32_t prog;
60 uint32_t vers;
61};
62
63#define RPC_DATA_IN 0
64/*
65 * Structures for sending / receiving direct RPC requests
66 * XXX: Any cred/verif lengths > 0 not supported
67 */
68
69struct rpc_request_hdr
70{
71 uint32_t xid;
72 uint32_t type; /* 0 */
73 uint32_t rpc_vers; /* 2 */
74 uint32_t prog;
75 uint32_t vers;
76 uint32_t procedure;
77 uint32_t cred_flavor;
78 uint32_t cred_length;
79 uint32_t verf_flavor;
80 uint32_t verf_length;
81};
82
83typedef struct
84{
85 uint32_t low;
86 uint32_t high;
87} rpc_reply_progmismatch_data;
88
89typedef struct
90{
91} rpc_denied_reply_hdr;
92
93typedef struct
94{
95 uint32_t verf_flavor;
96 uint32_t verf_length;
97 uint32_t accept_stat;
98#define RPC_ACCEPTSTAT_SUCCESS 0
99#define RPC_ACCEPTSTAT_PROG_UNAVAIL 1
100#define RPC_ACCEPTSTAT_PROG_MISMATCH 2
101#define RPC_ACCEPTSTAT_PROC_UNAVAIL 3
102#define RPC_ACCEPTSTAT_GARBAGE_ARGS 4
103#define RPC_ACCEPTSTAT_SYSTEM_ERR 5
104#define RPC_ACCEPTSTAT_PROG_LOCKED 6
105 /*
106 * Following data is dependant on accept_stat
107 * If ACCEPTSTAT == PROG_MISMATCH then there is a
108 * 'rpc_reply_progmismatch_data' structure following the header.
109 * Otherwise the data is procedure specific
110 */
111} rpc_accepted_reply_hdr;
112
113struct rpc_reply_hdr
114{
115 uint32_t xid;
116 uint32_t type;
117 uint32_t reply_stat;
118#define RPCMSG_REPLYSTAT_ACCEPTED 0
119#define RPCMSG_REPLYSTAT_DENIED 1
120 union {
121 rpc_accepted_reply_hdr acc_hdr;
122 rpc_denied_reply_hdr dny_hdr;
123 } data;
124};
125
126/* flags for msm_rpc_connect() */
127#define MSM_RPC_UNINTERRUPTIBLE 0x0001
128
129/* use IS_ERR() to check for failure */
130struct msm_rpc_endpoint *msm_rpc_open(void);
131/* Connect with the specified server version */
132struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags);
133uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept);
134/* check if server version can handle client requested version */
135int msm_rpc_is_compatible_version(uint32_t server_version,
136 uint32_t client_version);
137
138int msm_rpc_close(struct msm_rpc_endpoint *ept);
139int msm_rpc_write(struct msm_rpc_endpoint *ept,
140 void *data, int len);
141int msm_rpc_read(struct msm_rpc_endpoint *ept,
142 void **data, unsigned len, long timeout);
143void msm_rpc_setup_req(struct rpc_request_hdr *hdr,
144 uint32_t prog, uint32_t vers, uint32_t proc);
145int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
146 uint32_t prog, uint32_t vers);
147int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept,
148 uint32_t prog, uint32_t vers);
149
150/* simple blocking rpc call
151 *
152 * request is mandatory and must have a rpc_request_hdr
153 * at the start. The header will be filled out for you.
154 *
155 * reply provides a buffer for replies of reply_max_size
156 */
157int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc,
158 void *request, int request_size,
159 void *reply, int reply_max_size,
160 long timeout);
161int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc,
162 void *request, int request_size,
163 long timeout);
164
165struct msm_rpc_server
166{
167 struct list_head list;
168 uint32_t flags;
169
170 uint32_t prog;
171 uint32_t vers;
172
173 int (*rpc_call)(struct msm_rpc_server *server,
174 struct rpc_request_hdr *req, unsigned len);
175};
176
177int msm_rpc_create_server(struct msm_rpc_server *server);
178
179#endif
diff --git a/drivers/staging/dream/include/mach/msm_smd.h b/drivers/staging/dream/include/mach/msm_smd.h
new file mode 100644
index 000000000000..bdf7731ab680
--- /dev/null
+++ b/drivers/staging/dream/include/mach/msm_smd.h
@@ -0,0 +1,107 @@
1/* linux/include/asm-arm/arch-msm/msm_smd.h
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Author: Brian Swetland <swetland@google.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __ASM_ARCH_MSM_SMD_H
18#define __ASM_ARCH_MSM_SMD_H
19
20typedef struct smd_channel smd_channel_t;
21
22/* warning: notify() may be called before open returns */
23int smd_open(const char *name, smd_channel_t **ch, void *priv,
24 void (*notify)(void *priv, unsigned event));
25
26#define SMD_EVENT_DATA 1
27#define SMD_EVENT_OPEN 2
28#define SMD_EVENT_CLOSE 3
29
30int smd_close(smd_channel_t *ch);
31
32/* passing a null pointer for data reads and discards */
33int smd_read(smd_channel_t *ch, void *data, int len);
34
35/* Write to stream channels may do a partial write and return
36** the length actually written.
37** Write to packet channels will never do a partial write --
38** it will return the requested length written or an error.
39*/
40int smd_write(smd_channel_t *ch, const void *data, int len);
41
42int smd_write_avail(smd_channel_t *ch);
43int smd_read_avail(smd_channel_t *ch);
44
45/* Returns the total size of the current packet being read.
46** Returns 0 if no packets available or a stream channel.
47*/
48int smd_cur_packet_size(smd_channel_t *ch);
49
50/* used for tty unthrottling and the like -- causes the notify()
51** callback to be called from the same lock context as is used
52** when it is called from channel updates
53*/
54void smd_kick(smd_channel_t *ch);
55
56
57#if 0
58/* these are interruptable waits which will block you until the specified
59** number of bytes are readable or writable.
60*/
61int smd_wait_until_readable(smd_channel_t *ch, int bytes);
62int smd_wait_until_writable(smd_channel_t *ch, int bytes);
63#endif
64
65typedef enum
66{
67 SMD_PORT_DS = 0,
68 SMD_PORT_DIAG,
69 SMD_PORT_RPC_CALL,
70 SMD_PORT_RPC_REPLY,
71 SMD_PORT_BT,
72 SMD_PORT_CONTROL,
73 SMD_PORT_MEMCPY_SPARE1,
74 SMD_PORT_DATA1,
75 SMD_PORT_DATA2,
76 SMD_PORT_DATA3,
77 SMD_PORT_DATA4,
78 SMD_PORT_DATA5,
79 SMD_PORT_DATA6,
80 SMD_PORT_DATA7,
81 SMD_PORT_DATA8,
82 SMD_PORT_DATA9,
83 SMD_PORT_DATA10,
84 SMD_PORT_DATA11,
85 SMD_PORT_DATA12,
86 SMD_PORT_DATA13,
87 SMD_PORT_DATA14,
88 SMD_PORT_DATA15,
89 SMD_PORT_DATA16,
90 SMD_PORT_DATA17,
91 SMD_PORT_DATA18,
92 SMD_PORT_DATA19,
93 SMD_PORT_DATA20,
94 SMD_PORT_GPS_NMEA,
95 SMD_PORT_BRIDGE_1,
96 SMD_PORT_BRIDGE_2,
97 SMD_PORT_BRIDGE_3,
98 SMD_PORT_BRIDGE_4,
99 SMD_PORT_BRIDGE_5,
100 SMD_PORT_LOOPBACK,
101 SMD_PORT_CS_APPS_MODEM,
102 SMD_PORT_CS_APPS_DSP,
103 SMD_PORT_CS_MODEM_DSP,
104 SMD_NUM_PORTS,
105} smd_port_id_type;
106
107#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
new file mode 100644
index 000000000000..0b6a31259bb0
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaycmdi.h
@@ -0,0 +1,94 @@
1#ifndef QDSP5AUDPLAYCMDI_H
2#define QDSP5AUDPLAYCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 Q D S P 5 A U D I O P L A Y T A S K C O M M A N D S
7
8GENERAL DESCRIPTION
9 Command Interface for AUDPLAYTASK on QDSP5
10
11REFERENCES
12 None
13
14EXTERNALIZED FUNCTIONS
15
16 audplay_cmd_dec_data_avail
17 Send buffer to AUDPLAY task
18
19
20Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
21
22This software is licensed under the terms of the GNU General Public
23License version 2, as published by the Free Software Foundation, and
24may be copied, distributed, and modified under those terms.
25
26This program is distributed in the hope that it will be useful,
27but WITHOUT ANY WARRANTY; without even the implied warranty of
28MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29GNU General Public License for more details.
30
31*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
32/*===========================================================================
33
34 EDIT HISTORY FOR FILE
35
36This section contains comments describing changes made to this file.
37Notice that changes are listed in reverse chronological order.
38
39$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaycmdi.h#2 $
40
41===========================================================================*/
42
43#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL 0x0000
44#define AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_LEN \
45 sizeof(audplay_cmd_bitstream_data_avail)
46
47/* Type specification of dec_data_avail message sent to AUDPLAYTASK
48*/
49typedef struct {
50 /*command ID*/
51 unsigned int cmd_id;
52
53 /* Decoder ID for which message is being sent */
54 unsigned int decoder_id;
55
56 /* Start address of data in ARM global memory */
57 unsigned int buf_ptr;
58
59 /* Number of 16-bit words of bit-stream data contiguously available at the
60 * above-mentioned address. */
61 unsigned int buf_size;
62
63 /* Partition number used by audPlayTask to communicate with DSP's RTOS
64 * kernel */
65 unsigned int partition_number;
66} __attribute__((packed)) audplay_cmd_bitstream_data_avail;
67
68#define AUDPLAY_CMD_HPCM_BUF_CFG 0x0003
69#define AUDPLAY_CMD_HPCM_BUF_CFG_LEN \
70 sizeof(struct audplay_cmd_hpcm_buf_cfg)
71
72struct audplay_cmd_hpcm_buf_cfg {
73 unsigned int cmd_id;
74 unsigned int hostpcm_config;
75 unsigned int feedback_frequency;
76 unsigned int byte_swap;
77 unsigned int max_buffers;
78 unsigned int partition_number;
79} __attribute__((packed));
80
81#define AUDPLAY_CMD_BUFFER_REFRESH 0x0004
82#define AUDPLAY_CMD_BUFFER_REFRESH_LEN \
83 sizeof(struct audplay_cmd_buffer_update)
84
85struct audplay_cmd_buffer_refresh {
86 unsigned int cmd_id;
87 unsigned int num_buffers;
88 unsigned int buf_read_count;
89 unsigned int buf0_address;
90 unsigned int buf0_length;
91 unsigned int buf1_address;
92 unsigned int buf1_length;
93} __attribute__((packed));
94#endif /* QDSP5AUDPLAYCMD_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
new file mode 100644
index 000000000000..c63034b8bf13
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audplaymsg.h
@@ -0,0 +1,70 @@
1#ifndef QDSP5AUDPLAYMSG_H
2#define QDSP5AUDPLAYMSG_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 Q D S P 5 A U D I O P L A Y T A S K M S G
7
8GENERAL DESCRIPTION
9 Message sent by AUDPLAY task
10
11REFERENCES
12 None
13
14
15Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
16
17This software is licensed under the terms of the GNU General Public
18License version 2, as published by the Free Software Foundation, and
19may be copied, distributed, and modified under those terms.
20
21This program is distributed in the hope that it will be useful,
22but WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24GNU General Public License for more details.
25
26*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
27/*===========================================================================
28
29 EDIT HISTORY FOR FILE
30
31This section contains comments describing changes made to this file.
32Notice that changes are listed in reverse chronological order.
33
34$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audplaymsg.h#3 $
35
36===========================================================================*/
37#define AUDPLAY_MSG_DEC_NEEDS_DATA 0x0001
38#define AUDPLAY_MSG_DEC_NEEDS_DATA_MSG_LEN \
39 sizeof(audplay_msg_dec_needs_data)
40
41typedef struct{
42 /* reserved*/
43 unsigned int dec_id;
44
45 /* The read pointer offset of external memory until which the
46 * bitstream has been DMAed in. */
47 unsigned int adecDataReadPtrOffset;
48
49 /* The buffer size of external memory. */
50 unsigned int adecDataBufSize;
51
52 unsigned int bitstream_free_len;
53 unsigned int bitstream_write_ptr;
54 unsigned int bitstarem_buf_start;
55 unsigned int bitstream_buf_len;
56} __attribute__((packed)) audplay_msg_dec_needs_data;
57
58#define AUDPLAY_MSG_BUFFER_UPDATE 0x0004
59#define AUDPLAY_MSG_BUFFER_UPDATE_LEN \
60 sizeof(struct audplay_msg_buffer_update)
61
62struct audplay_msg_buffer_update {
63 unsigned int buffer_write_count;
64 unsigned int num_of_buffer;
65 unsigned int buf0_address;
66 unsigned int buf0_length;
67 unsigned int buf1_address;
68 unsigned int buf1_length;
69} __attribute__((packed));
70#endif /* QDSP5AUDPLAYMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
new file mode 100644
index 000000000000..8bee9c62980b
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppcmdi.h
@@ -0,0 +1,914 @@
1#ifndef QDSP5AUDPPCMDI_H
2#define QDSP5AUDPPCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O P O S T P R O C E S S I N G I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by AUDPP Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppcmdi.h#2 $
38
39===========================================================================*/
40
41/*
42 * ARM to AUDPPTASK Commands
43 *
44 * ARM uses three command queues to communicate with AUDPPTASK
45 * 1)uPAudPPCmd1Queue : Used for more frequent and shorter length commands
46 * Location : MEMA
47 * Buffer Size : 6 words
48 * No of buffers in a queue : 20 for gaming audio and 5 for other images
49 * 2)uPAudPPCmd2Queue : Used for commands which are not much lengthier
50 * Location : MEMA
51 * Buffer Size : 23
52 * No of buffers in a queue : 2
53 * 3)uPAudOOCmd3Queue : Used for lengthier and more frequent commands
54 * Location : MEMA
55 * Buffer Size : 145
56 * No of buffers in a queue : 3
57 */
58
59/*
60 * Commands Related to uPAudPPCmd1Queue
61 */
62
63/*
64 * Command Structure to enable or disable the active decoders
65 */
66
67#define AUDPP_CMD_CFG_DEC_TYPE 0x0001
68#define AUDPP_CMD_CFG_DEC_TYPE_LEN sizeof(audpp_cmd_cfg_dec_type)
69
70/* Enable the decoder */
71#define AUDPP_CMD_DEC_TYPE_M 0x000F
72
73#define AUDPP_CMD_ENA_DEC_V 0x4000
74#define AUDPP_CMD_DIS_DEC_V 0x0000
75#define AUDPP_CMD_DEC_STATE_M 0x4000
76
77#define AUDPP_CMD_UPDATDE_CFG_DEC 0x8000
78#define AUDPP_CMD_DONT_UPDATE_CFG_DEC 0x0000
79
80
81/* Type specification of cmd_cfg_dec */
82
83typedef struct {
84 unsigned short cmd_id;
85 unsigned short dec0_cfg;
86 unsigned short dec1_cfg;
87 unsigned short dec2_cfg;
88 unsigned short dec3_cfg;
89 unsigned short dec4_cfg;
90} __attribute__((packed)) audpp_cmd_cfg_dec_type;
91
92/*
93 * Command Structure to Pause , Resume and flushes the selected audio decoders
94 */
95
96#define AUDPP_CMD_DEC_CTRL 0x0002
97#define AUDPP_CMD_DEC_CTRL_LEN sizeof(audpp_cmd_dec_ctrl)
98
99/* Decoder control commands for pause, resume and flush */
100#define AUDPP_CMD_FLUSH_V 0x2000
101
102#define AUDPP_CMD_PAUSE_V 0x4000
103#define AUDPP_CMD_RESUME_V 0x0000
104
105#define AUDPP_CMD_UPDATE_V 0x8000
106#define AUDPP_CMD_IGNORE_V 0x0000
107
108
109/* Type Spec for decoder control command*/
110
111typedef struct {
112 unsigned short cmd_id;
113 unsigned short dec0_ctrl;
114 unsigned short dec1_ctrl;
115 unsigned short dec2_ctrl;
116 unsigned short dec3_ctrl;
117 unsigned short dec4_ctrl;
118} __attribute__((packed)) audpp_cmd_dec_ctrl;
119
120/*
121 * Command Structure to Configure the AVSync FeedBack Mechanism
122 */
123
124#define AUDPP_CMD_AVSYNC 0x0003
125#define AUDPP_CMD_AVSYNC_LEN sizeof(audpp_cmd_avsync)
126
127typedef struct {
128 unsigned short cmd_id;
129 unsigned short object_number;
130 unsigned short interrupt_interval_lsw;
131 unsigned short interrupt_interval_msw;
132} __attribute__((packed)) audpp_cmd_avsync;
133
134/*
135 * Command Structure to enable or disable(sleep) the AUDPPTASK
136 */
137
138#define AUDPP_CMD_CFG 0x0004
139#define AUDPP_CMD_CFG_LEN sizeof(audpp_cmd_cfg)
140
141#define AUDPP_CMD_CFG_SLEEP 0x0000
142#define AUDPP_CMD_CFG_ENABLE 0xFFFF
143
144typedef struct {
145 unsigned short cmd_id;
146 unsigned short cfg;
147} __attribute__((packed)) audpp_cmd_cfg;
148
149/*
150 * Command Structure to Inject or drop the specified no of samples
151 */
152
153#define AUDPP_CMD_ADJUST_SAMP 0x0005
154#define AUDPP_CMD_ADJUST_SAMP_LEN sizeof(audpp_cmd_adjust_samp)
155
156#define AUDPP_CMD_SAMP_DROP -1
157#define AUDPP_CMD_SAMP_INSERT 0x0001
158
159#define AUDPP_CMD_NUM_SAMPLES 0x0001
160
161typedef struct {
162 unsigned short cmd_id;
163 unsigned short object_no;
164 signed short sample_insert_or_drop;
165 unsigned short num_samples;
166} __attribute__((packed)) audpp_cmd_adjust_samp;
167
168/*
169 * Command Structure to Configure AVSync Feedback Mechanism
170 */
171
172#define AUDPP_CMD_AVSYNC_CMD_2 0x0006
173#define AUDPP_CMD_AVSYNC_CMD_2_LEN sizeof(audpp_cmd_avsync_cmd_2)
174
175typedef struct {
176 unsigned short cmd_id;
177 unsigned short object_number;
178 unsigned short interrupt_interval_lsw;
179 unsigned short interrupt_interval_msw;
180 unsigned short sample_counter_dlsw;
181 unsigned short sample_counter_dmsw;
182 unsigned short sample_counter_msw;
183 unsigned short byte_counter_dlsw;
184 unsigned short byte_counter_dmsw;
185 unsigned short byte_counter_msw;
186} __attribute__((packed)) audpp_cmd_avsync_cmd_2;
187
188/*
189 * Command Structure to Configure AVSync Feedback Mechanism
190 */
191
192#define AUDPP_CMD_AVSYNC_CMD_3 0x0007
193#define AUDPP_CMD_AVSYNC_CMD_3_LEN sizeof(audpp_cmd_avsync_cmd_3)
194
195typedef struct {
196 unsigned short cmd_id;
197 unsigned short object_number;
198 unsigned short interrupt_interval_lsw;
199 unsigned short interrupt_interval_msw;
200 unsigned short sample_counter_dlsw;
201 unsigned short sample_counter_dmsw;
202 unsigned short sample_counter_msw;
203 unsigned short byte_counter_dlsw;
204 unsigned short byte_counter_dmsw;
205 unsigned short byte_counter_msw;
206} __attribute__((packed)) audpp_cmd_avsync_cmd_3;
207
208#define AUDPP_CMD_ROUTING_MODE 0x0008
209#define AUDPP_CMD_ROUTING_MODE_LEN \
210sizeof(struct audpp_cmd_routing_mode)
211
212struct audpp_cmd_routing_mode {
213 unsigned short cmd_id;
214 unsigned short object_number;
215 unsigned short routing_mode;
216} __attribute__((packed));
217
218/*
219 * Commands Related to uPAudPPCmd2Queue
220 */
221
222/*
223 * Command Structure to configure Per decoder Parameters (Common)
224 */
225
226#define AUDPP_CMD_CFG_ADEC_PARAMS 0x0000
227#define AUDPP_CMD_CFG_ADEC_PARAMS_COMMON_LEN \
228 sizeof(audpp_cmd_cfg_adec_params_common)
229
230#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_FCM 0x4000
231#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_FCM 0x0000
232
233#define AUDPP_CMD_STATUS_MSG_FLAG_ENA_DCM 0x8000
234#define AUDPP_CMD_STATUS_MSG_FLAG_DIS_DCM 0x0000
235
236/* Sampling frequency*/
237#define AUDPP_CMD_SAMP_RATE_96000 0x0000
238#define AUDPP_CMD_SAMP_RATE_88200 0x0001
239#define AUDPP_CMD_SAMP_RATE_64000 0x0002
240#define AUDPP_CMD_SAMP_RATE_48000 0x0003
241#define AUDPP_CMD_SAMP_RATE_44100 0x0004
242#define AUDPP_CMD_SAMP_RATE_32000 0x0005
243#define AUDPP_CMD_SAMP_RATE_24000 0x0006
244#define AUDPP_CMD_SAMP_RATE_22050 0x0007
245#define AUDPP_CMD_SAMP_RATE_16000 0x0008
246#define AUDPP_CMD_SAMP_RATE_12000 0x0009
247#define AUDPP_CMD_SAMP_RATE_11025 0x000A
248#define AUDPP_CMD_SAMP_RATE_8000 0x000B
249
250
251/*
252 * Type specification of cmd_adec_cfg sent to all decoder
253 */
254
255typedef struct {
256 unsigned short cmd_id;
257 unsigned short length;
258 unsigned short dec_id;
259 unsigned short status_msg_flag;
260 unsigned short decoder_frame_counter_msg_period;
261 unsigned short input_sampling_frequency;
262} __attribute__((packed)) audpp_cmd_cfg_adec_params_common;
263
264/*
265 * Command Structure to configure Per decoder Parameters (Wav)
266 */
267
268#define AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN \
269 sizeof(audpp_cmd_cfg_adec_params_wav)
270
271
272#define AUDPP_CMD_WAV_STEREO_CFG_MONO 0x0001
273#define AUDPP_CMD_WAV_STEREO_CFG_STEREO 0x0002
274
275#define AUDPP_CMD_WAV_PCM_WIDTH_8 0x0000
276#define AUDPP_CMD_WAV_PCM_WIDTH_16 0x0001
277#define AUDPP_CMD_WAV_PCM_WIDTH_32 0x0002
278
279typedef struct {
280 audpp_cmd_cfg_adec_params_common common;
281 unsigned short stereo_cfg;
282 unsigned short pcm_width;
283 unsigned short sign;
284} __attribute__((packed)) audpp_cmd_cfg_adec_params_wav;
285
286/*
287 * Command Structure to configure Per decoder Parameters (ADPCM)
288 */
289
290#define AUDPP_CMD_CFG_ADEC_PARAMS_ADPCM_LEN \
291 sizeof(audpp_cmd_cfg_adec_params_adpcm)
292
293
294#define AUDPP_CMD_ADPCM_STEREO_CFG_MONO 0x0001
295#define AUDPP_CMD_ADPCM_STEREO_CFG_STEREO 0x0002
296
297typedef struct {
298 audpp_cmd_cfg_adec_params_common common;
299 unsigned short stereo_cfg;
300 unsigned short block_size;
301} __attribute__((packed)) audpp_cmd_cfg_adec_params_adpcm;
302
303/*
304 * Command Structure to configure Per decoder Parameters (MP3)
305 */
306
307#define AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN \
308 sizeof(audpp_cmd_cfg_adec_params_mp3)
309
310typedef struct {
311 audpp_cmd_cfg_adec_params_common common;
312} __attribute__((packed)) audpp_cmd_cfg_adec_params_mp3;
313
314
315/*
316 * Command Structure to configure Per decoder Parameters (AAC)
317 */
318
319#define AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN \
320 sizeof(audpp_cmd_cfg_adec_params_aac)
321
322
323#define AUDPP_CMD_AAC_FORMAT_ADTS -1
324#define AUDPP_CMD_AAC_FORMAT_RAW 0x0000
325#define AUDPP_CMD_AAC_FORMAT_PSUEDO_RAW 0x0001
326#define AUDPP_CMD_AAC_FORMAT_LOAS 0x0002
327
328#define AUDPP_CMD_AAC_AUDIO_OBJECT_LC 0x0002
329#define AUDPP_CMD_AAC_AUDIO_OBJECT_LTP 0x0004
330#define AUDPP_CMD_AAC_AUDIO_OBJECT_ERLC 0x0011
331
332#define AUDPP_CMD_AAC_SBR_ON_FLAG_ON 0x0001
333#define AUDPP_CMD_AAC_SBR_ON_FLAG_OFF 0x0000
334
335#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_ON 0x0001
336#define AUDPP_CMD_AAC_SBR_PS_ON_FLAG_OFF 0x0000
337
338typedef struct {
339 audpp_cmd_cfg_adec_params_common common;
340 signed short format;
341 unsigned short audio_object;
342 unsigned short ep_config;
343 unsigned short aac_section_data_resilience_flag;
344 unsigned short aac_scalefactor_data_resilience_flag;
345 unsigned short aac_spectral_data_resilience_flag;
346 unsigned short sbr_on_flag;
347 unsigned short sbr_ps_on_flag;
348 unsigned short dual_mono_mode;
349 unsigned short channel_configuration;
350} __attribute__((packed)) audpp_cmd_cfg_adec_params_aac;
351
352/*
353 * Command Structure to configure Per decoder Parameters (V13K)
354 */
355
356#define AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN \
357 sizeof(struct audpp_cmd_cfg_adec_params_v13k)
358
359
360#define AUDPP_CMD_STEREO_CFG_MONO 0x0001
361#define AUDPP_CMD_STEREO_CFG_STEREO 0x0002
362
363struct audpp_cmd_cfg_adec_params_v13k {
364 audpp_cmd_cfg_adec_params_common common;
365 unsigned short stereo_cfg;
366} __attribute__((packed));
367
368#define AUDPP_CMD_CFG_ADEC_PARAMS_EVRC_LEN \
369 sizeof(struct audpp_cmd_cfg_adec_params_evrc)
370
371struct audpp_cmd_cfg_adec_params_evrc {
372 audpp_cmd_cfg_adec_params_common common;
373 unsigned short stereo_cfg;
374} __attribute__ ((packed));
375
376/*
377 * Command Structure to configure the HOST PCM interface
378 */
379
380#define AUDPP_CMD_PCM_INTF 0x0001
381#define AUDPP_CMD_PCM_INTF_2 0x0002
382#define AUDPP_CMD_PCM_INTF_LEN sizeof(audpp_cmd_pcm_intf)
383
384#define AUDPP_CMD_PCM_INTF_MONO_V 0x0001
385#define AUDPP_CMD_PCM_INTF_STEREO_V 0x0002
386
387/* These two values differentiate the two types of commands that could be issued
388 * Interface configuration command and Buffer update command */
389
390#define AUDPP_CMD_PCM_INTF_CONFIG_CMD_V 0x0000
391#define AUDPP_CMD_PCM_INTF_BUFFER_CMD_V -1
392
393#define AUDPP_CMD_PCM_INTF_RX_ENA_M 0x000F
394#define AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V 0x0008
395#define AUDPP_CMD_PCM_INTF_RX_ENA_DSPTOARM_V 0x0004
396
397/* These flags control the enabling and disabling of the interface together
398 * with host interface bit mask. */
399
400#define AUDPP_CMD_PCM_INTF_ENA_V -1
401#define AUDPP_CMD_PCM_INTF_DIS_V 0x0000
402
403
404#define AUDPP_CMD_PCM_INTF_FULL_DUPLEX 0x0
405#define AUDPP_CMD_PCM_INTF_HALF_DUPLEX_TODSP 0x1
406
407
408#define AUDPP_CMD_PCM_INTF_OBJECT_NUM 0x5
409#define AUDPP_CMD_PCM_INTF_COMMON_OBJECT_NUM 0x6
410
411
412typedef struct {
413 unsigned short cmd_id;
414 unsigned short object_num;
415 signed short config;
416 unsigned short intf_type;
417
418 /* DSP -> ARM Configuration */
419 unsigned short read_buf1LSW;
420 unsigned short read_buf1MSW;
421 unsigned short read_buf1_len;
422
423 unsigned short read_buf2LSW;
424 unsigned short read_buf2MSW;
425 unsigned short read_buf2_len;
426 /* 0:HOST_PCM_INTF disable
427 ** 0xFFFF: HOST_PCM_INTF enable
428 */
429 signed short dsp_to_arm_flag;
430 unsigned short partition_number;
431
432 /* ARM -> DSP Configuration */
433 unsigned short write_buf1LSW;
434 unsigned short write_buf1MSW;
435 unsigned short write_buf1_len;
436
437 unsigned short write_buf2LSW;
438 unsigned short write_buf2MSW;
439 unsigned short write_buf2_len;
440
441 /* 0:HOST_PCM_INTF disable
442 ** 0xFFFF: HOST_PCM_INTF enable
443 */
444 signed short arm_to_rx_flag;
445 unsigned short weight_decoder_to_rx;
446 unsigned short weight_arm_to_rx;
447
448 unsigned short partition_number_arm_to_dsp;
449 unsigned short sample_rate;
450 unsigned short channel_mode;
451} __attribute__((packed)) audpp_cmd_pcm_intf;
452
453/*
454 ** BUFFER UPDATE COMMAND
455 */
456#define AUDPP_CMD_PCM_INTF_SEND_BUF_PARAMS_LEN \
457 sizeof(audpp_cmd_pcm_intf_send_buffer)
458
459typedef struct {
460 unsigned short cmd_id;
461 unsigned short host_pcm_object;
462 /* set config = 0xFFFF for configuration*/
463 signed short config;
464 unsigned short intf_type;
465 unsigned short dsp_to_arm_buf_id;
466 unsigned short arm_to_dsp_buf_id;
467 unsigned short arm_to_dsp_buf_len;
468} __attribute__((packed)) audpp_cmd_pcm_intf_send_buffer;
469
470
471/*
472 * Commands Related to uPAudPPCmd3Queue
473 */
474
475/*
476 * Command Structure to configure post processing params (Commmon)
477 */
478
479#define AUDPP_CMD_CFG_OBJECT_PARAMS 0x0000
480#define AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN \
481 sizeof(audpp_cmd_cfg_object_params_common)
482
483#define AUDPP_CMD_OBJ0_UPDATE 0x8000
484#define AUDPP_CMD_OBJ0_DONT_UPDATE 0x0000
485
486#define AUDPP_CMD_OBJ1_UPDATE 0x8000
487#define AUDPP_CMD_OBJ1_DONT_UPDATE 0x0000
488
489#define AUDPP_CMD_OBJ2_UPDATE 0x8000
490#define AUDPP_CMD_OBJ2_DONT_UPDATE 0x0000
491
492#define AUDPP_CMD_OBJ3_UPDATE 0x8000
493#define AUDPP_CMD_OBJ3_DONT_UPDATE 0x0000
494
495#define AUDPP_CMD_OBJ4_UPDATE 0x8000
496#define AUDPP_CMD_OBJ4_DONT_UPDATE 0x0000
497
498#define AUDPP_CMD_HPCM_UPDATE 0x8000
499#define AUDPP_CMD_HPCM_DONT_UPDATE 0x0000
500
501#define AUDPP_CMD_COMMON_CFG_UPDATE 0x8000
502#define AUDPP_CMD_COMMON_CFG_DONT_UPDATE 0x0000
503
504typedef struct {
505 unsigned short cmd_id;
506 unsigned short obj0_cfg;
507 unsigned short obj1_cfg;
508 unsigned short obj2_cfg;
509 unsigned short obj3_cfg;
510 unsigned short obj4_cfg;
511 unsigned short host_pcm_obj_cfg;
512 unsigned short comman_cfg;
513 unsigned short command_type;
514} __attribute__((packed)) audpp_cmd_cfg_object_params_common;
515
516/*
517 * Command Structure to configure post processing params (Volume)
518 */
519
520#define AUDPP_CMD_CFG_OBJECT_PARAMS_VOLUME_LEN \
521 sizeof(audpp_cmd_cfg_object_params_volume)
522
523typedef struct {
524 audpp_cmd_cfg_object_params_common common;
525 unsigned short volume;
526 unsigned short pan;
527} __attribute__((packed)) audpp_cmd_cfg_object_params_volume;
528
529/*
530 * Command Structure to configure post processing params (PCM Filter) --DOUBT
531 */
532
533typedef struct {
534 unsigned short numerator_b0_filter_lsw;
535 unsigned short numerator_b0_filter_msw;
536 unsigned short numerator_b1_filter_lsw;
537 unsigned short numerator_b1_filter_msw;
538 unsigned short numerator_b2_filter_lsw;
539 unsigned short numerator_b2_filter_msw;
540} __attribute__((packed)) numerator;
541
542typedef struct {
543 unsigned short denominator_a0_filter_lsw;
544 unsigned short denominator_a0_filter_msw;
545 unsigned short denominator_a1_filter_lsw;
546 unsigned short denominator_a1_filter_msw;
547} __attribute__((packed)) denominator;
548
549typedef struct {
550 unsigned short shift_factor_0;
551} __attribute__((packed)) shift_factor;
552
553typedef struct {
554 unsigned short pan_filter_0;
555} __attribute__((packed)) pan;
556
557typedef struct {
558 numerator numerator_filter;
559 denominator denominator_filter;
560 shift_factor shift_factor_filter;
561 pan pan_filter;
562} __attribute__((packed)) filter_1;
563
564typedef struct {
565 numerator numerator_filter[2];
566 denominator denominator_filter[2];
567 shift_factor shift_factor_filter[2];
568 pan pan_filter[2];
569} __attribute__((packed)) filter_2;
570
571typedef struct {
572 numerator numerator_filter[3];
573 denominator denominator_filter[3];
574 shift_factor shift_factor_filter[3];
575 pan pan_filter[3];
576} __attribute__((packed)) filter_3;
577
578typedef struct {
579 numerator numerator_filter[4];
580 denominator denominator_filter[4];
581 shift_factor shift_factor_filter[4];
582 pan pan_filter[4];
583} __attribute__((packed)) filter_4;
584
585#define AUDPP_CMD_CFG_OBJECT_PARAMS_PCM_LEN \
586 sizeof(audpp_cmd_cfg_object_params_pcm)
587
588
589typedef struct {
590 audpp_cmd_cfg_object_params_common common;
591 unsigned short active_flag;
592 unsigned short num_bands;
593 union {
594 filter_1 filter_1_params;
595 filter_2 filter_2_params;
596 filter_3 filter_3_params;
597 filter_4 filter_4_params;
598 } __attribute__((packed)) params_filter;
599} __attribute__((packed)) audpp_cmd_cfg_object_params_pcm;
600
601
602/*
603 * Command Structure to configure post processing parameters (equalizer)
604 */
605
606#define AUDPP_CMD_CFG_OBJECT_PARAMS_EQALIZER_LEN \
607 sizeof(audpp_cmd_cfg_object_params_eqalizer)
608
609typedef struct {
610 unsigned short numerator_coeff_0_lsw;
611 unsigned short numerator_coeff_0_msw;
612 unsigned short numerator_coeff_1_lsw;
613 unsigned short numerator_coeff_1_msw;
614 unsigned short numerator_coeff_2_lsw;
615 unsigned short numerator_coeff_2_msw;
616} __attribute__((packed)) eq_numerator;
617
618typedef struct {
619 unsigned short denominator_coeff_0_lsw;
620 unsigned short denominator_coeff_0_msw;
621 unsigned short denominator_coeff_1_lsw;
622 unsigned short denominator_coeff_1_msw;
623} __attribute__((packed)) eq_denominator;
624
625typedef struct {
626 unsigned short shift_factor;
627} __attribute__((packed)) eq_shiftfactor;
628
629typedef struct {
630 eq_numerator numerator;
631 eq_denominator denominator;
632 eq_shiftfactor shiftfactor;
633} __attribute__((packed)) eq_coeff_1;
634
635typedef struct {
636 eq_numerator numerator[2];
637 eq_denominator denominator[2];
638 eq_shiftfactor shiftfactor[2];
639} __attribute__((packed)) eq_coeff_2;
640
641typedef struct {
642 eq_numerator numerator[3];
643 eq_denominator denominator[3];
644 eq_shiftfactor shiftfactor[3];
645} __attribute__((packed)) eq_coeff_3;
646
647typedef struct {
648 eq_numerator numerator[4];
649 eq_denominator denominator[4];
650 eq_shiftfactor shiftfactor[4];
651} __attribute__((packed)) eq_coeff_4;
652
653typedef struct {
654 eq_numerator numerator[5];
655 eq_denominator denominator[5];
656 eq_shiftfactor shiftfactor[5];
657} __attribute__((packed)) eq_coeff_5;
658
659typedef struct {
660 eq_numerator numerator[6];
661 eq_denominator denominator[6];
662 eq_shiftfactor shiftfactor[6];
663} __attribute__((packed)) eq_coeff_6;
664
665typedef struct {
666 eq_numerator numerator[7];
667 eq_denominator denominator[7];
668 eq_shiftfactor shiftfactor[7];
669} __attribute__((packed)) eq_coeff_7;
670
671typedef struct {
672 eq_numerator numerator[8];
673 eq_denominator denominator[8];
674 eq_shiftfactor shiftfactor[8];
675} __attribute__((packed)) eq_coeff_8;
676
677typedef struct {
678 eq_numerator numerator[9];
679 eq_denominator denominator[9];
680 eq_shiftfactor shiftfactor[9];
681} __attribute__((packed)) eq_coeff_9;
682
683typedef struct {
684 eq_numerator numerator[10];
685 eq_denominator denominator[10];
686 eq_shiftfactor shiftfactor[10];
687} __attribute__((packed)) eq_coeff_10;
688
689typedef struct {
690 eq_numerator numerator[11];
691 eq_denominator denominator[11];
692 eq_shiftfactor shiftfactor[11];
693} __attribute__((packed)) eq_coeff_11;
694
695typedef struct {
696 eq_numerator numerator[12];
697 eq_denominator denominator[12];
698 eq_shiftfactor shiftfactor[12];
699} __attribute__((packed)) eq_coeff_12;
700
701
702typedef struct {
703 audpp_cmd_cfg_object_params_common common;
704 unsigned short eq_flag;
705 unsigned short num_bands;
706 union {
707 eq_coeff_1 eq_coeffs_1;
708 eq_coeff_2 eq_coeffs_2;
709 eq_coeff_3 eq_coeffs_3;
710 eq_coeff_4 eq_coeffs_4;
711 eq_coeff_5 eq_coeffs_5;
712 eq_coeff_6 eq_coeffs_6;
713 eq_coeff_7 eq_coeffs_7;
714 eq_coeff_8 eq_coeffs_8;
715 eq_coeff_9 eq_coeffs_9;
716 eq_coeff_10 eq_coeffs_10;
717 eq_coeff_11 eq_coeffs_11;
718 eq_coeff_12 eq_coeffs_12;
719 } __attribute__((packed)) eq_coeff;
720} __attribute__((packed)) audpp_cmd_cfg_object_params_eqalizer;
721
722
723/*
724 * Command Structure to configure post processing parameters (ADRC)
725 */
726
727#define AUDPP_CMD_CFG_OBJECT_PARAMS_ADRC_LEN \
728 sizeof(audpp_cmd_cfg_object_params_adrc)
729
730
731#define AUDPP_CMD_ADRC_FLAG_DIS 0x0000
732#define AUDPP_CMD_ADRC_FLAG_ENA -1
733
734typedef struct {
735 audpp_cmd_cfg_object_params_common common;
736 signed short adrc_flag;
737 unsigned short compression_th;
738 unsigned short compression_slope;
739 unsigned short rms_time;
740 unsigned short attack_const_lsw;
741 unsigned short attack_const_msw;
742 unsigned short release_const_lsw;
743 unsigned short release_const_msw;
744 unsigned short adrc_system_delay;
745} __attribute__((packed)) audpp_cmd_cfg_object_params_adrc;
746
747/*
748 * Command Structure to configure post processing parameters(Spectrum Analizer)
749 */
750
751#define AUDPP_CMD_CFG_OBJECT_PARAMS_SPECTRAM_LEN \
752 sizeof(audpp_cmd_cfg_object_params_spectram)
753
754
755typedef struct {
756 audpp_cmd_cfg_object_params_common common;
757 unsigned short sample_interval;
758 unsigned short num_coeff;
759} __attribute__((packed)) audpp_cmd_cfg_object_params_spectram;
760
761/*
762 * Command Structure to configure post processing parameters (QConcert)
763 */
764
765#define AUDPP_CMD_CFG_OBJECT_PARAMS_QCONCERT_LEN \
766 sizeof(audpp_cmd_cfg_object_params_qconcert)
767
768
769#define AUDPP_CMD_QCON_ENA_FLAG_ENA -1
770#define AUDPP_CMD_QCON_ENA_FLAG_DIS 0x0000
771
772#define AUDPP_CMD_QCON_OP_MODE_HEADPHONE -1
773#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_FRONT 0x0000
774#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_SIDE 0x0001
775#define AUDPP_CMD_QCON_OP_MODE_SPEAKER_DESKTOP 0x0002
776
777#define AUDPP_CMD_QCON_GAIN_UNIT 0x7FFF
778#define AUDPP_CMD_QCON_GAIN_SIX_DB 0x4027
779
780
781#define AUDPP_CMD_QCON_EXPANSION_MAX 0x7FFF
782
783
784typedef struct {
785 audpp_cmd_cfg_object_params_common common;
786 signed short enable_flag;
787 signed short output_mode;
788 signed short gain;
789 signed short expansion;
790 signed short delay;
791 unsigned short stages_per_mode;
792} __attribute__((packed)) audpp_cmd_cfg_object_params_qconcert;
793
794/*
795 * Command Structure to configure post processing parameters (Side Chain)
796 */
797
798#define AUDPP_CMD_CFG_OBJECT_PARAMS_SIDECHAIN_LEN \
799 sizeof(audpp_cmd_cfg_object_params_sidechain)
800
801
802#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_DIS 0x0000
803#define AUDPP_CMD_SIDECHAIN_ACTIVE_FLAG_ENA -1
804
805typedef struct {
806 audpp_cmd_cfg_object_params_common common;
807 signed short active_flag;
808 unsigned short num_bands;
809 union {
810 filter_1 filter_1_params;
811 filter_2 filter_2_params;
812 filter_3 filter_3_params;
813 filter_4 filter_4_params;
814 } __attribute__((packed)) params_filter;
815} __attribute__((packed)) audpp_cmd_cfg_object_params_sidechain;
816
817
818/*
819 * Command Structure to configure post processing parameters (QAFX)
820 */
821
822#define AUDPP_CMD_CFG_OBJECT_PARAMS_QAFX_LEN \
823 sizeof(audpp_cmd_cfg_object_params_qafx)
824
825#define AUDPP_CMD_QAFX_ENA_DISA 0x0000
826#define AUDPP_CMD_QAFX_ENA_ENA_CFG -1
827#define AUDPP_CMD_QAFX_ENA_DIS_CFG 0x0001
828
829#define AUDPP_CMD_QAFX_CMD_TYPE_ENV 0x0100
830#define AUDPP_CMD_QAFX_CMD_TYPE_OBJ 0x0010
831#define AUDPP_CMD_QAFX_CMD_TYPE_QUERY 0x1000
832
833#define AUDPP_CMD_QAFX_CMDS_ENV_OP_MODE 0x0100
834#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_POS 0x0101
835#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_ORI 0x0102
836#define AUDPP_CMD_QAFX_CMDS_ENV_LIS_VEL 0X0103
837#define AUDPP_CMD_QAFX_CMDS_ENV_ENV_RES 0x0107
838
839#define AUDPP_CMD_QAFX_CMDS_OBJ_SAMP_FREQ 0x0010
840#define AUDPP_CMD_QAFX_CMDS_OBJ_VOL 0x0011
841#define AUDPP_CMD_QAFX_CMDS_OBJ_DIST 0x0012
842#define AUDPP_CMD_QAFX_CMDS_OBJ_POS 0x0013
843#define AUDPP_CMD_QAFX_CMDS_OBJ_VEL 0x0014
844
845
846typedef struct {
847 audpp_cmd_cfg_object_params_common common;
848 signed short enable;
849 unsigned short command_type;
850 unsigned short num_commands;
851 unsigned short commands;
852} __attribute__((packed)) audpp_cmd_cfg_object_params_qafx;
853
854/*
855 * Command Structure to enable , disable or configure the reverberation effect
856 * (Common)
857 */
858
859#define AUDPP_CMD_REVERB_CONFIG 0x0001
860#define AUDPP_CMD_REVERB_CONFIG_COMMON_LEN \
861 sizeof(audpp_cmd_reverb_config_common)
862
863#define AUDPP_CMD_ENA_ENA 0xFFFF
864#define AUDPP_CMD_ENA_DIS 0x0000
865#define AUDPP_CMD_ENA_CFG 0x0001
866
867#define AUDPP_CMD_CMD_TYPE_ENV 0x0104
868#define AUDPP_CMD_CMD_TYPE_OBJ 0x0015
869#define AUDPP_CMD_CMD_TYPE_QUERY 0x1000
870
871
872typedef struct {
873 unsigned short cmd_id;
874 unsigned short enable;
875 unsigned short cmd_type;
876} __attribute__((packed)) audpp_cmd_reverb_config_common;
877
878/*
879 * Command Structure to enable , disable or configure the reverberation effect
880 * (ENV-0x0104)
881 */
882
883#define AUDPP_CMD_REVERB_CONFIG_ENV_104_LEN \
884 sizeof(audpp_cmd_reverb_config_env_104)
885
886typedef struct {
887 audpp_cmd_reverb_config_common common;
888 unsigned short env_gain;
889 unsigned short decay_msw;
890 unsigned short decay_lsw;
891 unsigned short decay_timeratio_msw;
892 unsigned short decay_timeratio_lsw;
893 unsigned short delay_time;
894 unsigned short reverb_gain;
895 unsigned short reverb_delay;
896} __attribute__((packed)) audpp_cmd_reverb_config_env_104;
897
898/*
899 * Command Structure to enable , disable or configure the reverberation effect
900 * (ENV-0x0015)
901 */
902
903#define AUDPP_CMD_REVERB_CONFIG_ENV_15_LEN \
904 sizeof(audpp_cmd_reverb_config_env_15)
905
906typedef struct {
907 audpp_cmd_reverb_config_common common;
908 unsigned short object_num;
909 unsigned short absolute_gain;
910} __attribute__((packed)) audpp_cmd_reverb_config_env_15;
911
912
913#endif /* QDSP5AUDPPCMDI_H */
914
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
new file mode 100644
index 000000000000..44fea224001a
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audppmsg.h
@@ -0,0 +1,318 @@
1#ifndef QDSP5AUDPPMSG_H
2#define QDSP5AUDPPMSG_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 Q D S P 5 A U D I O P O S T P R O C E S S I N G M S G
7
8GENERAL DESCRIPTION
9 Messages sent by AUDPPTASK to ARM
10
11REFERENCES
12 None
13
14EXTERNALIZED FUNCTIONS
15 None
16
17Copyright(c) 1992 - 2009 by QUALCOMM, Incorporated.
18
19This software is licensed under the terms of the GNU General Public
20License version 2, as published by the Free Software Foundation, and
21may be copied, distributed, and modified under those terms.
22
23This program is distributed in the hope that it will be useful,
24but WITHOUT ANY WARRANTY; without even the implied warranty of
25MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26GNU General Public License for more details.
27
28*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
29/*===========================================================================
30
31 EDIT HISTORY FOR FILE
32
33This section contains comments describing changes made to this file.
34Notice that changes are listed in reverse chronological order.
35
36 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audppmsg.h#4 $
37
38===========================================================================*/
39
40/*
41 * AUDPPTASK uses audPPuPRlist to send messages to the ARM
42 * Location : MEMA
43 * Buffer Size : 45
44 * No of Buffers in a queue : 5 for gaming audio and 1 for other images
45 */
46
47/*
48 * MSG to Informs the ARM os Success/Failure of bringing up the decoder
49 */
50
51#define AUDPP_MSG_STATUS_MSG 0x0001
52#define AUDPP_MSG_STATUS_MSG_LEN \
53 sizeof(audpp_msg_status_msg)
54
55#define AUDPP_MSG_STATUS_SLEEP 0x0000
56#define AUDPP_MSG__STATUS_INIT 0x0001
57#define AUDPP_MSG_MSG_STATUS_CFG 0x0002
58#define AUDPP_MSG_STATUS_PLAY 0x0003
59
60#define AUDPP_MSG_REASON_MIPS 0x0000
61#define AUDPP_MSG_REASON_MEM 0x0001
62
63typedef struct{
64 unsigned short dec_id;
65 unsigned short status;
66 unsigned short reason;
67} __attribute__((packed)) audpp_msg_status_msg;
68
69/*
70 * MSG to communicate the spectrum analyzer output bands to the ARM
71 */
72#define AUDPP_MSG_SPA_BANDS 0x0002
73#define AUDPP_MSG_SPA_BANDS_LEN \
74 sizeof(audpp_msg_spa_bands)
75
76typedef struct {
77 unsigned short current_object;
78 unsigned short spa_band_1;
79 unsigned short spa_band_2;
80 unsigned short spa_band_3;
81 unsigned short spa_band_4;
82 unsigned short spa_band_5;
83 unsigned short spa_band_6;
84 unsigned short spa_band_7;
85 unsigned short spa_band_8;
86 unsigned short spa_band_9;
87 unsigned short spa_band_10;
88 unsigned short spa_band_11;
89 unsigned short spa_band_12;
90 unsigned short spa_band_13;
91 unsigned short spa_band_14;
92 unsigned short spa_band_15;
93 unsigned short spa_band_16;
94 unsigned short spa_band_17;
95 unsigned short spa_band_18;
96 unsigned short spa_band_19;
97 unsigned short spa_band_20;
98 unsigned short spa_band_21;
99 unsigned short spa_band_22;
100 unsigned short spa_band_23;
101 unsigned short spa_band_24;
102 unsigned short spa_band_25;
103 unsigned short spa_band_26;
104 unsigned short spa_band_27;
105 unsigned short spa_band_28;
106 unsigned short spa_band_29;
107 unsigned short spa_band_30;
108 unsigned short spa_band_31;
109 unsigned short spa_band_32;
110} __attribute__((packed)) audpp_msg_spa_bands;
111
112/*
113 * MSG to communicate the PCM I/O buffer status to ARM
114 */
115#define AUDPP_MSG_HOST_PCM_INTF_MSG 0x0003
116#define AUDPP_MSG_HOST_PCM_INTF_MSG_LEN \
117 sizeof(audpp_msg_host_pcm_intf_msg)
118
119#define AUDPP_MSG_HOSTPCM_ID_TX_ARM 0x0000
120#define AUDPP_MSG_HOSTPCM_ID_ARM_TX 0x0001
121#define AUDPP_MSG_HOSTPCM_ID_RX_ARM 0x0002
122#define AUDPP_MSG_HOSTPCM_ID_ARM_RX 0x0003
123
124#define AUDPP_MSG_SAMP_FREQ_INDX_96000 0x0000
125#define AUDPP_MSG_SAMP_FREQ_INDX_88200 0x0001
126#define AUDPP_MSG_SAMP_FREQ_INDX_64000 0x0002
127#define AUDPP_MSG_SAMP_FREQ_INDX_48000 0x0003
128#define AUDPP_MSG_SAMP_FREQ_INDX_44100 0x0004
129#define AUDPP_MSG_SAMP_FREQ_INDX_32000 0x0005
130#define AUDPP_MSG_SAMP_FREQ_INDX_24000 0x0006
131#define AUDPP_MSG_SAMP_FREQ_INDX_22050 0x0007
132#define AUDPP_MSG_SAMP_FREQ_INDX_16000 0x0008
133#define AUDPP_MSG_SAMP_FREQ_INDX_12000 0x0009
134#define AUDPP_MSG_SAMP_FREQ_INDX_11025 0x000A
135#define AUDPP_MSG_SAMP_FREQ_INDX_8000 0x000B
136
137#define AUDPP_MSG_CHANNEL_MODE_MONO 0x0001
138#define AUDPP_MSG_CHANNEL_MODE_STEREO 0x0002
139
140typedef struct{
141 unsigned short obj_num;
142 unsigned short numbers_of_samples;
143 unsigned short host_pcm_id;
144 unsigned short buf_indx;
145 unsigned short samp_freq_indx;
146 unsigned short channel_mode;
147} __attribute__((packed)) audpp_msg_host_pcm_intf_msg;
148
149
150/*
151 * MSG to communicate 3D position of the source and listener , source volume
152 * source rolloff, source orientation
153 */
154
155#define AUDPP_MSG_QAFX_POS 0x0004
156#define AUDPP_MSG_QAFX_POS_LEN \
157 sizeof(audpp_msg_qafx_pos)
158
159typedef struct {
160 unsigned short current_object;
161 unsigned short x_pos_lis_msw;
162 unsigned short x_pos_lis_lsw;
163 unsigned short y_pos_lis_msw;
164 unsigned short y_pos_lis_lsw;
165 unsigned short z_pos_lis_msw;
166 unsigned short z_pos_lis_lsw;
167 unsigned short x_fwd_msw;
168 unsigned short x_fwd_lsw;
169 unsigned short y_fwd_msw;
170 unsigned short y_fwd_lsw;
171 unsigned short z_fwd_msw;
172 unsigned short z_fwd_lsw;
173 unsigned short x_up_msw;
174 unsigned short x_up_lsw;
175 unsigned short y_up_msw;
176 unsigned short y_up_lsw;
177 unsigned short z_up_msw;
178 unsigned short z_up_lsw;
179 unsigned short x_vel_lis_msw;
180 unsigned short x_vel_lis_lsw;
181 unsigned short y_vel_lis_msw;
182 unsigned short y_vel_lis_lsw;
183 unsigned short z_vel_lis_msw;
184 unsigned short z_vel_lis_lsw;
185 unsigned short threed_enable_flag;
186 unsigned short volume;
187 unsigned short x_pos_source_msw;
188 unsigned short x_pos_source_lsw;
189 unsigned short y_pos_source_msw;
190 unsigned short y_pos_source_lsw;
191 unsigned short z_pos_source_msw;
192 unsigned short z_pos_source_lsw;
193 unsigned short max_dist_0_msw;
194 unsigned short max_dist_0_lsw;
195 unsigned short min_dist_0_msw;
196 unsigned short min_dist_0_lsw;
197 unsigned short roll_off_factor;
198 unsigned short mute_after_max_flag;
199 unsigned short x_vel_source_msw;
200 unsigned short x_vel_source_lsw;
201 unsigned short y_vel_source_msw;
202 unsigned short y_vel_source_lsw;
203 unsigned short z_vel_source_msw;
204 unsigned short z_vel_source_lsw;
205} __attribute__((packed)) audpp_msg_qafx_pos;
206
207/*
208 * MSG to provide AVSYNC feedback from DSP to ARM
209 */
210
211#define AUDPP_MSG_AVSYNC_MSG 0x0005
212#define AUDPP_MSG_AVSYNC_MSG_LEN \
213 sizeof(audpp_msg_avsync_msg)
214
215typedef struct {
216 unsigned short active_flag;
217 unsigned short num_samples_counter0_HSW;
218 unsigned short num_samples_counter0_MSW;
219 unsigned short num_samples_counter0_LSW;
220 unsigned short num_bytes_counter0_HSW;
221 unsigned short num_bytes_counter0_MSW;
222 unsigned short num_bytes_counter0_LSW;
223 unsigned short samp_freq_obj_0;
224 unsigned short samp_freq_obj_1;
225 unsigned short samp_freq_obj_2;
226 unsigned short samp_freq_obj_3;
227 unsigned short samp_freq_obj_4;
228 unsigned short samp_freq_obj_5;
229 unsigned short samp_freq_obj_6;
230 unsigned short samp_freq_obj_7;
231 unsigned short samp_freq_obj_8;
232 unsigned short samp_freq_obj_9;
233 unsigned short samp_freq_obj_10;
234 unsigned short samp_freq_obj_11;
235 unsigned short samp_freq_obj_12;
236 unsigned short samp_freq_obj_13;
237 unsigned short samp_freq_obj_14;
238 unsigned short samp_freq_obj_15;
239 unsigned short num_samples_counter4_HSW;
240 unsigned short num_samples_counter4_MSW;
241 unsigned short num_samples_counter4_LSW;
242 unsigned short num_bytes_counter4_HSW;
243 unsigned short num_bytes_counter4_MSW;
244 unsigned short num_bytes_counter4_LSW;
245} __attribute__((packed)) audpp_msg_avsync_msg;
246
247/*
248 * MSG to provide PCM DMA Missed feedback from the DSP to ARM
249 */
250
251#define AUDPP_MSG_PCMDMAMISSED 0x0006
252#define AUDPP_MSG_PCMDMAMISSED_LEN \
253 sizeof(audpp_msg_pcmdmamissed);
254
255typedef struct{
256 /*
257 ** Bit 0 0 = PCM DMA not missed for object 0
258 ** 1 = PCM DMA missed for object0
259 ** Bit 1 0 = PCM DMA not missed for object 1
260 ** 1 = PCM DMA missed for object1
261 ** Bit 2 0 = PCM DMA not missed for object 2
262 ** 1 = PCM DMA missed for object2
263 ** Bit 3 0 = PCM DMA not missed for object 3
264 ** 1 = PCM DMA missed for object3
265 ** Bit 4 0 = PCM DMA not missed for object 4
266 ** 1 = PCM DMA missed for object4
267 */
268 unsigned short pcmdmamissed;
269} __attribute__((packed)) audpp_msg_pcmdmamissed;
270
271/*
272 * MSG to AUDPP enable or disable feedback form DSP to ARM
273 */
274
275#define AUDPP_MSG_CFG_MSG 0x0007
276#define AUDPP_MSG_CFG_MSG_LEN \
277 sizeof(audpp_msg_cfg_msg)
278
279#define AUDPP_MSG_ENA_ENA 0xFFFF
280#define AUDPP_MSG_ENA_DIS 0x0000
281
282typedef struct{
283 /* Enabled - 0xffff
284 ** Disabled - 0
285 */
286 unsigned short enabled;
287} __attribute__((packed)) audpp_msg_cfg_msg;
288
289/*
290 * MSG to communicate the reverb per object volume
291 */
292
293#define AUDPP_MSG_QREVERB_VOLUME 0x0008
294#define AUDPP_MSG_QREVERB_VOLUME_LEN \
295 sizeof(audpp_msg_qreverb_volume)
296
297
298typedef struct {
299 unsigned short obj_0_gain;
300 unsigned short obj_1_gain;
301 unsigned short obj_2_gain;
302 unsigned short obj_3_gain;
303 unsigned short obj_4_gain;
304 unsigned short hpcm_obj_volume;
305} __attribute__((packed)) audpp_msg_qreverb_volume;
306
307#define AUDPP_MSG_ROUTING_ACK 0x0009
308#define AUDPP_MSG_ROUTING_ACK_LEN \
309 sizeof(struct audpp_msg_routing_ack)
310
311struct audpp_msg_routing_ack {
312 unsigned short dec_id;
313 unsigned short routing_mode;
314} __attribute__((packed));
315
316#define AUDPP_MSG_FLUSH_ACK 0x000A
317
318#endif /* QDSP5AUDPPMSG_H */
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
new file mode 100644
index 000000000000..06d33d571583
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreproccmdi.h
@@ -0,0 +1,256 @@
1#ifndef QDSP5AUDPREPROCCMDI_H
2#define QDSP5AUDPREPROCCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O P R E P R O C E S S I N G I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by AUDPREPROC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreproccmdi.h#2 $
38
39===========================================================================*/
40
41/*
42 * AUDIOPREPROC COMMANDS:
43 * ARM uses uPAudPreProcCmdQueue to communicate with AUDPREPROCTASK
44 * Location : MEMB
45 * Buffer size : 51
46 * Number of buffers in a queue : 3
47 */
48
49/*
50 * Command to configure the parameters of AGC
51 */
52
53#define AUDPREPROC_CMD_CFG_AGC_PARAMS 0x0000
54#define AUDPREPROC_CMD_CFG_AGC_PARAMS_LEN \
55 sizeof(audpreproc_cmd_cfg_agc_params)
56
57#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE 0x0009
58#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH 0x000A
59#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE 0x000B
60#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH 0x000C
61#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG 0x000D
62#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN 0x000E
63#define AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG 0x000F
64
65#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA -1
66#define AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS 0x0000
67
68#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_ADP_GAIN -1
69#define AUDPREPROC_CMD_ADP_GAIN_FLAG_ENA_STATIC_GAIN 0x0000
70
71#define AUDPREPROC_CMD_PARAM_MASK_RMS_TAY 0x0004
72#define AUDPREPROC_CMD_PARAM_MASK_RELEASEK 0x0005
73#define AUDPREPROC_CMD_PARAM_MASK_DELAY 0x0006
74#define AUDPREPROC_CMD_PARAM_MASK_ATTACKK 0x0007
75#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW 0x0008
76#define AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST 0x0009
77#define AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK 0x000A
78#define AUDPREPROC_CMD_PARAM_MASK_AIG_MIN 0x000B
79#define AUDPREPROC_CMD_PARAM_MASK_AIG_MAX 0x000C
80#define AUDPREPROC_CMD_PARAM_MASK_LEAK_UP 0x000D
81#define AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN 0x000E
82#define AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK 0x000F
83
84typedef struct {
85 unsigned short cmd_id;
86 unsigned short tx_agc_param_mask;
87 unsigned short tx_agc_enable_flag;
88 unsigned short static_gain;
89 signed short adaptive_gain_flag;
90 unsigned short expander_th;
91 unsigned short expander_slope;
92 unsigned short compressor_th;
93 unsigned short compressor_slope;
94 unsigned short param_mask;
95 unsigned short aig_attackk;
96 unsigned short aig_leak_down;
97 unsigned short aig_leak_up;
98 unsigned short aig_max;
99 unsigned short aig_min;
100 unsigned short aig_releasek;
101 unsigned short aig_leakrate_fast;
102 unsigned short aig_leakrate_slow;
103 unsigned short attackk_msw;
104 unsigned short attackk_lsw;
105 unsigned short delay;
106 unsigned short releasek_msw;
107 unsigned short releasek_lsw;
108 unsigned short rms_tav;
109} __attribute__((packed)) audpreproc_cmd_cfg_agc_params;
110
111
112/*
113 * Command to configure the params of Advanved AGC
114 */
115
116#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2 0x0001
117#define AUDPREPROC_CMD_CFG_AGC_PARAMS_2_LEN \
118 sizeof(audpreproc_cmd_cfg_agc_params_2)
119
120#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_ENA -1;
121#define AUDPREPROC_CMD_2_TX_AGC_ENA_FLAG_DIS 0x0000;
122
123typedef struct {
124 unsigned short cmd_id;
125 unsigned short agc_param_mask;
126 signed short tx_agc_enable_flag;
127 unsigned short comp_static_gain;
128 unsigned short exp_th;
129 unsigned short exp_slope;
130 unsigned short comp_th;
131 unsigned short comp_slope;
132 unsigned short comp_rms_tav;
133 unsigned short comp_samp_mask;
134 unsigned short comp_attackk_msw;
135 unsigned short comp_attackk_lsw;
136 unsigned short comp_releasek_msw;
137 unsigned short comp_releasek_lsw;
138 unsigned short comp_delay;
139 unsigned short comp_makeup_gain;
140} __attribute__((packed)) audpreproc_cmd_cfg_agc_params_2;
141
142/*
143 * Command to configure params for ns
144 */
145
146#define AUDPREPROC_CMD_CFG_NS_PARAMS 0x0002
147#define AUDPREPROC_CMD_CFG_NS_PARAMS_LEN \
148 sizeof(audpreproc_cmd_cfg_ns_params)
149
150#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_ENA 0x0001
151#define AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS 0x0000
152#define AUDPREPROC_CMD_EC_MODE_NEW_DES_ENA 0x0002
153#define AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS 0x0000
154#define AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA 0x0004
155#define AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS 0x0000
156#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_ENA 0x0008
157#define AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS 0x0000
158
159#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_ENA 0x0010
160#define AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS 0x0000
161#define AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA 0x0020
162#define AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS 0x0000
163#define AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA 0x0040
164#define AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS 0x0000
165#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_ENA 0x0080
166#define AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS 0x0000
167#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_ENA 0x0100
168#define AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS 0x0000
169#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_ENA 0x0200
170#define AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS 0x0000
171#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_ENA 0x0400
172#define AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS 0x0000
173#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_ENA 0x0800
174#define AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS 0x0000
175#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_ENA 0x1000
176#define AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS 0x0000
177
178typedef struct {
179 unsigned short cmd_id;
180 unsigned short ec_mode_new;
181 unsigned short dens_gamma_n;
182 unsigned short dens_nfe_block_size;
183 unsigned short dens_limit_ns;
184 unsigned short dens_limit_ns_d;
185 unsigned short wb_gamma_e;
186 unsigned short wb_gamma_n;
187} __attribute__((packed)) audpreproc_cmd_cfg_ns_params;
188
189/*
190 * Command to configure parameters for IIR tuning filter
191 */
192
193#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS 0x0003
194#define AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS_LEN \
195 sizeof(audpreproc_cmd_cfg_iir_tuning_filter_params)
196
197#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS 0x0000
198#define AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA 0x0001
199
200typedef struct {
201 unsigned short cmd_id;
202 unsigned short active_flag;
203 unsigned short num_bands;
204 unsigned short numerator_coeff_b0_filter0_lsw;
205 unsigned short numerator_coeff_b0_filter0_msw;
206 unsigned short numerator_coeff_b1_filter0_lsw;
207 unsigned short numerator_coeff_b1_filter0_msw;
208 unsigned short numerator_coeff_b2_filter0_lsw;
209 unsigned short numerator_coeff_b2_filter0_msw;
210 unsigned short numerator_coeff_b0_filter1_lsw;
211 unsigned short numerator_coeff_b0_filter1_msw;
212 unsigned short numerator_coeff_b1_filter1_lsw;
213 unsigned short numerator_coeff_b1_filter1_msw;
214 unsigned short numerator_coeff_b2_filter1_lsw;
215 unsigned short numerator_coeff_b2_filter1_msw;
216 unsigned short numerator_coeff_b0_filter2_lsw;
217 unsigned short numerator_coeff_b0_filter2_msw;
218 unsigned short numerator_coeff_b1_filter2_lsw;
219 unsigned short numerator_coeff_b1_filter2_msw;
220 unsigned short numerator_coeff_b2_filter2_lsw;
221 unsigned short numerator_coeff_b2_filter2_msw;
222 unsigned short numerator_coeff_b0_filter3_lsw;
223 unsigned short numerator_coeff_b0_filter3_msw;
224 unsigned short numerator_coeff_b1_filter3_lsw;
225 unsigned short numerator_coeff_b1_filter3_msw;
226 unsigned short numerator_coeff_b2_filter3_lsw;
227 unsigned short numerator_coeff_b2_filter3_msw;
228 unsigned short denominator_coeff_a0_filter0_lsw;
229 unsigned short denominator_coeff_a0_filter0_msw;
230 unsigned short denominator_coeff_a1_filter0_lsw;
231 unsigned short denominator_coeff_a1_filter0_msw;
232 unsigned short denominator_coeff_a0_filter1_lsw;
233 unsigned short denominator_coeff_a0_filter1_msw;
234 unsigned short denominator_coeff_a1_filter1_lsw;
235 unsigned short denominator_coeff_a1_filter1_msw;
236 unsigned short denominator_coeff_a0_filter2_lsw;
237 unsigned short denominator_coeff_a0_filter2_msw;
238 unsigned short denominator_coeff_a1_filter2_lsw;
239 unsigned short denominator_coeff_a1_filter2_msw;
240 unsigned short denominator_coeff_a0_filter3_lsw;
241 unsigned short denominator_coeff_a0_filter3_msw;
242 unsigned short denominator_coeff_a1_filter3_lsw;
243 unsigned short denominator_coeff_a1_filter3_msw;
244
245 unsigned short shift_factor_filter0;
246 unsigned short shift_factor_filter1;
247 unsigned short shift_factor_filter2;
248 unsigned short shift_factor_filter3;
249
250 unsigned short channel_selected0;
251 unsigned short channel_selected1;
252 unsigned short channel_selected2;
253 unsigned short channel_selected3;
254} __attribute__((packed))audpreproc_cmd_cfg_iir_tuning_filter_params;
255
256#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
new file mode 100644
index 000000000000..f40e41e76737
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audpreprocmsg.h
@@ -0,0 +1,85 @@
1#ifndef QDSP5AUDPREPROCMSG_H
2#define QDSP5AUDPREPROCMSG_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O P R E P R O C E S S I N G M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are rcvd by AUDPREPROC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audpreprocmsg.h#3 $
38
39===========================================================================*/
40
41/*
42 * ADSPREPROCTASK Messages
43 * AUDPREPROCTASK uses audPreProcUpRlist to communicate with ARM
44 * Location : MEMA
45 * Message Length : 2
46 */
47
48/*
49 * Message to indicate particular feature has been enabled or disabled
50 */
51
52
53#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG 0x0000
54#define AUDPREPROC_MSG_CMD_CFG_DONE_MSG_LEN \
55 sizeof(audpreproc_msg_cmd_cfg_done_msg)
56
57#define AUDPREPROC_MSG_TYPE_AGC 0x0000
58#define AUDPREPROC_MSG_TYPE_NOISE_REDUCTION 0x0001
59#define AUDPREPROC_MSG_TYPE_IIR_FILTER 0x0002
60
61
62#define AUDPREPROC_MSG_STATUS_FLAG_ENA -1
63#define AUDPREPROC_MSG_STATUS_FLAG_DIS 0x0000
64
65typedef struct {
66 unsigned short type;
67 signed short status_flag;
68} __attribute__((packed)) audpreproc_msg_cmd_cfg_done_msg;
69
70
71/*
72 * Message to indicate particular feature has selected for wrong samp freq
73 */
74
75#define AUDPREPROC_MSG_ERROR_MSG_ID 0x0001
76#define AUDPREPROC_MSG_ERROR_MSG_ID_LEN \
77 sizeof(audpreproc_msg_error_msg_id)
78
79#define AUDPREPROC_MSG_ERR_INDEX_NS 0x0000
80
81typedef struct {
82 unsigned short err_index;
83} __attribute__((packed)) audpreproc_msg_error_msg_id;
84
85#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
new file mode 100644
index 000000000000..d03ee024ae91
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audreccmdi.h
@@ -0,0 +1,176 @@
1#ifndef QDSP5AUDRECCMDI_H
2#define QDSP5AUDRECCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O R E C O R D I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by AUDREC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30
31/*===========================================================================
32
33 EDIT HISTORY FOR FILE
34
35This section contains comments describing changes made to this file.
36Notice that changes are listed in reverse chronological order.
37
38 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audreccmdi.h#3 $
39
40============================================================================*/
41
42/*
43 * AUDRECTASK COMMANDS
44 * ARM uses 2 queues to communicate with the AUDRECTASK
45 * 1.uPAudRecCmdQueue
46 * Location :MEMC
47 * Buffer Size : 8
48 * No of Buffers in a queue : 3
49 * 2.audRecUpBitStreamQueue
50 * Location : MEMC
51 * Buffer Size : 4
52 * No of buffers in a queue : 2
53 */
54
55/*
56 * Commands on uPAudRecCmdQueue
57 */
58
59/*
60 * Command to initiate and terminate the audio recording section
61 */
62
63#define AUDREC_CMD_CFG 0x0000
64#define AUDREC_CMD_CFG_LEN sizeof(audrec_cmd_cfg)
65
66#define AUDREC_CMD_TYPE_0_INDEX_WAV 0x0000
67#define AUDREC_CMD_TYPE_0_INDEX_AAC 0x0001
68
69#define AUDREC_CMD_TYPE_0_ENA 0x4000
70#define AUDREC_CMD_TYPE_0_DIS 0x0000
71
72#define AUDREC_CMD_TYPE_0_NOUPDATE 0x0000
73#define AUDREC_CMD_TYPE_0_UPDATE 0x8000
74
75#define AUDREC_CMD_TYPE_1_INDEX_SBC 0x0002
76
77#define AUDREC_CMD_TYPE_1_ENA 0x4000
78#define AUDREC_CMD_TYPE_1_DIS 0x0000
79
80#define AUDREC_CMD_TYPE_1_NOUPDATE 0x0000
81#define AUDREC_CMD_TYPE_1_UPDATE 0x8000
82
83typedef struct {
84 unsigned short cmd_id;
85 unsigned short type_0;
86 unsigned short type_1;
87} __attribute__((packed)) audrec_cmd_cfg;
88
89
90/*
91 * Command to configure the recording parameters for RecType0(AAC/WAV) encoder
92 */
93
94#define AUDREC_CMD_AREC0PARAM_CFG 0x0001
95#define AUDREC_CMD_AREC0PARAM_CFG_LEN \
96 sizeof(audrec_cmd_arec0param_cfg)
97
98#define AUDREC_CMD_SAMP_RATE_INDX_8000 0x000B
99#define AUDREC_CMD_SAMP_RATE_INDX_11025 0x000A
100#define AUDREC_CMD_SAMP_RATE_INDX_12000 0x0009
101#define AUDREC_CMD_SAMP_RATE_INDX_16000 0x0008
102#define AUDREC_CMD_SAMP_RATE_INDX_22050 0x0007
103#define AUDREC_CMD_SAMP_RATE_INDX_24000 0x0006
104#define AUDREC_CMD_SAMP_RATE_INDX_32000 0x0005
105#define AUDREC_CMD_SAMP_RATE_INDX_44100 0x0004
106#define AUDREC_CMD_SAMP_RATE_INDX_48000 0x0003
107
108#define AUDREC_CMD_STEREO_MODE_MONO 0x0000
109#define AUDREC_CMD_STEREO_MODE_STEREO 0x0001
110
111typedef struct {
112 unsigned short cmd_id;
113 unsigned short ptr_to_extpkt_buffer_msw;
114 unsigned short ptr_to_extpkt_buffer_lsw;
115 unsigned short buf_len;
116 unsigned short samp_rate_index;
117 unsigned short stereo_mode;
118 unsigned short rec_quality;
119} __attribute__((packed)) audrec_cmd_arec0param_cfg;
120
121/*
122 * Command to configure the recording parameters for RecType1(SBC) encoder
123 */
124
125#define AUDREC_CMD_AREC1PARAM_CFG 0x0002
126#define AUDREC_CMD_AREC1PARAM_CFG_LEN \
127 sizeof(audrec_cmd_arec1param_cfg)
128
129#define AUDREC_CMD_PARAM_BUF_BLOCKS_4 0x0000
130#define AUDREC_CMD_PARAM_BUF_BLOCKS_8 0x0001
131#define AUDREC_CMD_PARAM_BUF_BLOCKS_12 0x0002
132#define AUDREC_CMD_PARAM_BUF_BLOCKS_16 0x0003
133
134#define AUDREC_CMD_PARAM_BUF_SUB_BANDS_8 0x0010
135#define AUDREC_CMD_PARAM_BUF_MODE_MONO 0x0000
136#define AUDREC_CMD_PARAM_BUF_MODE_DUAL 0x0040
137#define AUDREC_CMD_PARAM_BUF_MODE_STEREO 0x0050
138#define AUDREC_CMD_PARAM_BUF_MODE_JSTEREO 0x0060
139#define AUDREC_CMD_PARAM_BUF_LOUDNESS 0x0000
140#define AUDREC_CMD_PARAM_BUF_SNR 0x0100
141#define AUDREC_CMD_PARAM_BUF_BASIC_VER 0x0000
142
143typedef struct {
144 unsigned short cmd_id;
145 unsigned short ptr_to_extpkt_buffer_msw;
146 unsigned short ptr_to_extpkt_buffer_lsw;
147 unsigned short buf_len;
148 unsigned short param_buf;
149 unsigned short bit_rate_0;
150 unsigned short bit_rate_1;
151} __attribute__((packed)) audrec_cmd_arec1param_cfg;
152
153
154/*
155 * Commands on audRecUpBitStreamQueue
156 */
157
158/*
159 * Command to indicate the current packet read count
160 */
161
162#define AUDREC_CMD_PACKET_EXT_PTR 0x0000
163#define AUDREC_CMD_PACKET_EXT_PTR_LEN \
164 sizeof(audrec_cmd_packet_ext_ptr)
165
166#define AUDREC_CMD_TYPE_0 0x0000
167#define AUDREC_CMD_TYPE_1 0x0001
168
169typedef struct {
170 unsigned short cmd_id;
171 unsigned short type;
172 unsigned short curr_rec_count_msw;
173 unsigned short curr_rec_count_lsw;
174} __attribute__((packed)) audrec_cmd_packet_ext_ptr;
175
176#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
new file mode 100644
index 000000000000..bb6eb5093cf5
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5audrecmsg.h
@@ -0,0 +1,127 @@
1#ifndef QDSP5AUDRECMSGI_H
2#define QDSP5AUDRECMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 A U D I O R E C O R D M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are sent by AUDREC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30
31/*===========================================================================
32
33 EDIT HISTORY FOR FILE
34
35This section contains comments describing changes made to this file.
36Notice that changes are listed in reverse chronological order.
37
38 $Header: //source/qcom/qct/multimedia2/Audio/drivers/QDSP5Driver/QDSP5Interface/main/latest/qdsp5audrecmsg.h#3 $
39
40============================================================================*/
41
42/*
43 * AUDRECTASK MESSAGES
44 * AUDRECTASK uses audRecUpRlist to communicate with ARM
45 * Location : MEMC
46 * Buffer size : 4
47 * No of buffers in a queue : 2
48 */
49
50/*
51 * Message to notify that config command is done
52 */
53
54#define AUDREC_MSG_CMD_CFG_DONE_MSG 0x0002
55#define AUDREC_MSG_CMD_CFG_DONE_MSG_LEN \
56 sizeof(audrec_msg_cmd_cfg_done_msg)
57
58
59#define AUDREC_MSG_CFG_DONE_TYPE_0_ENA 0x4000
60#define AUDREC_MSG_CFG_DONE_TYPE_0_DIS 0x0000
61
62#define AUDREC_MSG_CFG_DONE_TYPE_0_NO_UPDATE 0x0000
63#define AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE 0x8000
64
65#define AUDREC_MSG_CFG_DONE_TYPE_1_ENA 0x4000
66#define AUDREC_MSG_CFG_DONE_TYPE_1_DIS 0x0000
67
68#define AUDREC_MSG_CFG_DONE_TYPE_1_NO_UPDATE 0x0000
69#define AUDREC_MSG_CFG_DONE_TYPE_1_UPDATE 0x8000
70
71typedef struct {
72 unsigned short type_0;
73 unsigned short type_1;
74} __attribute__((packed))audrec_msg_cmd_cfg_done_msg;
75
76
77/*
78 * Message to notify arec0/1 cfg done and recording params revd by task
79 */
80
81#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG 0x0003
82#define AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG_LEN \
83 sizeof(audrec_msg_cmd_arec_param_cfg_done_msg)
84
85#define AUDREC_MSG_AREC_PARAM_TYPE_0 0x0000
86#define AUDREC_MSG_AREC_PARAM_TYPE_1 0x0001
87
88typedef struct {
89 unsigned short type;
90} __attribute__((packed))audrec_msg_cmd_arec_param_cfg_done_msg;
91
92
93/*
94 * Message to notify no more buffers are available in ext mem to DME
95 */
96
97#define AUDREC_MSG_FATAL_ERR_MSG 0x0004
98#define AUDREC_MSG_FATAL_ERR_MSG_LEN \
99 sizeof(audrec_msg_fatal_err_msg)
100
101#define AUDREC_MSG_FATAL_ERR_TYPE_0 0x0000
102#define AUDREC_MSG_FATAL_ERR_TYPE_1 0x0001
103
104typedef struct {
105 unsigned short type;
106} __attribute__((packed))audrec_msg_fatal_err_msg;
107
108/*
109 * Message to notify DME deliverd the encoded pkt to ext pkt buffer
110 */
111
112#define AUDREC_MSG_PACKET_READY_MSG 0x0005
113#define AUDREC_MSG_PACKET_READY_MSG_LEN \
114 sizeof(audrec_msg_packet_ready_msg)
115
116#define AUDREC_MSG_PACKET_READY_TYPE_0 0x0000
117#define AUDREC_MSG_PACKET_READY_TYPE_1 0x0001
118
119typedef struct {
120 unsigned short type;
121 unsigned short pkt_counter_msw;
122 unsigned short pkt_counter_lsw;
123 unsigned short pkt_read_cnt_msw;
124 unsigned short pkt_read_cnt_lsw;
125} __attribute__((packed))audrec_msg_packet_ready_msg;
126
127#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
new file mode 100644
index 000000000000..574ad6bbcade
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegcmdi.h
@@ -0,0 +1,376 @@
1#ifndef QDSP5VIDJPEGCMDI_H
2#define QDSP5VIDJPEGCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 J P E G I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by JPEG Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39when who what, where, why
40-------- --- ----------------------------------------------------------
4106/09/08 sv initial version
42===========================================================================*/
43
44/*
45 * ARM to JPEG configuration commands are passed through the
46 * uPJpegCfgCmdQueue
47 */
48
49/*
50 * Command to configure JPEG Encoder
51 */
52
53#define JPEG_CMD_ENC_CFG 0x0000
54#define JPEG_CMD_ENC_CFG_LEN sizeof(jpeg_cmd_enc_cfg)
55
56#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_0 0x0000
57#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_90 0x0100
58#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_180 0x0200
59#define JPEG_CMD_ENC_PROCESS_CFG_OP_ROTATION_270 0x0300
60#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M 0x0003
61#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2 0x0000
62#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V1 0x0001
63#define JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H1V2 0x0002
64
65#define JPEG_CMD_IP_SIZE_CFG_LUMA_HEIGHT_M 0x0000FFFF
66#define JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M 0xFFFF0000
67#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_ENA 0x0001
68#define JPEG_CMD_ENC_UPSAMP_IP_SIZE_CFG_DIS 0x0000
69
70#define JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M 0xFFFF
71
72typedef struct {
73 unsigned int cmd_id;
74 unsigned int process_cfg;
75 unsigned int ip_size_cfg;
76 unsigned int op_size_cfg;
77 unsigned int frag_cfg;
78 unsigned int frag_cfg_part[16];
79
80 unsigned int part_num;
81
82 unsigned int op_buf_0_cfg_part1;
83 unsigned int op_buf_0_cfg_part2;
84 unsigned int op_buf_1_cfg_part1;
85 unsigned int op_buf_1_cfg_part2;
86
87 unsigned int luma_qunt_table[32];
88 unsigned int chroma_qunt_table[32];
89
90 unsigned int upsamp_ip_size_cfg;
91 unsigned int upsamp_ip_frame_off;
92 unsigned int upsamp_pp_filter_coeff[64];
93} __attribute__((packed)) jpeg_cmd_enc_cfg;
94
95/*
96 * Command to configure JPEG Decoder
97 */
98
99#define JPEG_CMD_DEC_CFG 0x0001
100#define JPEG_CMD_DEC_CFG_LEN sizeof(jpeg_cmd_dec_cfg)
101
102#define JPEG_CMD_DEC_OP_DATA_FORMAT_M 0x0001
103#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2 0x0000
104#define JPEG_CMD_DEC_OP_DATA_FORMAT_H2V1 0x0001
105
106#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_8 0x000000
107#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_4 0x010000
108#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_2 0x020000
109#define JPEG_CMD_DEC_OP_DATA_FORMAT_SCALE_FACTOR_1 0x030000
110
111#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_NOT_FINAL 0x0000
112#define JPEG_CMD_DEC_IP_STREAM_BUF_CFG_PART3_FINAL 0x0001
113
114
115typedef struct {
116 unsigned int cmd_id;
117 unsigned int img_dimension_cfg;
118 unsigned int op_data_format;
119 unsigned int restart_interval;
120 unsigned int ip_buf_partition_num;
121 unsigned int ip_stream_buf_cfg_part1;
122 unsigned int ip_stream_buf_cfg_part2;
123 unsigned int ip_stream_buf_cfg_part3;
124 unsigned int op_stream_buf_0_cfg_part1;
125 unsigned int op_stream_buf_0_cfg_part2;
126 unsigned int op_stream_buf_0_cfg_part3;
127 unsigned int op_stream_buf_1_cfg_part1;
128 unsigned int op_stream_buf_1_cfg_part2;
129 unsigned int op_stream_buf_1_cfg_part3;
130 unsigned int luma_qunt_table_0_3;
131 unsigned int luma_qunt_table_4_7;
132 unsigned int luma_qunt_table_8_11;
133 unsigned int luma_qunt_table_12_15;
134 unsigned int luma_qunt_table_16_19;
135 unsigned int luma_qunt_table_20_23;
136 unsigned int luma_qunt_table_24_27;
137 unsigned int luma_qunt_table_28_31;
138 unsigned int luma_qunt_table_32_35;
139 unsigned int luma_qunt_table_36_39;
140 unsigned int luma_qunt_table_40_43;
141 unsigned int luma_qunt_table_44_47;
142 unsigned int luma_qunt_table_48_51;
143 unsigned int luma_qunt_table_52_55;
144 unsigned int luma_qunt_table_56_59;
145 unsigned int luma_qunt_table_60_63;
146 unsigned int chroma_qunt_table_0_3;
147 unsigned int chroma_qunt_table_4_7;
148 unsigned int chroma_qunt_table_8_11;
149 unsigned int chroma_qunt_table_12_15;
150 unsigned int chroma_qunt_table_16_19;
151 unsigned int chroma_qunt_table_20_23;
152 unsigned int chroma_qunt_table_24_27;
153 unsigned int chroma_qunt_table_28_31;
154 unsigned int chroma_qunt_table_32_35;
155 unsigned int chroma_qunt_table_36_39;
156 unsigned int chroma_qunt_table_40_43;
157 unsigned int chroma_qunt_table_44_47;
158 unsigned int chroma_qunt_table_48_51;
159 unsigned int chroma_qunt_table_52_55;
160 unsigned int chroma_qunt_table_56_59;
161 unsigned int chroma_qunt_table_60_63;
162 unsigned int luma_dc_hm_code_cnt_table_0_3;
163 unsigned int luma_dc_hm_code_cnt_table_4_7;
164 unsigned int luma_dc_hm_code_cnt_table_8_11;
165 unsigned int luma_dc_hm_code_cnt_table_12_15;
166 unsigned int luma_dc_hm_code_val_table_0_3;
167 unsigned int luma_dc_hm_code_val_table_4_7;
168 unsigned int luma_dc_hm_code_val_table_8_11;
169 unsigned int chroma_dc_hm_code_cnt_table_0_3;
170 unsigned int chroma_dc_hm_code_cnt_table_4_7;
171 unsigned int chroma_dc_hm_code_cnt_table_8_11;
172 unsigned int chroma_dc_hm_code_cnt_table_12_15;
173 unsigned int chroma_dc_hm_code_val_table_0_3;
174 unsigned int chroma_dc_hm_code_val_table_4_7;
175 unsigned int chroma_dc_hm_code_val_table_8_11;
176 unsigned int luma_ac_hm_code_cnt_table_0_3;
177 unsigned int luma_ac_hm_code_cnt_table_4_7;
178 unsigned int luma_ac_hm_code_cnt_table_8_11;
179 unsigned int luma_ac_hm_code_cnt_table_12_15;
180 unsigned int luma_ac_hm_code_val_table_0_3;
181 unsigned int luma_ac_hm_code_val_table_4_7;
182 unsigned int luma_ac_hm_code_val_table_8_11;
183 unsigned int luma_ac_hm_code_val_table_12_15;
184 unsigned int luma_ac_hm_code_val_table_16_19;
185 unsigned int luma_ac_hm_code_val_table_20_23;
186 unsigned int luma_ac_hm_code_val_table_24_27;
187 unsigned int luma_ac_hm_code_val_table_28_31;
188 unsigned int luma_ac_hm_code_val_table_32_35;
189 unsigned int luma_ac_hm_code_val_table_36_39;
190 unsigned int luma_ac_hm_code_val_table_40_43;
191 unsigned int luma_ac_hm_code_val_table_44_47;
192 unsigned int luma_ac_hm_code_val_table_48_51;
193 unsigned int luma_ac_hm_code_val_table_52_55;
194 unsigned int luma_ac_hm_code_val_table_56_59;
195 unsigned int luma_ac_hm_code_val_table_60_63;
196 unsigned int luma_ac_hm_code_val_table_64_67;
197 unsigned int luma_ac_hm_code_val_table_68_71;
198 unsigned int luma_ac_hm_code_val_table_72_75;
199 unsigned int luma_ac_hm_code_val_table_76_79;
200 unsigned int luma_ac_hm_code_val_table_80_83;
201 unsigned int luma_ac_hm_code_val_table_84_87;
202 unsigned int luma_ac_hm_code_val_table_88_91;
203 unsigned int luma_ac_hm_code_val_table_92_95;
204 unsigned int luma_ac_hm_code_val_table_96_99;
205 unsigned int luma_ac_hm_code_val_table_100_103;
206 unsigned int luma_ac_hm_code_val_table_104_107;
207 unsigned int luma_ac_hm_code_val_table_108_111;
208 unsigned int luma_ac_hm_code_val_table_112_115;
209 unsigned int luma_ac_hm_code_val_table_116_119;
210 unsigned int luma_ac_hm_code_val_table_120_123;
211 unsigned int luma_ac_hm_code_val_table_124_127;
212 unsigned int luma_ac_hm_code_val_table_128_131;
213 unsigned int luma_ac_hm_code_val_table_132_135;
214 unsigned int luma_ac_hm_code_val_table_136_139;
215 unsigned int luma_ac_hm_code_val_table_140_143;
216 unsigned int luma_ac_hm_code_val_table_144_147;
217 unsigned int luma_ac_hm_code_val_table_148_151;
218 unsigned int luma_ac_hm_code_val_table_152_155;
219 unsigned int luma_ac_hm_code_val_table_156_159;
220 unsigned int luma_ac_hm_code_val_table_160_161;
221 unsigned int chroma_ac_hm_code_cnt_table_0_3;
222 unsigned int chroma_ac_hm_code_cnt_table_4_7;
223 unsigned int chroma_ac_hm_code_cnt_table_8_11;
224 unsigned int chroma_ac_hm_code_cnt_table_12_15;
225 unsigned int chroma_ac_hm_code_val_table_0_3;
226 unsigned int chroma_ac_hm_code_val_table_4_7;
227 unsigned int chroma_ac_hm_code_val_table_8_11;
228 unsigned int chroma_ac_hm_code_val_table_12_15;
229 unsigned int chroma_ac_hm_code_val_table_16_19;
230 unsigned int chroma_ac_hm_code_val_table_20_23;
231 unsigned int chroma_ac_hm_code_val_table_24_27;
232 unsigned int chroma_ac_hm_code_val_table_28_31;
233 unsigned int chroma_ac_hm_code_val_table_32_35;
234 unsigned int chroma_ac_hm_code_val_table_36_39;
235 unsigned int chroma_ac_hm_code_val_table_40_43;
236 unsigned int chroma_ac_hm_code_val_table_44_47;
237 unsigned int chroma_ac_hm_code_val_table_48_51;
238 unsigned int chroma_ac_hm_code_val_table_52_55;
239 unsigned int chroma_ac_hm_code_val_table_56_59;
240 unsigned int chroma_ac_hm_code_val_table_60_63;
241 unsigned int chroma_ac_hm_code_val_table_64_67;
242 unsigned int chroma_ac_hm_code_val_table_68_71;
243 unsigned int chroma_ac_hm_code_val_table_72_75;
244 unsigned int chroma_ac_hm_code_val_table_76_79;
245 unsigned int chroma_ac_hm_code_val_table_80_83;
246 unsigned int chroma_ac_hm_code_val_table_84_87;
247 unsigned int chroma_ac_hm_code_val_table_88_91;
248 unsigned int chroma_ac_hm_code_val_table_92_95;
249 unsigned int chroma_ac_hm_code_val_table_96_99;
250 unsigned int chroma_ac_hm_code_val_table_100_103;
251 unsigned int chroma_ac_hm_code_val_table_104_107;
252 unsigned int chroma_ac_hm_code_val_table_108_111;
253 unsigned int chroma_ac_hm_code_val_table_112_115;
254 unsigned int chroma_ac_hm_code_val_table_116_119;
255 unsigned int chroma_ac_hm_code_val_table_120_123;
256 unsigned int chroma_ac_hm_code_val_table_124_127;
257 unsigned int chroma_ac_hm_code_val_table_128_131;
258 unsigned int chroma_ac_hm_code_val_table_132_135;
259 unsigned int chroma_ac_hm_code_val_table_136_139;
260 unsigned int chroma_ac_hm_code_val_table_140_143;
261 unsigned int chroma_ac_hm_code_val_table_144_147;
262 unsigned int chroma_ac_hm_code_val_table_148_151;
263 unsigned int chroma_ac_hm_code_val_table_152_155;
264 unsigned int chroma_ac_hm_code_val_table_156_159;
265 unsigned int chroma_ac_hm_code_val_table_160_161;
266} __attribute__((packed)) jpeg_cmd_dec_cfg;
267
268
269/*
270 * ARM to JPEG configuration commands are passed through the
271 * uPJpegActionCmdQueue
272 */
273
274/*
275 * Command to start the encode process
276 */
277
278#define JPEG_CMD_ENC_ENCODE 0x0000
279#define JPEG_CMD_ENC_ENCODE_LEN sizeof(jpeg_cmd_enc_encode)
280
281
282typedef struct {
283 unsigned short cmd_id;
284} __attribute__((packed)) jpeg_cmd_enc_encode;
285
286
287/*
288 * Command to transition from current state of encoder to IDLE state
289 */
290
291#define JPEG_CMD_ENC_IDLE 0x0001
292#define JPEG_CMD_ENC_IDLE_LEN sizeof(jpeg_cmd_enc_idle)
293
294
295typedef struct {
296 unsigned short cmd_id;
297} __attribute__((packed)) jpeg_cmd_enc_idle;
298
299
300/*
301 * Command to inform the encoder that another buffer is ready
302 */
303
304#define JPEG_CMD_ENC_OP_CONSUMED 0x0002
305#define JPEG_CMD_ENC_OP_CONSUMED_LEN sizeof(jpeg_cmd_enc_op_consumed)
306
307
308typedef struct {
309 unsigned int cmd_id;
310 unsigned int op_buf_addr;
311 unsigned int op_buf_size;
312} __attribute__((packed)) jpeg_cmd_enc_op_consumed;
313
314
315/*
316 * Command to start the decoding process
317 */
318
319#define JPEG_CMD_DEC_DECODE 0x0003
320#define JPEG_CMD_DEC_DECODE_LEN sizeof(jpeg_cmd_dec_decode)
321
322
323typedef struct {
324 unsigned short cmd_id;
325} __attribute__((packed)) jpeg_cmd_dec_decode;
326
327
328/*
329 * Command to transition from the current state of decoder to IDLE
330 */
331
332#define JPEG_CMD_DEC_IDLE 0x0004
333#define JPEG_CMD_DEC_IDLE_LEN sizeof(jpeg_cmd_dec_idle)
334
335
336typedef struct {
337 unsigned short cmd_id;
338} __attribute__((packed)) jpeg_cmd_dec_idle;
339
340
341/*
342 * Command to inform that an op buffer is ready for use
343 */
344
345#define JPEG_CMD_DEC_OP_CONSUMED 0x0005
346#define JPEG_CMD_DEC_OP_CONSUMED_LEN sizeof(jpeg_cmd_dec_op_consumed)
347
348
349typedef struct {
350 unsigned int cmd_id;
351 unsigned int luma_op_buf_addr;
352 unsigned int luma_op_buf_size;
353 unsigned int chroma_op_buf_addr;
354} __attribute__((packed)) jpeg_cmd_dec_op_consumed;
355
356
357/*
358 * Command to pass a new ip buffer to the jpeg decoder
359 */
360
361#define JPEG_CMD_DEC_IP 0x0006
362#define JPEG_CMD_DEC_IP_LEN sizeof(jpeg_cmd_dec_ip_len)
363
364#define JPEG_CMD_EOI_INDICATOR_NOT_END 0x0000
365#define JPEG_CMD_EOI_INDICATOR_END 0x0001
366
367typedef struct {
368 unsigned int cmd_id;
369 unsigned int ip_buf_addr;
370 unsigned int ip_buf_size;
371 unsigned int eoi_indicator;
372} __attribute__((packed)) jpeg_cmd_dec_ip;
373
374
375
376#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
new file mode 100644
index 000000000000..d11aa3fbccb6
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5jpegmsg.h
@@ -0,0 +1,177 @@
1#ifndef QDSP5VIDJPEGMSGI_H
2#define QDSP5VIDJPEGMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 J P E G I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are sent by JPEG Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5jpegmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4205/10/08 sv initial version
43===========================================================================*/
44
45/*
46 * Messages from JPEG task to ARM through jpeguPMsgQueue
47 */
48
49/*
50 * Message is ACK for CMD_JPEGE_ENCODE cmd
51 */
52
53#define JPEG_MSG_ENC_ENCODE_ACK 0x0000
54#define JPEG_MSG_ENC_ENCODE_ACK_LEN \
55 sizeof(jpeg_msg_enc_encode_ack)
56
57typedef struct {
58} __attribute__((packed)) jpeg_msg_enc_encode_ack;
59
60
61/*
62 * Message informs the up when op buffer is ready for consumption and
63 * when encoding is complete or errors
64 */
65
66#define JPEG_MSG_ENC_OP_PRODUCED 0x0001
67#define JPEG_MSG_ENC_OP_PRODUCED_LEN \
68 sizeof(jpeg_msg_enc_op_produced)
69
70#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_PROGRESS 0x0000
71#define JPEG_MSGOP_OP_BUF_STATUS_ENC_DONE_COMPLETE 0x0001
72#define JPEG_MSGOP_OP_BUF_STATUS_ENC_ERR 0x10000
73
74typedef struct {
75 unsigned int op_buf_addr;
76 unsigned int op_buf_size;
77 unsigned int op_buf_status;
78} __attribute__((packed)) jpeg_msg_enc_op_produced;
79
80
81/*
82 * Message to ack CMD_JPEGE_IDLE
83 */
84
85#define JPEG_MSG_ENC_IDLE_ACK 0x0002
86#define JPEG_MSG_ENC_IDLE_ACK_LEN sizeof(jpeg_msg_enc_idle_ack)
87
88
89typedef struct {
90} __attribute__ ((packed)) jpeg_msg_enc_idle_ack;
91
92
93/*
94 * Message to indicate the illegal command
95 */
96
97#define JPEG_MSG_ENC_ILLEGAL_COMMAND 0x0003
98#define JPEG_MSG_ENC_ILLEGAL_COMMAND_LEN \
99 sizeof(jpeg_msg_enc_illegal_command)
100
101typedef struct {
102 unsigned int status;
103} __attribute__((packed)) jpeg_msg_enc_illegal_command;
104
105
106/*
107 * Message to ACK CMD_JPEGD_DECODE
108 */
109
110#define JPEG_MSG_DEC_DECODE_ACK 0x0004
111#define JPEG_MSG_DEC_DECODE_ACK_LEN \
112 sizeof(jpeg_msg_dec_decode_ack)
113
114
115typedef struct {
116} __attribute__((packed)) jpeg_msg_dec_decode_ack;
117
118
119/*
120 * Message to inform up that an op buffer is ready for consumption and when
121 * decoding is complete or an error occurs
122 */
123
124#define JPEG_MSG_DEC_OP_PRODUCED 0x0005
125#define JPEG_MSG_DEC_OP_PRODUCED_LEN \
126 sizeof(jpeg_msg_dec_op_produced)
127
128#define JPEG_MSG_DEC_OP_BUF_STATUS_PROGRESS 0x0000
129#define JPEG_MSG_DEC_OP_BUF_STATUS_DONE 0x0001
130
131typedef struct {
132 unsigned int luma_op_buf_addr;
133 unsigned int chroma_op_buf_addr;
134 unsigned int num_mcus;
135 unsigned int op_buf_status;
136} __attribute__((packed)) jpeg_msg_dec_op_produced;
137
138/*
139 * Message to ack CMD_JPEGD_IDLE cmd
140 */
141
142#define JPEG_MSG_DEC_IDLE_ACK 0x0006
143#define JPEG_MSG_DEC_IDLE_ACK_LEN sizeof(jpeg_msg_dec_idle_ack)
144
145
146typedef struct {
147} __attribute__((packed)) jpeg_msg_dec_idle_ack;
148
149
150/*
151 * Message to indicate illegal cmd was received
152 */
153
154#define JPEG_MSG_DEC_ILLEGAL_COMMAND 0x0007
155#define JPEG_MSG_DEC_ILLEGAL_COMMAND_LEN \
156 sizeof(jpeg_msg_dec_illegal_command)
157
158
159typedef struct {
160 unsigned int status;
161} __attribute__((packed)) jpeg_msg_dec_illegal_command;
162
163/*
164 * Message to request up for the next segment of ip bit stream
165 */
166
167#define JPEG_MSG_DEC_IP_REQUEST 0x0008
168#define JPEG_MSG_DEC_IP_REQUEST_LEN \
169 sizeof(jpeg_msg_dec_ip_request)
170
171
172typedef struct {
173} __attribute__((packed)) jpeg_msg_dec_ip_request;
174
175
176
177#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
new file mode 100644
index 000000000000..6c76e2c20cf4
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmcmdi.h
@@ -0,0 +1,82 @@
1#ifndef QDSP5LPMCMDI_H
2#define QDSP5LPMCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 L P M I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by LPM Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37
38$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmcmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
39Revision History:
40
41when who what, where, why
42-------- --- ----------------------------------------------------------
4306/12/08 sv initial version
44===========================================================================*/
45
46
47/*
48 * Command to start LPM processing based on the config params
49 */
50
51#define LPM_CMD_START 0x0000
52#define LPM_CMD_START_LEN sizeof(lpm_cmd_start)
53
54#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_0 0x00000000
55#define LPM_CMD_SPATIAL_FILTER_PART_OPMODE_1 0x00010000
56typedef struct {
57 unsigned int cmd_id;
58 unsigned int ip_data_cfg_part1;
59 unsigned int ip_data_cfg_part2;
60 unsigned int ip_data_cfg_part3;
61 unsigned int ip_data_cfg_part4;
62 unsigned int op_data_cfg_part1;
63 unsigned int op_data_cfg_part2;
64 unsigned int op_data_cfg_part3;
65 unsigned int spatial_filter_part[32];
66} __attribute__((packed)) lpm_cmd_start;
67
68
69
70/*
71 * Command to stop LPM processing
72 */
73
74#define LPM_CMD_IDLE 0x0001
75#define LPM_CMD_IDLE_LEN sizeof(lpm_cmd_idle)
76
77typedef struct {
78 unsigned int cmd_id;
79} __attribute__((packed)) lpm_cmd_idle;
80
81
82#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
new file mode 100644
index 000000000000..3d1039d6ba42
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5lpmmsg.h
@@ -0,0 +1,80 @@
1#ifndef QDSP5LPMMSGI_H
2#define QDSP5LPMMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 L P M I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by LPM Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5lpmmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4206/12/08 sv initial version
43===========================================================================*/
44
45/*
46 * Message to acknowledge CMD_LPM_IDLE command
47 */
48
49#define LPM_MSG_IDLE_ACK 0x0000
50#define LPM_MSG_IDLE_ACK_LEN sizeof(lpm_msg_idle_ack)
51
52typedef struct {
53} __attribute__((packed)) lpm_msg_idle_ack;
54
55
56/*
57 * Message to acknowledge CMD_LPM_START command
58 */
59
60
61#define LPM_MSG_START_ACK 0x0001
62#define LPM_MSG_START_ACK_LEN sizeof(lpm_msg_start_ack)
63
64
65typedef struct {
66} __attribute__((packed)) lpm_msg_start_ack;
67
68
69/*
70 * Message to notify the ARM that LPM processing is complete
71 */
72
73#define LPM_MSG_DONE 0x0002
74#define LPM_MSG_DONE_LEN sizeof(lpm_msg_done)
75
76typedef struct {
77} __attribute__((packed)) lpm_msg_done;
78
79
80#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
new file mode 100644
index 000000000000..3a32ee99c6e4
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdeccmdi.h
@@ -0,0 +1,235 @@
1#ifndef QDSP5VIDDECCMDI_H
2#define QDSP5VIDDECCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V I D E O D E C O D E R I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by VIDDEC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdeccmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4205/10/08 ac initial version
43===========================================================================*/
44
45
46/*
47 * Command to inform VIDDEC that new subframe packet is ready
48 */
49
50#define VIDDEC_CMD_SUBFRAME_PKT 0x0000
51#define VIDDEC_CMD_SUBFRAME_PKT_LEN \
52 sizeof(viddec_cmd_subframe_pkt)
53
54#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DM 0x0000
55#define VIDDEC_CMD_SF_INFO_1_DM_DMA_STATS_EXCHANGE_FLAG_DMA 0x0001
56
57#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_CONTI 0x0000
58#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST 0x0001
59#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_LAST 0x0002
60#define VIDDEC_CMD_SF_INFO_0_SUBFRAME_FIRST_AND_LAST 0x0003
61
62#define VIDDEC_CMD_CODEC_SELECTION_WORD_MPEG_4 0x0000
63#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_P0 0x0001
64#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_264 0x0002
65#define VIDDEC_CMD_CODEC_SELECTION_WORD_H_263_p3 0x0003
66#define VIDDEC_CMD_CODEC_SELECTION_WORD_RV9 0x0004
67#define VIDDEC_CMD_CODEC_SELECTION_WORD_WMV9 0x0005
68#define VIDDEC_CMD_CODEC_SELECTION_WORD_SMCDB 0x0006
69#define VIDDEC_CMD_CODEC_SELECTION_WORD_QFRE 0x0007
70#define VIDDEC_CMD_CODEC_SELECTION_WORD_VLD 0x0008
71
72typedef struct {
73 unsigned short cmd_id;
74 unsigned short packet_seq_number;
75 unsigned short codec_instance_id;
76 unsigned short subframe_packet_size_high;
77 unsigned short subframe_packet_size_low;
78 unsigned short subframe_packet_high;
79 unsigned short subframe_packet_low;
80 unsigned short subframe_packet_partition;
81 unsigned short statistics_packet_size_high;
82 unsigned short statistics_packet_size_low;
83 unsigned short statistics_packet_high;
84 unsigned short statistics_packet_low;
85 unsigned short statistics_partition;
86 unsigned short subframe_info_1;
87 unsigned short subframe_info_0;
88 unsigned short codec_selection_word;
89 unsigned short num_mbs;
90} __attribute__((packed)) viddec_cmd_subframe_pkt;
91
92
93/*
94 * Command to inform VIDDEC task that post processing is required for the frame
95 */
96
97#define VIDDEC_CMD_PP_ENABLE 0x0001
98#define VIDDEC_CMD_PP_ENABLE_LEN \
99 sizeof(viddec_cmd_pp_enable)
100
101#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DM 0x0000
102#define VIDDEC_CMD_PP_INFO_0_DM_DMA_LS_EXCHANGE_FLAG_DMA 0x0001
103
104typedef struct {
105 unsigned short cmd_id;
106 unsigned short packet_seq_num;
107 unsigned short codec_instance_id;
108 unsigned short postproc_info_0;
109 unsigned short codec_selection_word;
110 unsigned short pp_output_addr_high;
111 unsigned short pp_output_addr_low;
112 unsigned short postproc_info_1;
113 unsigned short load_sharing_packet_size_high;
114 unsigned short load_sharing_packet_size_low;
115 unsigned short load_sharing_packet_high;
116 unsigned short load_sharing_packet_low;
117 unsigned short load_sharing_partition;
118 unsigned short pp_param_0;
119 unsigned short pp_param_1;
120 unsigned short pp_param_2;
121 unsigned short pp_param_3;
122} __attribute__((packed)) viddec_cmd_pp_enable;
123
124
125/*
126 * FRAME Header Packet : It is at the start of new frame
127 */
128
129#define VIDDEC_CMD_FRAME_HEADER_PACKET 0x0002
130#define VIDDEC_CMD_FRAME_HEADER_PACKET_LEN \
131 sizeof(viddec_cmd_frame_header_packet)
132
133#define VIDDEC_CMD_FRAME_INFO_0_ERROR_SKIP 0x0000
134#define VIDDEC_CMD_FRAME_INFO_0_ERROR_BLACK 0x0800
135
136typedef struct {
137 unsigned short packet_id;
138 unsigned short x_dimension;
139 unsigned short y_dimension;
140 unsigned short line_width;
141 unsigned short frame_info_0;
142 unsigned short frame_buffer_0_high;
143 unsigned short frame_buffer_0_low;
144 unsigned short frame_buffer_1_high;
145 unsigned short frame_buffer_1_low;
146 unsigned short frame_buffer_2_high;
147 unsigned short frame_buffer_2_low;
148 unsigned short frame_buffer_3_high;
149 unsigned short frame_buffer_3_low;
150 unsigned short frame_buffer_4_high;
151 unsigned short frame_buffer_4_low;
152 unsigned short frame_buffer_5_high;
153 unsigned short frame_buffer_5_low;
154 unsigned short frame_buffer_6_high;
155 unsigned short frame_buffer_6_low;
156 unsigned short frame_buffer_7_high;
157 unsigned short frame_buffer_7_low;
158 unsigned short frame_buffer_8_high;
159 unsigned short frame_buffer_8_low;
160 unsigned short frame_buffer_9_high;
161 unsigned short frame_buffer_9_low;
162 unsigned short frame_buffer_10_high;
163 unsigned short frame_buffer_10_low;
164 unsigned short frame_buffer_11_high;
165 unsigned short frame_buffer_11_low;
166 unsigned short frame_buffer_12_high;
167 unsigned short frame_buffer_12_low;
168 unsigned short frame_buffer_13_high;
169 unsigned short frame_buffer_13_low;
170 unsigned short frame_buffer_14_high;
171 unsigned short frame_buffer_14_low;
172 unsigned short frame_buffer_15_high;
173 unsigned short frame_buffer_15_low;
174 unsigned short output_frame_buffer_high;
175 unsigned short output_frame_buffer_low;
176 unsigned short end_of_packet_marker;
177} __attribute__((packed)) viddec_cmd_frame_header_packet;
178
179
180/*
181 * SLICE HEADER PACKET
182 * I-Slice and P-Slice
183 */
184
185#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE 0x0003
186#define VIDDEC_CMD_SLICE_HEADER_PKT_ISLICE_LEN \
187 sizeof(viddec_cmd_slice_header_pkt_islice)
188
189#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_PSLICE 0x0000
190#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_BSLICE 0x0100
191#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_ISLICE 0x0200
192#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SPSLICE 0x0300
193#define VIDDEC_CMD_ISLICE_INFO_1_MOD_SLICE_TYPE_SISLICE 0x0400
194#define VIDDEC_CMD_ISLICE_INFO_1_NOPADDING 0x0000
195#define VIDDEC_CMD_ISLICE_INFO_1_PADDING 0x0800
196
197#define VIDDEC_CMD_ISLICE_EOP_MARKER 0x7FFF
198
199typedef struct {
200 unsigned short cmd_id;
201 unsigned short packet_id;
202 unsigned short slice_info_0;
203 unsigned short slice_info_1;
204 unsigned short slice_info_2;
205 unsigned short num_bytes_in_rbsp_high;
206 unsigned short num_bytes_in_rbsp_low;
207 unsigned short num_bytes_in_rbsp_consumed;
208 unsigned short end_of_packet_marker;
209} __attribute__((packed)) viddec_cmd_slice_header_pkt_islice;
210
211
212#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE 0x0003
213#define VIDDEC_CMD_SLICE_HEADER_PKT_PSLICE_LEN \
214 sizeof(viddec_cmd_slice_header_pkt_pslice)
215
216
217typedef struct {
218 unsigned short cmd_id;
219 unsigned short packet_id;
220 unsigned short slice_info_0;
221 unsigned short slice_info_1;
222 unsigned short slice_info_2;
223 unsigned short slice_info_3;
224 unsigned short refidx_l0_map_tab_info_0;
225 unsigned short refidx_l0_map_tab_info_1;
226 unsigned short refidx_l0_map_tab_info_2;
227 unsigned short refidx_l0_map_tab_info_3;
228 unsigned short num_bytes_in_rbsp_high;
229 unsigned short num_bytes_in_rbsp_low;
230 unsigned short num_bytes_in_rbsp_consumed;
231 unsigned short end_of_packet_marker;
232} __attribute__((packed)) viddec_cmd_slice_header_pkt_pslice;
233
234
235#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
new file mode 100644
index 000000000000..c1744c1644dd
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vdecmsg.h
@@ -0,0 +1,107 @@
1#ifndef QDSP5VIDDECMSGI_H
2#define QDSP5VIDDECMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V I D E O D E C O D E R I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of messages
10 that are sent by VIDDEC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vdecmsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4205/10/08 ac initial version
43===========================================================================*/
44
45/*
46 * Message to inform ARM which VDEC_SUBFRAME_PKT_CMD processed by VIDDEC TASK
47 */
48
49#define VIDDEC_MSG_SUBF_DONE 0x0000
50#define VIDDEC_MSG_SUBF_DONE_LEN \
51 sizeof(viddec_msg_subf_done)
52
53typedef struct {
54 unsigned short packet_seq_number;
55 unsigned short codec_instance_id;
56} __attribute__((packed)) viddec_msg_subf_done;
57
58
59/*
60 * Message to inform ARM one frame has been decoded
61 */
62
63#define VIDDEC_MSG_FRAME_DONE 0x0001
64#define VIDDEC_MSG_FRAME_DONE_LEN \
65 sizeof(viddec_msg_frame_done)
66
67typedef struct {
68 unsigned short packet_seq_number;
69 unsigned short codec_instance_id;
70} __attribute__((packed)) viddec_msg_frame_done;
71
72
73/*
74 * Message to inform ARM that post processing frame has been decoded
75 */
76
77#define VIDDEC_MSG_PP_ENABLE_CMD_DONE 0x0002
78#define VIDDEC_MSG_PP_ENABLE_CMD_DONE_LEN \
79 sizeof(viddec_msg_pp_enable_cmd_done)
80
81typedef struct {
82 unsigned short packet_seq_number;
83 unsigned short codec_instance_id;
84} __attribute__((packed)) viddec_msg_pp_enable_cmd_done;
85
86
87/*
88 * Message to inform ARM that one post processing frame has been decoded
89 */
90
91
92#define VIDDEC_MSG_PP_FRAME_DONE 0x0003
93#define VIDDEC_MSG_PP_FRAME_DONE_LEN \
94 sizeof(viddec_msg_pp_frame_done)
95
96#define VIDDEC_MSG_DISP_WORTHY_DISP 0x0000
97#define VIDDEC_MSG_DISP_WORTHY_DISP_NONE 0xFFFF
98
99
100typedef struct {
101 unsigned short packet_seq_number;
102 unsigned short codec_instance_id;
103 unsigned short display_worthy;
104} __attribute__((packed)) viddec_msg_pp_frame_done;
105
106
107#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
new file mode 100644
index 000000000000..819544d186da
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5venccmdi.h
@@ -0,0 +1,212 @@
1#ifndef QDSP5VIDENCCMDI_H
2#define QDSP5VIDENCCMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V I D E O E N C O D E R I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by VIDENC Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 2008 by QUALCOMM, Incorporated.
19*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
20/*===========================================================================
21
22 EDIT HISTORY FOR FILE
23
24This section contains comments describing changes made to this file.
25Notice that changes are listed in reverse chronological order.
26
27Revision History:
28
29when who what, where, why
30-------- --- ----------------------------------------------------------
3109/25/08 umeshp initial version
32===========================================================================*/
33
34 #define VIDENC_CMD_CFG 0x0000
35 #define VIDENC_CMD_ACTIVE 0x0001
36 #define VIDENC_CMD_IDLE 0x0002
37 #define VIDENC_CMD_FRAME_START 0x0003
38 #define VIDENC_CMD_STATUS_QUERY 0x0004
39 #define VIDENC_CMD_RC_CFG 0x0005
40 #define VIDENC_CMD_DIS_CFG 0x0006
41 #define VIDENC_CMD_DIS 0x0007
42 #define VIDENC_CMD_INTRA_REFRESH 0x0008
43 #define VIDENC_CMD_DIGITAL_ZOOM 0x0009
44
45
46/*
47 * Command to pass the frame message information to VIDENC
48 */
49
50
51#define VIDENC_CMD_FRAME_START_LEN \
52 sizeof(videnc_cmd_frame_start)
53
54typedef struct {
55 unsigned short cmd_id;
56 unsigned short frame_info;
57 unsigned short frame_rho_budget_word_high;
58 unsigned short frame_rho_budget_word_low;
59 unsigned short input_luma_addr_high;
60 unsigned short input_luma_addr_low;
61 unsigned short input_chroma_addr_high;
62 unsigned short input_chroma_addr_low;
63 unsigned short ref_vop_buf_ptr_high;
64 unsigned short ref_vop_buf_ptr_low;
65 unsigned short enc_pkt_buf_ptr_high;
66 unsigned short enc_pkt_buf_ptr_low;
67 unsigned short enc_pkt_buf_size_high;
68 unsigned short enc_pkt_buf_size_low;
69 unsigned short unfilt_recon_vop_buf_ptr_high;
70 unsigned short unfilt_recon_vop_buf_ptr_low;
71 unsigned short filt_recon_vop_buf_ptr_high;
72 unsigned short filt_recon_vop_buf_ptr_low;
73} __attribute__((packed)) videnc_cmd_frame_start;
74
75/*
76 * Command to pass the frame-level digital stabilization parameters to VIDENC
77 */
78
79
80#define VIDENC_CMD_DIS_LEN \
81 sizeof(videnc_cmd_dis)
82
83typedef struct {
84 unsigned short cmd_id;
85 unsigned short vfe_out_prev_luma_addr_high;
86 unsigned short vfe_out_prev_luma_addr_low;
87 unsigned short stabilization_info;
88} __attribute__((packed)) videnc_cmd_dis;
89
90/*
91 * Command to pass the codec related parameters to VIDENC
92 */
93
94
95#define VIDENC_CMD_CFG_LEN \
96 sizeof(videnc_cmd_cfg)
97
98typedef struct {
99 unsigned short cmd_id;
100 unsigned short cfg_info_0;
101 unsigned short cfg_info_1;
102 unsigned short four_mv_threshold;
103 unsigned short ise_fse_mv_cost_fac;
104 unsigned short venc_frame_dim;
105 unsigned short venc_DM_partition;
106} __attribute__((packed)) videnc_cmd_cfg;
107
108/*
109 * Command to start the video encoding
110 */
111
112
113#define VIDENC_CMD_ACTIVE_LEN \
114 sizeof(videnc_cmd_active)
115
116typedef struct {
117 unsigned short cmd_id;
118} __attribute__((packed)) videnc_cmd_active;
119
120/*
121 * Command to stop the video encoding
122 */
123
124
125#define VIDENC_CMD_IDLE_LEN \
126 sizeof(videnc_cmd_idle)
127
128typedef struct {
129 unsigned short cmd_id;
130} __attribute__((packed)) videnc_cmd_idle;
131
132/*
133 * Command to query staus of VIDENC
134 */
135
136
137#define VIDENC_CMD_STATUS_QUERY_LEN \
138 sizeof(videnc_cmd_status_query)
139
140typedef struct {
141 unsigned short cmd_id;
142} __attribute__((packed)) videnc_cmd_status_query;
143
144/*
145 * Command to set rate control for a frame
146 */
147
148
149#define VIDENC_CMD_RC_CFG_LEN \
150 sizeof(videnc_cmd_rc_cfg)
151
152typedef struct {
153 unsigned short cmd_id;
154 unsigned short max_frame_qp_delta;
155 unsigned short max_min_frame_qp;
156} __attribute__((packed)) videnc_cmd_rc_cfg;
157
158/*
159 * Command to set intra-refreshing
160 */
161
162
163#define VIDENC_CMD_INTRA_REFRESH_LEN \
164 sizeof(videnc_cmd_intra_refresh)
165
166typedef struct {
167 unsigned short cmd_id;
168 unsigned short num_mb_refresh;
169 unsigned short mb_index[15];
170} __attribute__((packed)) videnc_cmd_intra_refresh;
171
172/*
173 * Command to pass digital zoom information to the VIDENC
174 */
175#define VIDENC_CMD_DIGITAL_ZOOM_LEN \
176 sizeof(videnc_cmd_digital_zoom)
177
178typedef struct {
179 unsigned short cmd_id;
180 unsigned short digital_zoom_en;
181 unsigned short luma_frame_shift_X;
182 unsigned short luma_frame_shift_Y;
183 unsigned short up_ip_luma_rows;
184 unsigned short up_ip_luma_cols;
185 unsigned short up_ip_chroma_rows;
186 unsigned short up_ip_chroma_cols;
187 unsigned short luma_ph_incr_V_low;
188 unsigned short luma_ph_incr_V_high;
189 unsigned short luma_ph_incr_H_low;
190 unsigned short luma_ph_incr_H_high;
191 unsigned short chroma_ph_incr_V_low;
192 unsigned short chroma_ph_incr_V_high;
193 unsigned short chroma_ph_incr_H_low;
194 unsigned short chroma_ph_incr_H_high;
195} __attribute__((packed)) videnc_cmd_digital_zoom;
196
197/*
198 * Command to configure digital stabilization parameters
199 */
200
201#define VIDENC_CMD_DIS_CFG_LEN \
202 sizeof(videnc_cmd_dis_cfg)
203
204typedef struct {
205 unsigned short cmd_id;
206 unsigned short image_stab_subf_start_row_col;
207 unsigned short image_stab_subf_dim;
208 unsigned short image_stab_info_0;
209} __attribute__((packed)) videnc_cmd_dis_cfg;
210
211
212#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
new file mode 100644
index 000000000000..55e8fc2269f7
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfecmdi.h
@@ -0,0 +1,910 @@
1#ifndef QDSP5VFECMDI_H
2#define QDSP5VFECMDI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V F E I N T E R N A L C O M M A N D S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are accepted by VFE Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfecmdi.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4206/12/08 sv initial version
43===========================================================================*/
44
45/******************************************************************************
46 * Commands through vfeCommandScaleQueue
47 *****************************************************************************/
48
49/*
50 * Command to program scaler for op1 . max op of scaler is VGA
51 */
52
53
54#define VFE_CMD_SCALE_OP1_CFG 0x0000
55#define VFE_CMD_SCALE_OP1_CFG_LEN \
56 sizeof(vfe_cmd_scale_op1_cfg)
57
58#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_STANDARD 0x0000
59#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_Y_CASCADED 0x0001
60#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_DIS 0x0000
61#define VFE_CMD_SCALE_OP1_SEL_H_Y_SCALER_ENA 0x0002
62#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_DIS 0x0000
63#define VFE_CMD_SCALE_OP1_SEL_H_PP_Y_SCALER_ENA 0x0004
64#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_DIS 0x0000
65#define VFE_CMD_SCALE_OP1_SEL_V_Y_SCALER_ENA 0x0008
66#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_DIS 0x0000
67#define VFE_CMD_SCALE_OP1_SEL_V_PP_Y_SCALER_ENA 0x0010
68#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_STANDARD 0x0000
69#define VFE_CMD_SCALE_OP1_SEL_IP_SEL_CBCR_CASCADED 0x0020
70#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_DIS 0x0000
71#define VFE_CMD_SCALE_OP1_SEL_H_CBCR_SCALER_ENA 0x0040
72#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_DIS 0x0000
73#define VFE_CMD_SCALE_OP1_SEL_V_CBCR_SCALER_ENA 0x0080
74
75#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
76#define VFE_CMD_OP1_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
77
78typedef struct {
79 unsigned int cmd_id;
80 unsigned int scale_op1_sel;
81 unsigned int y_scaler_cfg_part1;
82 unsigned int y_scaler_cfg_part2;
83 unsigned int cbcr_scaler_cfg_part1;
84 unsigned int cbcr_scaler_cfg_part2;
85 unsigned int cbcr_scaler_cfg_part3;
86 unsigned int pp_y_scaler_cfg_part1;
87 unsigned int pp_y_scaler_cfg_part2;
88 unsigned int y_scaler_v_coeff_bank_part1[16];
89 unsigned int y_scaler_v_coeff_bank_part2[16];
90 unsigned int y_scaler_h_coeff_bank_part1[16];
91 unsigned int y_scaler_h_coeff_bank_part2[16];
92} __attribute__((packed)) vfe_cmd_scale_op1_cfg;
93
94
95/*
96 * Command to program scaler for op2
97 */
98
99#define VFE_CMD_SCALE_OP2_CFG 0x0001
100#define VFE_CMD_SCALE_OP2_CFG_LEN \
101 sizeof(vfe_cmd_scale_op2_cfg)
102
103#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_STANDARD 0x0000
104#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_Y_CASCADED 0x0001
105#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_DIS 0x0000
106#define VFE_CMD_SCALE_OP2_SEL_H_Y_SCALER_ENA 0x0002
107#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_DIS 0x0000
108#define VFE_CMD_SCALE_OP2_SEL_H_PP_Y_SCALER_ENA 0x0004
109#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_DIS 0x0000
110#define VFE_CMD_SCALE_OP2_SEL_V_Y_SCALER_ENA 0x0008
111#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_DIS 0x0000
112#define VFE_CMD_SCALE_OP2_SEL_V_PP_Y_SCALER_ENA 0x0010
113#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_STANDARD 0x0000
114#define VFE_CMD_SCALE_OP2_SEL_IP_SEL_CBCR_CASCADED 0x0020
115#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_DIS 0x0000
116#define VFE_CMD_SCALE_OP2_SEL_H_CBCR_SCALER_ENA 0x0040
117#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_DIS 0x0000
118#define VFE_CMD_SCALE_OP2_SEL_V_CBCR_SCALER_ENA 0x0080
119
120#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_DONT_LOAD_COEFFS 0x80000000
121#define VFE_CMD_OP2_PP_Y_SCALER_CFG_PART1_LOAD_COEFFS 0x80000000
122
123typedef struct {
124 unsigned int cmd_id;
125 unsigned int scale_op2_sel;
126 unsigned int y_scaler_cfg_part1;
127 unsigned int y_scaler_cfg_part2;
128 unsigned int cbcr_scaler_cfg_part1;
129 unsigned int cbcr_scaler_cfg_part2;
130 unsigned int cbcr_scaler_cfg_part3;
131 unsigned int pp_y_scaler_cfg_part1;
132 unsigned int pp_y_scaler_cfg_part2;
133 unsigned int y_scaler_v_coeff_bank_part1[16];
134 unsigned int y_scaler_v_coeff_bank_part2[16];
135 unsigned int y_scaler_h_coeff_bank_part1[16];
136 unsigned int y_scaler_h_coeff_bank_part2[16];
137} __attribute__((packed)) vfe_cmd_scale_op2_cfg;
138
139
140/******************************************************************************
141 * Commands through vfeCommandTableQueue
142 *****************************************************************************/
143
144/*
145 * Command to program the AXI ip paths
146 */
147
148#define VFE_CMD_AXI_IP_CFG 0x0000
149#define VFE_CMD_AXI_IP_CFG_LEN sizeof(vfe_cmd_axi_ip_cfg)
150
151#define VFE_CMD_IP_SEL_IP_FORMAT_8 0x0000
152#define VFE_CMD_IP_SEL_IP_FORMAT_10 0x0001
153#define VFE_CMD_IP_SEL_IP_FORMAT_12 0x0002
154
155typedef struct {
156 unsigned int cmd_id;
157 unsigned int ip_sel;
158 unsigned int ip_cfg_part1;
159 unsigned int ip_cfg_part2;
160 unsigned int ip_unpack_cfg_part[6];
161 unsigned int ip_buf_addr[8];
162} __attribute__ ((packed)) vfe_cmd_axi_ip_cfg;
163
164
165/*
166 * Command to program axi op paths
167 */
168
169#define VFE_CMD_AXI_OP_CFG 0x0001
170#define VFE_CMD_AXI_OP_CFG_LEN sizeof(vfe_cmd_axi_op_cfg)
171
172#define VFE_CMD_OP_SEL_OP1 0x0000
173#define VFE_CMD_OP_SEL_OP2 0x0001
174#define VFE_CMD_OP_SEL_OP1_OP2 0x0002
175#define VFE_CMD_OP_SEL_CTOA 0x0003
176#define VFE_CMD_OP_SEL_CTOA_OP1 0x0004
177#define VFE_CMD_OP_SEL_CTOA_OP2 0x0005
178#define VFE_CMD_OP_SEL_OP_FORMAT_8 0x0000
179#define VFE_CMD_OP_SEL_OP_FORMAT_10 0x0008
180#define VFE_CMD_OP_SEL_OP_FORMAT_12 0x0010
181
182
183typedef struct {
184 unsigned int cmd_id;
185 unsigned int op_sel;
186 unsigned int op1_y_cfg_part1;
187 unsigned int op1_y_cfg_part2;
188 unsigned int op1_cbcr_cfg_part1;
189 unsigned int op1_cbcr_cfg_part2;
190 unsigned int op2_y_cfg_part1;
191 unsigned int op2_y_cfg_part2;
192 unsigned int op2_cbcr_cfg_part1;
193 unsigned int op2_cbcr_cfg_part2;
194 unsigned int op1_buf1_addr[16];
195 unsigned int op2_buf1_addr[16];
196} __attribute__((packed)) vfe_cmd_axi_op_cfg;
197
198
199
200
201/*
202 * Command to program the roll off correction module
203 */
204
205#define VFE_CMD_ROLLOFF_CFG 0x0002
206#define VFE_CMD_ROLLOFF_CFG_LEN \
207 sizeof(vfe_cmd_rolloff_cfg)
208
209
210typedef struct {
211 unsigned int cmd_id;
212 unsigned int correction_opt_center_pos;
213 unsigned int radius_square_entry[32];
214 unsigned int red_table_entry[32];
215 unsigned int green_table_entry[32];
216 unsigned int blue_table_entry[32];
217} __attribute__((packed)) vfe_cmd_rolloff_cfg;
218
219/*
220 * Command to program RGB gamma table
221 */
222
223#define VFE_CMD_RGB_GAMMA_CFG 0x0003
224#define VFE_CMD_RGB_GAMMA_CFG_LEN \
225 sizeof(vfe_cmd_rgb_gamma_cfg)
226
227#define VFE_CMD_RGB_GAMMA_SEL_LINEAR 0x0000
228#define VFE_CMD_RGB_GAMMA_SEL_PW_LINEAR 0x0001
229typedef struct {
230 unsigned int cmd_id;
231 unsigned int rgb_gamma_sel;
232 unsigned int rgb_gamma_entry[256];
233} __attribute__((packed)) vfe_cmd_rgb_gamma_cfg;
234
235
236/*
237 * Command to program luma gamma table for the noise reduction path
238 */
239
240#define VFE_CMD_Y_GAMMA_CFG 0x0004
241#define VFE_CMD_Y_GAMMA_CFG_LEN \
242 sizeof(vfe_cmd_y_gamma_cfg)
243
244#define VFE_CMD_Y_GAMMA_SEL_LINEAR 0x0000
245#define VFE_CMD_Y_GAMMA_SEL_PW_LINEAR 0x0001
246
247typedef struct {
248 unsigned int cmd_id;
249 unsigned int y_gamma_sel;
250 unsigned int y_gamma_entry[256];
251} __attribute__((packed)) vfe_cmd_y_gamma_cfg;
252
253
254
255/******************************************************************************
256 * Commands through vfeCommandQueue
257 *****************************************************************************/
258
259/*
260 * Command to reset the VFE to a known good state.All previously programmed
261 * Params will be lost
262 */
263
264
265#define VFE_CMD_RESET 0x0000
266#define VFE_CMD_RESET_LEN sizeof(vfe_cmd_reset)
267
268
269typedef struct {
270 unsigned short cmd_id;
271} __attribute__((packed)) vfe_cmd_reset;
272
273
274/*
275 * Command to start VFE processing based on the config params
276 */
277
278
279#define VFE_CMD_START 0x0001
280#define VFE_CMD_START_LEN sizeof(vfe_cmd_start)
281
282#define VFE_CMD_STARTUP_PARAMS_SRC_CAMIF 0x0000
283#define VFE_CMD_STARTUP_PARAMS_SRC_AXI 0x0001
284#define VFE_CMD_STARTUP_PARAMS_MODE_CONTINUOUS 0x0000
285#define VFE_CMD_STARTUP_PARAMS_MODE_SNAPSHOT 0x0002
286
287#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_DIS 0x0000
288#define VFE_CMD_IMAGE_PL_BLACK_LVL_CORR_ENA 0x0001
289#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_DIS 0x0000
290#define VFE_CMD_IMAGE_PL_ROLLOFF_CORR_ENA 0x0002
291#define VFE_CMD_IMAGE_PL_WHITE_BAL_DIS 0x0000
292#define VFE_CMD_IMAGE_PL_WHITE_BAL_ENA 0x0004
293#define VFE_CMD_IMAGE_PL_RGB_GAMMA_DIS 0x0000
294#define VFE_CMD_IMAGE_PL_RGB_GAMMA_ENA 0x0008
295#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_DIS 0x0000
296#define VFE_CMD_IMAGE_PL_LUMA_NOISE_RED_PATH_ENA 0x0010
297#define VFE_CMD_IMAGE_PL_ADP_FILTER_DIS 0x0000
298#define VFE_CMD_IMAGE_PL_ADP_FILTER_ENA 0x0020
299#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_DIS 0x0000
300#define VFE_CMD_IMAGE_PL_CHROMA_SAMP_ENA 0x0040
301
302
303typedef struct {
304 unsigned int cmd_id;
305 unsigned int startup_params;
306 unsigned int image_pipeline;
307 unsigned int frame_dimension;
308} __attribute__((packed)) vfe_cmd_start;
309
310
311/*
312 * Command to halt all processing
313 */
314
315#define VFE_CMD_STOP 0x0002
316#define VFE_CMD_STOP_LEN sizeof(vfe_cmd_stop)
317
318typedef struct {
319 unsigned short cmd_id;
320} __attribute__((packed)) vfe_cmd_stop;
321
322
323/*
324 * Command to commit the params that have been programmed to take
325 * effect on the next frame
326 */
327
328#define VFE_CMD_UPDATE 0x0003
329#define VFE_CMD_UPDATE_LEN sizeof(vfe_cmd_update)
330
331
332typedef struct {
333 unsigned short cmd_id;
334} __attribute__((packed)) vfe_cmd_update;
335
336
337/*
338 * Command to program CAMIF module
339 */
340
341#define VFE_CMD_CAMIF_CFG 0x0004
342#define VFE_CMD_CAMIF_CFG_LEN sizeof(vfe_cmd_camif_cfg)
343
344#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_HIGH 0x0000
345#define VFE_CMD_CFG_VSYNC_SYNC_EDGE_LOW 0x0002
346#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_HIGH 0x0000
347#define VFE_CMD_CFG_HSYNC_SYNC_EDGE_LOW 0x0004
348#define VFE_CMD_CFG_SYNC_MODE_APS 0x0000
349#define VFE_CMD_CFG_SYNC_MODE_EFS 0X0008
350#define VFE_CMD_CFG_SYNC_MODE_ELS 0x0010
351#define VFE_CMD_CFG_SYNC_MODE_RVD 0x0018
352#define VFE_CMD_CFG_VFE_SUBSAMP_EN_DIS 0x0000
353#define VFE_CMD_CFG_VFE_SUBSAMP_EN_ENA 0x0020
354#define VFE_CMD_CFG_BUS_SUBSAMP_EN_DIS 0x0000
355#define VFE_CMD_CFG_BUS_SUBSAMP_EN_ENA 0x0080
356#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_DIS 0x0000
357#define VFE_CMD_CFG_IRQ_SUBSAMP_EN_ENA 0x0800
358
359#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_16 0x0000
360#define VFE_CMD_SUBSAMP2_CFG_PIXEL_SKIP_12 0x0010
361
362#define VFE_CMD_EPOCH_IRQ_1_DIS 0x0000
363#define VFE_CMD_EPOCH_IRQ_1_ENA 0x4000
364#define VFE_CMD_EPOCH_IRQ_2_DIS 0x0000
365#define VFE_CMD_EPOCH_IRQ_2_ENA 0x8000
366
367typedef struct {
368 unsigned int cmd_id;
369 unsigned int cfg;
370 unsigned int efs_cfg;
371 unsigned int frame_cfg;
372 unsigned int window_width_cfg;
373 unsigned int window_height_cfg;
374 unsigned int subsamp1_cfg;
375 unsigned int subsamp2_cfg;
376 unsigned int epoch_irq;
377} __attribute__((packed)) vfe_cmd_camif_cfg;
378
379
380
381/*
382 * Command to program the black level module
383 */
384
385#define VFE_CMD_BLACK_LVL_CFG 0x0005
386#define VFE_CMD_BLACK_LVL_CFG_LEN sizeof(vfe_cmd_black_lvl_cfg)
387
388#define VFE_CMD_BL_SEL_MANUAL 0x0000
389#define VFE_CMD_BL_SEL_AUTO 0x0001
390
391typedef struct {
392 unsigned int cmd_id;
393 unsigned int black_lvl_sel;
394 unsigned int cfg_part[3];
395} __attribute__((packed)) vfe_cmd_black_lvl_cfg;
396
397
398/*
399 * Command to program the active region by cropping the region of interest
400 */
401
402#define VFE_CMD_ACTIVE_REGION_CFG 0x0006
403#define VFE_CMD_ACTIVE_REGION_CFG_LEN \
404 sizeof(vfe_cmd_active_region_cfg)
405
406
407typedef struct {
408 unsigned int cmd_id;
409 unsigned int cfg_part1;
410 unsigned int cfg_part2;
411} __attribute__((packed)) vfe_cmd_active_region_cfg;
412
413
414
415/*
416 * Command to program the defective pixel correction(DPC) ,
417 * adaptive bayer filter (ABF) and demosaic modules
418 */
419
420#define VFE_CMD_DEMOSAIC_CFG 0x0007
421#define VFE_CMD_DEMOSAIC_CFG_LEN sizeof(vfe_cmd_demosaic_cfg)
422
423#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_DIS 0x0000
424#define VFE_CMD_DEMOSAIC_PART1_ABF_EN_ENA 0x0001
425#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_DIS 0x0000
426#define VFE_CMD_DEMOSAIC_PART1_DPC_EN_ENA 0x0002
427#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_OFF 0x0000
428#define VFE_CMD_DEMOSAIC_PART1_FORCE_ABF_ON 0x0004
429#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1 0x00000000
430#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_2 0x10000000
431#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_4 0x20000000
432#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_8 0x30000000
433#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_2 0x50000000
434#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_4 0x60000000
435#define VFE_CMD_DEMOSAIC_PART1_SLOPE_SHIFT_1_8 0x70000000
436
437typedef struct {
438 unsigned int cmd_id;
439 unsigned int demosaic_part1;
440 unsigned int demosaic_part2;
441 unsigned int demosaic_part3;
442 unsigned int demosaic_part4;
443 unsigned int demosaic_part5;
444} __attribute__((packed)) vfe_cmd_demosaic_cfg;
445
446
447/*
448 * Command to program the ip format
449 */
450
451#define VFE_CMD_IP_FORMAT_CFG 0x0008
452#define VFE_CMD_IP_FORMAT_CFG_LEN \
453 sizeof(vfe_cmd_ip_format_cfg)
454
455#define VFE_CMD_IP_FORMAT_SEL_RGRG 0x0000
456#define VFE_CMD_IP_FORMAT_SEL_GRGR 0x0001
457#define VFE_CMD_IP_FORMAT_SEL_BGBG 0x0002
458#define VFE_CMD_IP_FORMAT_SEL_GBGB 0x0003
459#define VFE_CMD_IP_FORMAT_SEL_YCBYCR 0x0004
460#define VFE_CMD_IP_FORMAT_SEL_YCRYCB 0x0005
461#define VFE_CMD_IP_FORMAT_SEL_CBYCRY 0x0006
462#define VFE_CMD_IP_FORMAT_SEL_CRYCBY 0x0007
463#define VFE_CMD_IP_FORMAT_SEL_NO_CHROMA 0x0000
464#define VFE_CMD_IP_FORMAT_SEL_CHROMA 0x0008
465
466
467typedef struct {
468 unsigned int cmd_id;
469 unsigned int ip_format_sel;
470 unsigned int balance_gains_part1;
471 unsigned int balance_gains_part2;
472} __attribute__((packed)) vfe_cmd_ip_format_cfg;
473
474
475
476/*
477 * Command to program max and min allowed op values
478 */
479
480#define VFE_CMD_OP_CLAMP_CFG 0x0009
481#define VFE_CMD_OP_CLAMP_CFG_LEN \
482 sizeof(vfe_cmd_op_clamp_cfg)
483
484typedef struct {
485 unsigned int cmd_id;
486 unsigned int op_clamp_max;
487 unsigned int op_clamp_min;
488} __attribute__((packed)) vfe_cmd_op_clamp_cfg;
489
490
491/*
492 * Command to program chroma sub sample module
493 */
494
495#define VFE_CMD_CHROMA_SUBSAMPLE_CFG 0x000A
496#define VFE_CMD_CHROMA_SUBSAMPLE_CFG_LEN \
497 sizeof(vfe_cmd_chroma_subsample_cfg)
498
499#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_INTERESTIAL_SAMPS 0x0000
500#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_COSITED_SAMPS 0x0001
501#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_INTERESTIAL_SAMPS 0x0000
502#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_COSITED_SAMPS 0x0002
503#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_DIS 0x0000
504#define VFE_CMD_CHROMA_SUBSAMP_SEL_H_SUBSAMP_ENA 0x0004
505#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_DIS 0x0000
506#define VFE_CMD_CHROMA_SUBSAMP_SEL_V_SUBSAMP_ENA 0x0008
507
508typedef struct {
509 unsigned int cmd_id;
510 unsigned int chroma_subsamp_sel;
511} __attribute__((packed)) vfe_cmd_chroma_subsample_cfg;
512
513
514/*
515 * Command to program the white balance module
516 */
517
518#define VFE_CMD_WHITE_BALANCE_CFG 0x000B
519#define VFE_CMD_WHITE_BALANCE_CFG_LEN \
520 sizeof(vfe_cmd_white_balance_cfg)
521
522typedef struct {
523 unsigned int cmd_id;
524 unsigned int white_balance_gains;
525} __attribute__((packed)) vfe_cmd_white_balance_cfg;
526
527
528/*
529 * Command to program the color processing module
530 */
531
532#define VFE_CMD_COLOR_PROCESS_CFG 0x000C
533#define VFE_CMD_COLOR_PROCESS_CFG_LEN \
534 sizeof(vfe_cmd_color_process_cfg)
535
536#define VFE_CMD_COLOR_CORRE_PART7_Q7_FACTORS 0x0000
537#define VFE_CMD_COLOR_CORRE_PART7_Q8_FACTORS 0x0001
538#define VFE_CMD_COLOR_CORRE_PART7_Q9_FACTORS 0x0002
539#define VFE_CMD_COLOR_CORRE_PART7_Q10_FACTORS 0x0003
540
541typedef struct {
542 unsigned int cmd_id;
543 unsigned int color_correction_part1;
544 unsigned int color_correction_part2;
545 unsigned int color_correction_part3;
546 unsigned int color_correction_part4;
547 unsigned int color_correction_part5;
548 unsigned int color_correction_part6;
549 unsigned int color_correction_part7;
550 unsigned int chroma_enhance_part1;
551 unsigned int chroma_enhance_part2;
552 unsigned int chroma_enhance_part3;
553 unsigned int chroma_enhance_part4;
554 unsigned int chroma_enhance_part5;
555 unsigned int luma_calc_part1;
556 unsigned int luma_calc_part2;
557} __attribute__((packed)) vfe_cmd_color_process_cfg;
558
559
560/*
561 * Command to program adaptive filter module
562 */
563
564#define VFE_CMD_ADP_FILTER_CFG 0x000D
565#define VFE_CMD_ADP_FILTER_CFG_LEN \
566 sizeof(vfe_cmd_adp_filter_cfg)
567
568#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_DIS 0x0000
569#define VFE_CMD_ASF_CFG_PART_SMOOTH_FILTER_ENA 0x0001
570#define VFE_CMD_ASF_CFG_PART_NO_SHARP_MODE 0x0000
571#define VFE_CMD_ASF_CFG_PART_SINGLE_FILTER 0x0002
572#define VFE_CMD_ASF_CFG_PART_DUAL_FILTER 0x0004
573#define VFE_CMD_ASF_CFG_PART_SHARP_MODE 0x0007
574
575typedef struct {
576 unsigned int cmd_id;
577 unsigned int asf_cfg_part[7];
578} __attribute__((packed)) vfe_cmd_adp_filter_cfg;
579
580
581/*
582 * Command to program for frame skip pattern for op1 and op2
583 */
584
585#define VFE_CMD_FRAME_SKIP_CFG 0x000E
586#define VFE_CMD_FRAME_SKIP_CFG_LEN \
587 sizeof(vfe_cmd_frame_skip_cfg)
588
589typedef struct {
590 unsigned int cmd_id;
591 unsigned int frame_skip_pattern_op1;
592 unsigned int frame_skip_pattern_op2;
593} __attribute__((packed)) vfe_cmd_frame_skip_cfg;
594
595
596/*
597 * Command to program field-of-view crop for digital zoom
598 */
599
600#define VFE_CMD_FOV_CROP 0x000F
601#define VFE_CMD_FOV_CROP_LEN sizeof(vfe_cmd_fov_crop)
602
603typedef struct {
604 unsigned int cmd_id;
605 unsigned int fov_crop_part1;
606 unsigned int fov_crop_part2;
607} __attribute__((packed)) vfe_cmd_fov_crop;
608
609
610
611/*
612 * Command to program auto focus(AF) statistics module
613 */
614
615#define VFE_CMD_STATS_AUTOFOCUS_CFG 0x0010
616#define VFE_CMD_STATS_AUTOFOCUS_CFG_LEN \
617 sizeof(vfe_cmd_stats_autofocus_cfg)
618
619#define VFE_CMD_AF_STATS_SEL_STATS_DIS 0x0000
620#define VFE_CMD_AF_STATS_SEL_STATS_ENA 0x0001
621#define VFE_CMD_AF_STATS_SEL_PRI_FIXED 0x0000
622#define VFE_CMD_AF_STATS_SEL_PRI_VAR 0x0002
623#define VFE_CMD_AF_STATS_CFG_PART_METRIC_SUM 0x00000000
624#define VFE_CMD_AF_STATS_CFG_PART_METRIC_MAX 0x00200000
625
626typedef struct {
627 unsigned int cmd_id;
628 unsigned int af_stats_sel;
629 unsigned int af_stats_cfg_part[8];
630 unsigned int af_stats_op_buf_hdr;
631 unsigned int af_stats_op_buf[3];
632} __attribute__((packed)) vfe_cmd_stats_autofocus_cfg;
633
634
635/*
636 * Command to program White balance(wb) and exposure (exp)
637 * statistics module
638 */
639
640#define VFE_CMD_STATS_WB_EXP_CFG 0x0011
641#define VFE_CMD_STATS_WB_EXP_CFG_LEN \
642 sizeof(vfe_cmd_stats_wb_exp_cfg)
643
644#define VFE_CMD_WB_EXP_STATS_SEL_STATS_DIS 0x0000
645#define VFE_CMD_WB_EXP_STATS_SEL_STATS_ENA 0x0001
646#define VFE_CMD_WB_EXP_STATS_SEL_PRI_FIXED 0x0000
647#define VFE_CMD_WB_EXP_STATS_SEL_PRI_VAR 0x0002
648
649#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_8_8 0x0000
650#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_REG_16_16 0x0001
651#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_8_8 0x0000
652#define VFE_CMD_WB_EXP_STATS_CFG_PART1_EXP_SREG_4_4 0x0002
653
654typedef struct {
655 unsigned int cmd_id;
656 unsigned int wb_exp_stats_sel;
657 unsigned int wb_exp_stats_cfg_part1;
658 unsigned int wb_exp_stats_cfg_part2;
659 unsigned int wb_exp_stats_cfg_part3;
660 unsigned int wb_exp_stats_cfg_part4;
661 unsigned int wb_exp_stats_op_buf_hdr;
662 unsigned int wb_exp_stats_op_buf[3];
663} __attribute__((packed)) vfe_cmd_stats_wb_exp_cfg;
664
665
666/*
667 * Command to program histogram(hg) stats module
668 */
669
670#define VFE_CMD_STATS_HG_CFG 0x0012
671#define VFE_CMD_STATS_HG_CFG_LEN \
672 sizeof(vfe_cmd_stats_hg_cfg)
673
674#define VFE_CMD_HG_STATS_SEL_PRI_FIXED 0x0000
675#define VFE_CMD_HG_STATS_SEL_PRI_VAR 0x0002
676
677typedef struct {
678 unsigned int cmd_id;
679 unsigned int hg_stats_sel;
680 unsigned int hg_stats_cfg_part1;
681 unsigned int hg_stats_cfg_part2;
682 unsigned int hg_stats_op_buf_hdr;
683 unsigned int hg_stats_op_buf;
684} __attribute__((packed)) vfe_cmd_stats_hg_cfg;
685
686
687/*
688 * Command to acknowledge last MSG_VFE_OP1 message
689 */
690
691#define VFE_CMD_OP1_ACK 0x0013
692#define VFE_CMD_OP1_ACK_LEN sizeof(vfe_cmd_op1_ack)
693
694typedef struct {
695 unsigned int cmd_id;
696 unsigned int op1_buf_y_addr;
697 unsigned int op1_buf_cbcr_addr;
698} __attribute__((packed)) vfe_cmd_op1_ack;
699
700
701
702/*
703 * Command to acknowledge last MSG_VFE_OP2 message
704 */
705
706#define VFE_CMD_OP2_ACK 0x0014
707#define VFE_CMD_OP2_ACK_LEN sizeof(vfe_cmd_op2_ack)
708
709typedef struct {
710 unsigned int cmd_id;
711 unsigned int op2_buf_y_addr;
712 unsigned int op2_buf_cbcr_addr;
713} __attribute__((packed)) vfe_cmd_op2_ack;
714
715
716
717/*
718 * Command to acknowledge MSG_VFE_STATS_AUTOFOCUS msg
719 */
720
721#define VFE_CMD_STATS_AF_ACK 0x0015
722#define VFE_CMD_STATS_AF_ACK_LEN sizeof(vfe_cmd_stats_af_ack)
723
724
725typedef struct {
726 unsigned int cmd_id;
727 unsigned int af_stats_op_buf;
728} __attribute__((packed)) vfe_cmd_stats_af_ack;
729
730
731/*
732 * Command to acknowledge MSG_VFE_STATS_WB_EXP msg
733 */
734
735#define VFE_CMD_STATS_WB_EXP_ACK 0x0016
736#define VFE_CMD_STATS_WB_EXP_ACK_LEN sizeof(vfe_cmd_stats_wb_exp_ack)
737
738typedef struct {
739 unsigned int cmd_id;
740 unsigned int wb_exp_stats_op_buf;
741} __attribute__((packed)) vfe_cmd_stats_wb_exp_ack;
742
743
744/*
745 * Command to acknowledge MSG_VFE_EPOCH1 message
746 */
747
748#define VFE_CMD_EPOCH1_ACK 0x0017
749#define VFE_CMD_EPOCH1_ACK_LEN sizeof(vfe_cmd_epoch1_ack)
750
751typedef struct {
752 unsigned short cmd_id;
753} __attribute__((packed)) vfe_cmd_epoch1_ack;
754
755
756/*
757 * Command to acknowledge MSG_VFE_EPOCH2 message
758 */
759
760#define VFE_CMD_EPOCH2_ACK 0x0018
761#define VFE_CMD_EPOCH2_ACK_LEN sizeof(vfe_cmd_epoch2_ack)
762
763typedef struct {
764 unsigned short cmd_id;
765} __attribute__((packed)) vfe_cmd_epoch2_ack;
766
767
768
769/*
770 * Command to configure, enable or disable synchronous timer1
771 */
772
773#define VFE_CMD_SYNC_TIMER1_CFG 0x0019
774#define VFE_CMD_SYNC_TIMER1_CFG_LEN \
775 sizeof(vfe_cmd_sync_timer1_cfg)
776
777#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_DIS 0x0000
778#define VFE_CMD_SYNC_T1_CFG_PART1_TIMER_ENA 0x0001
779#define VFE_CMD_SYNC_T1_CFG_PART1_POL_HIGH 0x0000
780#define VFE_CMD_SYNC_T1_CFG_PART1_POL_LOW 0x0002
781
782typedef struct {
783 unsigned int cmd_id;
784 unsigned int sync_t1_cfg_part1;
785 unsigned int sync_t1_h_sync_countdown;
786 unsigned int sync_t1_pclk_countdown;
787 unsigned int sync_t1_duration;
788} __attribute__((packed)) vfe_cmd_sync_timer1_cfg;
789
790
791/*
792 * Command to configure, enable or disable synchronous timer1
793 */
794
795#define VFE_CMD_SYNC_TIMER2_CFG 0x001A
796#define VFE_CMD_SYNC_TIMER2_CFG_LEN \
797 sizeof(vfe_cmd_sync_timer2_cfg)
798
799#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_DIS 0x0000
800#define VFE_CMD_SYNC_T2_CFG_PART1_TIMER_ENA 0x0001
801#define VFE_CMD_SYNC_T2_CFG_PART1_POL_HIGH 0x0000
802#define VFE_CMD_SYNC_T2_CFG_PART1_POL_LOW 0x0002
803
804typedef struct {
805 unsigned int cmd_id;
806 unsigned int sync_t2_cfg_part1;
807 unsigned int sync_t2_h_sync_countdown;
808 unsigned int sync_t2_pclk_countdown;
809 unsigned int sync_t2_duration;
810} __attribute__((packed)) vfe_cmd_sync_timer2_cfg;
811
812
813/*
814 * Command to configure and start asynchronous timer1
815 */
816
817#define VFE_CMD_ASYNC_TIMER1_START 0x001B
818#define VFE_CMD_ASYNC_TIMER1_START_LEN \
819 sizeof(vfe_cmd_async_timer1_start)
820
821#define VFE_CMD_ASYNC_T1_POLARITY_A_HIGH 0x0000
822#define VFE_CMD_ASYNC_T1_POLARITY_A_LOW 0x0001
823#define VFE_CMD_ASYNC_T1_POLARITY_B_HIGH 0x0000
824#define VFE_CMD_ASYNC_T1_POLARITY_B_LOW 0x0002
825
826typedef struct {
827 unsigned int cmd_id;
828 unsigned int async_t1a_cfg;
829 unsigned int async_t1b_cfg;
830 unsigned int async_t1_polarity;
831} __attribute__((packed)) vfe_cmd_async_timer1_start;
832
833
834/*
835 * Command to configure and start asynchronous timer2
836 */
837
838#define VFE_CMD_ASYNC_TIMER2_START 0x001C
839#define VFE_CMD_ASYNC_TIMER2_START_LEN \
840 sizeof(vfe_cmd_async_timer2_start)
841
842#define VFE_CMD_ASYNC_T2_POLARITY_A_HIGH 0x0000
843#define VFE_CMD_ASYNC_T2_POLARITY_A_LOW 0x0001
844#define VFE_CMD_ASYNC_T2_POLARITY_B_HIGH 0x0000
845#define VFE_CMD_ASYNC_T2_POLARITY_B_LOW 0x0002
846
847typedef struct {
848 unsigned int cmd_id;
849 unsigned int async_t2a_cfg;
850 unsigned int async_t2b_cfg;
851 unsigned int async_t2_polarity;
852} __attribute__((packed)) vfe_cmd_async_timer2_start;
853
854
855/*
856 * Command to program partial configurations of auto focus(af)
857 */
858
859#define VFE_CMD_STATS_AF_UPDATE 0x001D
860#define VFE_CMD_STATS_AF_UPDATE_LEN \
861 sizeof(vfe_cmd_stats_af_update)
862
863#define VFE_CMD_AF_UPDATE_PART1_WINDOW_ONE 0x00000000
864#define VFE_CMD_AF_UPDATE_PART1_WINDOW_MULTI 0x80000000
865
866typedef struct {
867 unsigned int cmd_id;
868 unsigned int af_update_part1;
869 unsigned int af_update_part2;
870} __attribute__((packed)) vfe_cmd_stats_af_update;
871
872
873/*
874 * Command to program partial cfg of wb and exp
875 */
876
877#define VFE_CMD_STATS_WB_EXP_UPDATE 0x001E
878#define VFE_CMD_STATS_WB_EXP_UPDATE_LEN \
879 sizeof(vfe_cmd_stats_wb_exp_update)
880
881#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_8_8 0x0000
882#define VFE_CMD_WB_EXP_UPDATE_PART1_REGIONS_16_16 0x0001
883#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_8_8 0x0000
884#define VFE_CMD_WB_EXP_UPDATE_PART1_SREGIONS_4_4 0x0002
885
886typedef struct {
887 unsigned int cmd_id;
888 unsigned int wb_exp_update_part1;
889 unsigned int wb_exp_update_part2;
890 unsigned int wb_exp_update_part3;
891 unsigned int wb_exp_update_part4;
892} __attribute__((packed)) vfe_cmd_stats_wb_exp_update;
893
894
895
896/*
897 * Command to re program the CAMIF FRAME CONFIG settings
898 */
899
900#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG 0x001F
901#define VFE_CMD_UPDATE_CAMIF_FRAME_CFG_LEN \
902 sizeof(vfe_cmd_update_camif_frame_cfg)
903
904typedef struct {
905 unsigned int cmd_id;
906 unsigned int camif_frame_cfg;
907} __attribute__((packed)) vfe_cmd_update_camif_frame_cfg;
908
909
910#endif
diff --git a/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
new file mode 100644
index 000000000000..0053cfb65ba1
--- /dev/null
+++ b/drivers/staging/dream/include/mach/qdsp5/qdsp5vfemsg.h
@@ -0,0 +1,290 @@
1#ifndef QDSP5VFEMSGI_H
2#define QDSP5VFEMSGI_H
3
4/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
5
6 V F E I N T E R N A L M E S S A G E S
7
8GENERAL DESCRIPTION
9 This file contains defintions of format blocks of commands
10 that are sent by VFE Task
11
12REFERENCES
13 None
14
15EXTERNALIZED FUNCTIONS
16 None
17
18Copyright(c) 1992 - 2008 by QUALCOMM, Incorporated.
19
20This software is licensed under the terms of the GNU General Public
21License version 2, as published by the Free Software Foundation, and
22may be copied, distributed, and modified under those terms.
23
24This program is distributed in the hope that it will be useful,
25but WITHOUT ANY WARRANTY; without even the implied warranty of
26MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27GNU General Public License for more details.
28
29*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/
30/*===========================================================================
31
32 EDIT HISTORY FOR FILE
33
34This section contains comments describing changes made to this file.
35Notice that changes are listed in reverse chronological order.
36
37$Header: //source/qcom/qct/multimedia2/AdspSvc/7XXX/qdsp5cmd/video/qdsp5vfemsg.h#2 $ $DateTime: 2008/07/30 10:50:23 $ $Author: pavanr $
38Revision History:
39
40when who what, where, why
41-------- --- ----------------------------------------------------------
4206/12/08 sv initial version
43===========================================================================*/
44
45
46/*
47 * Message to acknowledge CMD_VFE_REST command
48 */
49
50#define VFE_MSG_RESET_ACK 0x0000
51#define VFE_MSG_RESET_ACK_LEN sizeof(vfe_msg_reset_ack)
52
53typedef struct {
54} __attribute__((packed)) vfe_msg_reset_ack;
55
56
57/*
58 * Message to acknowledge CMD_VFE_START command
59 */
60
61#define VFE_MSG_START_ACK 0x0001
62#define VFE_MSG_START_ACK_LEN sizeof(vfe_msg_start_ack)
63
64typedef struct {
65} __attribute__((packed)) vfe_msg_start_ack;
66
67/*
68 * Message to acknowledge CMD_VFE_STOP command
69 */
70
71#define VFE_MSG_STOP_ACK 0x0002
72#define VFE_MSG_STOP_ACK_LEN sizeof(vfe_msg_stop_ack)
73
74typedef struct {
75} __attribute__((packed)) vfe_msg_stop_ack;
76
77
78/*
79 * Message to acknowledge CMD_VFE_UPDATE command
80 */
81
82#define VFE_MSG_UPDATE_ACK 0x0003
83#define VFE_MSG_UPDATE_ACK_LEN sizeof(vfe_msg_update_ack)
84
85typedef struct {
86} __attribute__((packed)) vfe_msg_update_ack;
87
88
89/*
90 * Message to notify the ARM that snapshot processing is complete
91 * and that the VFE is now STATE_VFE_IDLE
92 */
93
94#define VFE_MSG_SNAPSHOT_DONE 0x0004
95#define VFE_MSG_SNAPSHOT_DONE_LEN \
96 sizeof(vfe_msg_snapshot_done)
97
98typedef struct {
99} __attribute__((packed)) vfe_msg_snapshot_done;
100
101
102
103/*
104 * Message to notify ARM that illegal cmd was received and
105 * system is in the IDLE state
106 */
107
108#define VFE_MSG_ILLEGAL_CMD 0x0005
109#define VFE_MSG_ILLEGAL_CMD_LEN \
110 sizeof(vfe_msg_illegal_cmd)
111
112typedef struct {
113 unsigned int status;
114} __attribute__((packed)) vfe_msg_illegal_cmd;
115
116
117/*
118 * Message to notify ARM that op1 buf is full and ready
119 */
120
121#define VFE_MSG_OP1 0x0006
122#define VFE_MSG_OP1_LEN sizeof(vfe_msg_op1)
123
124typedef struct {
125 unsigned int op1_buf_y_addr;
126 unsigned int op1_buf_cbcr_addr;
127 unsigned int black_level_even_col;
128 unsigned int black_level_odd_col;
129 unsigned int defect_pixels_detected;
130 unsigned int asf_max_edge;
131} __attribute__((packed)) vfe_msg_op1;
132
133
134/*
135 * Message to notify ARM that op2 buf is full and ready
136 */
137
138#define VFE_MSG_OP2 0x0007
139#define VFE_MSG_OP2_LEN sizeof(vfe_msg_op2)
140
141typedef struct {
142 unsigned int op2_buf_y_addr;
143 unsigned int op2_buf_cbcr_addr;
144 unsigned int black_level_even_col;
145 unsigned int black_level_odd_col;
146 unsigned int defect_pixels_detected;
147 unsigned int asf_max_edge;
148} __attribute__((packed)) vfe_msg_op2;
149
150
151/*
152 * Message to notify ARM that autofocus(af) stats are ready
153 */
154
155#define VFE_MSG_STATS_AF 0x0008
156#define VFE_MSG_STATS_AF_LEN sizeof(vfe_msg_stats_af)
157
158typedef struct {
159 unsigned int af_stats_op_buffer;
160} __attribute__((packed)) vfe_msg_stats_af;
161
162
163/*
164 * Message to notify ARM that white balance(wb) and exposure (exp)
165 * stats are ready
166 */
167
168#define VFE_MSG_STATS_WB_EXP 0x0009
169#define VFE_MSG_STATS_WB_EXP_LEN \
170 sizeof(vfe_msg_stats_wb_exp)
171
172typedef struct {
173 unsigned int wb_exp_stats_op_buf;
174} __attribute__((packed)) vfe_msg_stats_wb_exp;
175
176
177/*
178 * Message to notify the ARM that histogram(hg) stats are ready
179 */
180
181#define VFE_MSG_STATS_HG 0x000A
182#define VFE_MSG_STATS_HG_LEN sizeof(vfe_msg_stats_hg)
183
184typedef struct {
185 unsigned int hg_stats_op_buf;
186} __attribute__((packed)) vfe_msg_stats_hg;
187
188
189/*
190 * Message to notify the ARM that epoch1 event occurred in the CAMIF
191 */
192
193#define VFE_MSG_EPOCH1 0x000B
194#define VFE_MSG_EPOCH1_LEN sizeof(vfe_msg_epoch1)
195
196typedef struct {
197} __attribute__((packed)) vfe_msg_epoch1;
198
199
200/*
201 * Message to notify the ARM that epoch2 event occurred in the CAMIF
202 */
203
204#define VFE_MSG_EPOCH2 0x000C
205#define VFE_MSG_EPOCH2_LEN sizeof(vfe_msg_epoch2)
206
207typedef struct {
208} __attribute__((packed)) vfe_msg_epoch2;
209
210
211/*
212 * Message to notify the ARM that sync timer1 op is completed
213 */
214
215#define VFE_MSG_SYNC_T1_DONE 0x000D
216#define VFE_MSG_SYNC_T1_DONE_LEN sizeof(vfe_msg_sync_t1_done)
217
218typedef struct {
219} __attribute__((packed)) vfe_msg_sync_t1_done;
220
221
222/*
223 * Message to notify the ARM that sync timer2 op is completed
224 */
225
226#define VFE_MSG_SYNC_T2_DONE 0x000E
227#define VFE_MSG_SYNC_T2_DONE_LEN sizeof(vfe_msg_sync_t2_done)
228
229typedef struct {
230} __attribute__((packed)) vfe_msg_sync_t2_done;
231
232
233/*
234 * Message to notify the ARM that async t1 operation completed
235 */
236
237#define VFE_MSG_ASYNC_T1_DONE 0x000F
238#define VFE_MSG_ASYNC_T1_DONE_LEN sizeof(vfe_msg_async_t1_done)
239
240typedef struct {
241} __attribute__((packed)) vfe_msg_async_t1_done;
242
243
244
245/*
246 * Message to notify the ARM that async t2 operation completed
247 */
248
249#define VFE_MSG_ASYNC_T2_DONE 0x0010
250#define VFE_MSG_ASYNC_T2_DONE_LEN sizeof(vfe_msg_async_t2_done)
251
252typedef struct {
253} __attribute__((packed)) vfe_msg_async_t2_done;
254
255
256
257/*
258 * Message to notify the ARM that an error has occurred
259 */
260
261#define VFE_MSG_ERROR 0x0011
262#define VFE_MSG_ERROR_LEN sizeof(vfe_msg_error)
263
264#define VFE_MSG_ERR_COND_NO_CAMIF_ERR 0x0000
265#define VFE_MSG_ERR_COND_CAMIF_ERR 0x0001
266#define VFE_MSG_ERR_COND_OP1_Y_NO_BUS_OF 0x0000
267#define VFE_MSG_ERR_COND_OP1_Y_BUS_OF 0x0002
268#define VFE_MSG_ERR_COND_OP1_CBCR_NO_BUS_OF 0x0000
269#define VFE_MSG_ERR_COND_OP1_CBCR_BUS_OF 0x0004
270#define VFE_MSG_ERR_COND_OP2_Y_NO_BUS_OF 0x0000
271#define VFE_MSG_ERR_COND_OP2_Y_BUS_OF 0x0008
272#define VFE_MSG_ERR_COND_OP2_CBCR_NO_BUS_OF 0x0000
273#define VFE_MSG_ERR_COND_OP2_CBCR_BUS_OF 0x0010
274#define VFE_MSG_ERR_COND_AF_NO_BUS_OF 0x0000
275#define VFE_MSG_ERR_COND_AF_BUS_OF 0x0020
276#define VFE_MSG_ERR_COND_WB_EXP_NO_BUS_OF 0x0000
277#define VFE_MSG_ERR_COND_WB_EXP_BUS_OF 0x0040
278#define VFE_MSG_ERR_COND_NO_AXI_ERR 0x0000
279#define VFE_MSG_ERR_COND_AXI_ERR 0x0080
280
281#define VFE_MSG_CAMIF_STS_IDLE 0x0000
282#define VFE_MSG_CAMIF_STS_CAPTURE_DATA 0x0001
283
284typedef struct {
285 unsigned int err_cond;
286 unsigned int camif_sts;
287} __attribute__((packed)) vfe_msg_error;
288
289
290#endif
diff --git a/drivers/staging/dream/include/media/msm_camera.h b/drivers/staging/dream/include/media/msm_camera.h
new file mode 100644
index 000000000000..09812d62cc1e
--- /dev/null
+++ b/drivers/staging/dream/include/media/msm_camera.h
@@ -0,0 +1,388 @@
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4#ifndef __LINUX_MSM_CAMERA_H
5#define __LINUX_MSM_CAMERA_H
6
7#include <linux/types.h>
8#include <asm/sizes.h>
9#include <linux/ioctl.h>
10
11#define MSM_CAM_IOCTL_MAGIC 'm'
12
13#define MSM_CAM_IOCTL_GET_SENSOR_INFO \
14 _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *)
15
16#define MSM_CAM_IOCTL_REGISTER_PMEM \
17 _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *)
18
19#define MSM_CAM_IOCTL_UNREGISTER_PMEM \
20 _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned)
21
22#define MSM_CAM_IOCTL_CTRL_COMMAND \
23 _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *)
24
25#define MSM_CAM_IOCTL_CONFIG_VFE \
26 _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *)
27
28#define MSM_CAM_IOCTL_GET_STATS \
29 _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *)
30
31#define MSM_CAM_IOCTL_GETFRAME \
32 _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *)
33
34#define MSM_CAM_IOCTL_ENABLE_VFE \
35 _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *)
36
37#define MSM_CAM_IOCTL_CTRL_CMD_DONE \
38 _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *)
39
40#define MSM_CAM_IOCTL_CONFIG_CMD \
41 _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *)
42
43#define MSM_CAM_IOCTL_DISABLE_VFE \
44 _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *)
45
46#define MSM_CAM_IOCTL_PAD_REG_RESET2 \
47 _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *)
48
49#define MSM_CAM_IOCTL_VFE_APPS_RESET \
50 _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *)
51
52#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \
53 _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *)
54
55#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \
56 _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *)
57
58#define MSM_CAM_IOCTL_AXI_CONFIG \
59 _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *)
60
61#define MSM_CAM_IOCTL_GET_PICTURE \
62 _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_camera_ctrl_cmd *)
63
64#define MSM_CAM_IOCTL_SET_CROP \
65 _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *)
66
67#define MSM_CAM_IOCTL_PICT_PP \
68 _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *)
69
70#define MSM_CAM_IOCTL_PICT_PP_DONE \
71 _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *)
72
73#define MSM_CAM_IOCTL_SENSOR_IO_CFG \
74 _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *)
75
76#define MSM_CAMERA_LED_OFF 0
77#define MSM_CAMERA_LED_LOW 1
78#define MSM_CAMERA_LED_HIGH 2
79
80#define MSM_CAM_IOCTL_FLASH_LED_CFG \
81 _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *)
82
83#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \
84 _IO(MSM_CAM_IOCTL_MAGIC, 23)
85
86#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \
87 _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *)
88
89#define MAX_SENSOR_NUM 3
90#define MAX_SENSOR_NAME 32
91
92#define MSM_CAM_CTRL_CMD_DONE 0
93#define MSM_CAM_SENSOR_VFE_CMD 1
94
95/*****************************************************
96 * structure
97 *****************************************************/
98
99/* define five type of structures for userspace <==> kernel
100 * space communication:
101 * command 1 - 2 are from userspace ==> kernel
102 * command 3 - 4 are from kernel ==> userspace
103 *
104 * 1. control command: control command(from control thread),
105 * control status (from config thread);
106 */
107struct msm_ctrl_cmd {
108 uint16_t type;
109 uint16_t length;
110 void *value;
111 uint16_t status;
112 uint32_t timeout_ms;
113 int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */
114};
115
116struct msm_vfe_evt_msg {
117 unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */
118 unsigned short msg_id;
119 unsigned int len; /* size in, number of bytes out */
120 void *data;
121};
122
123#define MSM_CAM_RESP_CTRL 0
124#define MSM_CAM_RESP_STAT_EVT_MSG 1
125#define MSM_CAM_RESP_V4L2 2
126#define MSM_CAM_RESP_MAX 3
127
128/* this one is used to send ctrl/status up to config thread */
129struct msm_stats_event_ctrl {
130 /* 0 - ctrl_cmd from control thread,
131 * 1 - stats/event kernel,
132 * 2 - V4L control or read request */
133 int resptype;
134 int timeout_ms;
135 struct msm_ctrl_cmd ctrl_cmd;
136 /* struct vfe_event_t stats_event; */
137 struct msm_vfe_evt_msg stats_event;
138};
139
140/* 2. config command: config command(from config thread); */
141struct msm_camera_cfg_cmd {
142 /* what to config:
143 * 1 - sensor config, 2 - vfe config */
144 uint16_t cfg_type;
145
146 /* sensor config type */
147 uint16_t cmd_type;
148 uint16_t queue;
149 uint16_t length;
150 void *value;
151};
152
153#define CMD_GENERAL 0
154#define CMD_AXI_CFG_OUT1 1
155#define CMD_AXI_CFG_SNAP_O1_AND_O2 2
156#define CMD_AXI_CFG_OUT2 3
157#define CMD_PICT_T_AXI_CFG 4
158#define CMD_PICT_M_AXI_CFG 5
159#define CMD_RAW_PICT_AXI_CFG 6
160#define CMD_STATS_AXI_CFG 7
161#define CMD_STATS_AF_AXI_CFG 8
162#define CMD_FRAME_BUF_RELEASE 9
163#define CMD_PREV_BUF_CFG 10
164#define CMD_SNAP_BUF_RELEASE 11
165#define CMD_SNAP_BUF_CFG 12
166#define CMD_STATS_DISABLE 13
167#define CMD_STATS_ENABLE 14
168#define CMD_STATS_AF_ENABLE 15
169#define CMD_STATS_BUF_RELEASE 16
170#define CMD_STATS_AF_BUF_RELEASE 17
171#define UPDATE_STATS_INVALID 18
172
173/* vfe config command: config command(from config thread)*/
174struct msm_vfe_cfg_cmd {
175 int cmd_type;
176 uint16_t length;
177 void *value;
178};
179
180#define MAX_CAMERA_ENABLE_NAME_LEN 32
181struct camera_enable_cmd {
182 char name[MAX_CAMERA_ENABLE_NAME_LEN];
183};
184
185#define MSM_PMEM_OUTPUT1 0
186#define MSM_PMEM_OUTPUT2 1
187#define MSM_PMEM_OUTPUT1_OUTPUT2 2
188#define MSM_PMEM_THUMBAIL 3
189#define MSM_PMEM_MAINIMG 4
190#define MSM_PMEM_RAW_MAINIMG 5
191#define MSM_PMEM_AEC_AWB 6
192#define MSM_PMEM_AF 7
193#define MSM_PMEM_MAX 8
194
195#define FRAME_PREVIEW_OUTPUT1 0
196#define FRAME_PREVIEW_OUTPUT2 1
197#define FRAME_SNAPSHOT 2
198#define FRAME_THUMBAIL 3
199#define FRAME_RAW_SNAPSHOT 4
200#define FRAME_MAX 5
201
202struct msm_pmem_info {
203 int type;
204 int fd;
205 void *vaddr;
206 uint32_t y_off;
207 uint32_t cbcr_off;
208 uint8_t active;
209};
210
211struct outputCfg {
212 uint32_t height;
213 uint32_t width;
214
215 uint32_t window_height_firstline;
216 uint32_t window_height_lastline;
217};
218
219#define OUTPUT_1 0
220#define OUTPUT_2 1
221#define OUTPUT_1_AND_2 2
222#define CAMIF_TO_AXI_VIA_OUTPUT_2 3
223#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 4
224#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 5
225#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
226
227#define MSM_FRAME_PREV_1 0
228#define MSM_FRAME_PREV_2 1
229#define MSM_FRAME_ENC 2
230
231struct msm_frame {
232 int path;
233 unsigned long buffer;
234 uint32_t y_off;
235 uint32_t cbcr_off;
236 int fd;
237
238 void *cropinfo;
239 int croplen;
240};
241
242#define STAT_AEAW 0
243#define STAT_AF 1
244#define STAT_MAX 2
245
246struct msm_stats_buf {
247 int type;
248 unsigned long buffer;
249 int fd;
250};
251
252#define MSM_V4L2_VID_CAP_TYPE 0
253#define MSM_V4L2_STREAM_ON 1
254#define MSM_V4L2_STREAM_OFF 2
255#define MSM_V4L2_SNAPSHOT 3
256#define MSM_V4L2_QUERY_CTRL 4
257#define MSM_V4L2_GET_CTRL 5
258#define MSM_V4L2_SET_CTRL 6
259#define MSM_V4L2_QUERY 7
260#define MSM_V4L2_MAX 8
261
262struct crop_info {
263 void *info;
264 int len;
265};
266
267struct msm_postproc {
268 int ftnum;
269 struct msm_frame fthumnail;
270 int fmnum;
271 struct msm_frame fmain;
272};
273
274struct msm_snapshot_pp_status {
275 void *status;
276};
277
278#define CFG_SET_MODE 0
279#define CFG_SET_EFFECT 1
280#define CFG_START 2
281#define CFG_PWR_UP 3
282#define CFG_PWR_DOWN 4
283#define CFG_WRITE_EXPOSURE_GAIN 5
284#define CFG_SET_DEFAULT_FOCUS 6
285#define CFG_MOVE_FOCUS 7
286#define CFG_REGISTER_TO_REAL_GAIN 8
287#define CFG_REAL_TO_REGISTER_GAIN 9
288#define CFG_SET_FPS 10
289#define CFG_SET_PICT_FPS 11
290#define CFG_SET_BRIGHTNESS 12
291#define CFG_SET_CONTRAST 13
292#define CFG_SET_ZOOM 14
293#define CFG_SET_EXPOSURE_MODE 15
294#define CFG_SET_WB 16
295#define CFG_SET_ANTIBANDING 17
296#define CFG_SET_EXP_GAIN 18
297#define CFG_SET_PICT_EXP_GAIN 19
298#define CFG_SET_LENS_SHADING 20
299#define CFG_GET_PICT_FPS 21
300#define CFG_GET_PREV_L_PF 22
301#define CFG_GET_PREV_P_PL 23
302#define CFG_GET_PICT_L_PF 24
303#define CFG_GET_PICT_P_PL 25
304#define CFG_GET_AF_MAX_STEPS 26
305#define CFG_GET_PICT_MAX_EXP_LC 27
306#define CFG_MAX 28
307
308#define MOVE_NEAR 0
309#define MOVE_FAR 1
310
311#define SENSOR_PREVIEW_MODE 0
312#define SENSOR_SNAPSHOT_MODE 1
313#define SENSOR_RAW_SNAPSHOT_MODE 2
314
315#define SENSOR_QTR_SIZE 0
316#define SENSOR_FULL_SIZE 1
317#define SENSOR_INVALID_SIZE 2
318
319#define CAMERA_EFFECT_OFF 0
320#define CAMERA_EFFECT_MONO 1
321#define CAMERA_EFFECT_NEGATIVE 2
322#define CAMERA_EFFECT_SOLARIZE 3
323#define CAMERA_EFFECT_PASTEL 4
324#define CAMERA_EFFECT_MOSAIC 5
325#define CAMERA_EFFECT_RESIZE 6
326#define CAMERA_EFFECT_SEPIA 7
327#define CAMERA_EFFECT_POSTERIZE 8
328#define CAMERA_EFFECT_WHITEBOARD 9
329#define CAMERA_EFFECT_BLACKBOARD 10
330#define CAMERA_EFFECT_AQUA 11
331#define CAMERA_EFFECT_MAX 12
332
333struct sensor_pict_fps {
334 uint16_t prevfps;
335 uint16_t pictfps;
336};
337
338struct exp_gain_cfg {
339 uint16_t gain;
340 uint32_t line;
341};
342
343struct focus_cfg {
344 int32_t steps;
345 int dir;
346};
347
348struct fps_cfg {
349 uint16_t f_mult;
350 uint16_t fps_div;
351 uint32_t pict_fps_div;
352};
353
354struct sensor_cfg_data {
355 int cfgtype;
356 int mode;
357 int rs;
358 uint8_t max_steps;
359
360 union {
361 int8_t effect;
362 uint8_t lens_shading;
363 uint16_t prevl_pf;
364 uint16_t prevp_pl;
365 uint16_t pictl_pf;
366 uint16_t pictp_pl;
367 uint32_t pict_max_exp_lc;
368 uint16_t p_fps;
369 struct sensor_pict_fps gfps;
370 struct exp_gain_cfg exp_gain;
371 struct focus_cfg focus;
372 struct fps_cfg fps;
373 } cfg;
374};
375
376#define GET_NAME 0
377#define GET_PREVIEW_LINE_PER_FRAME 1
378#define GET_PREVIEW_PIXELS_PER_LINE 2
379#define GET_SNAPSHOT_LINE_PER_FRAME 3
380#define GET_SNAPSHOT_PIXELS_PER_LINE 4
381#define GET_SNAPSHOT_FPS 5
382#define GET_SNAPSHOT_MAX_EP_LINE_CNT 6
383
384struct msm_camsensor_info {
385 char name[MAX_SENSOR_NAME];
386 uint8_t flash_enabled;
387};
388#endif /* __LINUX_MSM_CAMERA_H */
diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c
index def646812348..503ba212dc96 100644
--- a/drivers/staging/dream/pmem.c
+++ b/drivers/staging/dream/pmem.c
@@ -37,17 +37,17 @@
37 * the file should not be released until put_pmem_file is called */ 37 * the file should not be released until put_pmem_file is called */
38#define PMEM_FLAGS_BUSY 0x1 38#define PMEM_FLAGS_BUSY 0x1
39/* indicates that this is a suballocation of a larger master range */ 39/* indicates that this is a suballocation of a larger master range */
40#define PMEM_FLAGS_CONNECTED 0x1 << 1 40#define PMEM_FLAGS_CONNECTED ( 0x1 << 1 )
41/* indicates this is a master and not a sub allocation and that it is mmaped */ 41/* indicates this is a master and not a sub allocation and that it is mmaped */
42#define PMEM_FLAGS_MASTERMAP 0x1 << 2 42#define PMEM_FLAGS_MASTERMAP ( 0x1 << 2 )
43/* submap and unsubmap flags indicate: 43/* submap and unsubmap flags indicate:
44 * 00: subregion has never been mmaped 44 * 00: subregion has never been mmaped
45 * 10: subregion has been mmaped, reference to the mm was taken 45 * 10: subregion has been mmaped, reference to the mm was taken
46 * 11: subretion has ben released, refernece to the mm still held 46 * 11: subretion has ben released, refernece to the mm still held
47 * 01: subretion has been released, reference to the mm has been released 47 * 01: subretion has been released, reference to the mm has been released
48 */ 48 */
49#define PMEM_FLAGS_SUBMAP 0x1 << 3 49#define PMEM_FLAGS_SUBMAP ( 0x1 << 3 )
50#define PMEM_FLAGS_UNSUBMAP 0x1 << 4 50#define PMEM_FLAGS_UNSUBMAP ( 0x1 << 4 )
51 51
52 52
53struct pmem_data { 53struct pmem_data {
@@ -91,7 +91,7 @@ struct pmem_region_node {
91 91
92#define PMEM_DEBUG_MSGS 0 92#define PMEM_DEBUG_MSGS 0
93#if PMEM_DEBUG_MSGS 93#if PMEM_DEBUG_MSGS
94#define DLOG(fmt,args...) \ 94#define DLOG(fmt, args...) \
95 do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ 95 do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
96 ##args); } \ 96 ##args); } \
97 while (0) 97 while (0)
@@ -152,7 +152,7 @@ struct pmem_info {
152static struct pmem_info pmem[PMEM_MAX_DEVICES]; 152static struct pmem_info pmem[PMEM_MAX_DEVICES];
153static int id_count; 153static int id_count;
154 154
155#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated) 155#define PMEM_IS_FREE(id, index) ( !(pmem[id].bitmap[index].allocated) )
156#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order 156#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order
157#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index))) 157#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index)))
158#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index))) 158#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index)))
@@ -708,9 +708,8 @@ int get_pmem_addr(struct file *file, unsigned long *start,
708 struct pmem_data *data; 708 struct pmem_data *data;
709 int id; 709 int id;
710 710
711 if (!is_pmem_file(file) || !has_allocation(file)) { 711 if (!is_pmem_file(file) || !has_allocation(file))
712 return -1; 712 return -1;
713 }
714 713
715 data = (struct pmem_data *)file->private_data; 714 data = (struct pmem_data *)file->private_data;
716 if (data->index == -1) { 715 if (data->index == -1) {
@@ -789,9 +788,8 @@ void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len)
789 struct list_head *elt; 788 struct list_head *elt;
790 void *flush_start, *flush_end; 789 void *flush_start, *flush_end;
791 790
792 if (!is_pmem_file(file) || !has_allocation(file)) { 791 if (!is_pmem_file(file) || !has_allocation(file))
793 return; 792 return;
794 }
795 793
796 id = get_id(file); 794 id = get_id(file);
797 data = (struct pmem_data *)file->private_data; 795 data = (struct pmem_data *)file->private_data;
@@ -833,7 +831,7 @@ static int pmem_connect(unsigned long connect, struct file *file)
833 src_file = fget_light(connect, &put_needed); 831 src_file = fget_light(connect, &put_needed);
834 DLOG("connect %p to %p\n", file, src_file); 832 DLOG("connect %p to %p\n", file, src_file);
835 if (!src_file) { 833 if (!src_file) {
836 printk("pmem: src file not found!\n"); 834 printk(KERN_INFO "pmem: src file not found!\n");
837 ret = -EINVAL; 835 ret = -EINVAL;
838 goto err_no_file; 836 goto err_no_file;
839 } 837 }
@@ -846,7 +844,7 @@ static int pmem_connect(unsigned long connect, struct file *file)
846 src_data = (struct pmem_data *)src_file->private_data; 844 src_data = (struct pmem_data *)src_file->private_data;
847 845
848 if (has_allocation(file) && (data->index != src_data->index)) { 846 if (has_allocation(file) && (data->index != src_data->index)) {
849 printk("pmem: file is already mapped but doesn't match this" 847 printk(KERN_INFO "pmem: file is already mapped but doesn't match this"
850 " src_file!\n"); 848 " src_file!\n");
851 ret = -EINVAL; 849 ret = -EINVAL;
852 goto err_bad_file; 850 goto err_bad_file;
@@ -885,7 +883,7 @@ lock_mm:
885 mm = get_task_mm(data->task); 883 mm = get_task_mm(data->task);
886 if (!mm) { 884 if (!mm) {
887#if PMEM_DEBUG 885#if PMEM_DEBUG
888 printk("pmem: can't remap task is gone!\n"); 886 printk(KERN_DEBUG "pmem: can't remap task is gone!\n");
889#endif 887#endif
890 up_read(&data->sem); 888 up_read(&data->sem);
891 return -1; 889 return -1;
@@ -936,7 +934,7 @@ int pmem_remap(struct pmem_region *region, struct file *file,
936 if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) || 934 if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) ||
937 !PMEM_IS_PAGE_ALIGNED(region->len))) { 935 !PMEM_IS_PAGE_ALIGNED(region->len))) {
938#if PMEM_DEBUG 936#if PMEM_DEBUG
939 printk("pmem: request for unaligned pmem suballocation " 937 printk(KERN_DEBUG "pmem: request for unaligned pmem suballocation "
940 "%lx %lx\n", region->offset, region->len); 938 "%lx %lx\n", region->offset, region->len);
941#endif 939#endif
942 return -EINVAL; 940 return -EINVAL;
diff --git a/drivers/staging/dream/qdsp5/Makefile b/drivers/staging/dream/qdsp5/Makefile
index 991d4a7e157f..beedaaff5cc5 100644
--- a/drivers/staging/dream/qdsp5/Makefile
+++ b/drivers/staging/dream/qdsp5/Makefile
@@ -1,3 +1,4 @@
1EXTRA_CFLAGS=-Idrivers/staging/dream/include
1obj-y += adsp.o 2obj-y += adsp.o
2ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y) 3ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y)
3obj-y += adsp_info.o 4obj-y += adsp_info.o
diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c
index b95574f699ff..7ed6e261d6c9 100644
--- a/drivers/staging/dream/qdsp5/audio_mp3.c
+++ b/drivers/staging/dream/qdsp5/audio_mp3.c
@@ -650,8 +650,7 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
650 &audio->read_phys, 650 &audio->read_phys,
651 GFP_KERNEL); 651 GFP_KERNEL);
652 if (!audio->read_data) { 652 if (!audio->read_data) {
653 pr_err("audio_mp3: malloc pcm \ 653 pr_err("audio_mp3: malloc pcm buf failed\n");
654 buf failed\n");
655 rc = -1; 654 rc = -1;
656 } else { 655 } else {
657 uint8_t index; 656 uint8_t index;
diff --git a/drivers/staging/dream/smd/Makefile b/drivers/staging/dream/smd/Makefile
index 892c7414bbed..1c87618366a7 100644
--- a/drivers/staging/dream/smd/Makefile
+++ b/drivers/staging/dream/smd/Makefile
@@ -1,3 +1,4 @@
1EXTRA_CFLAGS=-Idrivers/staging/dream/include
1obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o 2obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o
2obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o 3obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o
3obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o 4obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o
diff --git a/drivers/staging/dream/smd/smd_rpcrouter.c b/drivers/staging/dream/smd/smd_rpcrouter.c
index 5ac2cd4a5978..69911a7bc87a 100644
--- a/drivers/staging/dream/smd/smd_rpcrouter.c
+++ b/drivers/staging/dream/smd/smd_rpcrouter.c
@@ -38,8 +38,6 @@
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/uaccess.h> 39#include <linux/uaccess.h>
40 40
41#include <asm/byteorder.h>
42
43#include <mach/msm_smd.h> 41#include <mach/msm_smd.h>
44#include "smd_rpcrouter.h" 42#include "smd_rpcrouter.h"
45 43
diff --git a/drivers/staging/dt3155/Kconfig b/drivers/staging/dt3155/Kconfig
new file mode 100644
index 000000000000..4a3293c721b1
--- /dev/null
+++ b/drivers/staging/dt3155/Kconfig
@@ -0,0 +1,4 @@
1config DT3155
2 tristate "DT3155 Digitizer support"
3 depends on PCI
4
diff --git a/drivers/staging/dt3155/Makefile b/drivers/staging/dt3155/Makefile
new file mode 100644
index 000000000000..136f21fdbbee
--- /dev/null
+++ b/drivers/staging/dt3155/Makefile
@@ -0,0 +1,6 @@
1obj-$(CONFIG_DT3155) += dt3155.o
2dt3155-objs := \
3 dt3155_drv.o \
4 dt3155_isr.o \
5 dt3155_io.o \
6 allocator.o
diff --git a/drivers/staging/dt3155/TODO b/drivers/staging/dt3155/TODO
new file mode 100644
index 000000000000..3baa3b6294cc
--- /dev/null
+++ b/drivers/staging/dt3155/TODO
@@ -0,0 +1,10 @@
1TODO:
2 - fix checkpatch.pl issues
3 - remove old kernel support, it is not needed
4 - convert to proper PCI device API
5 - fix sparse warnings
6 - audit for correct subsystem interaction
7 - review review review!
8
9Please send patches to Greg Kroah-Hartman <greg@kroah.com>
10and Scott Smedley <ss@aao.gov.au>
diff --git a/drivers/staging/dt3155/allocator.README b/drivers/staging/dt3155/allocator.README
new file mode 100644
index 000000000000..05700b6c926c
--- /dev/null
+++ b/drivers/staging/dt3155/allocator.README
@@ -0,0 +1,98 @@
1
2The allocator shown here exploits high memory. This document explains
3how a user can deal with drivers uses this allocator and how a
4programmer can link in the module.
5
6The module is being used by my pxc and pxdrv device drivers (as well as
7other ones), available from ftp.systemy.it/pub/develop and
8ftp.linux.it/pub/People/Rubini
9
10 User's manual
11 =============
12
13
14One of the most compelling problems with any DMA-capable device is the
15allocation of a suitable memory buffer. The "allocator" module tries
16to deal with the problem in a clean way. The module is able to use
17high memory (above the one used in normal operation) for DMA
18allocation.
19
20To prevent the kernel for using high memory, so that it remains
21available for DMA, you should pass a command line argument to the
22kernel. Command line arguments can be passed to Lilo, to Loadlin or
23to whichever loader you are using (unless it's very poor in design).
24For Lilo, either use "append=" in /etc/lilo.conf or add commandline
25arguments to the interactive prompt. For example, I have a 32MB box
26and reserve two megs for DMA:
27
28In lilo.conf:
29 image = /zImage
30 label = linux
31 append = "mem=30M"
32
33Or, interactively:
34 LILO: linux mem=30M
35
36Once the kernel is booted with the right command-line argument, any
37driver linked with the allocator module will be able to get
38DMA-capable memory without much trouble (unless the various drivers
39need more memory than available).
40
41The module implements an alloc/free mechanism, so that it can serve
42multiple drivers at the same time. Note however that the allocator
43uses all of high memory and assumes to be the only piece of software
44using such memory.
45
46
47 Programmer's manual
48 ===================
49
50The allocator, as released, is designed to be linked to a device
51driver. In this case, the driver must call allocator_init() before
52using the allocator and must call allocator_cleanup() before
53unloading. This is usually done from within init_module() and
54cleanup_module(). If the allocator is linked to a driver, it won't be
55possible for several drivers to allocate high DMA memory, as explained
56above.
57
58It is possible, on the other hand, to compile the module as a standalone
59module, so that several modules can rely on the allocator for they DMA
60buffers. To compile the allocator as a standalone module, do the
61following in this directory (or provide a suitable Makefile, or edit
62the source code):
63
64 make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h"
65
66The previous commandline tells to include <linux/module.h> in the
67first place, and to rename the init and cleanup function to the ones
68needed for module loading and unloading. Drivers using a standalone
69allocator won't need to call allocator_init() nor allocator_cleanup().
70
71The allocator exports the following functions (declared in allocator.h):
72
73 unsigned long allocator_allocate_dma (unsigned long kilobytes,
74 int priority);
75
76 This function returns a physical address, over high_memory,
77 which corresponds to an area of at least "kilobytes" kilobytes.
78 The area will be owned by the module calling the function.
79 The returned address can be passed to device boards, to instruct
80 their DMA controllers, via phys_to_bus(). The address can be used
81 by C code after vremap()/ioremap(). The "priority" argument should
82 be GFP_KERNEL or GFP_ATOMIC, according to the context of the
83 caller; it is used to call kmalloc(), as the allocator must keep
84 track of any region it gives away. In case of error the function
85 returns 0, and the caller is expected to issue a -ENOMEM error.
86
87
88 void allocator_free_dma (unsigned long address);
89
90 This function is the reverse of the previous one. If a driver
91 doesn't free the DMA memory it allocated, the allocator will
92 consider such memory as busy. Note, however, that
93 allocator_cleanup() calls kfree() on every region it reclaimed,
94 so that a driver with the allocator linked in can avoid calling
95 allocator_free_dma() at unload time.
96
97
98
diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c
new file mode 100644
index 000000000000..c74234c66895
--- /dev/null
+++ b/drivers/staging/dt3155/allocator.c
@@ -0,0 +1,295 @@
1/*
2 * allocator.c -- allocate after high_memory, if available
3 *
4 * NOTE: this is different from my previous allocator, the one that
5 * assembles pages, which revealed itself both slow and unreliable.
6 *
7 * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23
24-- Changes --
25
26 Date Programmer Description of changes made
27 -------------------------------------------------------------------
28 02-Aug-2002 NJC allocator now steps in 1MB increments, rather
29 than doubling its size each time.
30 Also, allocator_init(u32 *) now returns
31 (in the first arg) the size of the free
32 space. This is no longer consistent with
33 using the allocator as a module, and some changes
34 may be necessary for that purpose. This was
35 designed to work with the DT3155 driver, in
36 stand alone mode only!!!
37 26-Oct-2009 SS Port to 2.6.30 kernel.
38 */
39
40
41#ifndef __KERNEL__
42# define __KERNEL__
43#endif
44#ifndef MODULE
45# define MODULE
46#endif
47
48#include <linux/version.h>
49
50#include <linux/sched.h>
51#include <linux/kernel.h>
52#include <linux/fs.h>
53#include <linux/proc_fs.h>
54#include <linux/errno.h>
55#include <linux/types.h>
56#include <linux/mm.h> /* PAGE_ALIGN() */
57#include <linux/io.h>
58
59#include <asm/page.h>
60
61/*#define ALL_DEBUG*/
62#define ALL_MSG "allocator: "
63
64#undef PDEBUG /* undef it, just in case */
65#ifdef ALL_DEBUG
66# define __static
67# define DUMP_LIST() dump_list()
68# ifdef __KERNEL__
69 /* This one if debugging is on, and kernel space */
70# define PDEBUG(fmt, args...) printk(KERN_DEBUG ALL_MSG fmt, ## args)
71# else
72 /* This one for user space */
73# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
74# endif
75#else
76# define PDEBUG(fmt, args...) /* not debugging: nothing */
77# define DUMP_LIST()
78# define __static static
79#endif
80
81#undef PDEBUGG
82#define PDEBUGG(fmt, args...)
83/*#define PDEBUGG(fmt, args...) printk( KERN_DEBUG ALL_MSG fmt, ## args)*/
84
85
86int allocator_himem = 1; /* 0 = probe, pos. = megs, neg. = disable */
87int allocator_step = 1; /* This is the step size in MB */
88int allocator_probe = 1; /* This is a flag -- 1=probe, 0=don't probe */
89
90static unsigned long allocator_buffer; /* physical address */
91static unsigned long allocator_buffer_size; /* kilobytes */
92
93/*
94 * The allocator keeps a list of DMA areas, so multiple devices
95 * can coexist. The list is kept sorted by address
96 */
97
98struct allocator_struct {
99 unsigned long address;
100 unsigned long size;
101 struct allocator_struct *next;
102};
103
104struct allocator_struct *allocator_list;
105
106
107#ifdef ALL_DEBUG
108static int dump_list(void)
109{
110 struct allocator_struct *ptr;
111
112 PDEBUG("Current list:\n");
113 for (ptr = allocator_list; ptr; ptr = ptr->next)
114 PDEBUG("0x%08lx (size %likB)\n", ptr->address, ptr->size>>10);
115 return 0;
116}
117#endif
118
119/* ========================================================================
120 * This function is the actual allocator.
121 *
122 * If space is available in high memory (as detected at load time), that
123 * one is returned. The return value is a physical address (i.e., it can
124 * be used straight ahead for DMA, but needs remapping for program use).
125 */
126
127unsigned long allocator_allocate_dma(unsigned long kilobytes, int prio)
128{
129 struct allocator_struct *ptr = allocator_list, *newptr;
130 unsigned long bytes = kilobytes << 10;
131
132 /* check if high memory is available */
133 if (!allocator_buffer)
134 return 0;
135
136 /* Round it to a multiple of the pagesize */
137 bytes = PAGE_ALIGN(bytes);
138 PDEBUG("request for %li bytes\n", bytes);
139
140 while (ptr && ptr->next) {
141 if (ptr->next->address - (ptr->address + ptr->size) >= bytes)
142 break; /* enough space */
143 ptr = ptr->next;
144 }
145 if (!ptr->next) {
146 DUMP_LIST();
147 PDEBUG("alloc failed\n");
148 return 0; /* end of list */
149 }
150 newptr = kmalloc(sizeof(struct allocator_struct), prio);
151 if (!newptr)
152 return 0;
153
154 /* ok, now stick it after ptr */
155 newptr->address = ptr->address + ptr->size;
156 newptr->size = bytes;
157 newptr->next = ptr->next;
158 ptr->next = newptr;
159
160 DUMP_LIST();
161 PDEBUG("returning 0x%08lx\n", newptr->address);
162 return newptr->address;
163}
164
165int allocator_free_dma(unsigned long address)
166{
167 struct allocator_struct *ptr = allocator_list, *prev;
168
169 while (ptr && ptr->next) {
170 if (ptr->next->address == address)
171 break;
172 ptr = ptr->next;
173 }
174 /* the one being freed is ptr->next */
175 prev = ptr; ptr = ptr->next;
176
177 if (!ptr) {
178 printk(KERN_ERR ALL_MSG
179 "free_dma(0x%08lx) but add. not allocated\n",
180 ptr->address);
181 return -EINVAL;
182 }
183 PDEBUGG("freeing: %08lx (%li) next %08lx\n", ptr->address, ptr->size,
184 ptr->next->address);
185 prev->next = ptr->next;
186 kfree(ptr);
187
188 /* dump_list(); */
189 return 0;
190}
191
192/* ========================================================================
193 * Init and cleanup
194 *
195 * On cleanup everything is released. If the list is not empty, that a
196 * problem of our clients
197 */
198int allocator_init(u32 *allocator_max)
199{
200 /* check how much free memory is there */
201 void *remapped;
202 unsigned long max;
203 unsigned long trial_size = allocator_himem<<20;
204 unsigned long last_trial = 0;
205 unsigned long step = allocator_step<<20;
206 unsigned long i = 0;
207 struct allocator_struct *head, *tail;
208 char test_string[] = "0123456789abcde"; /* 16 bytes */
209
210 PDEBUGG("himem = %i\n", allocator_himem);
211 if (allocator_himem < 0) /* don't even try */
212 return -EINVAL;
213
214 if (!trial_size)
215 trial_size = 1<<20; /* not specified: try one meg */
216
217 while (1) {
218 remapped = ioremap(__pa(high_memory), trial_size);
219 if (!remapped) {
220 PDEBUGG("%li megs failed!\n", trial_size>>20);
221 break;
222 }
223 PDEBUGG("Trying %li megs (at %p, %p)\n", trial_size>>20,
224 (void *)__pa(high_memory), remapped);
225 for (i = last_trial; i < trial_size; i += 16) {
226 strcpy((char *)(remapped)+i, test_string);
227 if (strcmp((char *)(remapped)+i, test_string))
228 break;
229 }
230 iounmap((void *)remapped);
231 schedule();
232 last_trial = trial_size;
233 if (i == trial_size)
234 trial_size += step; /* increment, if all went well */
235 else {
236 PDEBUGG("%li megs copy test failed!\n", trial_size>>20);
237 break;
238 }
239 if (!allocator_probe)
240 break;
241 }
242 PDEBUG("%li megs (%li k, %li b)\n", i>>20, i>>10, i);
243 allocator_buffer_size = i>>10; /* kilobytes */
244 allocator_buffer = __pa(high_memory);
245 if (!allocator_buffer_size) {
246 printk(KERN_WARNING ALL_MSG "no free high memory to use\n");
247 return -ENOMEM;
248 }
249
250 /*
251 * to simplify things, always have two cells in the list:
252 * the first and the last. This avoids some conditionals and
253 * extra code when allocating and deallocating: we only play
254 * in the middle of the list
255 */
256 head = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
257 if (!head)
258 return -ENOMEM;
259 tail = kmalloc(sizeof(struct allocator_struct), GFP_KERNEL);
260 if (!tail) {
261 kfree(head);
262 return -ENOMEM;
263 }
264
265 max = allocator_buffer_size<<10;
266
267 head->size = tail->size = 0;
268 head->address = allocator_buffer;
269 tail->address = allocator_buffer + max;
270 head->next = tail;
271 tail->next = NULL;
272 allocator_list = head;
273
274 /* Back to the user code, in KB */
275 *allocator_max = allocator_buffer_size;
276
277 return 0; /* ok, ready */
278}
279
280void allocator_cleanup(void)
281{
282 struct allocator_struct *ptr, *next;
283
284 for (ptr = allocator_list; ptr; ptr = next) {
285 next = ptr->next;
286 PDEBUG("freeing list: 0x%08lx\n", ptr->address);
287 kfree(ptr);
288 }
289
290 allocator_buffer = 0;
291 allocator_buffer_size = 0;
292 allocator_list = NULL;
293}
294
295
diff --git a/drivers/staging/dt3155/allocator.h b/drivers/staging/dt3155/allocator.h
new file mode 100644
index 000000000000..bdf3268ca52d
--- /dev/null
+++ b/drivers/staging/dt3155/allocator.h
@@ -0,0 +1,28 @@
1/*
2 * allocator.h -- prototypes for allocating high memory
3 *
4 * NOTE: this is different from my previous allocator, the one that
5 * assembles pages, which revealed itself both slow and unreliable.
6 *
7 * Copyright (C) 1998 rubini@linux.it (Alessandro Rubini)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25void allocator_free_dma(unsigned long address);
26unsigned long allocator_allocate_dma(unsigned long kilobytes, int priority);
27int allocator_init(u32 *);
28void allocator_cleanup(void);
diff --git a/drivers/staging/dt3155/dt3155.h b/drivers/staging/dt3155/dt3155.h
new file mode 100644
index 000000000000..1bf786364eec
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155.h
@@ -0,0 +1,171 @@
1/*
2
3Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley
5
6This file is part of the DT3155 Device Driver.
7
8The DT3155 Device Driver is free software; you can redistribute it
9and/or modify it under the terms of the GNU General Public License as
10published by the Free Software Foundation; either version 2 of the
11License, or (at your option) any later version.
12
13The DT3155 Device Driver is distributed in the hope that it will be
14useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with the DT3155 Device Driver; if not, write to the Free
20Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21MA 02111-1307 USA
22
23-- Changes --
24
25 Date Programmer Description of changes made
26 -------------------------------------------------------------------
27 03-Jul-2000 JML n/a
28 10-Oct-2001 SS port to 2.4 kernel.
29 24-Jul-2002 SS remove unused code & added GPL licence.
30 05-Aug-2005 SS port to 2.6 kernel; make CCIR mode default.
31
32*/
33
34#ifndef _DT3155_INC
35#define _DT3155_INC
36
37#ifdef __KERNEL__
38#include <linux/types.h>
39#include <linux/time.h> /* struct timeval */
40#else
41#include <sys/ioctl.h>
42#include <sys/param.h>
43#include <sys/time.h>
44#include <unistd.h>
45#endif
46
47
48#define TRUE 1
49#define FALSE 0
50
51/* Uncomment this for 50Hz CCIR */
52#define CCIR 1
53
54/* Can be 1 or 2 */
55#define MAXBOARDS 1
56
57#define BOARD_MAX_BUFFS 3
58#define MAXBUFFERS (BOARD_MAX_BUFFS*MAXBOARDS)
59
60#define PCI_PAGE_SIZE (1 << 12)
61
62#ifdef CCIR
63#define DT3155_MAX_ROWS 576
64#define DT3155_MAX_COLS 768
65#define FORMAT50HZ TRUE
66#else
67#define DT3155_MAX_ROWS 480
68#define DT3155_MAX_COLS 640
69#define FORMAT50HZ FALSE
70#endif
71
72/* Configuration structure */
73struct dt3155_config_s {
74 u32 acq_mode;
75 u32 cols, rows;
76 u32 continuous;
77};
78
79
80/* hold data for each frame */
81typedef struct {
82 u32 addr; /* address of the buffer with the frame */
83 u32 tag; /* unique number for the frame */
84 struct timeval time; /* time that capture took place */
85} frame_info_t;
86
87/*
88 * Structure for interrupt and buffer handling.
89 * This is the setup for 1 card
90 */
91struct dt3155_fbuffer_s {
92 int nbuffers;
93
94 frame_info_t frame_info[BOARD_MAX_BUFFS];
95
96 int empty_buffers[BOARD_MAX_BUFFS]; /* indexes empty frames */
97 int empty_len; /* Number of empty buffers */
98 /* Zero means empty */
99
100 int active_buf; /* Where data is currently dma'ing */
101 int locked_buf; /* Buffers used by user */
102
103 int ready_que[BOARD_MAX_BUFFS];
104 u32 ready_head; /* The most recent buffer located here */
105 u32 ready_len; /* The number of ready buffers */
106
107 int even_happened;
108 int even_stopped;
109
110 int stop_acquire; /* Flag to stop interrupts */
111 u32 frame_count; /* Counter for frames acquired by this card */
112};
113
114
115
116#define DT3155_MODE_FRAME 1
117#define DT3155_MODE_FIELD 2
118
119#define DT3155_SNAP 1
120#define DT3155_ACQ 2
121
122/* There is one status structure for each card. */
123typedef struct dt3155_status_s {
124 int fixed_mode; /* if 1, we are in fixed frame mode */
125 u32 reg_addr; /* Register address for a single card */
126 u32 mem_addr; /* Buffer start addr for this card */
127 u32 mem_size; /* This is the amount of mem available */
128 u32 irq; /* this card's irq */
129 struct dt3155_config_s config; /* configuration struct */
130 struct dt3155_fbuffer_s fbuffer; /* frame buffer state struct */
131 u32 state; /* this card's state */
132 u32 device_installed; /* Flag if installed. 1=installed */
133} dt3155_status_t;
134
135/* Reference to global status structure */
136extern struct dt3155_status_s dt3155_status[MAXBOARDS];
137
138#define DT3155_STATE_IDLE 0x00
139#define DT3155_STATE_FRAME 0x01
140#define DT3155_STATE_FLD 0x02
141#define DT3155_STATE_STOP 0x100
142#define DT3155_STATE_ERROR 0x200
143#define DT3155_STATE_MODE 0x0ff
144
145#define DT3155_IOC_MAGIC '!'
146
147#define DT3155_SET_CONFIG _IOW(DT3155_IOC_MAGIC, 1, struct dt3155_config_s)
148#define DT3155_GET_CONFIG _IOR(DT3155_IOC_MAGIC, 2, struct dt3155_status_s)
149#define DT3155_STOP _IO(DT3155_IOC_MAGIC, 3)
150#define DT3155_START _IO(DT3155_IOC_MAGIC, 4)
151#define DT3155_FLUSH _IO(DT3155_IOC_MAGIC, 5)
152#define DT3155_IOC_MAXNR 5
153
154/* Error codes */
155
156#define DT_ERR_NO_BUFFERS 0x10000 /* not used but it might be one day */
157#define DT_ERR_CORRUPT 0x20000
158#define DT_ERR_OVERRUN 0x30000
159#define DT_ERR_I2C_TIMEOUT 0x40000
160#define DT_ERR_MASK 0xff0000/* not used but it might be one day */
161
162/* User code will probably want to declare one of these for each card */
163typedef struct dt3155_read_s {
164 u32 offset;
165 u32 frame_seq;
166 u32 state;
167
168 frame_info_t frame_info;
169} dt3155_read_t;
170
171#endif /* _DT3155_inc */
diff --git a/drivers/staging/dt3155/dt3155.sysvinit b/drivers/staging/dt3155/dt3155.sysvinit
new file mode 100644
index 000000000000..92ec0939cb7a
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155.sysvinit
@@ -0,0 +1,60 @@
1#! /bin/sh
2#
3# Module load/unload script for use with SysV-style /etc/init.d/ systems.
4# On a Debian system, copy this to /etc/init.d/dt3155 and then run
5# /usr/sbin/update-rc.d dt3155 defaults 55
6# to create the appropriate /etc/rc?.d/[SK]55dt3155 start/stop links.
7# (The "55" is arbitrary but is what I use to load this rather late.)
8#
9# Andy Dougherty Feb 22 2000 doughera@lafayette.edu
10# Dept. of Physics
11# Lafayette College, Easton PA 18042
12#
13
14PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
15
16# Edit to point to your local copy.
17FILE=/usr/local/lib/modules/dt3155/dt3155.o
18NAME="dt3155"
19DESC="dt3155 Frame Grabber module"
20DEV="dt3155"
21
22if test ! -f $FILE; then
23 echo "Unable to locate $FILE"
24 exit 0
25fi
26
27set -e
28
29case "$1" in
30 start)
31 echo -n "Loading $DESC "
32 if /sbin/insmod -v -f $FILE; then
33 major=`grep $DEV /proc/devices | awk "{print \\$1}"`
34 rm -f /dev/dt3155?
35 mknod /dev/dt3155a c $major 0
36 mknod /dev/dt3155b c $major 1
37 chmod go+rw /dev/dt3155?
38 echo
39 else
40 echo "$FILE not loaded."
41 fi
42 ;;
43 stop)
44 echo -n "Unloading $DESC: "
45 if /sbin/rmmod $NAME ; then
46 echo
47 else
48 echo "$DEV not removed"
49 exit 0
50 fi
51 rm -f /dev/dt3155?
52 ;;
53 *)
54 echo "Usage: /etc/init.d/$NAME {start|stop}"
55 exit 1
56 ;;
57esac
58
59exit 0
60
diff --git a/drivers/staging/dt3155/dt3155_drv.c b/drivers/staging/dt3155/dt3155_drv.c
new file mode 100644
index 000000000000..a67c622869d2
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_drv.c
@@ -0,0 +1,1095 @@
1/*
2
3Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley, Greg Sharp
5
6This file is part of the DT3155 Device Driver.
7
8The DT3155 Device Driver is free software; you can redistribute it
9and/or modify it under the terms of the GNU General Public License as
10published by the Free Software Foundation; either version 2 of the
11License, or (at your option) any later version.
12
13The DT3155 Device Driver is distributed in the hope that it will be
14useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with the DT3155 Device Driver; if not, write to the Free
20Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21MA 02111-1307 USA
22
23-- Changes --
24
25 Date Programmer Description of changes made
26 -------------------------------------------------------------------
27 03-Jul-2000 JML n/a
28 10-Oct-2001 SS port to 2.4 kernel
29 02-Apr-2002 SS Mods to use allocator as a standalone module;
30 Merged John Roll's changes (john@cfa.harvard.edu)
31 to make work with multiple boards.
32 02-Jul-2002 SS Merged James Rose's chages (rosejr@purdue.edu) to:
33 * fix successive interrupt-driven captures
34 * add select/poll support.
35 10-Jul-2002 GCS Add error check when ndevices > MAXBOARDS.
36 02-Aug-2002 GCS Fix field mode so that odd (lower) field is stored
37 in lower half of buffer.
38 05-Aug-2005 SS port to 2.6 kernel.
39 26-Oct-2009 SS port to 2.6.30 kernel.
40
41-- Notes --
42
43** appended "mem=124" in lilo.conf to allow for 4megs free on my 128meg system.
44 * using allocator.c and allocator.h from o'reilly book (alessandro rubini)
45 ftp://ftp.systemy.it/pub/develop (see README.allocator)
46
47 + might want to get rid of MAXboards for allocating initial buffer.
48 confusing and not necessary
49
50 + in cleanup_module the MOD_IN_USE looks like it is check after it should
51
52 * GFP_DMA should not be set with a PCI system (pg 291)
53
54 - NJC why are only two buffers allowed? (see isr, approx line 358)
55
56*/
57
58extern void printques(int);
59
60#ifdef MODULE
61#include <linux/module.h>
62#include <linux/interrupt.h>
63
64
65MODULE_LICENSE("GPL");
66
67#endif
68
69#ifndef CONFIG_PCI
70#error "DT3155 : Kernel PCI support not enabled (DT3155 drive requires PCI)"
71#endif
72
73#include <linux/pci.h>
74#include <linux/types.h>
75#include <linux/poll.h>
76#include <linux/sched.h>
77
78#include <asm/io.h>
79#include <asm/uaccess.h>
80
81#include "dt3155.h"
82#include "dt3155_drv.h"
83#include "dt3155_isr.h"
84#include "dt3155_io.h"
85#include "allocator.h"
86
87/* Error variable. Zero means no error. */
88int dt3155_errno = 0;
89
90#ifndef PCI_DEVICE_ID_INTEL_7116
91#define PCI_DEVICE_ID_INTEL_7116 0x1223
92#endif
93
94#define DT3155_VENDORID PCI_VENDOR_ID_INTEL
95#define DT3155_DEVICEID PCI_DEVICE_ID_INTEL_7116
96#define MAXPCI 16
97
98#ifdef DT_DEBUG
99#define DT_3155_DEBUG_MSG(x,y) printk(x,y)
100#else
101#define DT_3155_DEBUG_MSG(x,y)
102#endif
103
104/* wait queue for interrupts */
105wait_queue_head_t dt3155_read_wait_queue[ MAXBOARDS ];
106
107#define DT_3155_SUCCESS 0
108#define DT_3155_FAILURE -EIO
109
110/* set to dynamicaly allocate, but it is tunable: */
111/* insmod DT_3155 dt3155 dt3155_major=XX */
112int dt3155_major = 0;
113
114/* The minor numbers are 0 and 1 ... they are not tunable.
115 * They are used as the indices for the structure vectors,
116 * and register address vectors
117 */
118
119/* Global structures and variables */
120
121/* Status of each device */
122struct dt3155_status_s dt3155_status[ MAXBOARDS ];
123
124/* kernel logical address of the board */
125u8 *dt3155_lbase[ MAXBOARDS ] = { NULL
126#if MAXBOARDS == 2
127 , NULL
128#endif
129};
130/* DT3155 registers */
131u8 *dt3155_bbase = NULL; /* kernel logical address of the *
132 * buffer region */
133u32 dt3155_dev_open[ MAXBOARDS ] = {0
134#if MAXBOARDS == 2
135 , 0
136#endif
137};
138
139u32 ndevices = 0;
140u32 unique_tag = 0;;
141
142
143/*
144 * Stops interrupt generation right away and resets the status
145 * to idle. I don't know why this works and the other way doesn't.
146 * (James Rose)
147 */
148static void quick_stop (int minor)
149{
150 // TODO: scott was here
151#if 1
152 ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
153 /* disable interrupts */
154 int_csr_r.fld.FLD_END_EVE_EN = 0;
155 int_csr_r.fld.FLD_END_ODD_EN = 0;
156 WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
157
158 dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff);
159 /* mark the system stopped: */
160 dt3155_status[ minor ].state |= DT3155_STATE_IDLE;
161 dt3155_fbuffer[ minor ]->stop_acquire = 0;
162 dt3155_fbuffer[ minor ]->even_stopped = 0;
163#else
164 dt3155_status[minor].state |= DT3155_STATE_STOP;
165 dt3155_status[minor].fbuffer.stop_acquire = 1;
166#endif
167
168}
169
170
171/*****************************************************
172 * dt3155_isr() Interrupt service routien
173 *
174 * - looks like this isr supports IRQ sharing (or could) JML
175 * - Assumes irq's are disabled, via SA_INTERRUPT flag
176 * being set in request_irq() call from init_module()
177 *****************************************************/
178static inline void dt3155_isr( int irq, void *dev_id, struct pt_regs *regs )
179{
180 int minor = -1;
181 int index;
182 unsigned long flags;
183 u32 buffer_addr;
184
185 /* find out who issued the interrupt */
186 for ( index = 0; index < ndevices; index++ ) {
187 if( dev_id == (void*) &dt3155_status[ index ])
188 {
189 minor = index;
190 break;
191 }
192 }
193
194 /* hopefully we should not get here */
195 if ( minor < 0 || minor >= MAXBOARDS ) {
196 printk(KERN_ERR "dt3155_isr called with invalid dev_id\n");
197 return;
198 }
199
200 /* Check for corruption and set a flag if so */
201 ReadMReg( (dt3155_lbase[ minor ] + CSR1), csr1_r.reg );
202
203 if ( (csr1_r.fld.FLD_CRPT_EVE) || (csr1_r.fld.FLD_CRPT_ODD) )
204 {
205 /* TODO: this should probably stop acquisition */
206 /* and set some flags so that dt3155_read */
207 /* returns an error next time it is called */
208 dt3155_errno = DT_ERR_CORRUPT;
209 printk("dt3155: corrupt field\n");
210 return;
211 }
212
213 ReadMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
214
215 /* Handle the even field ... */
216 if (int_csr_r.fld.FLD_END_EVE)
217 {
218 if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
219 DT3155_STATE_FLD )
220 {
221 dt3155_fbuffer[ minor ]->frame_count++;
222 }
223
224 ReadI2C(dt3155_lbase[ minor ], EVEN_CSR, &i2c_even_csr.reg);
225
226 /* Clear the interrupt? */
227 int_csr_r.fld.FLD_END_EVE = 1;
228
229 /* disable the interrupt if last field */
230 if (dt3155_fbuffer[ minor ]->stop_acquire)
231 {
232 printk("dt3155: even stopped.\n");
233 dt3155_fbuffer[ minor ]->even_stopped = 1;
234 if (i2c_even_csr.fld.SNGL_EVE)
235 {
236 int_csr_r.fld.FLD_END_EVE_EN = 0;
237 }
238 else
239 {
240 i2c_even_csr.fld.SNGL_EVE = 1;
241 }
242 }
243
244 WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
245
246 /* Set up next DMA if we are doing FIELDS */
247 if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE ) ==
248 DT3155_STATE_FLD)
249 {
250 /* GCS (Aug 2, 2002) -- In field mode, dma the odd field
251 into the lower half of the buffer */
252 const u32 stride = dt3155_status[ minor ].config.cols;
253 buffer_addr = dt3155_fbuffer[ minor ]->
254 frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr
255 + (DT3155_MAX_ROWS / 2) * stride;
256 local_save_flags(flags);
257 local_irq_disable();
258 wake_up_interruptible( &dt3155_read_wait_queue[ minor ] );
259
260 /* Set up the DMA address for the next field */
261 local_irq_restore(flags);
262 WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr);
263 }
264
265 /* Check for errors. */
266 i2c_even_csr.fld.DONE_EVE = 1;
267 if ( i2c_even_csr.fld.ERROR_EVE )
268 dt3155_errno = DT_ERR_OVERRUN;
269
270 WriteI2C( dt3155_lbase[ minor ], EVEN_CSR, i2c_even_csr.reg );
271
272 /* Note that we actually saw an even field meaning */
273 /* that subsequent odd field complete the frame */
274 dt3155_fbuffer[ minor ]->even_happened = 1;
275
276 /* recording the time that the even field finished, this should be */
277 /* about time in the middle of the frame */
278 do_gettimeofday( &(dt3155_fbuffer[ minor ]->
279 frame_info[ dt3155_fbuffer[ minor ]->
280 active_buf ].time) );
281 return;
282 }
283
284 /* ... now handle the odd field */
285 if ( int_csr_r.fld.FLD_END_ODD )
286 {
287 ReadI2C( dt3155_lbase[ minor ], ODD_CSR, &i2c_odd_csr.reg );
288
289 /* Clear the interrupt? */
290 int_csr_r.fld.FLD_END_ODD = 1;
291
292 if (dt3155_fbuffer[ minor ]->even_happened ||
293 (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
294 DT3155_STATE_FLD)
295 {
296 dt3155_fbuffer[ minor ]->frame_count++;
297 }
298
299 if ( dt3155_fbuffer[ minor ]->stop_acquire &&
300 dt3155_fbuffer[ minor ]->even_stopped )
301 {
302 printk(KERN_DEBUG "dt3155: stopping odd..\n");
303 if ( i2c_odd_csr.fld.SNGL_ODD )
304 {
305 /* disable interrupts */
306 int_csr_r.fld.FLD_END_ODD_EN = 0;
307 dt3155_status[ minor ].state &= ~(DT3155_STATE_STOP|0xff);
308
309 /* mark the system stopped: */
310 dt3155_status[ minor ].state |= DT3155_STATE_IDLE;
311 dt3155_fbuffer[ minor ]->stop_acquire = 0;
312 dt3155_fbuffer[ minor ]->even_stopped = 0;
313
314 printk(KERN_DEBUG "dt3155: state is now %x\n",
315 dt3155_status[minor].state);
316 }
317 else
318 {
319 i2c_odd_csr.fld.SNGL_ODD = 1;
320 }
321 }
322
323 WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
324
325 /* if the odd field has been acquired, then */
326 /* change the next dma location for both fields */
327 /* and wake up the process if sleeping */
328 if ( dt3155_fbuffer[ minor ]->even_happened ||
329 (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
330 DT3155_STATE_FLD )
331 {
332
333 local_save_flags(flags);
334 local_irq_disable();
335
336#ifdef DEBUG_QUES_B
337 printques( minor );
338#endif
339 if ( dt3155_fbuffer[ minor ]->nbuffers > 2 )
340 {
341 if ( !are_empty_buffers( minor ) )
342 {
343 /* The number of active + locked buffers is
344 * at most 2, and since there are none empty, there
345 * must be at least nbuffers-2 ready buffers.
346 * This is where we 'drop frames', oldest first. */
347 push_empty( pop_ready( minor ), minor );
348 }
349
350 /* The ready_que can't be full, since we know
351 * there is one active buffer right now, so it's safe
352 * to push the active buf on the ready_que. */
353 push_ready( minor, dt3155_fbuffer[ minor ]->active_buf );
354 /* There's at least 1 empty -- make it active */
355 dt3155_fbuffer[ minor ]->active_buf = pop_empty( minor );
356 dt3155_fbuffer[ minor ]->
357 frame_info[ dt3155_fbuffer[ minor ]->
358 active_buf ].tag = ++unique_tag;
359 }
360 else /* nbuffers == 2, special case */
361 { /* There is 1 active buffer.
362 * If there is a locked buffer, keep the active buffer
363 * the same -- that means we drop a frame.
364 */
365 if ( dt3155_fbuffer[ minor ]->locked_buf < 0 )
366 {
367 push_ready( minor,
368 dt3155_fbuffer[ minor ]->active_buf );
369 if (are_empty_buffers( minor ) )
370 {
371 dt3155_fbuffer[ minor ]->active_buf =
372 pop_empty( minor );
373 }
374 else
375 { /* no empty or locked buffers, so use a readybuf */
376 dt3155_fbuffer[ minor ]->active_buf =
377 pop_ready( minor );
378 }
379 }
380 }
381
382#ifdef DEBUG_QUES_B
383 printques( minor );
384#endif
385
386 dt3155_fbuffer[ minor ]->even_happened = 0;
387
388 wake_up_interruptible( &dt3155_read_wait_queue[ minor ] );
389
390 local_irq_restore(flags);
391 }
392
393
394 /* Set up the DMA address for the next frame/field */
395 buffer_addr = dt3155_fbuffer[ minor ]->
396 frame_info[ dt3155_fbuffer[ minor ]->active_buf ].addr;
397 if ( (dt3155_status[ minor ].state & DT3155_STATE_MODE) ==
398 DT3155_STATE_FLD )
399 {
400 WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr);
401 }
402 else
403 {
404 WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START), buffer_addr);
405
406 WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START), buffer_addr
407 + dt3155_status[ minor ].config.cols);
408 }
409
410 /* Do error checking */
411 i2c_odd_csr.fld.DONE_ODD = 1;
412 if ( i2c_odd_csr.fld.ERROR_ODD )
413 dt3155_errno = DT_ERR_OVERRUN;
414
415 WriteI2C(dt3155_lbase[ minor ], ODD_CSR, i2c_odd_csr.reg );
416
417 return;
418 }
419 /* If we get here, the Odd Field wasn't it either... */
420 printk( "neither even nor odd. shared perhaps?\n");
421}
422
423/*****************************************************
424 * init_isr(int minor)
425 * turns on interupt generation for the card
426 * designated by "minor".
427 * It is called *only* from inside ioctl().
428 *****************************************************/
429static void dt3155_init_isr(int minor)
430{
431 const u32 stride = dt3155_status[ minor ].config.cols;
432
433 switch (dt3155_status[ minor ].state & DT3155_STATE_MODE)
434 {
435 case DT3155_STATE_FLD:
436 {
437 even_dma_start_r = dt3155_status[ minor ].
438 fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr;
439 even_dma_stride_r = 0;
440 odd_dma_stride_r = 0;
441
442 WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START),
443 even_dma_start_r);
444 WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE),
445 even_dma_stride_r);
446 WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE),
447 odd_dma_stride_r);
448 break;
449 }
450
451 case DT3155_STATE_FRAME:
452 default:
453 {
454 even_dma_start_r = dt3155_status[ minor ].
455 fbuffer.frame_info[ dt3155_status[ minor ].fbuffer.active_buf ].addr;
456 odd_dma_start_r = even_dma_start_r + stride;
457 even_dma_stride_r = stride;
458 odd_dma_stride_r = stride;
459
460 WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_START),
461 even_dma_start_r);
462 WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_START),
463 odd_dma_start_r);
464 WriteMReg((dt3155_lbase[ minor ] + EVEN_DMA_STRIDE),
465 even_dma_stride_r);
466 WriteMReg((dt3155_lbase[ minor ] + ODD_DMA_STRIDE),
467 odd_dma_stride_r);
468 break;
469 }
470 }
471
472 /* 50/60 Hz should be set before this point but let's make sure it is */
473 /* right anyway */
474
475 ReadI2C(dt3155_lbase[ minor ], CONFIG, &i2c_csr2.reg);
476 i2c_csr2.fld.HZ50 = FORMAT50HZ;
477 WriteI2C(dt3155_lbase[ minor ], CONFIG, i2c_config.reg);
478
479 /* enable busmaster chip, clear flags */
480
481 /*
482 * TODO:
483 * shouldn't we be concered with continuous values of
484 * DT3155_SNAP & DT3155_ACQ here? (SS)
485 */
486
487 csr1_r.reg = 0;
488 csr1_r.fld.CAP_CONT_EVE = 1; /* use continuous capture bits to */
489 csr1_r.fld.CAP_CONT_ODD = 1; /* enable */
490 csr1_r.fld.FLD_DN_EVE = 1; /* writing a 1 clears flags */
491 csr1_r.fld.FLD_DN_ODD = 1;
492 csr1_r.fld.SRST = 1; /* reset - must be 1 */
493 csr1_r.fld.FIFO_EN = 1; /* fifo control - must be 1 */
494 csr1_r.fld.FLD_CRPT_EVE = 1; /* writing a 1 clears flags */
495 csr1_r.fld.FLD_CRPT_ODD = 1;
496
497 WriteMReg((dt3155_lbase[ minor ] + CSR1),csr1_r.reg);
498
499 /* Enable interrupts at the end of each field */
500
501 int_csr_r.reg = 0;
502 int_csr_r.fld.FLD_END_EVE_EN = 1;
503 int_csr_r.fld.FLD_END_ODD_EN = 1;
504 int_csr_r.fld.FLD_START_EN = 0;
505
506 WriteMReg((dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg);
507
508 /* start internal BUSY bits */
509
510 ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg);
511 i2c_csr2.fld.BUSY_ODD = 1;
512 i2c_csr2.fld.BUSY_EVE = 1;
513 WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg);
514
515 /* Now its up to the interrupt routine!! */
516
517 return;
518}
519
520
521/*****************************************************
522 * ioctl()
523 *
524 *****************************************************/
525static int dt3155_ioctl(struct inode *inode,
526 struct file *file,
527 unsigned int cmd,
528 unsigned long arg)
529{
530 int minor = MINOR(inode->i_rdev); /* What device are we ioctl()'ing? */
531
532 if ( minor >= MAXBOARDS || minor < 0 )
533 return -ENODEV;
534
535 /* make sure it is valid command */
536 if (_IOC_NR(cmd) > DT3155_IOC_MAXNR)
537 {
538 printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
539 printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
540 (unsigned int)DT3155_GET_CONFIG,
541 (unsigned int)DT3155_SET_CONFIG,
542 (unsigned int)DT3155_START,
543 (unsigned int)DT3155_STOP,
544 (unsigned int)DT3155_FLUSH);
545 return -EINVAL;
546 }
547
548 switch (cmd)
549 {
550 case DT3155_SET_CONFIG:
551 {
552 if (dt3155_status[minor].state != DT3155_STATE_IDLE)
553 return -EBUSY;
554
555 {
556 struct dt3155_config_s tmp;
557 if (copy_from_user((void *)&tmp, (void *) arg, sizeof(tmp)))
558 return -EFAULT;
559 /* check for valid settings */
560 if (tmp.rows > DT3155_MAX_ROWS ||
561 tmp.cols > DT3155_MAX_COLS ||
562 (tmp.acq_mode != DT3155_MODE_FRAME &&
563 tmp.acq_mode != DT3155_MODE_FIELD) ||
564 (tmp.continuous != DT3155_SNAP &&
565 tmp.continuous != DT3155_ACQ))
566 {
567 return -EINVAL;
568 }
569 dt3155_status[minor].config = tmp;
570 }
571 return 0;
572 }
573 case DT3155_GET_CONFIG:
574 {
575 if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
576 sizeof(dt3155_status_t) ))
577 return -EFAULT;
578 return 0;
579 }
580 case DT3155_FLUSH: /* Flushes the buffers -- ensures fresh data */
581 {
582 if (dt3155_status[minor].state != DT3155_STATE_IDLE)
583 return -EBUSY;
584 return dt3155_flush(minor);
585 }
586 case DT3155_STOP:
587 {
588 if (dt3155_status[minor].state & DT3155_STATE_STOP ||
589 dt3155_status[minor].fbuffer.stop_acquire)
590 return -EBUSY;
591
592 if (dt3155_status[minor].state == DT3155_STATE_IDLE)
593 return 0;
594
595 quick_stop(minor);
596 if (copy_to_user((void *) arg, (void *) &dt3155_status[minor],
597 sizeof(dt3155_status_t)))
598 return -EFAULT;
599 return 0;
600 }
601 case DT3155_START:
602 {
603 if (dt3155_status[minor].state != DT3155_STATE_IDLE)
604 return -EBUSY;
605
606 dt3155_status[minor].fbuffer.stop_acquire = 0;
607 dt3155_status[minor].fbuffer.frame_count = 0;
608
609 /* Set the MODE in the status -- we default to FRAME */
610 if (dt3155_status[minor].config.acq_mode == DT3155_MODE_FIELD)
611 {
612 dt3155_status[minor].state = DT3155_STATE_FLD;
613 }
614 else
615 {
616 dt3155_status[minor].state = DT3155_STATE_FRAME;
617 }
618
619 dt3155_init_isr(minor);
620 if (copy_to_user( (void *) arg, (void *) &dt3155_status[minor],
621 sizeof(dt3155_status_t)))
622 return -EFAULT;
623 return 0;
624 }
625 default:
626 {
627 printk("DT3155: invalid IOCTL(0x%x)\n",cmd);
628 printk("DT3155: Valid commands (0x%x), (0x%x), (0x%x), (0x%x), (0x%x)\n",
629 (unsigned int)DT3155_GET_CONFIG,
630 (unsigned int)DT3155_SET_CONFIG,
631 DT3155_START, DT3155_STOP, DT3155_FLUSH);
632 return -ENOSYS;
633 }
634 }
635 return -ENOSYS;
636}
637
638/*****************************************************
639 * mmap()
640 *
641 * only allow the user to mmap the registers and buffer
642 * It is quite possible that this is broken, since the
643 * addition of of the capacity for two cards!!!!!!!!
644 * It *looks* like it should work but since I'm not
645 * sure how to use it, I'm not actually sure. (NJC? ditto by SS)
646 *****************************************************/
647static int dt3155_mmap (struct file * file, struct vm_area_struct * vma)
648{
649 /* which device are we mmapping? */
650 int minor = MINOR(file->f_dentry->d_inode->i_rdev);
651 unsigned long offset;
652 offset = vma->vm_pgoff << PAGE_SHIFT;
653
654 if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
655 vma->vm_flags |= VM_IO;
656
657 /* Don't try to swap out physical pages.. */
658 vma->vm_flags |= VM_RESERVED;
659
660 /* they are mapping the registers or the buffer */
661 if ((offset == dt3155_status[minor].reg_addr &&
662 vma->vm_end - vma->vm_start == PCI_PAGE_SIZE) ||
663 (offset == dt3155_status[minor].mem_addr &&
664 vma->vm_end - vma->vm_start == dt3155_status[minor].mem_size))
665 {
666 if (remap_pfn_range(vma,
667 vma->vm_start,
668 offset >> PAGE_SHIFT,
669 vma->vm_end - vma->vm_start,
670 vma->vm_page_prot)) {
671 printk("DT3155: remap_page_range() failed.\n");
672 return -EAGAIN;
673 }
674 }
675 else
676 {
677 printk("DT3155: dt3155_mmap() bad call.\n");
678 return -ENXIO;
679 }
680
681 return 0;
682}
683
684
685/*****************************************************
686 * open()
687 *
688 * Our special open code.
689 * MOD_INC_USE_COUNT make sure that the driver memory is not freed
690 * while the device is in use.
691 *****************************************************/
692static int dt3155_open( struct inode* inode, struct file* filep)
693{
694 int minor = MINOR(inode->i_rdev); /* what device are we opening? */
695 if (dt3155_dev_open[ minor ]) {
696 printk ("DT3155: Already opened by another process.\n");
697 return -EBUSY;
698 }
699
700 if (dt3155_status[ minor ].device_installed==0)
701 {
702 printk("DT3155 Open Error: No such device dt3155 minor number %d\n",
703 minor);
704 return -EIO;
705 }
706
707 if (dt3155_status[ minor ].state != DT3155_STATE_IDLE) {
708 printk ("DT3155: Not in idle state (state = %x)\n",
709 dt3155_status[ minor ].state);
710 return -EBUSY;
711 }
712
713 printk("DT3155: Device opened.\n");
714
715 dt3155_dev_open[ minor ] = 1 ;
716
717 dt3155_flush( minor );
718
719 /* Disable ALL interrupts */
720 int_csr_r.reg = 0;
721 WriteMReg( (dt3155_lbase[ minor ] + INT_CSR), int_csr_r.reg );
722
723 init_waitqueue_head(&(dt3155_read_wait_queue[minor]));
724
725 return 0;
726}
727
728
729/*****************************************************
730 * close()
731 *
732 * Now decrement the use count.
733 *
734 *****************************************************/
735static int dt3155_close( struct inode *inode, struct file *filep)
736{
737 int minor;
738
739 minor = MINOR(inode->i_rdev); /* which device are we closing */
740 if (!dt3155_dev_open[ minor ])
741 {
742 printk("DT3155: attempt to CLOSE a not OPEN device\n");
743 }
744 else
745 {
746 dt3155_dev_open[ minor ] = 0;
747
748 if (dt3155_status[ minor ].state != DT3155_STATE_IDLE)
749 {
750 quick_stop(minor);
751 }
752 }
753 return 0;
754}
755
756/*****************************************************
757 * read()
758 *
759 *****************************************************/
760static ssize_t dt3155_read(struct file *filep, char __user *buf,
761 size_t count, loff_t *ppos)
762{
763 /* which device are we reading from? */
764 int minor = MINOR(filep->f_dentry->d_inode->i_rdev);
765 u32 offset;
766 int frame_index;
767 frame_info_t *frame_info_p;
768
769 /* TODO: this should check the error flag and */
770 /* return an error on hardware failures */
771 if (count != sizeof(dt3155_read_t))
772 {
773 printk("DT3155 ERROR (NJC): count is not right\n");
774 return -EINVAL;
775 }
776
777
778 /* Hack here -- I'm going to allow reading even when idle.
779 * this is so that the frames can be read after STOP has
780 * been called. Leaving it here, commented out, as a reminder
781 * for a short while to make sure there are no problems.
782 * Note that if the driver is not opened in non_blocking mode,
783 * and the device is idle, then it could sit here forever! */
784
785 /* if (dt3155_status[minor].state == DT3155_STATE_IDLE)*/
786 /* return -EBUSY;*/
787
788 /* non-blocking reads should return if no data */
789 if (filep->f_flags & O_NDELAY)
790 {
791 if ((frame_index = dt3155_get_ready_buffer(minor)) < 0) {
792 /*printk( "dt3155: no buffers available (?)\n");*/
793 /* printques(minor); */
794 return -EAGAIN;
795 }
796 }
797 else
798 {
799 /*
800 * sleep till data arrives , or we get interrupted.
801 * Note that wait_event_interruptible() does not actually
802 * sleep/wait if it's condition evaluates to true upon entry.
803 */
804 wait_event_interruptible(dt3155_read_wait_queue[minor],
805 (frame_index = dt3155_get_ready_buffer(minor))
806 >= 0);
807
808 if (frame_index < 0)
809 {
810 printk ("DT3155: read: interrupted\n");
811 quick_stop (minor);
812 printques(minor);
813 return -EINTR;
814 }
815 }
816
817 frame_info_p = &dt3155_status[minor].fbuffer.frame_info[frame_index];
818
819 /* make this an offset */
820 offset = frame_info_p->addr - dt3155_status[minor].mem_addr;
821
822 put_user(offset, (unsigned int *) buf);
823 buf += sizeof(u32);
824 put_user( dt3155_status[minor].fbuffer.frame_count, (unsigned int *) buf);
825 buf += sizeof(u32);
826 put_user(dt3155_status[minor].state, (unsigned int *) buf);
827 buf += sizeof(u32);
828 if (copy_to_user(buf, frame_info_p, sizeof(frame_info_t)))
829 return -EFAULT;
830
831 return sizeof(dt3155_read_t);
832}
833
834static unsigned int dt3155_poll (struct file * filp, poll_table *wait)
835{
836 int minor = MINOR(filp->f_dentry->d_inode->i_rdev);
837
838 if (!is_ready_buf_empty(minor))
839 return POLLIN | POLLRDNORM;
840
841 poll_wait (filp, &dt3155_read_wait_queue[minor], wait);
842
843 return 0;
844}
845
846
847/*****************************************************
848 * file operations supported by DT3155 driver
849 * needed by init_module
850 * register_chrdev
851 *****************************************************/
852static struct file_operations dt3155_fops = {
853 read: dt3155_read,
854 ioctl: dt3155_ioctl,
855 mmap: dt3155_mmap,
856 poll: dt3155_poll,
857 open: dt3155_open,
858 release: dt3155_close
859};
860
861
862/*****************************************************
863 * find_PCI();
864 *
865 * PCI has been totally reworked in 2.1..
866 *****************************************************/
867static int find_PCI (void)
868{
869 struct pci_dev *pci_dev = NULL;
870 int error, pci_index = 0;
871 unsigned short rev_device;
872 unsigned long base;
873 unsigned char irq;
874
875 while ((pci_dev = pci_get_device
876 (DT3155_VENDORID, DT3155_DEVICEID, pci_dev)) != NULL)
877 {
878 pci_index ++;
879
880 /* Is it really there? */
881 if ((error =
882 pci_read_config_word(pci_dev, PCI_CLASS_DEVICE, &rev_device)))
883 continue;
884
885 /* Found a board */
886 DT_3155_DEBUG_MSG("DT3155: Device number %d \n", pci_index);
887
888 /* Make sure the driver was compiled with enough buffers to handle
889 this many boards */
890 if (pci_index > MAXBOARDS) {
891 printk("DT3155: ERROR - found %d devices, but driver only configured "
892 "for %d devices\n"
893 "DT3155: Please change MAXBOARDS in dt3155.h\n",
894 pci_index, MAXBOARDS);
895 goto err;
896 }
897
898 /* Now, just go out and make sure that this/these device(s) is/are
899 actually mapped into the kernel address space */
900 if ((error = pci_read_config_dword( pci_dev, PCI_BASE_ADDRESS_0,
901 (u32 *) &base)))
902 {
903 printk("DT3155: Was not able to find device \n");
904 goto err;
905 }
906
907 DT_3155_DEBUG_MSG("DT3155: Base address 0 for device is %lx \n", base);
908 dt3155_status[pci_index-1].reg_addr = base;
909
910 /* Remap the base address to a logical address through which we
911 * can access it. */
912 dt3155_lbase[ pci_index - 1 ] = ioremap(base,PCI_PAGE_SIZE);
913 dt3155_status[ pci_index - 1 ].reg_addr = base;
914 DT_3155_DEBUG_MSG("DT3155: New logical address is %p \n",
915 dt3155_lbase[pci_index-1]);
916 if ( !dt3155_lbase[pci_index-1] )
917 {
918 printk("DT3155: Unable to remap control registers\n");
919 goto err;
920 }
921
922 if ( (error = pci_read_config_byte( pci_dev, PCI_INTERRUPT_LINE, &irq)) )
923 {
924 printk("DT3155: Was not able to find device \n");
925 goto err;
926 }
927
928 DT_3155_DEBUG_MSG("DT3155: IRQ is %d \n",irq);
929 dt3155_status[ pci_index-1 ].irq = irq;
930 /* Set flag: kth device found! */
931 dt3155_status[ pci_index-1 ].device_installed = 1;
932 printk("DT3155: Installing device %d w/irq %d and address %p\n",
933 pci_index,
934 dt3155_status[pci_index-1].irq,
935 dt3155_lbase[pci_index-1]);
936
937 }
938 ndevices = pci_index;
939
940 return DT_3155_SUCCESS;
941
942err:
943 pci_dev_put(pci_dev);
944 return DT_3155_FAILURE;
945}
946
947u32 allocatorAddr = 0;
948
949/*****************************************************
950 * init_module()
951 *****************************************************/
952int init_module(void)
953{
954 int index;
955 int rcode = 0;
956 char *devname[ MAXBOARDS ];
957
958 devname[ 0 ] = "dt3155a";
959#if MAXBOARDS == 2
960 devname[ 1 ] = "dt3155b";
961#endif
962
963 printk("DT3155: Loading module...\n");
964
965 /* Register the device driver */
966 rcode = register_chrdev( dt3155_major, "dt3155", &dt3155_fops );
967 if( rcode < 0 )
968 {
969 printk( KERN_INFO "DT3155: register_chrdev failed \n");
970 return rcode;
971 }
972
973 if( dt3155_major == 0 )
974 dt3155_major = rcode; /* dynamic */
975
976
977 /* init the status variables. */
978 /* DMA memory is taken care of in setup_buffers() */
979 for ( index = 0; index < MAXBOARDS; index++ )
980 {
981 dt3155_status[ index ].config.acq_mode = DT3155_MODE_FRAME;
982 dt3155_status[ index ].config.continuous = DT3155_ACQ;
983 dt3155_status[ index ].config.cols = DT3155_MAX_COLS;
984 dt3155_status[ index ].config.rows = DT3155_MAX_ROWS;
985 dt3155_status[ index ].state = DT3155_STATE_IDLE;
986
987 /* find_PCI() will check if devices are installed; */
988 /* first assume they're not: */
989 dt3155_status[ index ].mem_addr = 0;
990 dt3155_status[ index ].mem_size = 0;
991 dt3155_status[ index ].state = DT3155_STATE_IDLE;
992 dt3155_status[ index ].device_installed = 0;
993 }
994
995 /* Now let's find the hardware. find_PCI() will set ndevices to the
996 * number of cards found in this machine. */
997 {
998 if ( (rcode = find_PCI()) != DT_3155_SUCCESS )
999 {
1000 printk("DT3155 error: find_PCI() failed to find dt3155 board(s)\n");
1001 unregister_chrdev( dt3155_major, "dt3155" );
1002 return rcode;
1003 }
1004 }
1005
1006 /* Ok, time to setup the frame buffers */
1007 if( (rcode = dt3155_setup_buffers(&allocatorAddr)) < 0 )
1008 {
1009 printk("DT3155: Error: setting up buffer not large enough.");
1010 unregister_chrdev( dt3155_major, "dt3155" );
1011 return rcode;
1012 }
1013
1014 /* If we are this far, then there is enough RAM */
1015 /* for the buffers: Print the configuration. */
1016 for( index = 0; index < ndevices; index++ )
1017 {
1018 printk("DT3155: Device = %d; acq_mode = %d; "
1019 "continuous = %d; cols = %d; rows = %d;\n",
1020 index ,
1021 dt3155_status[ index ].config.acq_mode,
1022 dt3155_status[ index ].config.continuous,
1023 dt3155_status[ index ].config.cols,
1024 dt3155_status[ index ].config.rows);
1025 printk("DT3155: m_addr = 0x%x; m_size = %ld; "
1026 "state = %d; device_installed = %d\n",
1027 dt3155_status[ index ].mem_addr,
1028 (long int)dt3155_status[ index ].mem_size,
1029 dt3155_status[ index ].state,
1030 dt3155_status[ index ].device_installed);
1031 }
1032
1033 /* Disable ALL interrupts */
1034 int_csr_r.reg = 0;
1035 for( index = 0; index < ndevices; index++ )
1036 {
1037 WriteMReg( (dt3155_lbase[ index ] + INT_CSR), int_csr_r.reg );
1038 if( dt3155_status[ index ].device_installed )
1039 {
1040 /*
1041 * This driver *looks* like it can handle sharing interrupts,
1042 * but I can't actually test myself. I've had reports that it
1043 * DOES work so I'll enable it for now. This comment will remain
1044 * as a reminder in case any problems arise. (SS)
1045 */
1046 /* in older kernels flags are: SA_SHIRQ | SA_INTERRUPT */
1047 rcode = request_irq( dt3155_status[ index ].irq, (void *)dt3155_isr,
1048 IRQF_SHARED | IRQF_DISABLED, devname[ index ],
1049 (void*) &dt3155_status[index]);
1050 if( rcode < 0 )
1051 {
1052 printk("DT3155: minor %d request_irq failed for IRQ %d\n",
1053 index, dt3155_status[index].irq);
1054 unregister_chrdev( dt3155_major, "dt3155" );
1055 return rcode;
1056 }
1057 }
1058 }
1059
1060 printk("DT3155: finished loading\n");
1061
1062 return 0;
1063}
1064
1065/*****************************************************
1066 * cleanup_module(void)
1067 *
1068 *****************************************************/
1069void cleanup_module(void)
1070{
1071 int index;
1072
1073 printk("DT3155: cleanup_module called\n");
1074
1075 /* removed DMA allocated with the allocator */
1076#ifdef STANDALONE_ALLOCATOR
1077 if (allocatorAddr != 0)
1078 allocator_free_dma(allocatorAddr);
1079#else
1080 allocator_cleanup();
1081#endif
1082
1083 unregister_chrdev( dt3155_major, "dt3155" );
1084
1085 for( index = 0; index < ndevices; index++ )
1086 {
1087 if( dt3155_status[ index ].device_installed == 1 )
1088 {
1089 printk( "DT3155: Freeing irq %d for device %d\n",
1090 dt3155_status[ index ].irq, index );
1091 free_irq( dt3155_status[ index ].irq, (void*)&dt3155_status[index] );
1092 }
1093 }
1094}
1095
diff --git a/drivers/staging/dt3155/dt3155_drv.h b/drivers/staging/dt3155/dt3155_drv.h
new file mode 100644
index 000000000000..95e68c3388a4
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_drv.h
@@ -0,0 +1,45 @@
1/*
2
3Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Scott Smedley
5
6This file is part of the DT3155 Device Driver.
7
8The DT3155 Device Driver is free software; you can redistribute it
9and/or modify it under the terms of the GNU General Public License as
10published by the Free Software Foundation; either version 2 of the
11License, or (at your option) any later version.
12
13The DT3155 Device Driver is distributed in the hope that it will be
14useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with the DT3155 Device Driver; if not, write to the Free
20Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21MA 02111-1307 USA
22*/
23
24#ifndef DT3155_DRV_INC
25#define DT3155_DRV_INC
26
27/* kernel logical address of the frame grabbers */
28extern u8 *dt3155_lbase[MAXBOARDS];
29
30/* kernel logical address of ram buffer */
31extern u8 *dt3155_bbase;
32
33#ifdef __KERNEL__
34#include <linux/wait.h>
35
36/* wait queue for reads */
37extern wait_queue_head_t dt3155_read_wait_queue[MAXBOARDS];
38#endif
39
40/* number of devices */
41extern u32 ndevices;
42
43extern int dt3155_errno;
44
45#endif
diff --git a/drivers/staging/dt3155/dt3155_io.c b/drivers/staging/dt3155/dt3155_io.c
new file mode 100644
index 000000000000..6b9c68501a61
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_io.c
@@ -0,0 +1,175 @@
1/*
2 * Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
3 * Jason Lapenta, Scott Smedley
4 *
5 * This file is part of the DT3155 Device Driver.
6 *
7 * The DT3155 Device Driver is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * The DT3155 Device Driver is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details.
16 */
17
18/*
19 * This file provides some basic register io routines. It is modified from
20 * demo code provided by Data Translations.
21 */
22
23#include <linux/delay.h>
24#include "dt3155.h"
25#include "dt3155_io.h"
26#include "dt3155_drv.h"
27
28
29/****** local copies of board's 32 bit registers ******/
30u32 even_dma_start_r; /* bit 0 should always be 0 */
31u32 odd_dma_start_r; /* .. */
32u32 even_dma_stride_r; /* bits 0&1 should always be 0 */
33u32 odd_dma_stride_r; /* .. */
34u32 even_pixel_fmt_r;
35u32 odd_pixel_fmt_r;
36
37FIFO_TRIGGER_R fifo_trigger_r;
38XFER_MODE_R xfer_mode_r;
39CSR1_R csr1_r;
40RETRY_WAIT_CNT_R retry_wait_cnt_r;
41INT_CSR_R int_csr_r;
42
43u32 even_fld_mask_r;
44u32 odd_fld_mask_r;
45
46MASK_LENGTH_R mask_length_r;
47FIFO_FLAG_CNT_R fifo_flag_cnt_r;
48IIC_CLK_DUR_R iic_clk_dur_r;
49IIC_CSR1_R iic_csr1_r;
50IIC_CSR2_R iic_csr2_r;
51DMA_UPPER_LMT_R even_dma_upper_lmt_r;
52DMA_UPPER_LMT_R odd_dma_upper_lmt_r;
53
54
55
56/******** local copies of board's 8 bit I2C registers ******/
57I2C_CSR2 i2c_csr2;
58I2C_EVEN_CSR i2c_even_csr;
59I2C_ODD_CSR i2c_odd_csr;
60I2C_CONFIG i2c_config;
61u8 i2c_dt_id;
62u8 i2c_x_clip_start;
63u8 i2c_y_clip_start;
64u8 i2c_x_clip_end;
65u8 i2c_y_clip_end;
66u8 i2c_ad_addr;
67u8 i2c_ad_lut;
68I2C_AD_CMD i2c_ad_cmd;
69u8 i2c_dig_out;
70u8 i2c_pm_lut_addr;
71u8 i2c_pm_lut_data;
72
73/*
74 * wait_ibsyclr()
75 *
76 * This function handles read/write timing and r/w timeout error
77 *
78 * Returns TRUE if NEW_CYCLE clears
79 * Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs, otherwise
80 * returns 0
81 */
82static int wait_ibsyclr(u8 *lpReg)
83{
84 /* wait 100 microseconds */
85 udelay(100L);
86 /* __delay(loops_per_sec/10000); */
87 if (iic_csr2_r.fld.NEW_CYCLE) {
88 /* if NEW_CYCLE didn't clear */
89 /* TIMEOUT ERROR */
90 dt3155_errno = DT_ERR_I2C_TIMEOUT;
91 return FALSE;
92 } else
93 return TRUE; /* no error */
94}
95
96/*
97 * WriteI2C()
98 *
99 * This function handles writing to 8-bit DT3155 registers
100 *
101 * 1st parameter is pointer to 32-bit register base address
102 * 2nd parameter is reg. index;
103 * 3rd is value to be written
104 *
105 * Returns TRUE - Successful completion
106 * FALSE - Timeout error - cycle did not complete!
107 */
108int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal)
109{
110 int writestat; /* status for return */
111
112 /* read 32 bit IIC_CSR2 register data into union */
113
114 ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
115
116 /* for write operation */
117 iic_csr2_r.fld.DIR_RD = 0;
118 /* I2C address of I2C register: */
119 iic_csr2_r.fld.DIR_ADDR = wIregIndex;
120 /* 8 bit data to be written to I2C reg */
121 iic_csr2_r.fld.DIR_WR_DATA = byVal;
122 /* will start a direct I2C cycle: */
123 iic_csr2_r.fld.NEW_CYCLE = 1;
124
125 /* xfer union data into 32 bit IIC_CSR2 register */
126 WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
127
128 /* wait for IIC cycle to finish */
129 writestat = wait_ibsyclr(lpReg);
130 return writestat;
131}
132
133/*
134 * ReadI2C()
135 *
136 * This function handles reading from 8-bit DT3155 registers
137 *
138 * 1st parameter is pointer to 32-bit register base address
139 * 2nd parameter is reg. index;
140 * 3rd is adrs of value to be read
141 *
142 * Returns TRUE - Successful completion
143 * FALSE - Timeout error - cycle did not complete!
144 */
145int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal)
146{
147 int writestat; /* status for return */
148
149 /* read 32 bit IIC_CSR2 register data into union */
150 ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
151
152 /* for read operation */
153 iic_csr2_r.fld.DIR_RD = 1;
154
155 /* I2C address of I2C register: */
156 iic_csr2_r.fld.DIR_ADDR = wIregIndex;
157
158 /* will start a direct I2C cycle: */
159 iic_csr2_r.fld.NEW_CYCLE = 1;
160
161 /* xfer union's data into 32 bit IIC_CSR2 register */
162 WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
163
164 /* wait for IIC cycle to finish */
165 writestat = wait_ibsyclr(lpReg);
166
167 /* Next 2 commands read 32 bit IIC_CSR1 register's data into union */
168 /* first read data is in IIC_CSR1 */
169 ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg);
170
171 /* now get data u8 out of register */
172 *byVal = (u8) iic_csr1_r.fld.RD_DATA;
173
174 return writestat;
175}
diff --git a/drivers/staging/dt3155/dt3155_io.h b/drivers/staging/dt3155/dt3155_io.h
new file mode 100644
index 000000000000..d1a25100169f
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_io.h
@@ -0,0 +1,358 @@
1/*
2
3Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley
5
6This file is part of the DT3155 Device Driver.
7
8The DT3155 Device Driver is free software; you can redistribute it
9and/or modify it under the terms of the GNU General Public License as
10published by the Free Software Foundation; either version 2 of the
11License, or (at your option) any later version.
12
13The DT3155 Device Driver is distributed in the hope that it will be
14useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with the DT3155 Device Driver; if not, write to the Free
20Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21MA 02111-1307 USA
22
23
24-- Changes --
25
26 Date Programmer Description of changes made
27 -------------------------------------------------------------------
28 24-Jul-2002 SS GPL licence.
29
30*/
31
32/* This code is a modified version of examples provided by Data Translations.*/
33
34#ifndef DT3155_IO_INC
35#define DT3155_IO_INC
36
37/* macros to access registers */
38
39#define WriteMReg(Address, Data) (*((u32 *)(Address)) = Data)
40#define ReadMReg(Address, Data) (Data = *((u32 *)(Address)))
41
42/***************** 32 bit register globals **************/
43
44/* offsets for 32-bit memory mapped registers */
45
46#define EVEN_DMA_START 0x000
47#define ODD_DMA_START 0x00C
48#define EVEN_DMA_STRIDE 0x018
49#define ODD_DMA_STRIDE 0x024
50#define EVEN_PIXEL_FMT 0x030
51#define ODD_PIXEL_FMT 0x034
52#define FIFO_TRIGGER 0x038
53#define XFER_MODE 0x03C
54#define CSR1 0x040
55#define RETRY_WAIT_CNT 0x044
56#define INT_CSR 0x048
57#define EVEN_FLD_MASK 0x04C
58#define ODD_FLD_MASK 0x050
59#define MASK_LENGTH 0x054
60#define FIFO_FLAG_CNT 0x058
61#define IIC_CLK_DUR 0x05C
62#define IIC_CSR1 0x060
63#define IIC_CSR2 0x064
64#define EVEN_DMA_UPPR_LMT 0x08C
65#define ODD_DMA_UPPR_LMT 0x090
66
67#define CLK_DUR_VAL 0x01010101
68
69
70
71/******** Assignments and Typedefs for 32 bit Memory Mapped Registers ********/
72
73typedef union fifo_trigger_tag {
74 u32 reg;
75 struct {
76 u32 PACKED:6;
77 u32 :9;
78 u32 PLANER:7;
79 u32 :9;
80 } fld;
81} FIFO_TRIGGER_R;
82
83typedef union xfer_mode_tag {
84 u32 reg;
85 struct {
86 u32 :2;
87 u32 FIELD_TOGGLE:1;
88 u32 :5;
89 u32 :2;
90 u32 :22;
91 } fld;
92} XFER_MODE_R;
93
94typedef union csr1_tag {
95 u32 reg;
96 struct {
97 u32 CAP_CONT_EVE:1;
98 u32 CAP_CONT_ODD:1;
99 u32 CAP_SNGL_EVE:1;
100 u32 CAP_SNGL_ODD:1;
101 u32 FLD_DN_EVE :1;
102 u32 FLD_DN_ODD :1;
103 u32 SRST :1;
104 u32 FIFO_EN :1;
105 u32 FLD_CRPT_EVE:1;
106 u32 FLD_CRPT_ODD:1;
107 u32 ADDR_ERR_EVE:1;
108 u32 ADDR_ERR_ODD:1;
109 u32 CRPT_DIS :1;
110 u32 RANGE_EN :1;
111 u32 :16;
112 } fld;
113} CSR1_R;
114
115typedef union retry_wait_cnt_tag {
116 u32 reg;
117 struct {
118 u32 RTRY_WAIT_CNT:8;
119 u32 :24;
120 } fld;
121} RETRY_WAIT_CNT_R;
122
123typedef union int_csr_tag {
124 u32 reg;
125 struct {
126 u32 FLD_END_EVE :1;
127 u32 FLD_END_ODD :1;
128 u32 FLD_START :1;
129 u32 :5;
130 u32 FLD_END_EVE_EN:1;
131 u32 FLD_END_ODD_EN:1;
132 u32 FLD_START_EN :1;
133 u32 :21;
134 } fld;
135} INT_CSR_R;
136
137typedef union mask_length_tag {
138 u32 reg;
139 struct {
140 u32 MASK_LEN_EVE:5;
141 u32 :11;
142 u32 MASK_LEN_ODD:5;
143 u32 :11;
144 } fld;
145} MASK_LENGTH_R;
146
147typedef union fifo_flag_cnt_tag {
148 u32 reg;
149 struct {
150 u32 AF_COUNT:7;
151 u32 :9;
152 u32 AE_COUNT:7;
153 u32 :9;
154 } fld;
155} FIFO_FLAG_CNT_R;
156
157typedef union iic_clk_dur {
158 u32 reg;
159 struct {
160 u32 PHASE_1:8;
161 u32 PHASE_2:8;
162 u32 PHASE_3:8;
163 u32 PHASE_4:8;
164 } fld;
165} IIC_CLK_DUR_R;
166
167typedef union iic_csr1_tag {
168 u32 reg;
169 struct {
170 u32 AUTO_EN :1;
171 u32 BYPASS :1;
172 u32 SDA_OUT :1;
173 u32 SCL_OUT :1;
174 u32 :4;
175 u32 AUTO_ABORT :1;
176 u32 DIRECT_ABORT:1;
177 u32 SDA_IN :1;
178 u32 SCL_IN :1;
179 u32 :4;
180 u32 AUTO_ADDR :8;
181 u32 RD_DATA :8;
182 } fld;
183} IIC_CSR1_R;
184
185/**********************************
186 * iic_csr2_tag
187 */
188typedef union iic_csr2_tag {
189 u32 reg;
190 struct {
191 u32 DIR_WR_DATA :8;
192 u32 DIR_SUB_ADDR:8;
193 u32 DIR_RD :1;
194 u32 DIR_ADDR :7;
195 u32 NEW_CYCLE :1;
196 u32 :7;
197 } fld;
198} IIC_CSR2_R;
199
200/* use for both EVEN and ODD DMA UPPER LIMITS */
201
202/*
203 * dma_upper_lmt_tag
204 */
205typedef union dma_upper_lmt_tag {
206 u32 reg;
207 struct {
208 u32 DMA_UPPER_LMT_VAL:24;
209 u32 :8;
210 } fld;
211} DMA_UPPER_LMT_R;
212
213
214/*
215 * Global declarations of local copies of boards' 32 bit registers
216 */
217extern u32 even_dma_start_r; /* bit 0 should always be 0 */
218extern u32 odd_dma_start_r; /* .. */
219extern u32 even_dma_stride_r; /* bits 0&1 should always be 0 */
220extern u32 odd_dma_stride_r; /* .. */
221extern u32 even_pixel_fmt_r;
222extern u32 odd_pixel_fmt_r;
223
224extern FIFO_TRIGGER_R fifo_trigger_r;
225extern XFER_MODE_R xfer_mode_r;
226extern CSR1_R csr1_r;
227extern RETRY_WAIT_CNT_R retry_wait_cnt_r;
228extern INT_CSR_R int_csr_r;
229
230extern u32 even_fld_mask_r;
231extern u32 odd_fld_mask_r;
232
233extern MASK_LENGTH_R mask_length_r;
234extern FIFO_FLAG_CNT_R fifo_flag_cnt_r;
235extern IIC_CLK_DUR_R iic_clk_dur_r;
236extern IIC_CSR1_R iic_csr1_r;
237extern IIC_CSR2_R iic_csr2_r;
238extern DMA_UPPER_LMT_R even_dma_upper_lmt_r;
239extern DMA_UPPER_LMT_R odd_dma_upper_lmt_r;
240
241
242
243/***************** 8 bit I2C register globals ***********/
244#define CSR2 0x010 /* indices of 8-bit I2C mapped reg's*/
245#define EVEN_CSR 0x011
246#define ODD_CSR 0x012
247#define CONFIG 0x013
248#define DT_ID 0x01F
249#define X_CLIP_START 0x020
250#define Y_CLIP_START 0x022
251#define X_CLIP_END 0x024
252#define Y_CLIP_END 0x026
253#define AD_ADDR 0x030
254#define AD_LUT 0x031
255#define AD_CMD 0x032
256#define DIG_OUT 0x040
257#define PM_LUT_ADDR 0x050
258#define PM_LUT_DATA 0x051
259
260
261/******** Assignments and Typedefs for 8 bit I2C Registers********************/
262
263typedef union i2c_csr2_tag {
264 u8 reg;
265 struct {
266 u8 CHROM_FIL:1;
267 u8 SYNC_SNTL:1;
268 u8 HZ50:1;
269 u8 SYNC_PRESENT:1;
270 u8 BUSY_EVE:1;
271 u8 BUSY_ODD:1;
272 u8 DISP_PASS:1;
273 } fld;
274} I2C_CSR2;
275
276typedef union i2c_even_csr_tag {
277 u8 reg;
278 struct {
279 u8 DONE_EVE :1;
280 u8 SNGL_EVE :1;
281 u8 ERROR_EVE:1;
282 u8 :5;
283 } fld;
284} I2C_EVEN_CSR;
285
286typedef union i2c_odd_csr_tag {
287 u8 reg;
288 struct {
289 u8 DONE_ODD:1;
290 u8 SNGL_ODD:1;
291 u8 ERROR_ODD:1;
292 u8 :5;
293 } fld;
294} I2C_ODD_CSR;
295
296typedef union i2c_config_tag {
297 u8 reg;
298 struct {
299 u8 ACQ_MODE:2;
300 u8 EXT_TRIG_EN:1;
301 u8 EXT_TRIG_POL:1;
302 u8 H_SCALE:1;
303 u8 CLIP:1;
304 u8 PM_LUT_SEL:1;
305 u8 PM_LUT_PGM:1;
306 } fld;
307} I2C_CONFIG;
308
309
310typedef union i2c_ad_cmd_tag {
311 /* bits can have 3 different meanings depending on value of AD_ADDR */
312 u8 reg;
313 /* Bt252 Command Register if AD_ADDR = 00h */
314 struct {
315 u8 :2;
316 u8 SYNC_LVL_SEL:2;
317 u8 SYNC_CNL_SEL:2;
318 u8 DIGITIZE_CNL_SEL1:2;
319 } bt252_command;
320
321 /* Bt252 IOUT0 register if AD_ADDR = 01h */
322 struct {
323 u8 IOUT_DATA:8;
324 } bt252_iout0;
325
326 /* BT252 IOUT1 register if AD_ADDR = 02h */
327 struct {
328 u8 IOUT_DATA:8;
329 } bt252_iout1;
330} I2C_AD_CMD;
331
332
333/***** Global declarations of local copies of boards' 8 bit I2C registers ***/
334
335extern I2C_CSR2 i2c_csr2;
336extern I2C_EVEN_CSR i2c_even_csr;
337extern I2C_ODD_CSR i2c_odd_csr;
338extern I2C_CONFIG i2c_config;
339extern u8 i2c_dt_id;
340extern u8 i2c_x_clip_start;
341extern u8 i2c_y_clip_start;
342extern u8 i2c_x_clip_end;
343extern u8 i2c_y_clip_end;
344extern u8 i2c_ad_addr;
345extern u8 i2c_ad_lut;
346extern I2C_AD_CMD i2c_ad_cmd;
347extern u8 i2c_dig_out;
348extern u8 i2c_pm_lut_addr;
349extern u8 i2c_pm_lut_data;
350
351/* Functions for Global use */
352
353/* access 8-bit IIC registers */
354
355extern int ReadI2C(u8 *lpReg, u_short wIregIndex, u8 *byVal);
356extern int WriteI2C(u8 *lpReg, u_short wIregIndex, u8 byVal);
357
358#endif
diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c
new file mode 100644
index 000000000000..fd7f93d6c33d
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_isr.c
@@ -0,0 +1,516 @@
1/*
2
3Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley, Greg Sharp
5
6This file is part of the DT3155 Device Driver.
7
8The DT3155 Device Driver is free software; you can redistribute it
9and/or modify it under the terms of the GNU General Public License as
10published by the Free Software Foundation; either version 2 of the
11License, or (at your option) any later version.
12
13The DT3155 Device Driver is distributed in the hope that it will be
14useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with the DT3155 Device Driver; if not, write to the Free
20Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21MA 02111-1307 USA
22
23 File: dt3155_isr.c
24Purpose: Buffer management routines, and other routines for the ISR
25 (the actual isr is in dt3155_drv.c)
26
27-- Changes --
28
29 Date Programmer Description of changes made
30 -------------------------------------------------------------------
31 03-Jul-2000 JML n/a
32 02-Apr-2002 SS Mods to make work with separate allocator
33 module; Merged John Roll's mods to make work with
34 multiple boards.
35 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow
36 buffers which span a 4MB boundary.
37 24-Jul-2002 SS GPL licence.
38 30-Jul-2002 NJC Added support for buffer loop.
39 31-Jul-2002 NJC Complete rewrite of buffer management
40 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning).
41 Also, allocator_init() now returns allocator_max
42 so cleaned up allocate_buffers() accordingly.
43 08-Aug-2005 SS port to 2.6 kernel.
44
45*/
46
47#include <asm/system.h>
48#include <linux/slab.h>
49#include <linux/sched.h>
50#include <linux/types.h>
51
52#include "dt3155.h"
53#include "dt3155_drv.h"
54#include "dt3155_io.h"
55#include "dt3155_isr.h"
56#include "allocator.h"
57
58#define FOUR_MB (0x0400000) /* Can't DMA accross a 4MB boundary!*/
59#define UPPER_10_BITS (0x3FF<<22) /* Can't DMA accross a 4MB boundary!*/
60
61
62/* Pointer into global structure for handling buffers */
63struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS] = {NULL
64#if MAXBOARDS == 2
65 , NULL
66#endif
67};
68
69/******************************************************************************
70 * Simple array based que struct
71 *
72 * Some handy functions using the buffering structure.
73 *****************************************************************************/
74
75
76/***************************
77 * are_empty_buffers
78 * m is minor # of device
79 ***************************/
80inline bool are_empty_buffers( int m )
81{
82 return ( dt3155_fbuffer[ m ]->empty_len );
83}
84
85/**************************
86 * push_empty
87 * m is minor # of device
88 *
89 * This is slightly confusing. The number empty_len is the literal #
90 * of empty buffers. After calling, empty_len-1 is the index into the
91 * empty buffer stack. So, if empty_len == 1, there is one empty buffer,
92 * given by dt3155_fbuffer[m]->empty_buffers[0].
93 * empty_buffers should never fill up, though this is not checked.
94 **************************/
95inline void push_empty( int index, int m )
96{
97 dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ] = index;
98 dt3155_fbuffer[m]->empty_len++;
99}
100
101/**************************
102 * pop_empty( m )
103 * m is minor # of device
104 **************************/
105inline int pop_empty( int m )
106{
107 dt3155_fbuffer[m]->empty_len--;
108 return dt3155_fbuffer[m]->empty_buffers[ dt3155_fbuffer[m]->empty_len ];
109}
110
111/*************************
112 * is_ready_buf_empty( m )
113 * m is minor # of device
114 *************************/
115inline bool is_ready_buf_empty( int m )
116{
117 return ((dt3155_fbuffer[ m ]->ready_len) == 0);
118}
119
120/*************************
121 * is_ready_buf_full( m )
122 * m is minor # of device
123 * this should *never* be true if there are any active, locked or empty
124 * buffers, since it corresponds to nbuffers ready buffers!!
125 * 7/31/02: total rewrite. --NJC
126 *************************/
127inline bool is_ready_buf_full( int m )
128{
129 return ( dt3155_fbuffer[ m ]->ready_len == dt3155_fbuffer[ m ]->nbuffers );
130}
131
132/*****************************************************
133 * push_ready( m, buffer )
134 * m is minor # of device
135 *
136 *****************************************************/
137inline void push_ready( int m, int index )
138{
139 int head = dt3155_fbuffer[m]->ready_head;
140
141 dt3155_fbuffer[ m ]->ready_que[ head ] = index;
142 dt3155_fbuffer[ m ]->ready_head = ( (head + 1) %
143 (dt3155_fbuffer[ m ]->nbuffers) );
144 dt3155_fbuffer[ m ]->ready_len++;
145
146}
147
148/*****************************************************
149 * get_tail()
150 * m is minor # of device
151 *
152 * Simply comptutes the tail given the head and the length.
153 *****************************************************/
154static inline int get_tail( int m )
155{
156 return ((dt3155_fbuffer[ m ]->ready_head -
157 dt3155_fbuffer[ m ]->ready_len +
158 dt3155_fbuffer[ m ]->nbuffers)%
159 (dt3155_fbuffer[ m ]->nbuffers));
160}
161
162
163
164/*****************************************************
165 * pop_ready()
166 * m is minor # of device
167 *
168 * This assumes that there is a ready buffer ready... should
169 * be checked (e.g. with is_ready_buf_empty() prior to call.
170 *****************************************************/
171inline int pop_ready( int m )
172{
173 int tail;
174 tail = get_tail(m);
175 dt3155_fbuffer[ m ]->ready_len--;
176 return dt3155_fbuffer[ m ]->ready_que[ tail ];
177}
178
179
180/*****************************************************
181 * printques
182 * m is minor # of device
183 *****************************************************/
184inline void printques( int m )
185{
186 int head = dt3155_fbuffer[ m ]->ready_head;
187 int tail;
188 int num = dt3155_fbuffer[ m ]->nbuffers;
189 int frame_index;
190 int index;
191
192 tail = get_tail(m);
193
194 printk("\n R:");
195 for ( index = tail; index != head; index++, index = index % (num) )
196 {
197 frame_index = dt3155_fbuffer[ m ]->ready_que[ index ];
198 printk(" %d ", frame_index );
199 }
200
201 printk("\n E:");
202 for ( index = 0; index < dt3155_fbuffer[ m ]->empty_len; index++ )
203 {
204 frame_index = dt3155_fbuffer[ m ]->empty_buffers[ index ];
205 printk(" %d ", frame_index );
206 }
207
208 frame_index = dt3155_fbuffer[ m ]->active_buf;
209 printk("\n A: %d", frame_index);
210
211 frame_index = dt3155_fbuffer[ m ]->locked_buf;
212 printk("\n L: %d \n", frame_index );
213
214}
215
216/*****************************************************
217 * adjust_4MB
218 *
219 * If a buffer intersects the 4MB boundary, push
220 * the start address up to the beginning of the
221 * next 4MB chunk (assuming bufsize < 4MB).
222 *****************************************************/
223u32 adjust_4MB (u32 buf_addr, u32 bufsize) {
224 if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS))
225 return (buf_addr+bufsize) & UPPER_10_BITS;
226 else
227 return buf_addr;
228}
229
230
231/*****************************************************
232 * allocate_buffers
233 *
234 * Try to allocate enough memory for all requested
235 * buffers. If there is not enough free space
236 * try for less memory.
237 *****************************************************/
238void allocate_buffers (u32 *buf_addr, u32* total_size_kbs,
239 u32 bufsize)
240{
241 /* Compute the minimum amount of memory guaranteed to hold all
242 MAXBUFFERS such that no buffer crosses the 4MB boundary.
243 Store this value in the variable "full_size" */
244
245 u32 allocator_max;
246 u32 bufs_per_chunk = (FOUR_MB / bufsize);
247 u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk;
248 u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk;
249
250 u32 full_size = bufsize /* possibly unusable part of 1st chunk */
251 + filled_chunks * FOUR_MB /* max # of completely filled 4mb chunks */
252 + leftover_bufs * bufsize; /* these buffs will be in a partly filled
253 chunk at beginning or end */
254
255 u32 full_size_kbs = 1 + (full_size-1) / 1024;
256 u32 min_size_kbs = 2*ndevices*bufsize / 1024;
257 u32 size_kbs;
258
259 /* Now, try to allocate full_size. If this fails, keep trying for
260 less & less memory until it succeeds. */
261#ifndef STANDALONE_ALLOCATOR
262 /* initialize the allocator */
263 allocator_init(&allocator_max);
264#endif
265 size_kbs = full_size_kbs;
266 *buf_addr = 0;
267 printk("DT3155: We would like to get: %d KB\n", full_size_kbs);
268 printk("DT3155: ...but need at least: %d KB\n", min_size_kbs);
269 printk("DT3155: ...the allocator has: %d KB\n", allocator_max);
270 size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max);
271 if (size_kbs > min_size_kbs) {
272 if ((*buf_addr = allocator_allocate_dma (size_kbs, GFP_KERNEL)) != 0) {
273 printk("DT3155: Managed to allocate: %d KB\n", size_kbs);
274 *total_size_kbs = size_kbs;
275 return;
276 }
277 }
278 /* If we got here, the allocation failed */
279 printk ("DT3155: Allocator failed!\n");
280 *buf_addr = 0;
281 *total_size_kbs = 0;
282 return;
283
284}
285
286
287/*****************************************************
288 * dt3155_setup_buffers
289 *
290 * setup_buffers just puts the buffering system into
291 * a consistent state before the start of interrupts
292 *
293 * JML : it looks like all the buffers need to be
294 * continuous. So I'm going to try and allocate one
295 * continuous buffer.
296 *
297 * GCS : Fix DMA problems when buffer spans
298 * 4MB boundary. Also, add error checking. This
299 * function will return -ENOMEM when not enough memory.
300 *****************************************************/
301u32 dt3155_setup_buffers(u32 *allocatorAddr)
302
303{
304 u32 index;
305 u32 rambuff_addr; /* start of allocation */
306 u32 rambuff_size; /* total size allocated to driver */
307 u32 rambuff_acm; /* accumlator, keep track of how much
308 is left after being split up*/
309 u32 rambuff_end; /* end of rambuff */
310 u32 numbufs; /* number of useful buffers allocated (per device) */
311 u32 bufsize = DT3155_MAX_ROWS * DT3155_MAX_COLS;
312 int m; /* minor # of device, looped for all devs */
313
314 /* zero the fbuffer status and address structure */
315 for ( m = 0; m < ndevices; m++)
316 {
317 dt3155_fbuffer[ m ] = &(dt3155_status[ m ].fbuffer);
318
319 /* Make sure the buffering variables are consistent */
320 {
321 u8 *ptr = (u8 *) dt3155_fbuffer[ m ];
322 for( index = 0; index < sizeof(struct dt3155_fbuffer_s); index++)
323 *(ptr++)=0;
324 }
325 }
326
327 /* allocate a large contiguous chunk of RAM */
328 allocate_buffers (&rambuff_addr, &rambuff_size, bufsize);
329 printk("DT3155: mem info\n");
330 printk(" - rambuf_addr = 0x%x \n", rambuff_addr);
331 printk(" - length (kb) = %u \n", rambuff_size);
332 if( rambuff_addr == 0 )
333 {
334 printk( KERN_INFO
335 "DT3155: Error setup_buffers() allocator dma failed \n" );
336 return -ENOMEM;
337 }
338 *allocatorAddr = rambuff_addr;
339 rambuff_end = rambuff_addr + 1024 * rambuff_size;
340
341 /* after allocation, we need to count how many useful buffers there
342 are so we can give an equal number to each device */
343 rambuff_acm = rambuff_addr;
344 for ( index = 0; index < MAXBUFFERS; index++) {
345 rambuff_acm = adjust_4MB (rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/
346 if (rambuff_acm + bufsize > rambuff_end)
347 break;
348 rambuff_acm += bufsize;
349 }
350 /* Following line is OK, will waste buffers if index
351 * not evenly divisible by ndevices -NJC*/
352 numbufs = index / ndevices;
353 printk(" - numbufs = %u\n", numbufs);
354 if (numbufs < 2) {
355 printk( KERN_INFO
356 "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n" );
357 return -ENOMEM;
358 }
359
360 /* now that we have board memory we spit it up */
361 /* between the boards and the buffers */
362 rambuff_acm = rambuff_addr;
363 for ( m = 0; m < ndevices; m ++)
364 {
365 rambuff_acm = adjust_4MB (rambuff_acm, bufsize);
366
367 /* Save the start of this boards buffer space (for mmap). */
368 dt3155_status[ m ].mem_addr = rambuff_acm;
369
370 for (index = 0; index < numbufs; index++)
371 {
372 rambuff_acm = adjust_4MB (rambuff_acm, bufsize);
373 if (rambuff_acm + bufsize > rambuff_end) {
374 /* Should never happen */
375 printk ("DT3155 PROGRAM ERROR (GCS)\n"
376 "Error distributing allocated buffers\n");
377 return -ENOMEM;
378 }
379
380 dt3155_fbuffer[ m ]->frame_info[ index ].addr = rambuff_acm;
381 push_empty( index, m );
382 /* printk(" - Buffer : %lx\n",
383 * dt3155_fbuffer[ m ]->frame_info[ index ].addr );
384 */
385 dt3155_fbuffer[ m ]->nbuffers += 1;
386 rambuff_acm += bufsize;
387 }
388
389 /* Make sure there is an active buffer there. */
390 dt3155_fbuffer[ m ]->active_buf = pop_empty( m );
391 dt3155_fbuffer[ m ]->even_happened = 0;
392 dt3155_fbuffer[ m ]->even_stopped = 0;
393
394 /* make sure there is no locked_buf JML 2/28/00 */
395 dt3155_fbuffer[ m ]->locked_buf = -1;
396
397 dt3155_status[ m ].mem_size =
398 rambuff_acm - dt3155_status[ m ].mem_addr;
399
400 /* setup the ready queue */
401 dt3155_fbuffer[ m ]->ready_head = 0;
402 dt3155_fbuffer[ m ]->ready_len = 0;
403 printk("Available buffers for device %d: %d\n",
404 m, dt3155_fbuffer[ m ]->nbuffers);
405 }
406
407 return 1;
408}
409
410/*****************************************************
411 * internal_release_locked_buffer
412 *
413 * The internal function for releasing a locked buffer.
414 * It assumes interrupts are turned off.
415 *
416 * m is minor number of device
417 *****************************************************/
418static inline void internal_release_locked_buffer( int m )
419{
420 /* Pointer into global structure for handling buffers */
421 if ( dt3155_fbuffer[ m ]->locked_buf >= 0 )
422 {
423 push_empty( dt3155_fbuffer[ m ]->locked_buf, m );
424 dt3155_fbuffer[ m ]->locked_buf = -1;
425 }
426}
427
428
429/*****************************************************
430 * dt3155_release_locked_buffer()
431 * m is minor # of device
432 *
433 * The user function of the above.
434 *
435 *****************************************************/
436inline void dt3155_release_locked_buffer( int m )
437{
438 unsigned long int flags;
439 local_save_flags(flags);
440 local_irq_disable();
441 internal_release_locked_buffer(m);
442 local_irq_restore(flags);
443}
444
445
446/*****************************************************
447 * dt3155_flush()
448 * m is minor # of device
449 *
450 *****************************************************/
451inline int dt3155_flush( int m )
452{
453 int index;
454 unsigned long int flags;
455 local_save_flags(flags);
456 local_irq_disable();
457
458 internal_release_locked_buffer( m );
459 dt3155_fbuffer[ m ]->empty_len = 0;
460
461 for ( index = 0; index < dt3155_fbuffer[ m ]->nbuffers; index++ )
462 push_empty( index, m );
463
464 /* Make sure there is an active buffer there. */
465 dt3155_fbuffer[ m ]->active_buf = pop_empty( m );
466
467 dt3155_fbuffer[ m ]->even_happened = 0;
468 dt3155_fbuffer[ m ]->even_stopped = 0;
469
470 /* setup the ready queue */
471 dt3155_fbuffer[ m ]->ready_head = 0;
472 dt3155_fbuffer[ m ]->ready_len = 0;
473
474 local_irq_restore(flags);
475
476 return 0;
477}
478
479/*****************************************************
480 * dt3155_get_ready_buffer()
481 * m is minor # of device
482 *
483 * get_ready_buffer will grab the next chunk of data
484 * if it is already there, otherwise it returns 0.
485 * If the user has a buffer locked it will unlock
486 * that buffer before returning the new one.
487 *****************************************************/
488inline int dt3155_get_ready_buffer( int m )
489{
490 int frame_index;
491 unsigned long int flags;
492 local_save_flags(flags);
493 local_irq_disable();
494
495#ifdef DEBUG_QUES_A
496 printques( m );
497#endif
498
499 internal_release_locked_buffer( m );
500
501 if (is_ready_buf_empty( m ))
502 frame_index = -1;
503 else
504 {
505 frame_index = pop_ready( m );
506 dt3155_fbuffer[ m ]->locked_buf = frame_index;
507 }
508
509#ifdef DEBUG_QUES_B
510 printques( m );
511#endif
512
513 local_irq_restore(flags);
514
515 return frame_index;
516}
diff --git a/drivers/staging/dt3155/dt3155_isr.h b/drivers/staging/dt3155/dt3155_isr.h
new file mode 100644
index 000000000000..7595cb16c988
--- /dev/null
+++ b/drivers/staging/dt3155/dt3155_isr.h
@@ -0,0 +1,77 @@
1/*
2
3Copyright 1996,2002 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley
5
6This file is part of the DT3155 Device Driver.
7
8The DT3155 Device Driver is free software; you can redistribute it
9and/or modify it under the terms of the GNU General Public License as
10published by the Free Software Foundation; either version 2 of the
11License, or (at your option) any later version.
12
13The DT3155 Device Driver is distributed in the hope that it will be
14useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with the DT3155 Device Driver; if not, write to the Free
20Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21MA 02111-1307 USA
22
23
24-- Changes --
25
26 Date Programmer Description of changes made
27 -------------------------------------------------------------------
28 03-Jul-2000 JML n/a
29 24-Jul-2002 SS GPL licence.
30 26-Oct-2009 SS Porting to 2.6.30 kernel.
31
32-- notes --
33
34*/
35
36#ifndef DT3155_ISR_H
37#define DT3155_ISR_H
38
39extern struct dt3155_fbuffer_s *dt3155_fbuffer[MAXBOARDS];
40
41/* User functions for buffering */
42/* Initialize the buffering system. This should */
43/* be called prior to enabling interrupts */
44
45u32 dt3155_setup_buffers(u32 *allocatorAddr);
46
47/* Get the next frame of data if it is ready. Returns */
48/* zero if no data is ready. If there is data but */
49/* the user has a locked buffer, it will unlock that */
50/* buffer and return it to the free list. */
51
52int dt3155_get_ready_buffer(int minor);
53
54/* Return a locked buffer to the free list */
55
56void dt3155_release_locked_buffer(int minor);
57
58/* Flush the buffer system */
59int dt3155_flush(int minor);
60
61/**********************************
62 * Simple array based que struct
63 **********************************/
64
65bool are_empty_buffers(int minor);
66void push_empty(int index, int minor);
67
68int pop_empty(int minor);
69
70bool is_ready_buf_empty(int minor);
71bool is_ready_buf_full(int minor);
72
73void push_ready(int minor, int index);
74int pop_ready(int minor);
75
76
77#endif
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
index e715e4dcb523..ea746ba41faf 100644
--- a/drivers/staging/et131x/et1310_address_map.h
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -149,7 +149,7 @@
149 * GLOBAL Module of JAGCore Address Mapping 149 * GLOBAL Module of JAGCore Address Mapping
150 * Located at address 0x0000 150 * Located at address 0x0000
151 */ 151 */
152typedef struct _GLOBAL_t { /* Location: */ 152struct global_regs { /* Location: */
153 u32 txq_start_addr; /* 0x0000 */ 153 u32 txq_start_addr; /* 0x0000 */
154 u32 txq_end_addr; /* 0x0004 */ 154 u32 txq_end_addr; /* 0x0004 */
155 u32 rxq_start_addr; /* 0x0008 */ 155 u32 rxq_start_addr; /* 0x0008 */
@@ -165,9 +165,7 @@ typedef struct _GLOBAL_t { /* Location: */
165 u32 msi_config; /* 0x0030 */ 165 u32 msi_config; /* 0x0030 */
166 u32 loopback; /* 0x0034 */ 166 u32 loopback; /* 0x0034 */
167 u32 watchdog_timer; /* 0x0038 */ 167 u32 watchdog_timer; /* 0x0038 */
168} GLOBAL_t, *PGLOBAL_t; 168};
169
170/* END OF GLOBAL REGISTER ADDRESS MAP */
171 169
172 170
173/* START OF TXDMA REGISTER ADDRESS MAP */ 171/* START OF TXDMA REGISTER ADDRESS MAP */
@@ -255,7 +253,7 @@ extern inline void add_12bit(u32 *v, int n)
255 * Tx DMA Module of JAGCore Address Mapping 253 * Tx DMA Module of JAGCore Address Mapping
256 * Located at address 0x1000 254 * Located at address 0x1000
257 */ 255 */
258typedef struct _TXDMA_t { /* Location: */ 256struct txdma_regs { /* Location: */
259 u32 csr; /* 0x1000 */ 257 u32 csr; /* 0x1000 */
260 u32 pr_base_hi; /* 0x1004 */ 258 u32 pr_base_hi; /* 0x1004 */
261 u32 pr_base_lo; /* 0x1008 */ 259 u32 pr_base_lo; /* 0x1008 */
@@ -282,7 +280,7 @@ typedef struct _TXDMA_t { /* Location: */
282 u32 DroppedTLPCount; /* 0x105c */ 280 u32 DroppedTLPCount; /* 0x105c */
283 u32 NewServiceComplete; /* 0x1060 */ 281 u32 NewServiceComplete; /* 0x1060 */
284 u32 EthernetPacketCount; /* 0x1064 */ 282 u32 EthernetPacketCount; /* 0x1064 */
285} TXDMA_t, *PTXDMA_t; 283};
286 284
287/* END OF TXDMA REGISTER ADDRESS MAP */ 285/* END OF TXDMA REGISTER ADDRESS MAP */
288 286
@@ -292,45 +290,25 @@ typedef struct _TXDMA_t { /* Location: */
292/* 290/*
293 * structure for control status reg in rxdma address map 291 * structure for control status reg in rxdma address map
294 * Located at address 0x2000 292 * Located at address 0x2000
293 *
294 * CSR
295 * 0: halt
296 * 1-3: tc
297 * 4: fbr_big_endian
298 * 5: psr_big_endian
299 * 6: pkt_big_endian
300 * 7: dma_big_endian
301 * 8-9: fbr0_size
302 * 10: fbr0_enable
303 * 11-12: fbr1_size
304 * 13: fbr1_enable
305 * 14: unused
306 * 15: pkt_drop_disable
307 * 16: pkt_done_flush
308 * 17: halt_status
309 * 18-31: unused
295 */ 310 */
296typedef union _RXDMA_CSR_t { 311
297 u32 value;
298 struct {
299#ifdef _BIT_FIELDS_HTOL
300 u32 unused2:14; /* bits 18-31 */
301 u32 halt_status:1; /* bit 17 */
302 u32 pkt_done_flush:1; /* bit 16 */
303 u32 pkt_drop_disable:1; /* bit 15 */
304 u32 unused1:1; /* bit 14 */
305 u32 fbr1_enable:1; /* bit 13 */
306 u32 fbr1_size:2; /* bits 11-12 */
307 u32 fbr0_enable:1; /* bit 10 */
308 u32 fbr0_size:2; /* bits 8-9 */
309 u32 dma_big_endian:1; /* bit 7 */
310 u32 pkt_big_endian:1; /* bit 6 */
311 u32 psr_big_endian:1; /* bit 5 */
312 u32 fbr_big_endian:1; /* bit 4 */
313 u32 tc:3; /* bits 1-3 */
314 u32 halt:1; /* bit 0 */
315#else
316 u32 halt:1; /* bit 0 */
317 u32 tc:3; /* bits 1-3 */
318 u32 fbr_big_endian:1; /* bit 4 */
319 u32 psr_big_endian:1; /* bit 5 */
320 u32 pkt_big_endian:1; /* bit 6 */
321 u32 dma_big_endian:1; /* bit 7 */
322 u32 fbr0_size:2; /* bits 8-9 */
323 u32 fbr0_enable:1; /* bit 10 */
324 u32 fbr1_size:2; /* bits 11-12 */
325 u32 fbr1_enable:1; /* bit 13 */
326 u32 unused1:1; /* bit 14 */
327 u32 pkt_drop_disable:1; /* bit 15 */
328 u32 pkt_done_flush:1; /* bit 16 */
329 u32 halt_status:1; /* bit 17 */
330 u32 unused2:14; /* bits 18-31 */
331#endif
332 } bits;
333} RXDMA_CSR_t, *PRXDMA_CSR_t;
334 312
335/* 313/*
336 * structure for dma writeback lo reg in rxdma address map 314 * structure for dma writeback lo reg in rxdma address map
@@ -451,18 +429,6 @@ typedef union _RXDMA_CSR_t {
451 * 31-10: unused 429 * 31-10: unused
452 * 9-0: fbr ndesc 430 * 9-0: fbr ndesc
453 */ 431 */
454typedef union _RXDMA_FBR_NUM_DES_t {
455 u32 value;
456 struct {
457#ifdef _BIT_FIELDS_HTOL
458 u32 unused:22; /* bits 10-31 */
459 u32 fbr_ndesc:10; /* bits 0-9 */
460#else
461 u32 fbr_ndesc:10; /* bits 0-9 */
462 u32 unused:22; /* bits 10-31 */
463#endif
464 } bits;
465} RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t;
466 432
467/* 433/*
468 * structure for free buffer ring 0 available offset reg in rxdma address map 434 * structure for free buffer ring 0 available offset reg in rxdma address map
@@ -532,8 +498,8 @@ typedef union _RXDMA_FBR_NUM_DES_t {
532 * Rx DMA Module of JAGCore Address Mapping 498 * Rx DMA Module of JAGCore Address Mapping
533 * Located at address 0x2000 499 * Located at address 0x2000
534 */ 500 */
535typedef struct _RXDMA_t { /* Location: */ 501struct rxdma_regs { /* Location: */
536 RXDMA_CSR_t csr; /* 0x2000 */ 502 u32 csr; /* 0x2000 */
537 u32 dma_wb_base_lo; /* 0x2004 */ 503 u32 dma_wb_base_lo; /* 0x2004 */
538 u32 dma_wb_base_hi; /* 0x2008 */ 504 u32 dma_wb_base_hi; /* 0x2008 */
539 u32 num_pkt_done; /* 0x200C */ 505 u32 num_pkt_done; /* 0x200C */
@@ -562,7 +528,7 @@ typedef struct _RXDMA_t { /* Location: */
562 u32 fbr1_full_offset; /* 0x2068 */ 528 u32 fbr1_full_offset; /* 0x2068 */
563 u32 fbr1_rd_index; /* 0x206C */ 529 u32 fbr1_rd_index; /* 0x206C */
564 u32 fbr1_min_des; /* 0x2070 */ 530 u32 fbr1_min_des; /* 0x2070 */
565} RXDMA_t, *PRXDMA_t; 531};
566 532
567/* END OF RXDMA REGISTER ADDRESS MAP */ 533/* END OF RXDMA REGISTER ADDRESS MAP */
568 534
@@ -572,33 +538,18 @@ typedef struct _RXDMA_t { /* Location: */
572/* 538/*
573 * structure for control reg in txmac address map 539 * structure for control reg in txmac address map
574 * located at address 0x3000 540 * located at address 0x3000
541 *
542 * bits
543 * 31-8: unused
544 * 7: cklseg_disable
545 * 6: ckbcnt_disable
546 * 5: cksegnum
547 * 4: async_disable
548 * 3: fc_disable
549 * 2: mcif_disable
550 * 1: mif_disable
551 * 0: txmac_en
575 */ 552 */
576typedef union _TXMAC_CTL_t {
577 u32 value;
578 struct {
579#ifdef _BIT_FIELDS_HTOL
580 u32 unused:24; /* bits 8-31 */
581 u32 cklseg_diable:1; /* bit 7 */
582 u32 ckbcnt_disable:1; /* bit 6 */
583 u32 cksegnum:1; /* bit 5 */
584 u32 async_disable:1; /* bit 4 */
585 u32 fc_disable:1; /* bit 3 */
586 u32 mcif_disable:1; /* bit 2 */
587 u32 mif_disable:1; /* bit 1 */
588 u32 txmac_en:1; /* bit 0 */
589#else
590 u32 txmac_en:1; /* bit 0 */
591 u32 mif_disable:1; /* bit 1 mac interface */
592 u32 mcif_disable:1; /* bit 2 mem. contr. interface */
593 u32 fc_disable:1; /* bit 3 */
594 u32 async_disable:1; /* bit 4 */
595 u32 cksegnum:1; /* bit 5 */
596 u32 ckbcnt_disable:1; /* bit 6 */
597 u32 cklseg_diable:1; /* bit 7 */
598 u32 unused:24; /* bits 8-31 */
599#endif
600 } bits;
601} TXMAC_CTL_t, *PTXMAC_CTL_t;
602 553
603/* 554/*
604 * structure for shadow pointer reg in txmac address map 555 * structure for shadow pointer reg in txmac address map
@@ -612,23 +563,12 @@ typedef union _TXMAC_CTL_t {
612/* 563/*
613 * structure for error count reg in txmac address map 564 * structure for error count reg in txmac address map
614 * located at address 0x3008 565 * located at address 0x3008
566 *
567 * 31-12: unused
568 * 11-8: reserved
569 * 7-4: txq_underrun
570 * 3-0: fifo_underrun
615 */ 571 */
616typedef union _TXMAC_ERR_CNT_t {
617 u32 value;
618 struct {
619#ifdef _BIT_FIELDS_HTOL
620 u32 unused:20; /* bits 12-31 */
621 u32 reserved:4; /* bits 8-11 */
622 u32 txq_underrun:4; /* bits 4-7 */
623 u32 fifo_underrun:4; /* bits 0-3 */
624#else
625 u32 fifo_underrun:4; /* bits 0-3 */
626 u32 txq_underrun:4; /* bits 4-7 */
627 u32 reserved:4; /* bits 8-11 */
628 u32 unused:20; /* bits 12-31 */
629#endif
630 } bits;
631} TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t;
632 572
633/* 573/*
634 * structure for max fill reg in txmac address map 574 * structure for max fill reg in txmac address map
@@ -657,64 +597,32 @@ typedef union _TXMAC_ERR_CNT_t {
657/* 597/*
658 * structure for error reg in txmac address map 598 * structure for error reg in txmac address map
659 * located at address 0x3018 599 * located at address 0x3018
600 *
601 * 31-9: unused
602 * 8: fifo_underrun
603 * 7-6: unused
604 * 5: ctrl2_err
605 * 4: txq_underrun
606 * 3: bcnt_err
607 * 2: lseg_err
608 * 1: segnum_err
609 * 0: seg0_err
660 */ 610 */
661typedef union _TXMAC_ERR_t {
662 u32 value;
663 struct {
664#ifdef _BIT_FIELDS_HTOL
665 u32 unused2:23; /* bits 9-31 */
666 u32 fifo_underrun:1; /* bit 8 */
667 u32 unused1:2; /* bits 6-7 */
668 u32 ctrl2_err:1; /* bit 5 */
669 u32 txq_underrun:1; /* bit 4 */
670 u32 bcnt_err:1; /* bit 3 */
671 u32 lseg_err:1; /* bit 2 */
672 u32 segnum_err:1; /* bit 1 */
673 u32 seg0_err:1; /* bit 0 */
674#else
675 u32 seg0_err:1; /* bit 0 */
676 u32 segnum_err:1; /* bit 1 */
677 u32 lseg_err:1; /* bit 2 */
678 u32 bcnt_err:1; /* bit 3 */
679 u32 txq_underrun:1; /* bit 4 */
680 u32 ctrl2_err:1; /* bit 5 */
681 u32 unused1:2; /* bits 6-7 */
682 u32 fifo_underrun:1; /* bit 8 */
683 u32 unused2:23; /* bits 9-31 */
684#endif
685 } bits;
686} TXMAC_ERR_t, *PTXMAC_ERR_t;
687 611
688/* 612/*
689 * structure for error interrupt reg in txmac address map 613 * structure for error interrupt reg in txmac address map
690 * located at address 0x301C 614 * located at address 0x301C
615 *
616 * 31-9: unused
617 * 8: fifo_underrun
618 * 7-6: unused
619 * 5: ctrl2_err
620 * 4: txq_underrun
621 * 3: bcnt_err
622 * 2: lseg_err
623 * 1: segnum_err
624 * 0: seg0_err
691 */ 625 */
692typedef union _TXMAC_ERR_INT_t {
693 u32 value;
694 struct {
695#ifdef _BIT_FIELDS_HTOL
696 u32 unused2:23; /* bits 9-31 */
697 u32 fifo_underrun:1; /* bit 8 */
698 u32 unused1:2; /* bits 6-7 */
699 u32 ctrl2_err:1; /* bit 5 */
700 u32 txq_underrun:1; /* bit 4 */
701 u32 bcnt_err:1; /* bit 3 */
702 u32 lseg_err:1; /* bit 2 */
703 u32 segnum_err:1; /* bit 1 */
704 u32 seg0_err:1; /* bit 0 */
705#else
706 u32 seg0_err:1; /* bit 0 */
707 u32 segnum_err:1; /* bit 1 */
708 u32 lseg_err:1; /* bit 2 */
709 u32 bcnt_err:1; /* bit 3 */
710 u32 txq_underrun:1; /* bit 4 */
711 u32 ctrl2_err:1; /* bit 5 */
712 u32 unused1:2; /* bits 6-7 */
713 u32 fifo_underrun:1; /* bit 8 */
714 u32 unused2:23; /* bits 9-31 */
715#endif
716 } bits;
717} TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t;
718 626
719/* 627/*
720 * structure for error interrupt reg in txmac address map 628 * structure for error interrupt reg in txmac address map
@@ -728,17 +636,17 @@ typedef union _TXMAC_ERR_INT_t {
728/* 636/*
729 * Tx MAC Module of JAGCore Address Mapping 637 * Tx MAC Module of JAGCore Address Mapping
730 */ 638 */
731typedef struct _TXMAC_t { /* Location: */ 639struct txmac_regs { /* Location: */
732 TXMAC_CTL_t ctl; /* 0x3000 */ 640 u32 ctl; /* 0x3000 */
733 u32 shadow_ptr; /* 0x3004 */ 641 u32 shadow_ptr; /* 0x3004 */
734 TXMAC_ERR_CNT_t err_cnt; /* 0x3008 */ 642 u32 err_cnt; /* 0x3008 */
735 u32 max_fill; /* 0x300C */ 643 u32 max_fill; /* 0x300C */
736 u32 cf_param; /* 0x3010 */ 644 u32 cf_param; /* 0x3010 */
737 u32 tx_test; /* 0x3014 */ 645 u32 tx_test; /* 0x3014 */
738 TXMAC_ERR_t err; /* 0x3018 */ 646 u32 err; /* 0x3018 */
739 TXMAC_ERR_INT_t err_int; /* 0x301C */ 647 u32 err_int; /* 0x301C */
740 u32 bp_ctrl; /* 0x3020 */ 648 u32 bp_ctrl; /* 0x3020 */
741} TXMAC_t, *PTXMAC_t; 649};
742 650
743/* END OF TXMAC REGISTER ADDRESS MAP */ 651/* END OF TXMAC REGISTER ADDRESS MAP */
744 652
@@ -747,106 +655,47 @@ typedef struct _TXMAC_t { /* Location: */
747/* 655/*
748 * structure for rxmac control reg in rxmac address map 656 * structure for rxmac control reg in rxmac address map
749 * located at address 0x4000 657 * located at address 0x4000
658 *
659 * 31-7: reserved
660 * 6: rxmac_int_disable
661 * 5: async_disable
662 * 4: mif_disable
663 * 3: wol_disable
664 * 2: pkt_filter_disable
665 * 1: mcif_disable
666 * 0: rxmac_en
750 */ 667 */
751typedef union _RXMAC_CTRL_t {
752 u32 value;
753 struct {
754#ifdef _BIT_FIELDS_HTOL
755 u32 reserved:25; /* bits 7-31 */
756 u32 rxmac_int_disable:1; /* bit 6 */
757 u32 async_disable:1; /* bit 5 */
758 u32 mif_disable:1; /* bit 4 */
759 u32 wol_disable:1; /* bit 3 */
760 u32 pkt_filter_disable:1; /* bit 2 */
761 u32 mcif_disable:1; /* bit 1 */
762 u32 rxmac_en:1; /* bit 0 */
763#else
764 u32 rxmac_en:1; /* bit 0 */
765 u32 mcif_disable:1; /* bit 1 */
766 u32 pkt_filter_disable:1; /* bit 2 */
767 u32 wol_disable:1; /* bit 3 */
768 u32 mif_disable:1; /* bit 4 */
769 u32 async_disable:1; /* bit 5 */
770 u32 rxmac_int_disable:1; /* bit 6 */
771 u32 reserved:25; /* bits 7-31 */
772#endif
773 } bits;
774} RXMAC_CTRL_t, *PRXMAC_CTRL_t;
775 668
776/* 669/*
777 * structure for Wake On Lan Control and CRC 0 reg in rxmac address map 670 * structure for Wake On Lan Control and CRC 0 reg in rxmac address map
778 * located at address 0x4004 671 * located at address 0x4004
672 * 31-16: crc
673 * 15-12: reserved
674 * 11: ignore_pp
675 * 10: ignore_mp
676 * 9: clr_intr
677 * 8: ignore_link_chg
678 * 7: ignore_uni
679 * 6: ignore_multi
680 * 5: ignore_broad
681 * 4-0: valid_crc 4-0
779 */ 682 */
780typedef union _RXMAC_WOL_CTL_CRC0_t {
781 u32 value;
782 struct {
783#ifdef _BIT_FIELDS_HTOL
784 u32 crc0:16; /* bits 16-31 */
785 u32 reserve:4; /* bits 12-15 */
786 u32 ignore_pp:1; /* bit 11 */
787 u32 ignore_mp:1; /* bit 10 */
788 u32 clr_intr:1; /* bit 9 */
789 u32 ignore_link_chg:1; /* bit 8 */
790 u32 ignore_uni:1; /* bit 7 */
791 u32 ignore_multi:1; /* bit 6 */
792 u32 ignore_broad:1; /* bit 5 */
793 u32 valid_crc4:1; /* bit 4 */
794 u32 valid_crc3:1; /* bit 3 */
795 u32 valid_crc2:1; /* bit 2 */
796 u32 valid_crc1:1; /* bit 1 */
797 u32 valid_crc0:1; /* bit 0 */
798#else
799 u32 valid_crc0:1; /* bit 0 */
800 u32 valid_crc1:1; /* bit 1 */
801 u32 valid_crc2:1; /* bit 2 */
802 u32 valid_crc3:1; /* bit 3 */
803 u32 valid_crc4:1; /* bit 4 */
804 u32 ignore_broad:1; /* bit 5 */
805 u32 ignore_multi:1; /* bit 6 */
806 u32 ignore_uni:1; /* bit 7 */
807 u32 ignore_link_chg:1; /* bit 8 */
808 u32 clr_intr:1; /* bit 9 */
809 u32 ignore_mp:1; /* bit 10 */
810 u32 ignore_pp:1; /* bit 11 */
811 u32 reserve:4; /* bits 12-15 */
812 u32 crc0:16; /* bits 16-31 */
813#endif
814 } bits;
815} RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t;
816 683
817/* 684/*
818 * structure for CRC 1 and CRC 2 reg in rxmac address map 685 * structure for CRC 1 and CRC 2 reg in rxmac address map
819 * located at address 0x4008 686 * located at address 0x4008
687 *
688 * 31-16: crc2
689 * 15-0: crc1
820 */ 690 */
821typedef union _RXMAC_WOL_CRC12_t {
822 u32 value;
823 struct {
824#ifdef _BIT_FIELDS_HTOL
825 u32 crc2:16; /* bits 16-31 */
826 u32 crc1:16; /* bits 0-15 */
827#else
828 u32 crc1:16; /* bits 0-15 */
829 u32 crc2:16; /* bits 16-31 */
830#endif
831 } bits;
832} RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t;
833 691
834/* 692/*
835 * structure for CRC 3 and CRC 4 reg in rxmac address map 693 * structure for CRC 3 and CRC 4 reg in rxmac address map
836 * located at address 0x400C 694 * located at address 0x400C
695 *
696 * 31-16: crc4
697 * 15-0: crc3
837 */ 698 */
838typedef union _RXMAC_WOL_CRC34_t {
839 u32 value;
840 struct {
841#ifdef _BIT_FIELDS_HTOL
842 u32 crc4:16; /* bits 16-31 */
843 u32 crc3:16; /* bits 0-15 */
844#else
845 u32 crc3:16; /* bits 0-15 */
846 u32 crc4:16; /* bits 16-31 */
847#endif
848 } bits;
849} RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t;
850 699
851/* 700/*
852 * structure for Wake On Lan Source Address Lo reg in rxmac address map 701 * structure for Wake On Lan Source Address Lo reg in rxmac address map
@@ -966,164 +815,84 @@ typedef union _RXMAC_UNI_PF_ADDR3_t {
966/* 815/*
967 * structure for Packet Filter Control reg in rxmac address map 816 * structure for Packet Filter Control reg in rxmac address map
968 * located at address 0x4084 817 * located at address 0x4084
818 *
819 * 31-23: unused
820 * 22-16: min_pkt_size
821 * 15-4: unused
822 * 3: filter_frag_en
823 * 2: filter_uni_en
824 * 1: filter_multi_en
825 * 0: filter_broad_en
969 */ 826 */
970typedef union _RXMAC_PF_CTRL_t {
971 u32 value;
972 struct {
973#ifdef _BIT_FIELDS_HTOL
974 u32 unused2:9; /* bits 23-31 */
975 u32 min_pkt_size:7; /* bits 16-22 */
976 u32 unused1:12; /* bits 4-15 */
977 u32 filter_frag_en:1; /* bit 3 */
978 u32 filter_uni_en:1; /* bit 2 */
979 u32 filter_multi_en:1; /* bit 1 */
980 u32 filter_broad_en:1; /* bit 0 */
981#else
982 u32 filter_broad_en:1; /* bit 0 */
983 u32 filter_multi_en:1; /* bit 1 */
984 u32 filter_uni_en:1; /* bit 2 */
985 u32 filter_frag_en:1; /* bit 3 */
986 u32 unused1:12; /* bits 4-15 */
987 u32 min_pkt_size:7; /* bits 16-22 */
988 u32 unused2:9; /* bits 23-31 */
989#endif
990 } bits;
991} RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t;
992 827
993/* 828/*
994 * structure for Memory Controller Interface Control Max Segment reg in rxmac 829 * structure for Memory Controller Interface Control Max Segment reg in rxmac
995 * address map. Located at address 0x4088 830 * address map. Located at address 0x4088
831 *
832 * 31-10: reserved
833 * 9-2: max_size
834 * 1: fc_en
835 * 0: seg_en
996 */ 836 */
997typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t {
998 u32 value;
999 struct {
1000#ifdef _BIT_FIELDS_HTOL
1001 u32 reserved:22; /* bits 10-31 */
1002 u32 max_size:8; /* bits 2-9 */
1003 u32 fc_en:1; /* bit 1 */
1004 u32 seg_en:1; /* bit 0 */
1005#else
1006 u32 seg_en:1; /* bit 0 */
1007 u32 fc_en:1; /* bit 1 */
1008 u32 max_size:8; /* bits 2-9 */
1009 u32 reserved:22; /* bits 10-31 */
1010#endif
1011 } bits;
1012} RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t;
1013 837
1014/* 838/*
1015 * structure for Memory Controller Interface Water Mark reg in rxmac address 839 * structure for Memory Controller Interface Water Mark reg in rxmac address
1016 * map. Located at address 0x408C 840 * map. Located at address 0x408C
841 *
842 * 31-26: unused
843 * 25-16: mark_hi
844 * 15-10: unused
845 * 9-0: mark_lo
1017 */ 846 */
1018typedef union _RXMAC_MCIF_WATER_MARK_t {
1019 u32 value;
1020 struct {
1021#ifdef _BIT_FIELDS_HTOL
1022 u32 reserved2:6; /* bits 26-31 */
1023 u32 mark_hi:10; /* bits 16-25 */
1024 u32 reserved1:6; /* bits 10-15 */
1025 u32 mark_lo:10; /* bits 0-9 */
1026#else
1027 u32 mark_lo:10; /* bits 0-9 */
1028 u32 reserved1:6; /* bits 10-15 */
1029 u32 mark_hi:10; /* bits 16-25 */
1030 u32 reserved2:6; /* bits 26-31 */
1031#endif
1032 } bits;
1033} RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t;
1034 847
1035/* 848/*
1036 * structure for Rx Queue Dialog reg in rxmac address map. 849 * structure for Rx Queue Dialog reg in rxmac address map.
1037 * located at address 0x4090 850 * located at address 0x4090
851 *
852 * 31-26: reserved
853 * 25-16: rd_ptr
854 * 15-10: reserved
855 * 9-0: wr_ptr
1038 */ 856 */
1039typedef union _RXMAC_RXQ_DIAG_t {
1040 u32 value;
1041 struct {
1042#ifdef _BIT_FIELDS_HTOL
1043 u32 reserved2:6; /* bits 26-31 */
1044 u32 rd_ptr:10; /* bits 16-25 */
1045 u32 reserved1:6; /* bits 10-15 */
1046 u32 wr_ptr:10; /* bits 0-9 */
1047#else
1048 u32 wr_ptr:10; /* bits 0-9 */
1049 u32 reserved1:6; /* bits 10-15 */
1050 u32 rd_ptr:10; /* bits 16-25 */
1051 u32 reserved2:6; /* bits 26-31 */
1052#endif
1053 } bits;
1054} RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t;
1055 857
1056/* 858/*
1057 * structure for space availiable reg in rxmac address map. 859 * structure for space availiable reg in rxmac address map.
1058 * located at address 0x4094 860 * located at address 0x4094
861 *
862 * 31-17: reserved
863 * 16: space_avail_en
864 * 15-10: reserved
865 * 9-0: space_avail
1059 */ 866 */
1060typedef union _RXMAC_SPACE_AVAIL_t {
1061 u32 value;
1062 struct {
1063#ifdef _BIT_FIELDS_HTOL
1064 u32 reserved2:15; /* bits 17-31 */
1065 u32 space_avail_en:1; /* bit 16 */
1066 u32 reserved1:6; /* bits 10-15 */
1067 u32 space_avail:10; /* bits 0-9 */
1068#else
1069 u32 space_avail:10; /* bits 0-9 */
1070 u32 reserved1:6; /* bits 10-15 */
1071 u32 space_avail_en:1; /* bit 16 */
1072 u32 reserved2:15; /* bits 17-31 */
1073#endif
1074 } bits;
1075} RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t;
1076 867
1077/* 868/*
1078 * structure for management interface reg in rxmac address map. 869 * structure for management interface reg in rxmac address map.
1079 * located at address 0x4098 870 * located at address 0x4098
871 *
872 * 31-18: reserved
873 * 17: drop_pkt_en
874 * 16-0: drop_pkt_mask
1080 */ 875 */
1081typedef union _RXMAC_MIF_CTL_t {
1082 u32 value;
1083 struct {
1084#ifdef _BIT_FIELDS_HTOL
1085 u32 reserve:14; /* bits 18-31 */
1086 u32 drop_pkt_en:1; /* bit 17 */
1087 u32 drop_pkt_mask:17; /* bits 0-16 */
1088#else
1089 u32 drop_pkt_mask:17; /* bits 0-16 */
1090 u32 drop_pkt_en:1; /* bit 17 */
1091 u32 reserve:14; /* bits 18-31 */
1092#endif
1093 } bits;
1094} RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t;
1095 876
1096/* 877/*
1097 * structure for Error reg in rxmac address map. 878 * structure for Error reg in rxmac address map.
1098 * located at address 0x409C 879 * located at address 0x409C
880 *
881 * 31-4: unused
882 * 3: mif
883 * 2: async
884 * 1: pkt_filter
885 * 0: mcif
1099 */ 886 */
1100typedef union _RXMAC_ERROR_REG_t {
1101 u32 value;
1102 struct {
1103#ifdef _BIT_FIELDS_HTOL
1104 u32 reserve:28; /* bits 4-31 */
1105 u32 mif:1; /* bit 3 */
1106 u32 async:1; /* bit 2 */
1107 u32 pkt_filter:1; /* bit 1 */
1108 u32 mcif:1; /* bit 0 */
1109#else
1110 u32 mcif:1; /* bit 0 */
1111 u32 pkt_filter:1; /* bit 1 */
1112 u32 async:1; /* bit 2 */
1113 u32 mif:1; /* bit 3 */
1114 u32 reserve:28; /* bits 4-31 */
1115#endif
1116 } bits;
1117} RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t;
1118 887
1119/* 888/*
1120 * Rx MAC Module of JAGCore Address Mapping 889 * Rx MAC Module of JAGCore Address Mapping
1121 */ 890 */
1122typedef struct _RXMAC_t { /* Location: */ 891typedef struct _RXMAC_t { /* Location: */
1123 RXMAC_CTRL_t ctrl; /* 0x4000 */ 892 u32 ctrl; /* 0x4000 */
1124 RXMAC_WOL_CTL_CRC0_t crc0; /* 0x4004 */ 893 u32 crc0; /* 0x4004 */
1125 RXMAC_WOL_CRC12_t crc12; /* 0x4008 */ 894 u32 crc12; /* 0x4008 */
1126 RXMAC_WOL_CRC34_t crc34; /* 0x400C */ 895 u32 crc34; /* 0x400C */
1127 RXMAC_WOL_SA_LO_t sa_lo; /* 0x4010 */ 896 RXMAC_WOL_SA_LO_t sa_lo; /* 0x4010 */
1128 RXMAC_WOL_SA_HI_t sa_hi; /* 0x4014 */ 897 RXMAC_WOL_SA_HI_t sa_hi; /* 0x4014 */
1129 u32 mask0_word0; /* 0x4018 */ 898 u32 mask0_word0; /* 0x4018 */
@@ -1153,17 +922,17 @@ typedef struct _RXMAC_t { /* Location: */
1153 u32 multi_hash2; /* 0x4078 */ 922 u32 multi_hash2; /* 0x4078 */
1154 u32 multi_hash3; /* 0x407C */ 923 u32 multi_hash3; /* 0x407C */
1155 u32 multi_hash4; /* 0x4080 */ 924 u32 multi_hash4; /* 0x4080 */
1156 RXMAC_PF_CTRL_t pf_ctrl; /* 0x4084 */ 925 u32 pf_ctrl; /* 0x4084 */
1157 RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; /* 0x4088 */ 926 u32 mcif_ctrl_max_seg; /* 0x4088 */
1158 RXMAC_MCIF_WATER_MARK_t mcif_water_mark; /* 0x408C */ 927 u32 mcif_water_mark; /* 0x408C */
1159 RXMAC_RXQ_DIAG_t rxq_diag; /* 0x4090 */ 928 u32 rxq_diag; /* 0x4090 */
1160 RXMAC_SPACE_AVAIL_t space_avail; /* 0x4094 */ 929 u32 space_avail; /* 0x4094 */
1161 930
1162 RXMAC_MIF_CTL_t mif_ctrl; /* 0x4098 */ 931 u32 mif_ctrl; /* 0x4098 */
1163 RXMAC_ERROR_REG_t err_reg; /* 0x409C */ 932 u32 err_reg; /* 0x409C */
1164} RXMAC_t, *PRXMAC_t; 933} RXMAC_t, *PRXMAC_t;
1165 934
1166/* END OF TXMAC REGISTER ADDRESS MAP */ 935/* END OF RXMAC REGISTER ADDRESS MAP */
1167 936
1168 937
1169/* START OF MAC REGISTER ADDRESS MAP */ 938/* START OF MAC REGISTER ADDRESS MAP */
@@ -1337,37 +1106,19 @@ typedef struct _RXMAC_t { /* Location: */
1337/* 1106/*
1338 * structure for Interface Status reg in mac address map. 1107 * structure for Interface Status reg in mac address map.
1339 * located at address 0x503C 1108 * located at address 0x503C
1109 *
1110 * 31-10: reserved
1111 * 9: excess_defer
1112 * 8: clash
1113 * 7: phy_jabber
1114 * 6: phy_link_ok
1115 * 5: phy_full_duplex
1116 * 4: phy_speed
1117 * 3: pe100x_link_fail
1118 * 2: pe10t_loss_carrier
1119 * 1: pe10t_sqe_error
1120 * 0: pe10t_jabber
1340 */ 1121 */
1341typedef union _MAC_IF_STAT_t {
1342 u32 value;
1343 struct {
1344#ifdef _BIT_FIELDS_HTOL
1345 u32 reserved:22; /* bits 10-31 */
1346 u32 excess_defer:1; /* bit 9 */
1347 u32 clash:1; /* bit 8 */
1348 u32 phy_jabber:1; /* bit 7 */
1349 u32 phy_link_ok:1; /* bit 6 */
1350 u32 phy_full_duplex:1; /* bit 5 */
1351 u32 phy_speed:1; /* bit 4 */
1352 u32 pe100x_link_fail:1; /* bit 3 */
1353 u32 pe10t_loss_carrie:1; /* bit 2 */
1354 u32 pe10t_sqe_error:1; /* bit 1 */
1355 u32 pe10t_jabber:1; /* bit 0 */
1356#else
1357 u32 pe10t_jabber:1; /* bit 0 */
1358 u32 pe10t_sqe_error:1; /* bit 1 */
1359 u32 pe10t_loss_carrie:1; /* bit 2 */
1360 u32 pe100x_link_fail:1; /* bit 3 */
1361 u32 phy_speed:1; /* bit 4 */
1362 u32 phy_full_duplex:1; /* bit 5 */
1363 u32 phy_link_ok:1; /* bit 6 */
1364 u32 phy_jabber:1; /* bit 7 */
1365 u32 clash:1; /* bit 8 */
1366 u32 excess_defer:1; /* bit 9 */
1367 u32 reserved:22; /* bits 10-31 */
1368#endif
1369 } bits;
1370} MAC_IF_STAT_t, *PMAC_IF_STAT_t;
1371 1122
1372/* 1123/*
1373 * structure for Mac Station Address, Part 1 reg in mac address map. 1124 * structure for Mac Station Address, Part 1 reg in mac address map.
@@ -1428,7 +1179,7 @@ typedef struct _MAC_t { /* Location: */
1428 u32 mii_mgmt_stat; /* 0x5030 */ 1179 u32 mii_mgmt_stat; /* 0x5030 */
1429 u32 mii_mgmt_indicator; /* 0x5034 */ 1180 u32 mii_mgmt_indicator; /* 0x5034 */
1430 u32 if_ctrl; /* 0x5038 */ 1181 u32 if_ctrl; /* 0x5038 */
1431 MAC_IF_STAT_t if_stat; /* 0x503C */ 1182 u32 if_stat; /* 0x503C */
1432 MAC_STATION_ADDR1_t station_addr_1; /* 0x5040 */ 1183 MAC_STATION_ADDR1_t station_addr_1; /* 0x5040 */
1433 MAC_STATION_ADDR2_t station_addr_2; /* 0x5044 */ 1184 MAC_STATION_ADDR2_t station_addr_2; /* 0x5044 */
1434} MAC_t, *PMAC_t; 1185} MAC_t, *PMAC_t;
@@ -1498,8 +1249,9 @@ typedef struct _MAC_t { /* Location: */
1498/* 1249/*
1499 * MAC STATS Module of JAGCore Address Mapping 1250 * MAC STATS Module of JAGCore Address Mapping
1500 */ 1251 */
1501typedef struct _MAC_STAT_t { /* Location: */ 1252struct macstat_regs
1502 u32 pad[32]; /* 0x6000 - 607C */ 1253{ /* Location: */
1254 u32 pad[32]; /* 0x6000 - 607C */
1503 1255
1504 /* Tx/Rx 0-64 Byte Frame Counter */ 1256 /* Tx/Rx 0-64 Byte Frame Counter */
1505 u32 TR64; /* 0x6080 */ 1257 u32 TR64; /* 0x6080 */
@@ -1644,7 +1396,7 @@ typedef struct _MAC_STAT_t { /* Location: */
1644 1396
1645 /* Carry Register Two Mask Register */ 1397 /* Carry Register Two Mask Register */
1646 u32 Carry2M; /* 0x613C */ 1398 u32 Carry2M; /* 0x613C */
1647} MAC_STAT_t, *PMAC_STAT_t; 1399};
1648 1400
1649/* END OF MAC STAT REGISTER ADDRESS MAP */ 1401/* END OF MAC STAT REGISTER ADDRESS MAP */
1650 1402
@@ -1682,70 +1434,49 @@ typedef struct _MAC_STAT_t { /* Location: */
1682/* 1434/*
1683 * Memory Control Module of JAGCore Address Mapping 1435 * Memory Control Module of JAGCore Address Mapping
1684 */ 1436 */
1685typedef struct _MMC_t { /* Location: */ 1437struct mmc_regs { /* Location: */
1686 u32 mmc_ctrl; /* 0x7000 */ 1438 u32 mmc_ctrl; /* 0x7000 */
1687 u32 sram_access; /* 0x7004 */ 1439 u32 sram_access; /* 0x7004 */
1688 u32 sram_word1; /* 0x7008 */ 1440 u32 sram_word1; /* 0x7008 */
1689 u32 sram_word2; /* 0x700C */ 1441 u32 sram_word2; /* 0x700C */
1690 u32 sram_word3; /* 0x7010 */ 1442 u32 sram_word3; /* 0x7010 */
1691 u32 sram_word4; /* 0x7014 */ 1443 u32 sram_word4; /* 0x7014 */
1692} MMC_t, *PMMC_t; 1444};
1693 1445
1694/* END OF MMC REGISTER ADDRESS MAP */ 1446/* END OF MMC REGISTER ADDRESS MAP */
1695 1447
1696 1448
1697/* START OF EXP ROM REGISTER ADDRESS MAP */
1698
1699/*
1700 * Expansion ROM Module of JAGCore Address Mapping
1701 */
1702
1703/* Take this out until it is not empty */
1704#if 0
1705typedef struct _EXP_ROM_t {
1706
1707} EXP_ROM_t, *PEXP_ROM_t;
1708#endif
1709
1710/* END OF EXP ROM REGISTER ADDRESS MAP */
1711
1712
1713/* 1449/*
1714 * JAGCore Address Mapping 1450 * JAGCore Address Mapping
1715 */ 1451 */
1716typedef struct _ADDRESS_MAP_t { 1452typedef struct _ADDRESS_MAP_t {
1717 GLOBAL_t global; 1453 struct global_regs global;
1718 /* unused section of global address map */ 1454 /* unused section of global address map */
1719 u8 unused_global[4096 - sizeof(GLOBAL_t)]; 1455 u8 unused_global[4096 - sizeof(struct global_regs)];
1720 TXDMA_t txdma; 1456 struct txdma_regs txdma;
1721 /* unused section of txdma address map */ 1457 /* unused section of txdma address map */
1722 u8 unused_txdma[4096 - sizeof(TXDMA_t)]; 1458 u8 unused_txdma[4096 - sizeof(struct txdma_regs)];
1723 RXDMA_t rxdma; 1459 struct rxdma_regs rxdma;
1724 /* unused section of rxdma address map */ 1460 /* unused section of rxdma address map */
1725 u8 unused_rxdma[4096 - sizeof(RXDMA_t)]; 1461 u8 unused_rxdma[4096 - sizeof(struct rxdma_regs)];
1726 TXMAC_t txmac; 1462 struct txmac_regs txmac;
1727 /* unused section of txmac address map */ 1463 /* unused section of txmac address map */
1728 u8 unused_txmac[4096 - sizeof(TXMAC_t)]; 1464 u8 unused_txmac[4096 - sizeof(struct txmac_regs)];
1729 RXMAC_t rxmac; 1465 RXMAC_t rxmac;
1730 /* unused section of rxmac address map */ 1466 /* unused section of rxmac address map */
1731 u8 unused_rxmac[4096 - sizeof(RXMAC_t)]; 1467 u8 unused_rxmac[4096 - sizeof(RXMAC_t)];
1732 MAC_t mac; 1468 MAC_t mac;
1733 /* unused section of mac address map */ 1469 /* unused section of mac address map */
1734 u8 unused_mac[4096 - sizeof(MAC_t)]; 1470 u8 unused_mac[4096 - sizeof(MAC_t)];
1735 MAC_STAT_t macStat; 1471 struct macstat_regs macstat;
1736 /* unused section of mac stat address map */ 1472 /* unused section of mac stat address map */
1737 u8 unused_mac_stat[4096 - sizeof(MAC_STAT_t)]; 1473 u8 unused_mac_stat[4096 - sizeof(struct macstat_regs)];
1738 MMC_t mmc; 1474 struct mmc_regs mmc;
1739 /* unused section of mmc address map */ 1475 /* unused section of mmc address map */
1740 u8 unused_mmc[4096 - sizeof(MMC_t)]; 1476 u8 unused_mmc[4096 - sizeof(struct mmc_regs)];
1741 /* unused section of address map */ 1477 /* unused section of address map */
1742 u8 unused_[1015808]; 1478 u8 unused_[1015808];
1743 1479
1744/* Take this out until it is not empty */
1745#if 0
1746 EXP_ROM_t exp_rom;
1747#endif
1748
1749 u8 unused_exp_rom[4096]; /* MGS-size TBD */ 1480 u8 unused_exp_rom[4096]; /* MGS-size TBD */
1750 u8 unused__[524288]; /* unused section of address map */ 1481 u8 unused__[524288]; /* unused section of address map */
1751} ADDRESS_MAP_t, *PADDRESS_MAP_t; 1482} ADDRESS_MAP_t, *PADDRESS_MAP_t;
diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c
index bcca1f86f516..3ca253672ba1 100644
--- a/drivers/staging/et131x/et1310_eeprom.c
+++ b/drivers/staging/et131x/et1310_eeprom.c
@@ -84,17 +84,42 @@
84#include <linux/ioport.h> 84#include <linux/ioport.h>
85 85
86#include "et1310_phy.h" 86#include "et1310_phy.h"
87#include "et1310_pm.h"
88#include "et1310_jagcore.h"
89#include "et1310_eeprom.h"
90
91#include "et131x_adapter.h" 87#include "et131x_adapter.h"
92#include "et131x_initpci.h" 88#include "et131x.h"
93#include "et131x_isr.h"
94
95#include "et1310_tx.h"
96 89
90/*
91 * EEPROM Defines
92 */
97 93
94/* LBCIF Register Groups (addressed via 32-bit offsets) */
95#define LBCIF_DWORD0_GROUP 0xAC
96#define LBCIF_DWORD1_GROUP 0xB0
97
98/* LBCIF Registers (addressed via 8-bit offsets) */
99#define LBCIF_ADDRESS_REGISTER 0xAC
100#define LBCIF_DATA_REGISTER 0xB0
101#define LBCIF_CONTROL_REGISTER 0xB1
102#define LBCIF_STATUS_REGISTER 0xB2
103
104/* LBCIF Control Register Bits */
105#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01
106#define LBCIF_CONTROL_PAGE_WRITE 0x02
107#define LBCIF_CONTROL_EEPROM_RELOAD 0x08
108#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20
109#define LBCIF_CONTROL_I2C_WRITE 0x40
110#define LBCIF_CONTROL_LBCIF_ENABLE 0x80
111
112/* LBCIF Status Register Bits */
113#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01
114#define LBCIF_STATUS_I2C_IDLE 0x02
115#define LBCIF_STATUS_ACK_ERROR 0x04
116#define LBCIF_STATUS_GENERAL_ERROR 0x08
117#define LBCIF_STATUS_CHECKSUM_ERROR 0x40
118#define LBCIF_STATUS_EEPROM_PRESENT 0x80
119
120/* Miscellaneous Constraints */
121#define MAX_NUM_REGISTER_POLLS 1000
122#define MAX_NUM_WRITE_RETRIES 2
98 123
99static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status) 124static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status)
100{ 125{
diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h
deleted file mode 100644
index 6a6c6a632a8f..000000000000
--- a/drivers/staging/et131x/et1310_eeprom.h
+++ /dev/null
@@ -1,103 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM
12 * access routines
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef __ET1310_EEPROM_H__
60#define __ET1310_EEPROM_H__
61
62#include "et1310_address_map.h"
63
64/*
65 * EEPROM Defines
66 */
67
68/* LBCIF Register Groups (addressed via 32-bit offsets) */
69#define LBCIF_DWORD0_GROUP 0xAC
70#define LBCIF_DWORD1_GROUP 0xB0
71
72/* LBCIF Registers (addressed via 8-bit offsets) */
73#define LBCIF_ADDRESS_REGISTER 0xAC
74#define LBCIF_DATA_REGISTER 0xB0
75#define LBCIF_CONTROL_REGISTER 0xB1
76#define LBCIF_STATUS_REGISTER 0xB2
77
78/* LBCIF Control Register Bits */
79#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01
80#define LBCIF_CONTROL_PAGE_WRITE 0x02
81#define LBCIF_CONTROL_EEPROM_RELOAD 0x08
82#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20
83#define LBCIF_CONTROL_I2C_WRITE 0x40
84#define LBCIF_CONTROL_LBCIF_ENABLE 0x80
85
86/* LBCIF Status Register Bits */
87#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01
88#define LBCIF_STATUS_I2C_IDLE 0x02
89#define LBCIF_STATUS_ACK_ERROR 0x04
90#define LBCIF_STATUS_GENERAL_ERROR 0x08
91#define LBCIF_STATUS_CHECKSUM_ERROR 0x40
92#define LBCIF_STATUS_EEPROM_PRESENT 0x80
93
94/* Miscellaneous Constraints */
95#define MAX_NUM_REGISTER_POLLS 1000
96#define MAX_NUM_WRITE_RETRIES 2
97
98/* Forward declaration of the private adapter structure */
99struct et131x_adapter;
100
101int et131x_init_eeprom(struct et131x_adapter *etdev);
102
103#endif /* _ET1310_EEPROM_H_ */
diff --git a/drivers/staging/et131x/et1310_jagcore.h b/drivers/staging/et131x/et1310_jagcore.h
deleted file mode 100644
index 0807a01d88ae..000000000000
--- a/drivers/staging/et131x/et1310_jagcore.h
+++ /dev/null
@@ -1,94 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to
12 * the JAGCore
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef __ET1310_JAGCORE_H__
60#define __ET1310_JAGCORE_H__
61
62#include "et1310_address_map.h"
63
64
65#define INTERNAL_MEM_SIZE 0x400 /* 1024 of internal memory */
66#define INTERNAL_MEM_RX_OFFSET 0x1FF /* 50% Tx, 50% Rx */
67
68/*
69 * For interrupts, normal running is:
70 * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt,
71 * watchdog_interrupt & txdma_xfer_done
72 *
73 * In both cases, when flow control is enabled for either Tx or bi-direction,
74 * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the
75 * buffer rings are running low.
76 */
77#define INT_MASK_DISABLE 0xffffffff
78
79/* NOTE: Masking out MAC_STAT Interrupt for now...
80 * #define INT_MASK_ENABLE 0xfff6bf17
81 * #define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7
82 */
83#define INT_MASK_ENABLE 0xfffebf17
84#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7
85
86/* Forward declaration of the private adapter structure */
87struct et131x_adapter;
88
89void ConfigGlobalRegs(struct et131x_adapter *pAdapter);
90void ConfigMMCRegs(struct et131x_adapter *pAdapter);
91void et131x_enable_interrupts(struct et131x_adapter *adapter);
92void et131x_disable_interrupts(struct et131x_adapter *adapter);
93
94#endif /* __ET1310_JAGCORE_H__ */
diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c
index b8a1f2037314..a292b1edc414 100644
--- a/drivers/staging/et131x/et1310_mac.c
+++ b/drivers/staging/et131x/et1310_mac.c
@@ -85,12 +85,19 @@
85#include <linux/crc32.h> 85#include <linux/crc32.h>
86 86
87#include "et1310_phy.h" 87#include "et1310_phy.h"
88#include "et1310_pm.h"
89#include "et1310_jagcore.h"
90#include "et1310_mac.h"
91
92#include "et131x_adapter.h" 88#include "et131x_adapter.h"
93#include "et131x_initpci.h" 89#include "et131x.h"
90
91
92#define COUNTER_WRAP_28_BIT 0x10000000
93#define COUNTER_WRAP_22_BIT 0x400000
94#define COUNTER_WRAP_16_BIT 0x10000
95#define COUNTER_WRAP_12_BIT 0x1000
96
97#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1)
98#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1)
99#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
100#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
94 101
95/** 102/**
96 * ConfigMacRegs1 - Initialize the first part of MAC regs 103 * ConfigMacRegs1 - Initialize the first part of MAC regs
@@ -163,9 +170,9 @@ void ConfigMACRegs2(struct et131x_adapter *etdev)
163 u32 cfg1; 170 u32 cfg1;
164 u32 cfg2; 171 u32 cfg2;
165 u32 ifctrl; 172 u32 ifctrl;
166 TXMAC_CTL_t ctl; 173 u32 ctl;
167 174
168 ctl.value = readl(&etdev->regs->txmac.ctl.value); 175 ctl = readl(&etdev->regs->txmac.ctl);
169 cfg1 = readl(&pMac->cfg1); 176 cfg1 = readl(&pMac->cfg1);
170 cfg2 = readl(&pMac->cfg2); 177 cfg2 = readl(&pMac->cfg2);
171 ifctrl = readl(&pMac->if_ctrl); 178 ifctrl = readl(&pMac->if_ctrl);
@@ -219,9 +226,8 @@ void ConfigMACRegs2(struct et131x_adapter *etdev)
219 } 226 }
220 227
221 /* Enable TXMAC */ 228 /* Enable TXMAC */
222 ctl.bits.txmac_en = 0x1; 229 ctl |= 0x05; /* TX mac enable, FC disable */
223 ctl.bits.fc_disable = 0x1; 230 writel(ctl, &etdev->regs->txmac.ctl);
224 writel(ctl.value, &etdev->regs->txmac.ctl.value);
225 231
226 /* Ready to start the RXDMA/TXDMA engine */ 232 /* Ready to start the RXDMA/TXDMA engine */
227 if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) { 233 if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) {
@@ -235,15 +241,15 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
235 struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac; 241 struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac;
236 RXMAC_WOL_SA_LO_t sa_lo; 242 RXMAC_WOL_SA_LO_t sa_lo;
237 RXMAC_WOL_SA_HI_t sa_hi; 243 RXMAC_WOL_SA_HI_t sa_hi;
238 RXMAC_PF_CTRL_t pf_ctrl = { 0 }; 244 u32 pf_ctrl = 0;
239 245
240 /* Disable the MAC while it is being configured (also disable WOL) */ 246 /* Disable the MAC while it is being configured (also disable WOL) */
241 writel(0x8, &pRxMac->ctrl.value); 247 writel(0x8, &pRxMac->ctrl);
242 248
243 /* Initialize WOL to disabled. */ 249 /* Initialize WOL to disabled. */
244 writel(0, &pRxMac->crc0.value); 250 writel(0, &pRxMac->crc0);
245 writel(0, &pRxMac->crc12.value); 251 writel(0, &pRxMac->crc12);
246 writel(0, &pRxMac->crc34.value); 252 writel(0, &pRxMac->crc34);
247 253
248 /* We need to set the WOL mask0 - mask4 next. We initialize it to 254 /* We need to set the WOL mask0 - mask4 next. We initialize it to
249 * its default Values of 0x00000000 because there are not WOL masks 255 * its default Values of 0x00000000 because there are not WOL masks
@@ -286,12 +292,12 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
286 writel(sa_hi.value, &pRxMac->sa_hi.value); 292 writel(sa_hi.value, &pRxMac->sa_hi.value);
287 293
288 /* Disable all Packet Filtering */ 294 /* Disable all Packet Filtering */
289 writel(0, &pRxMac->pf_ctrl.value); 295 writel(0, &pRxMac->pf_ctrl);
290 296
291 /* Let's initialize the Unicast Packet filtering address */ 297 /* Let's initialize the Unicast Packet filtering address */
292 if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) { 298 if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) {
293 SetupDeviceForUnicast(etdev); 299 SetupDeviceForUnicast(etdev);
294 pf_ctrl.bits.filter_uni_en = 1; 300 pf_ctrl |= 4; /* Unicast filter */
295 } else { 301 } else {
296 writel(0, &pRxMac->uni_pf_addr1.value); 302 writel(0, &pRxMac->uni_pf_addr1.value);
297 writel(0, &pRxMac->uni_pf_addr2.value); 303 writel(0, &pRxMac->uni_pf_addr2.value);
@@ -299,20 +305,16 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
299 } 305 }
300 306
301 /* Let's initialize the Multicast hash */ 307 /* Let's initialize the Multicast hash */
302 if (etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) { 308 if (!(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
303 pf_ctrl.bits.filter_multi_en = 0; 309 pf_ctrl |= 2; /* Multicast filter */
304 } else {
305 pf_ctrl.bits.filter_multi_en = 1;
306 SetupDeviceForMulticast(etdev); 310 SetupDeviceForMulticast(etdev);
307 } 311 }
308 312
309 /* Runt packet filtering. Didn't work in version A silicon. */ 313 /* Runt packet filtering. Didn't work in version A silicon. */
310 pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4; 314 pf_ctrl |= (NIC_MIN_PACKET_SIZE + 4) << 16;
311 pf_ctrl.bits.filter_frag_en = 1; 315 pf_ctrl |= 8; /* Fragment filter */
312
313 if (etdev->RegistryJumboPacket > 8192) {
314 RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;
315 316
317 if (etdev->RegistryJumboPacket > 8192)
316 /* In order to transmit jumbo packets greater than 8k, the 318 /* In order to transmit jumbo packets greater than 8k, the
317 * FIFO between RxMAC and RxDMA needs to be reduced in size 319 * FIFO between RxMAC and RxDMA needs to be reduced in size
318 * to (16k - Jumbo packet size). In order to implement this, 320 * to (16k - Jumbo packet size). In order to implement this,
@@ -320,25 +322,21 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
320 * packets down into segments which are (max_size * 16). In 322 * packets down into segments which are (max_size * 16). In
321 * this case we selected 256 bytes, since this is the size of 323 * this case we selected 256 bytes, since this is the size of
322 * the PCI-Express TLP's that the 1310 uses. 324 * the PCI-Express TLP's that the 1310 uses.
325 *
326 * seg_en on, fc_en off, size 0x10
323 */ 327 */
324 mcif_ctrl_max_seg.bits.seg_en = 0x1; 328 writel(0x41, &pRxMac->mcif_ctrl_max_seg);
325 mcif_ctrl_max_seg.bits.fc_en = 0x0; 329 else
326 mcif_ctrl_max_seg.bits.max_size = 0x10; 330 writel(0, &pRxMac->mcif_ctrl_max_seg);
327
328 writel(mcif_ctrl_max_seg.value,
329 &pRxMac->mcif_ctrl_max_seg.value);
330 } else {
331 writel(0, &pRxMac->mcif_ctrl_max_seg.value);
332 }
333 331
334 /* Initialize the MCIF water marks */ 332 /* Initialize the MCIF water marks */
335 writel(0, &pRxMac->mcif_water_mark.value); 333 writel(0, &pRxMac->mcif_water_mark);
336 334
337 /* Initialize the MIF control */ 335 /* Initialize the MIF control */
338 writel(0, &pRxMac->mif_ctrl.value); 336 writel(0, &pRxMac->mif_ctrl);
339 337
340 /* Initialize the Space Available Register */ 338 /* Initialize the Space Available Register */
341 writel(0, &pRxMac->space_avail.value); 339 writel(0, &pRxMac->space_avail);
342 340
343 /* Initialize the the mif_ctrl register 341 /* Initialize the the mif_ctrl register
344 * bit 3: Receive code error. One or more nibbles were signaled as 342 * bit 3: Receive code error. One or more nibbles were signaled as
@@ -354,9 +352,9 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
354 * bit 17: Drop packet enable 352 * bit 17: Drop packet enable
355 */ 353 */
356 if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS) 354 if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS)
357 writel(0x30038, &pRxMac->mif_ctrl.value); 355 writel(0x30038, &pRxMac->mif_ctrl);
358 else 356 else
359 writel(0x30030, &pRxMac->mif_ctrl.value); 357 writel(0x30030, &pRxMac->mif_ctrl);
360 358
361 /* Finally we initialize RxMac to be enabled & WOL disabled. Packet 359 /* Finally we initialize RxMac to be enabled & WOL disabled. Packet
362 * filter is always enabled since it is where the runt packets are 360 * filter is always enabled since it is where the runt packets are
@@ -364,28 +362,28 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev)
364 * dropping doesn't work, so it is disabled in the pf_ctrl register, 362 * dropping doesn't work, so it is disabled in the pf_ctrl register,
365 * but we still leave the packet filter on. 363 * but we still leave the packet filter on.
366 */ 364 */
367 writel(pf_ctrl.value, &pRxMac->pf_ctrl.value); 365 writel(pf_ctrl, &pRxMac->pf_ctrl);
368 writel(0x9, &pRxMac->ctrl.value); 366 writel(0x9, &pRxMac->ctrl);
369} 367}
370 368
371void ConfigTxMacRegs(struct et131x_adapter *etdev) 369void ConfigTxMacRegs(struct et131x_adapter *etdev)
372{ 370{
373 struct _TXMAC_t __iomem *pTxMac = &etdev->regs->txmac; 371 struct txmac_regs *txmac = &etdev->regs->txmac;
374 372
375 /* We need to update the Control Frame Parameters 373 /* We need to update the Control Frame Parameters
376 * cfpt - control frame pause timer set to 64 (0x40) 374 * cfpt - control frame pause timer set to 64 (0x40)
377 * cfep - control frame extended pause timer set to 0x0 375 * cfep - control frame extended pause timer set to 0x0
378 */ 376 */
379 if (etdev->FlowControl == None) 377 if (etdev->FlowControl == None)
380 writel(0, &pTxMac->cf_param); 378 writel(0, &txmac->cf_param);
381 else 379 else
382 writel(0x40, &pTxMac->cf_param); 380 writel(0x40, &txmac->cf_param);
383} 381}
384 382
385void ConfigMacStatRegs(struct et131x_adapter *etdev) 383void ConfigMacStatRegs(struct et131x_adapter *etdev)
386{ 384{
387 struct _MAC_STAT_t __iomem *macstat = 385 struct macstat_regs __iomem *macstat =
388 &etdev->regs->macStat; 386 &etdev->regs->macstat;
389 387
390 /* Next we need to initialize all the MAC_STAT registers to zero on 388 /* Next we need to initialize all the MAC_STAT registers to zero on
391 * the device. 389 * the device.
@@ -456,8 +454,8 @@ void ConfigFlowControl(struct et131x_adapter *etdev)
456void UpdateMacStatHostCounters(struct et131x_adapter *etdev) 454void UpdateMacStatHostCounters(struct et131x_adapter *etdev)
457{ 455{
458 struct _ce_stats_t *stats = &etdev->Stats; 456 struct _ce_stats_t *stats = &etdev->Stats;
459 struct _MAC_STAT_t __iomem *macstat = 457 struct macstat_regs __iomem *macstat =
460 &etdev->regs->macStat; 458 &etdev->regs->macstat;
461 459
462 stats->collisions += readl(&macstat->TNcl); 460 stats->collisions += readl(&macstat->TNcl);
463 stats->first_collision += readl(&macstat->TScl); 461 stats->first_collision += readl(&macstat->TScl);
@@ -493,11 +491,11 @@ void HandleMacStatInterrupt(struct et131x_adapter *etdev)
493 /* Read the interrupt bits from the register(s). These are Clear On 491 /* Read the interrupt bits from the register(s). These are Clear On
494 * Write. 492 * Write.
495 */ 493 */
496 Carry1 = readl(&etdev->regs->macStat.Carry1); 494 Carry1 = readl(&etdev->regs->macstat.Carry1);
497 Carry2 = readl(&etdev->regs->macStat.Carry2); 495 Carry2 = readl(&etdev->regs->macstat.Carry2);
498 496
499 writel(Carry1, &etdev->regs->macStat.Carry1); 497 writel(Carry1, &etdev->regs->macstat.Carry1);
500 writel(Carry2, &etdev->regs->macStat.Carry2); 498 writel(Carry2, &etdev->regs->macstat.Carry2);
501 499
502 /* We need to do update the host copy of all the MAC_STAT counters. 500 /* We need to do update the host copy of all the MAC_STAT counters.
503 * For each counter, check it's overflow bit. If the overflow bit is 501 * For each counter, check it's overflow bit. If the overflow bit is
diff --git a/drivers/staging/et131x/et1310_mac.h b/drivers/staging/et131x/et1310_mac.h
deleted file mode 100644
index 2c3859594538..000000000000
--- a/drivers/staging/et131x/et1310_mac.h
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et1310_mac.h - Defines, structs, enums, prototypes, etc. pertaining to the
12 * MAC.
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef _ET1310_MAC_H_
60#define _ET1310_MAC_H_
61
62
63#include "et1310_address_map.h"
64
65
66#define COUNTER_WRAP_28_BIT 0x10000000
67#define COUNTER_WRAP_22_BIT 0x400000
68#define COUNTER_WRAP_16_BIT 0x10000
69#define COUNTER_WRAP_12_BIT 0x1000
70
71#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1)
72#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1)
73#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
74#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
75
76#define UPDATE_COUNTER(HostCnt, DevCnt) \
77 HostCnt = HostCnt + DevCnt;
78
79/* Forward declaration of the private adapter structure */
80struct et131x_adapter;
81
82void ConfigMACRegs1(struct et131x_adapter *adapter);
83void ConfigMACRegs2(struct et131x_adapter *adapter);
84void ConfigRxMacRegs(struct et131x_adapter *adapter);
85void ConfigTxMacRegs(struct et131x_adapter *adapter);
86void ConfigMacStatRegs(struct et131x_adapter *adapter);
87void ConfigFlowControl(struct et131x_adapter *adapter);
88void UpdateMacStatHostCounters(struct et131x_adapter *adapter);
89void HandleMacStatInterrupt(struct et131x_adapter *adapter);
90void SetupDeviceForMulticast(struct et131x_adapter *adapter);
91void SetupDeviceForUnicast(struct et131x_adapter *adapter);
92
93#endif /* _ET1310_MAC_H_ */
diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c
index 6ecad619f779..4a55fbfbd59d 100644
--- a/drivers/staging/et131x/et1310_phy.c
+++ b/drivers/staging/et131x/et1310_phy.c
@@ -85,17 +85,14 @@
85#include <linux/random.h> 85#include <linux/random.h>
86 86
87#include "et1310_phy.h" 87#include "et1310_phy.h"
88#include "et1310_pm.h"
89#include "et1310_jagcore.h"
90 88
91#include "et131x_adapter.h" 89#include "et131x_adapter.h"
92#include "et131x_netdev.h"
93#include "et131x_initpci.h"
94 90
95#include "et1310_address_map.h" 91#include "et1310_address_map.h"
96#include "et1310_tx.h" 92#include "et1310_tx.h"
97#include "et1310_rx.h" 93#include "et1310_rx.h"
98#include "et1310_mac.h" 94
95#include "et131x.h"
99 96
100/* Prototypes for functions with local scope */ 97/* Prototypes for functions with local scope */
101static void et131x_xcvr_init(struct et131x_adapter *etdev); 98static void et131x_xcvr_init(struct et131x_adapter *etdev);
diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h
index 758b9b251715..47907ba76012 100644
--- a/drivers/staging/et131x/et1310_phy.h
+++ b/drivers/staging/et131x/et1310_phy.h
@@ -736,32 +736,8 @@ typedef union _MI_LCR2_t {
736 736
737/* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */ 737/* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */
738 738
739/* Forward declaration of the private adapter structure */
740struct et131x_adapter;
741 739
742/* Prototypes for ET1310_phy.c */ 740/* Prototypes for ET1310_phy.c */
743int et131x_xcvr_find(struct et131x_adapter *adapter);
744void et131x_setphy_normal(struct et131x_adapter *adapter);
745
746/* static inline function does not work because et131x_adapter is not always
747 * defined
748 */
749int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr,
750 u8 xcvrReg, u16 *value);
751#define MiRead(adapter, xcvrReg, value) \
752 PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
753
754int32_t MiWrite(struct et131x_adapter *adapter,
755 u8 xcvReg, u16 value);
756void et131x_Mii_check(struct et131x_adapter *pAdapter,
757 MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints);
758
759/* This last is not strictly required (the driver could call the TPAL
760 * version instead), but this sets the adapter up correctly, and calls the
761 * access routine indirectly. This protects the driver from changes in TPAL.
762 */
763void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
764
765/* Defines for PHY access routines */ 741/* Defines for PHY access routines */
766 742
767/* Define bit operation flags */ 743/* Define bit operation flags */
@@ -843,14 +819,4 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
843 /* #define TRU_VMI_LINK_CONTROL_REGISTER 29 */ 819 /* #define TRU_VMI_LINK_CONTROL_REGISTER 29 */
844 /* #define TRU_VMI_TIMING_CONTROL_REGISTER */ 820 /* #define TRU_VMI_TIMING_CONTROL_REGISTER */
845 821
846/* Prototypes for PHY access routines */
847void ET1310_PhyInit(struct et131x_adapter *adapter);
848void ET1310_PhyReset(struct et131x_adapter *adapter);
849void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
850void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
851 u16 duplex);
852void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
853 u16 action,
854 u16 regnum, u16 bitnum, u8 *value);
855
856#endif /* _ET1310_PHY_H_ */ 822#endif /* _ET1310_PHY_H_ */
diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c
index 7d0772359291..41019e390af5 100644
--- a/drivers/staging/et131x/et1310_pm.c
+++ b/drivers/staging/et131x/et1310_pm.c
@@ -83,13 +83,9 @@
83#include <linux/ioport.h> 83#include <linux/ioport.h>
84 84
85#include "et1310_phy.h" 85#include "et1310_phy.h"
86#include "et1310_pm.h"
87#include "et1310_jagcore.h"
88#include "et1310_mac.h"
89#include "et1310_rx.h" 86#include "et1310_rx.h"
90
91#include "et131x_adapter.h" 87#include "et131x_adapter.h"
92#include "et131x_initpci.h" 88#include "et131x.h"
93 89
94/** 90/**
95 * EnablePhyComa - called when network cable is unplugged 91 * EnablePhyComa - called when network cable is unplugged
diff --git a/drivers/staging/et131x/et1310_pm.h b/drivers/staging/et131x/et1310_pm.h
deleted file mode 100644
index 295f3ab132fb..000000000000
--- a/drivers/staging/et131x/et1310_pm.h
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power
12 * management.
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef _ET1310_PM_H_
60#define _ET1310_PM_H_
61
62#include "et1310_address_map.h"
63
64typedef struct _MP_POWER_MGMT {
65 /* variable putting the phy into coma mode when boot up with no cable
66 * plugged in after 5 seconds
67 */
68 u8 TransPhyComaModeOnBoot;
69
70 /* Next two used to save power information at power down. This
71 * information will be used during power up to set up parts of Power
72 * Management in JAGCore
73 */
74 u16 PowerDownSpeed;
75 u8 PowerDownDuplex;
76} MP_POWER_MGMT, *PMP_POWER_MGMT;
77
78/* Forward declaration of the private adapter structure
79 */
80struct et131x_adapter;
81
82void EnablePhyComa(struct et131x_adapter *adapter);
83void DisablePhyComa(struct et131x_adapter *adapter);
84
85#endif /* _ET1310_PM_H_ */
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index 81c1a7478ad6..54686e2ace69 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -84,14 +84,9 @@
84#include <linux/ioport.h> 84#include <linux/ioport.h>
85 85
86#include "et1310_phy.h" 86#include "et1310_phy.h"
87#include "et1310_pm.h"
88#include "et1310_jagcore.h"
89
90#include "et131x_adapter.h" 87#include "et131x_adapter.h"
91#include "et131x_initpci.h"
92
93#include "et1310_rx.h" 88#include "et1310_rx.h"
94 89#include "et131x.h"
95 90
96void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd); 91void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd);
97 92
@@ -109,17 +104,16 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
109 u32 i, j; 104 u32 i, j;
110 u32 bufsize; 105 u32 bufsize;
111 u32 pktStatRingSize, FBRChunkSize; 106 u32 pktStatRingSize, FBRChunkSize;
112 RX_RING_t *rx_ring; 107 struct rx_ring *rx_ring;
113 108
114 /* Setup some convenience pointers */ 109 /* Setup some convenience pointers */
115 rx_ring = (RX_RING_t *) &adapter->RxRing; 110 rx_ring = &adapter->rx_ring;
116 111
117 /* Alloc memory for the lookup table */ 112 /* Alloc memory for the lookup table */
118#ifdef USE_FBR0 113#ifdef USE_FBR0
119 rx_ring->Fbr[0] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL); 114 rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
120#endif 115#endif
121 116 rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL);
122 rx_ring->Fbr[1] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL);
123 117
124 /* The first thing we will do is configure the sizes of the buffer 118 /* The first thing we will do is configure the sizes of the buffer
125 * rings. These will change based on jumbo packet support. Larger 119 * rings. These will change based on jumbo packet support. Larger
@@ -163,14 +157,14 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
163 } 157 }
164 158
165#ifdef USE_FBR0 159#ifdef USE_FBR0
166 adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries + 160 adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr0NumEntries +
167 adapter->RxRing.Fbr1NumEntries; 161 adapter->rx_ring.Fbr1NumEntries;
168#else 162#else
169 adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries; 163 adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr1NumEntries;
170#endif 164#endif
171 165
172 /* Allocate an area of memory for Free Buffer Ring 1 */ 166 /* Allocate an area of memory for Free Buffer Ring 1 */
173 bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff; 167 bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + 0xfff;
174 rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev, 168 rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev,
175 bufsize, 169 bufsize,
176 &rx_ring->pFbr1RingPa); 170 &rx_ring->pFbr1RingPa);
@@ -194,12 +188,12 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
194 &rx_ring->Fbr1Realpa, 188 &rx_ring->Fbr1Realpa,
195 &rx_ring->Fbr1offset, 0x0FFF); 189 &rx_ring->Fbr1offset, 0x0FFF);
196 190
197 rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa + 191 rx_ring->pFbr1RingVa = (void *)((u8 *) rx_ring->pFbr1RingVa +
198 rx_ring->Fbr1offset); 192 rx_ring->Fbr1offset);
199 193
200#ifdef USE_FBR0 194#ifdef USE_FBR0
201 /* Allocate an area of memory for Free Buffer Ring 0 */ 195 /* Allocate an area of memory for Free Buffer Ring 0 */
202 bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff; 196 bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + 0xfff;
203 rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev, 197 rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev,
204 bufsize, 198 bufsize,
205 &rx_ring->pFbr0RingPa); 199 &rx_ring->pFbr0RingPa);
@@ -223,7 +217,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
223 &rx_ring->Fbr0Realpa, 217 &rx_ring->Fbr0Realpa,
224 &rx_ring->Fbr0offset, 0x0FFF); 218 &rx_ring->Fbr0offset, 0x0FFF);
225 219
226 rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa + 220 rx_ring->pFbr0RingVa = (void *)((u8 *) rx_ring->pFbr0RingVa +
227 rx_ring->Fbr0offset); 221 rx_ring->Fbr0offset);
228#endif 222#endif
229 223
@@ -270,23 +264,23 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
270 /* Save the Virtual address of this index for quick 264 /* Save the Virtual address of this index for quick
271 * access later 265 * access later
272 */ 266 */
273 rx_ring->Fbr[1]->Va[index] = 267 rx_ring->fbr[1]->virt[index] =
274 (uint8_t *) rx_ring->Fbr1MemVa[i] + 268 (u8 *) rx_ring->Fbr1MemVa[i] +
275 (j * rx_ring->Fbr1BufferSize) + Fbr1Offset; 269 (j * rx_ring->Fbr1BufferSize) + Fbr1Offset;
276 270
277 /* now store the physical address in the descriptor 271 /* now store the physical address in the descriptor
278 * so the device can access it 272 * so the device can access it
279 */ 273 */
280 rx_ring->Fbr[1]->PAHigh[index] = 274 rx_ring->fbr[1]->bus_high[index] =
281 (u32) (Fbr1TempPa >> 32); 275 (u32) (Fbr1TempPa >> 32);
282 rx_ring->Fbr[1]->PALow[index] = (u32) Fbr1TempPa; 276 rx_ring->fbr[1]->bus_low[index] = (u32) Fbr1TempPa;
283 277
284 Fbr1TempPa += rx_ring->Fbr1BufferSize; 278 Fbr1TempPa += rx_ring->Fbr1BufferSize;
285 279
286 rx_ring->Fbr[1]->Buffer1[index] = 280 rx_ring->fbr[1]->buffer1[index] =
287 rx_ring->Fbr[1]->Va[index]; 281 rx_ring->fbr[1]->virt[index];
288 rx_ring->Fbr[1]->Buffer2[index] = 282 rx_ring->fbr[1]->buffer2[index] =
289 rx_ring->Fbr[1]->Va[index] - 4; 283 rx_ring->fbr[1]->virt[index] - 4;
290 } 284 }
291 } 285 }
292 286
@@ -319,27 +313,27 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
319 for (j = 0; j < FBR_CHUNKS; j++) { 313 for (j = 0; j < FBR_CHUNKS; j++) {
320 u32 index = (i * FBR_CHUNKS) + j; 314 u32 index = (i * FBR_CHUNKS) + j;
321 315
322 rx_ring->Fbr[0]->Va[index] = 316 rx_ring->fbr[0]->virt[index] =
323 (uint8_t *) rx_ring->Fbr0MemVa[i] + 317 (u8 *) rx_ring->Fbr0MemVa[i] +
324 (j * rx_ring->Fbr0BufferSize) + Fbr0Offset; 318 (j * rx_ring->Fbr0BufferSize) + Fbr0Offset;
325 319
326 rx_ring->Fbr[0]->PAHigh[index] = 320 rx_ring->fbr[0]->bus_high[index] =
327 (u32) (Fbr0TempPa >> 32); 321 (u32) (Fbr0TempPa >> 32);
328 rx_ring->Fbr[0]->PALow[index] = (u32) Fbr0TempPa; 322 rx_ring->fbr[0]->bus_low[index] = (u32) Fbr0TempPa;
329 323
330 Fbr0TempPa += rx_ring->Fbr0BufferSize; 324 Fbr0TempPa += rx_ring->Fbr0BufferSize;
331 325
332 rx_ring->Fbr[0]->Buffer1[index] = 326 rx_ring->fbr[0]->buffer1[index] =
333 rx_ring->Fbr[0]->Va[index]; 327 rx_ring->fbr[0]->virt[index];
334 rx_ring->Fbr[0]->Buffer2[index] = 328 rx_ring->fbr[0]->buffer2[index] =
335 rx_ring->Fbr[0]->Va[index] - 4; 329 rx_ring->fbr[0]->virt[index] - 4;
336 } 330 }
337 } 331 }
338#endif 332#endif
339 333
340 /* Allocate an area of memory for FIFO of Packet Status ring entries */ 334 /* Allocate an area of memory for FIFO of Packet Status ring entries */
341 pktStatRingSize = 335 pktStatRingSize =
342 sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; 336 sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;
343 337
344 rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev, 338 rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev,
345 pktStatRingSize, 339 pktStatRingSize,
@@ -360,16 +354,16 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
360 */ 354 */
361 355
362 /* Allocate an area of memory for writeback of status information */ 356 /* Allocate an area of memory for writeback of status information */
363 rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev, 357 rx_ring->rx_status_block = pci_alloc_consistent(adapter->pdev,
364 sizeof(RX_STATUS_BLOCK_t), 358 sizeof(struct rx_status_block),
365 &rx_ring->pRxStatusPa); 359 &rx_ring->rx_status_bus);
366 if (!rx_ring->pRxStatusVa) { 360 if (!rx_ring->rx_status_block) {
367 dev_err(&adapter->pdev->dev, 361 dev_err(&adapter->pdev->dev,
368 "Cannot alloc memory for Status Block\n"); 362 "Cannot alloc memory for Status Block\n");
369 return -ENOMEM; 363 return -ENOMEM;
370 } 364 }
371 rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; 365 rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD;
372 printk("PRS %lx\n", (unsigned long)rx_ring->pRxStatusPa); 366 printk("PRS %lx\n", (unsigned long)rx_ring->rx_status_bus);
373 367
374 /* Recv 368 /* Recv
375 * pci_pool_create initializes a lookaside list. After successful 369 * pci_pool_create initializes a lookaside list. After successful
@@ -403,10 +397,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
403 u32 bufsize; 397 u32 bufsize;
404 u32 pktStatRingSize; 398 u32 pktStatRingSize;
405 PMP_RFD rfd; 399 PMP_RFD rfd;
406 RX_RING_t *rx_ring; 400 struct rx_ring *rx_ring;
407 401
408 /* Setup some convenience pointers */ 402 /* Setup some convenience pointers */
409 rx_ring = (RX_RING_t *) &adapter->RxRing; 403 rx_ring = &adapter->rx_ring;
410 404
411 /* Free RFDs and associated packet descriptors */ 405 /* Free RFDs and associated packet descriptors */
412 WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd); 406 WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd);
@@ -417,7 +411,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
417 411
418 list_del(&rfd->list_node); 412 list_del(&rfd->list_node);
419 rfd->Packet = NULL; 413 rfd->Packet = NULL;
420 kmem_cache_free(adapter->RxRing.RecvLookaside, rfd); 414 kmem_cache_free(adapter->rx_ring.RecvLookaside, rfd);
421 } 415 }
422 416
423 /* Free Free Buffer Ring 1 */ 417 /* Free Free Buffer Ring 1 */
@@ -447,15 +441,14 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
447 } 441 }
448 442
449 /* Now the FIFO itself */ 443 /* Now the FIFO itself */
450 rx_ring->pFbr1RingVa = (void *)((uint8_t *) 444 rx_ring->pFbr1RingVa = (void *)((u8 *)
451 rx_ring->pFbr1RingVa - rx_ring->Fbr1offset); 445 rx_ring->pFbr1RingVa - rx_ring->Fbr1offset);
452 446
453 bufsize = 447 bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries)
454 (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff; 448 + 0xfff;
455 449
456 pci_free_consistent(adapter->pdev, 450 pci_free_consistent(adapter->pdev, bufsize,
457 bufsize, 451 rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);
458 rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);
459 452
460 rx_ring->pFbr1RingVa = NULL; 453 rx_ring->pFbr1RingVa = NULL;
461 } 454 }
@@ -481,11 +474,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
481 } 474 }
482 475
483 /* Now the FIFO itself */ 476 /* Now the FIFO itself */
484 rx_ring->pFbr0RingVa = (void *)((uint8_t *) 477 rx_ring->pFbr0RingVa = (void *)((u8 *)
485 rx_ring->pFbr0RingVa - rx_ring->Fbr0offset); 478 rx_ring->pFbr0RingVa - rx_ring->Fbr0offset);
486 479
487 bufsize = 480 bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries)
488 (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff; 481 + 0xfff;
489 482
490 pci_free_consistent(adapter->pdev, 483 pci_free_consistent(adapter->pdev,
491 bufsize, 484 bufsize,
@@ -498,7 +491,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
498 /* Free Packet Status Ring */ 491 /* Free Packet Status Ring */
499 if (rx_ring->pPSRingVa) { 492 if (rx_ring->pPSRingVa) {
500 pktStatRingSize = 493 pktStatRingSize =
501 sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries; 494 sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries;
502 495
503 pci_free_consistent(adapter->pdev, pktStatRingSize, 496 pci_free_consistent(adapter->pdev, pktStatRingSize,
504 rx_ring->pPSRingVa, rx_ring->pPSRingPa); 497 rx_ring->pPSRingVa, rx_ring->pPSRingPa);
@@ -507,12 +500,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
507 } 500 }
508 501
509 /* Free area of memory for the writeback of status information */ 502 /* Free area of memory for the writeback of status information */
510 if (rx_ring->pRxStatusVa) { 503 if (rx_ring->rx_status_block) {
511 pci_free_consistent(adapter->pdev, 504 pci_free_consistent(adapter->pdev,
512 sizeof(RX_STATUS_BLOCK_t), 505 sizeof(struct rx_status_block),
513 rx_ring->pRxStatusVa, rx_ring->pRxStatusPa); 506 rx_ring->rx_status_block, rx_ring->rx_status_bus);
514 507 rx_ring->rx_status_block = NULL;
515 rx_ring->pRxStatusVa = NULL;
516 } 508 }
517 509
518 /* Free receive buffer pool */ 510 /* Free receive buffer pool */
@@ -527,10 +519,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
527 519
528 /* Free the FBR Lookup Table */ 520 /* Free the FBR Lookup Table */
529#ifdef USE_FBR0 521#ifdef USE_FBR0
530 kfree(rx_ring->Fbr[0]); 522 kfree(rx_ring->fbr[0]);
531#endif 523#endif
532 524
533 kfree(rx_ring->Fbr[1]); 525 kfree(rx_ring->fbr[1]);
534 526
535 /* Reset Counters */ 527 /* Reset Counters */
536 rx_ring->nReadyRecv = 0; 528 rx_ring->nReadyRecv = 0;
@@ -548,10 +540,10 @@ int et131x_init_recv(struct et131x_adapter *adapter)
548 PMP_RFD rfd = NULL; 540 PMP_RFD rfd = NULL;
549 u32 rfdct; 541 u32 rfdct;
550 u32 numrfd = 0; 542 u32 numrfd = 0;
551 RX_RING_t *rx_ring = NULL; 543 struct rx_ring *rx_ring;
552 544
553 /* Setup some convenience pointers */ 545 /* Setup some convenience pointers */
554 rx_ring = (RX_RING_t *) &adapter->RxRing; 546 rx_ring = &adapter->rx_ring;
555 547
556 /* Setup each RFD */ 548 /* Setup each RFD */
557 for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) { 549 for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) {
@@ -594,9 +586,9 @@ int et131x_init_recv(struct et131x_adapter *adapter)
594 */ 586 */
595void ConfigRxDmaRegs(struct et131x_adapter *etdev) 587void ConfigRxDmaRegs(struct et131x_adapter *etdev)
596{ 588{
597 struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma; 589 struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
598 struct _rx_ring_t *rx_local = &etdev->RxRing; 590 struct rx_ring *rx_local = &etdev->rx_ring;
599 PFBR_DESC_t fbr_entry; 591 struct fbr_desc *fbr_entry;
600 u32 entry; 592 u32 entry;
601 u32 psr_num_des; 593 u32 psr_num_des;
602 unsigned long flags; 594 unsigned long flags;
@@ -611,11 +603,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev)
611 * are ever returned, make sure the high part is retrieved here 603 * are ever returned, make sure the high part is retrieved here
612 * before storing the adjusted address. 604 * before storing the adjusted address.
613 */ 605 */
614 writel((u32) ((u64)rx_local->pRxStatusPa >> 32), 606 writel((u32) ((u64)rx_local->rx_status_bus >> 32),
615 &rx_dma->dma_wb_base_hi); 607 &rx_dma->dma_wb_base_hi);
616 writel((u32) rx_local->pRxStatusPa, &rx_dma->dma_wb_base_lo); 608 writel((u32) rx_local->rx_status_bus, &rx_dma->dma_wb_base_lo);
617 609
618 memset(rx_local->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t)); 610 memset(rx_local->rx_status_block, 0, sizeof(struct rx_status_block));
619 611
620 /* Set the address and parameters of the packet status ring into the 612 /* Set the address and parameters of the packet status ring into the
621 * 1310's registers 613 * 1310's registers
@@ -636,11 +628,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev)
636 rx_local->local_psr_full = 0; 628 rx_local->local_psr_full = 0;
637 629
638 /* Now's the best time to initialize FBR1 contents */ 630 /* Now's the best time to initialize FBR1 contents */
639 fbr_entry = (PFBR_DESC_t) rx_local->pFbr1RingVa; 631 fbr_entry = (struct fbr_desc *) rx_local->pFbr1RingVa;
640 for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) { 632 for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) {
641 fbr_entry->addr_hi = rx_local->Fbr[1]->PAHigh[entry]; 633 fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry];
642 fbr_entry->addr_lo = rx_local->Fbr[1]->PALow[entry]; 634 fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry];
643 fbr_entry->word2.bits.bi = entry; 635 fbr_entry->word2 = entry;
644 fbr_entry++; 636 fbr_entry++;
645 } 637 }
646 638
@@ -661,11 +653,11 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev)
661 653
662#ifdef USE_FBR0 654#ifdef USE_FBR0
663 /* Now's the best time to initialize FBR0 contents */ 655 /* Now's the best time to initialize FBR0 contents */
664 fbr_entry = (PFBR_DESC_t) rx_local->pFbr0RingVa; 656 fbr_entry = (struct fbr_desc *) rx_local->pFbr0RingVa;
665 for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) { 657 for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) {
666 fbr_entry->addr_hi = rx_local->Fbr[0]->PAHigh[entry]; 658 fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry];
667 fbr_entry->addr_lo = rx_local->Fbr[0]->PALow[entry]; 659 fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry];
668 fbr_entry->word2.bits.bi = entry; 660 fbr_entry->word2 = entry;
669 fbr_entry++; 661 fbr_entry++;
670 } 662 }
671 663
@@ -721,18 +713,17 @@ void SetRxDmaTimer(struct et131x_adapter *etdev)
721 */ 713 */
722void et131x_rx_dma_disable(struct et131x_adapter *etdev) 714void et131x_rx_dma_disable(struct et131x_adapter *etdev)
723{ 715{
724 RXDMA_CSR_t csr; 716 u32 csr;
725
726 /* Setup the receive dma configuration register */ 717 /* Setup the receive dma configuration register */
727 writel(0x00002001, &etdev->regs->rxdma.csr.value); 718 writel(0x00002001, &etdev->regs->rxdma.csr);
728 csr.value = readl(&etdev->regs->rxdma.csr.value); 719 csr = readl(&etdev->regs->rxdma.csr);
729 if (csr.bits.halt_status != 1) { 720 if ((csr & 0x00020000) != 1) { /* Check halt status (bit 17) */
730 udelay(5); 721 udelay(5);
731 csr.value = readl(&etdev->regs->rxdma.csr.value); 722 csr = readl(&etdev->regs->rxdma.csr);
732 if (csr.bits.halt_status != 1) 723 if ((csr & 0x00020000) != 1)
733 dev_err(&etdev->pdev->dev, 724 dev_err(&etdev->pdev->dev,
734 "RX Dma failed to enter halt state. CSR 0x%08x\n", 725 "RX Dma failed to enter halt state. CSR 0x%08x\n",
735 csr.value); 726 csr);
736 } 727 }
737} 728}
738 729
@@ -743,34 +734,33 @@ void et131x_rx_dma_disable(struct et131x_adapter *etdev)
743void et131x_rx_dma_enable(struct et131x_adapter *etdev) 734void et131x_rx_dma_enable(struct et131x_adapter *etdev)
744{ 735{
745 /* Setup the receive dma configuration register for normal operation */ 736 /* Setup the receive dma configuration register for normal operation */
746 RXDMA_CSR_t csr = { 0 }; 737 u32 csr = 0x2000; /* FBR1 enable */
747 738
748 csr.bits.fbr1_enable = 1; 739 if (etdev->rx_ring.Fbr1BufferSize == 4096)
749 if (etdev->RxRing.Fbr1BufferSize == 4096) 740 csr |= 0x0800;
750 csr.bits.fbr1_size = 1; 741 else if (etdev->rx_ring.Fbr1BufferSize == 8192)
751 else if (etdev->RxRing.Fbr1BufferSize == 8192) 742 csr |= 0x1000;
752 csr.bits.fbr1_size = 2; 743 else if (etdev->rx_ring.Fbr1BufferSize == 16384)
753 else if (etdev->RxRing.Fbr1BufferSize == 16384) 744 csr |= 0x1800;
754 csr.bits.fbr1_size = 3;
755#ifdef USE_FBR0 745#ifdef USE_FBR0
756 csr.bits.fbr0_enable = 1; 746 csr |= 0x0400; /* FBR0 enable */
757 if (etdev->RxRing.Fbr0BufferSize == 256) 747 if (etdev->rx_ring.Fbr0BufferSize == 256)
758 csr.bits.fbr0_size = 1; 748 csr |= 0x0100;
759 else if (etdev->RxRing.Fbr0BufferSize == 512) 749 else if (etdev->rx_ring.Fbr0BufferSize == 512)
760 csr.bits.fbr0_size = 2; 750 csr |= 0x0200;
761 else if (etdev->RxRing.Fbr0BufferSize == 1024) 751 else if (etdev->rx_ring.Fbr0BufferSize == 1024)
762 csr.bits.fbr0_size = 3; 752 csr |= 0x0300;
763#endif 753#endif
764 writel(csr.value, &etdev->regs->rxdma.csr.value); 754 writel(csr, &etdev->regs->rxdma.csr);
765 755
766 csr.value = readl(&etdev->regs->rxdma.csr.value); 756 csr = readl(&etdev->regs->rxdma.csr);
767 if (csr.bits.halt_status != 0) { 757 if ((csr & 0x00020000) != 0) {
768 udelay(5); 758 udelay(5);
769 csr.value = readl(&etdev->regs->rxdma.csr.value); 759 csr = readl(&etdev->regs->rxdma.csr);
770 if (csr.bits.halt_status != 0) { 760 if ((csr & 0x00020000) != 0) {
771 dev_err(&etdev->pdev->dev, 761 dev_err(&etdev->pdev->dev,
772 "RX Dma failed to exit halt state. CSR 0x%08x\n", 762 "RX Dma failed to exit halt state. CSR 0x%08x\n",
773 csr.value); 763 csr);
774 } 764 }
775 } 765 }
776} 766}
@@ -788,46 +778,44 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev)
788 */ 778 */
789PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) 779PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
790{ 780{
791 struct _rx_ring_t *rx_local = &etdev->RxRing; 781 struct rx_ring *rx_local = &etdev->rx_ring;
792 PRX_STATUS_BLOCK_t status; 782 struct rx_status_block *status;
793 PPKT_STAT_DESC_t psr; 783 struct pkt_stat_desc *psr;
794 PMP_RFD rfd; 784 PMP_RFD rfd;
795 u32 i; 785 u32 i;
796 uint8_t *buf; 786 u8 *buf;
797 unsigned long flags; 787 unsigned long flags;
798 struct list_head *element; 788 struct list_head *element;
799 uint8_t rindex; 789 u8 rindex;
800 uint16_t bindex; 790 u16 bindex;
801 u32 len; 791 u32 len;
802 PKT_STAT_DESC_WORD0_t Word0; 792 u32 word0;
793 u32 word1;
803 794
804 /* RX Status block is written by the DMA engine prior to every 795 /* RX Status block is written by the DMA engine prior to every
805 * interrupt. It contains the next to be used entry in the Packet 796 * interrupt. It contains the next to be used entry in the Packet
806 * Status Ring, and also the two Free Buffer rings. 797 * Status Ring, and also the two Free Buffer rings.
807 */ 798 */
808 status = (PRX_STATUS_BLOCK_t) rx_local->pRxStatusVa; 799 status = rx_local->rx_status_block;
800 word1 = status->Word1 >> 16; /* Get the useful bits */
809 801
810 /* FIXME: tidy later when conversions complete */ 802 /* Check the PSR and wrap bits do not match */
811 if (status->Word1.bits.PSRoffset == 803 if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF))
812 (rx_local->local_psr_full & 0xFFF) &&
813 status->Word1.bits.PSRwrap ==
814 ((rx_local->local_psr_full >> 12) & 1)) {
815 /* Looks like this ring is not updated yet */ 804 /* Looks like this ring is not updated yet */
816 return NULL; 805 return NULL;
817 }
818 806
819 /* The packet status ring indicates that data is available. */ 807 /* The packet status ring indicates that data is available. */
820 psr = (PPKT_STAT_DESC_t) (rx_local->pPSRingVa) + 808 psr = (struct pkt_stat_desc *) (rx_local->pPSRingVa) +
821 (rx_local->local_psr_full & 0xFFF); 809 (rx_local->local_psr_full & 0xFFF);
822 810
823 /* Grab any information that is required once the PSR is 811 /* Grab any information that is required once the PSR is
824 * advanced, since we can no longer rely on the memory being 812 * advanced, since we can no longer rely on the memory being
825 * accurate 813 * accurate
826 */ 814 */
827 len = psr->word1.bits.length; 815 len = psr->word1 & 0xFFFF;
828 rindex = (uint8_t) psr->word1.bits.ri; 816 rindex = (psr->word1 >> 26) & 0x03;
829 bindex = (uint16_t) psr->word1.bits.bi; 817 bindex = (psr->word1 >> 16) & 0x3FF;
830 Word0 = psr->word0; 818 word0 = psr->word0;
831 819
832 /* Indicate that we have used this PSR entry. */ 820 /* Indicate that we have used this PSR entry. */
833 /* FIXME wrap 12 */ 821 /* FIXME wrap 12 */
@@ -842,9 +830,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
842 &etdev->regs->rxdma.psr_full_offset); 830 &etdev->regs->rxdma.psr_full_offset);
843 831
844#ifndef USE_FBR0 832#ifndef USE_FBR0
845 if (rindex != 1) { 833 if (rindex != 1)
846 return NULL; 834 return NULL;
847 }
848#endif 835#endif
849 836
850#ifdef USE_FBR0 837#ifdef USE_FBR0
@@ -899,7 +886,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
899 886
900 if (len) { 887 if (len) {
901 if (etdev->ReplicaPhyLoopbk == 1) { 888 if (etdev->ReplicaPhyLoopbk == 1) {
902 buf = rx_local->Fbr[rindex]->Va[bindex]; 889 buf = rx_local->fbr[rindex]->virt[bindex];
903 890
904 if (memcmp(&buf[6], &etdev->CurrentAddress[0], 891 if (memcmp(&buf[6], &etdev->CurrentAddress[0],
905 ETH_ALEN) == 0) { 892 ETH_ALEN) == 0) {
@@ -911,8 +898,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
911 } 898 }
912 899
913 /* Determine if this is a multicast packet coming in */ 900 /* Determine if this is a multicast packet coming in */
914 if ((Word0.value & ALCATEL_MULTICAST_PKT) && 901 if ((word0 & ALCATEL_MULTICAST_PKT) &&
915 !(Word0.value & ALCATEL_BROADCAST_PKT)) { 902 !(word0 & ALCATEL_BROADCAST_PKT)) {
916 /* Promiscuous mode and Multicast mode are 903 /* Promiscuous mode and Multicast mode are
917 * not mutually exclusive as was first 904 * not mutually exclusive as was first
918 * thought. I guess Promiscuous is just 905 * thought. I guess Promiscuous is just
@@ -923,8 +910,8 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
923 if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) 910 if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
924 && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS) 911 && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
925 && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { 912 && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
926 buf = rx_local->Fbr[rindex]-> 913 buf = rx_local->fbr[rindex]->
927 Va[bindex]; 914 virt[bindex];
928 915
929 /* Loop through our list to see if the 916 /* Loop through our list to see if the
930 * destination address of this packet 917 * destination address of this packet
@@ -963,7 +950,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
963 950
964 if (len > 0) 951 if (len > 0)
965 etdev->Stats.multircv++; 952 etdev->Stats.multircv++;
966 } else if (Word0.value & ALCATEL_BROADCAST_PKT) 953 } else if (word0 & ALCATEL_BROADCAST_PKT)
967 etdev->Stats.brdcstrcv++; 954 etdev->Stats.brdcstrcv++;
968 else 955 else
969 /* Not sure what this counter measures in 956 /* Not sure what this counter measures in
@@ -990,7 +977,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
990 etdev->net_stats.rx_bytes += rfd->PacketSize; 977 etdev->net_stats.rx_bytes += rfd->PacketSize;
991 978
992 memcpy(skb_put(skb, rfd->PacketSize), 979 memcpy(skb_put(skb, rfd->PacketSize),
993 rx_local->Fbr[rindex]->Va[bindex], 980 rx_local->fbr[rindex]->virt[bindex],
994 rfd->PacketSize); 981 rfd->PacketSize);
995 982
996 skb->dev = etdev->netdev; 983 skb->dev = etdev->netdev;
@@ -1014,7 +1001,7 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
1014 */ 1001 */
1015void et131x_reset_recv(struct et131x_adapter *etdev) 1002void et131x_reset_recv(struct et131x_adapter *etdev)
1016{ 1003{
1017 WARN_ON(list_empty(&etdev->RxRing.RecvList)); 1004 WARN_ON(list_empty(&etdev->rx_ring.RecvList));
1018 1005
1019} 1006}
1020 1007
@@ -1032,8 +1019,8 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
1032 1019
1033 /* Process up to available RFD's */ 1020 /* Process up to available RFD's */
1034 while (count < NUM_PACKETS_HANDLED) { 1021 while (count < NUM_PACKETS_HANDLED) {
1035 if (list_empty(&etdev->RxRing.RecvList)) { 1022 if (list_empty(&etdev->rx_ring.RecvList)) {
1036 WARN_ON(etdev->RxRing.nReadyRecv != 0); 1023 WARN_ON(etdev->rx_ring.nReadyRecv != 0);
1037 done = false; 1024 done = false;
1038 break; 1025 break;
1039 } 1026 }
@@ -1058,7 +1045,7 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
1058 etdev->Stats.ipackets++; 1045 etdev->Stats.ipackets++;
1059 1046
1060 /* Set the status on the packet, either resources or success */ 1047 /* Set the status on the packet, either resources or success */
1061 if (etdev->RxRing.nReadyRecv < RFD_LOW_WATER_MARK) { 1048 if (etdev->rx_ring.nReadyRecv < RFD_LOW_WATER_MARK) {
1062 dev_warn(&etdev->pdev->dev, 1049 dev_warn(&etdev->pdev->dev,
1063 "RFD's are running out\n"); 1050 "RFD's are running out\n");
1064 } 1051 }
@@ -1066,12 +1053,12 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
1066 } 1053 }
1067 1054
1068 if (count == NUM_PACKETS_HANDLED || !done) { 1055 if (count == NUM_PACKETS_HANDLED || !done) {
1069 etdev->RxRing.UnfinishedReceives = true; 1056 etdev->rx_ring.UnfinishedReceives = true;
1070 writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO, 1057 writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
1071 &etdev->regs->global.watchdog_timer); 1058 &etdev->regs->global.watchdog_timer);
1072 } else 1059 } else
1073 /* Watchdog timer will disable itself if appropriate. */ 1060 /* Watchdog timer will disable itself if appropriate. */
1074 etdev->RxRing.UnfinishedReceives = false; 1061 etdev->rx_ring.UnfinishedReceives = false;
1075} 1062}
1076 1063
1077static inline u32 bump_fbr(u32 *fbr, u32 limit) 1064static inline u32 bump_fbr(u32 *fbr, u32 limit)
@@ -1099,10 +1086,10 @@ static inline u32 bump_fbr(u32 *fbr, u32 limit)
1099 */ 1086 */
1100void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd) 1087void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
1101{ 1088{
1102 struct _rx_ring_t *rx_local = &etdev->RxRing; 1089 struct rx_ring *rx_local = &etdev->rx_ring;
1103 struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma; 1090 struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma;
1104 uint16_t bi = rfd->bufferindex; 1091 u16 bi = rfd->bufferindex;
1105 uint8_t ri = rfd->ringindex; 1092 u8 ri = rfd->ringindex;
1106 unsigned long flags; 1093 unsigned long flags;
1107 1094
1108 /* We don't use any of the OOB data besides status. Otherwise, we 1095 /* We don't use any of the OOB data besides status. Otherwise, we
@@ -1116,17 +1103,17 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
1116 spin_lock_irqsave(&etdev->FbrLock, flags); 1103 spin_lock_irqsave(&etdev->FbrLock, flags);
1117 1104
1118 if (ri == 1) { 1105 if (ri == 1) {
1119 PFBR_DESC_t next = 1106 struct fbr_desc *next =
1120 (PFBR_DESC_t) (rx_local->pFbr1RingVa) + 1107 (struct fbr_desc *) (rx_local->pFbr1RingVa) +
1121 INDEX10(rx_local->local_Fbr1_full); 1108 INDEX10(rx_local->local_Fbr1_full);
1122 1109
1123 /* Handle the Free Buffer Ring advancement here. Write 1110 /* Handle the Free Buffer Ring advancement here. Write
1124 * the PA / Buffer Index for the returned buffer into 1111 * the PA / Buffer Index for the returned buffer into
1125 * the oldest (next to be freed)FBR entry 1112 * the oldest (next to be freed)FBR entry
1126 */ 1113 */
1127 next->addr_hi = rx_local->Fbr[1]->PAHigh[bi]; 1114 next->addr_hi = rx_local->fbr[1]->bus_high[bi];
1128 next->addr_lo = rx_local->Fbr[1]->PALow[bi]; 1115 next->addr_lo = rx_local->fbr[1]->bus_low[bi];
1129 next->word2.value = bi; 1116 next->word2 = bi;
1130 1117
1131 writel(bump_fbr(&rx_local->local_Fbr1_full, 1118 writel(bump_fbr(&rx_local->local_Fbr1_full,
1132 rx_local->Fbr1NumEntries - 1), 1119 rx_local->Fbr1NumEntries - 1),
@@ -1134,17 +1121,17 @@ void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD rfd)
1134 } 1121 }
1135#ifdef USE_FBR0 1122#ifdef USE_FBR0
1136 else { 1123 else {
1137 PFBR_DESC_t next = 1124 struct fbr_desc *next = (struct fbr_desc *)
1138 (PFBR_DESC_t) rx_local->pFbr0RingVa + 1125 rx_local->pFbr0RingVa +
1139 INDEX10(rx_local->local_Fbr0_full); 1126 INDEX10(rx_local->local_Fbr0_full);
1140 1127
1141 /* Handle the Free Buffer Ring advancement here. Write 1128 /* Handle the Free Buffer Ring advancement here. Write
1142 * the PA / Buffer Index for the returned buffer into 1129 * the PA / Buffer Index for the returned buffer into
1143 * the oldest (next to be freed) FBR entry 1130 * the oldest (next to be freed) FBR entry
1144 */ 1131 */
1145 next->addr_hi = rx_local->Fbr[0]->PAHigh[bi]; 1132 next->addr_hi = rx_local->fbr[0]->bus_high[bi];
1146 next->addr_lo = rx_local->Fbr[0]->PALow[bi]; 1133 next->addr_lo = rx_local->fbr[0]->bus_low[bi];
1147 next->word2.value = bi; 1134 next->word2 = bi;
1148 1135
1149 writel(bump_fbr(&rx_local->local_Fbr0_full, 1136 writel(bump_fbr(&rx_local->local_Fbr0_full,
1150 rx_local->Fbr0NumEntries - 1), 1137 rx_local->Fbr0NumEntries - 1),
diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h
index 69514593612c..ca84a9146d69 100644
--- a/drivers/staging/et131x/et1310_rx.h
+++ b/drivers/staging/et131x/et1310_rx.h
@@ -91,120 +91,60 @@
91#define ALCATEL_BROADCAST_PKT 0x02000000 91#define ALCATEL_BROADCAST_PKT 0x02000000
92 92
93/* typedefs for Free Buffer Descriptors */ 93/* typedefs for Free Buffer Descriptors */
94typedef union _FBR_WORD2_t { 94struct fbr_desc
95 u32 value; 95{
96 struct {
97#ifdef _BIT_FIELDS_HTOL
98 u32 reserved:22; /* bits 10-31 */
99 u32 bi:10; /* bits 0-9(Buffer Index) */
100#else
101 u32 bi:10; /* bits 0-9(Buffer Index) */
102 u32 reserved:22; /* bit 10-31 */
103#endif
104 } bits;
105} FBR_WORD2_t, *PFBR_WORD2_t;
106
107typedef struct _FBR_DESC_t {
108 u32 addr_lo; 96 u32 addr_lo;
109 u32 addr_hi; 97 u32 addr_hi;
110 FBR_WORD2_t word2; 98 u32 word2; /* Bits 10-31 reserved, 0-9 descriptor */
111} FBR_DESC_t, *PFBR_DESC_t; 99};
112
113/* Typedefs for Packet Status Ring Descriptors */
114typedef union _PKT_STAT_DESC_WORD0_t {
115 u32 value;
116 struct {
117#ifdef _BIT_FIELDS_HTOL
118 /* top 16 bits are from the Alcatel Status Word as enumerated in */
119 /* PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) */
120#if 0
121 u32 asw_trunc:1; /* bit 31(Rx frame truncated) */
122#endif
123 u32 asw_long_evt:1; /* bit 31(Rx long event) */
124 u32 asw_VLAN_tag:1; /* bit 30(VLAN tag detected) */
125 u32 asw_unsupported_op:1; /* bit 29(unsupported OP code) */
126 u32 asw_pause_frame:1; /* bit 28(is a pause frame) */
127 u32 asw_control_frame:1; /* bit 27(is a control frame) */
128 u32 asw_dribble_nibble:1; /* bit 26(spurious bits after EOP) */
129 u32 asw_broadcast:1; /* bit 25(has a broadcast address) */
130 u32 asw_multicast:1; /* bit 24(has a multicast address) */
131 u32 asw_OK:1; /* bit 23(valid CRC + no code error) */
132 u32 asw_too_long:1; /* bit 22(frame length > 1518 bytes) */
133 u32 asw_len_chk_err:1; /* bit 21(frame length field incorrect) */
134 u32 asw_CRC_err:1; /* bit 20(CRC error) */
135 u32 asw_code_err:1; /* bit 19(one or more nibbles signalled as errors) */
136 u32 asw_false_carrier_event:1; /* bit 18(bad carrier since last good packet) */
137 u32 asw_RX_DV_event:1; /* bit 17(short receive event detected) */
138 u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
139 u32 unused:5; /* bits 11-15 */
140 u32 vp:1; /* bit 10(VLAN Packet) */
141 u32 jp:1; /* bit 9(Jumbo Packet) */
142 u32 ft:1; /* bit 8(Frame Truncated) */
143 u32 drop:1; /* bit 7(Drop packet) */
144 u32 rxmac_error:1; /* bit 6(RXMAC Error Indicator) */
145 u32 wol:1; /* bit 5(WOL Event) */
146 u32 tcpp:1; /* bit 4(TCP checksum pass) */
147 u32 tcpa:1; /* bit 3(TCP checksum assist) */
148 u32 ipp:1; /* bit 2(IP checksum pass) */
149 u32 ipa:1; /* bit 1(IP checksum assist) */
150 u32 hp:1; /* bit 0(hash pass) */
151#else
152 u32 hp:1; /* bit 0(hash pass) */
153 u32 ipa:1; /* bit 1(IP checksum assist) */
154 u32 ipp:1; /* bit 2(IP checksum pass) */
155 u32 tcpa:1; /* bit 3(TCP checksum assist) */
156 u32 tcpp:1; /* bit 4(TCP checksum pass) */
157 u32 wol:1; /* bit 5(WOL Event) */
158 u32 rxmac_error:1; /* bit 6(RXMAC Error Indicator) */
159 u32 drop:1; /* bit 7(Drop packet) */
160 u32 ft:1; /* bit 8(Frame Truncated) */
161 u32 jp:1; /* bit 9(Jumbo Packet) */
162 u32 vp:1; /* bit 10(VLAN Packet) */
163 u32 unused:5; /* bits 11-15 */
164 u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
165 u32 asw_RX_DV_event:1; /* bit 17(short receive event detected) */
166 u32 asw_false_carrier_event:1; /* bit 18(bad carrier since last good packet) */
167 u32 asw_code_err:1; /* bit 19(one or more nibbles signalled as errors) */
168 u32 asw_CRC_err:1; /* bit 20(CRC error) */
169 u32 asw_len_chk_err:1; /* bit 21(frame length field incorrect) */
170 u32 asw_too_long:1; /* bit 22(frame length > 1518 bytes) */
171 u32 asw_OK:1; /* bit 23(valid CRC + no code error) */
172 u32 asw_multicast:1; /* bit 24(has a multicast address) */
173 u32 asw_broadcast:1; /* bit 25(has a broadcast address) */
174 u32 asw_dribble_nibble:1; /* bit 26(spurious bits after EOP) */
175 u32 asw_control_frame:1; /* bit 27(is a control frame) */
176 u32 asw_pause_frame:1; /* bit 28(is a pause frame) */
177 u32 asw_unsupported_op:1; /* bit 29(unsupported OP code) */
178 u32 asw_VLAN_tag:1; /* bit 30(VLAN tag detected) */
179 u32 asw_long_evt:1; /* bit 31(Rx long event) */
180#if 0
181 u32 asw_trunc:1; /* bit 31(Rx frame truncated) */
182#endif
183#endif
184 } bits;
185} PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t;
186 100
187typedef union _PKT_STAT_DESC_WORD1_t { 101/* Packet Status Ring Descriptors
188 u32 value; 102 *
189 struct { 103 * Word 0:
190#ifdef _BIT_FIELDS_HTOL 104 *
191 u32 unused:4; /* bits 28-31 */ 105 * top 16 bits are from the Alcatel Status Word as enumerated in
192 u32 ri:2; /* bits 26-27(Ring Index) */ 106 * PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2)
193 u32 bi:10; /* bits 16-25(Buffer Index) */ 107 *
194 u32 length:16; /* bit 0-15(length in bytes) */ 108 * 0: hp hash pass
195#else 109 * 1: ipa IP checksum assist
196 u32 length:16; /* bit 0-15(length in bytes) */ 110 * 2: ipp IP checksum pass
197 u32 bi:10; /* bits 16-25(Buffer Index) */ 111 * 3: tcpa TCP checksum assist
198 u32 ri:2; /* bits 26-27(Ring Index) */ 112 * 4: tcpp TCP checksum pass
199 u32 unused:4; /* bits 28-31 */ 113 * 5: wol WOL Event
200#endif 114 * 6: rxmac_error RXMAC Error Indicator
201 } bits; 115 * 7: drop Drop packet
202} PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t; 116 * 8: ft Frame Truncated
117 * 9: jp Jumbo Packet
118 * 10: vp VLAN Packet
119 * 11-15: unused
120 * 16: asw_prev_pkt_dropped e.g. IFG too small on previous
121 * 17: asw_RX_DV_event short receive event detected
122 * 18: asw_false_carrier_event bad carrier since last good packet
123 * 19: asw_code_err one or more nibbles signalled as errors
124 * 20: asw_CRC_err CRC error
125 * 21: asw_len_chk_err frame length field incorrect
126 * 22: asw_too_long frame length > 1518 bytes
127 * 23: asw_OK valid CRC + no code error
128 * 24: asw_multicast has a multicast address
129 * 25: asw_broadcast has a broadcast address
130 * 26: asw_dribble_nibble spurious bits after EOP
131 * 27: asw_control_frame is a control frame
132 * 28: asw_pause_frame is a pause frame
133 * 29: asw_unsupported_op unsupported OP code
134 * 30: asw_VLAN_tag VLAN tag detected
135 * 31: asw_long_evt Rx long event
136 *
137 * Word 1:
138 * 0-15: length length in bytes
139 * 16-25: bi Buffer Index
140 * 26-27: ri Ring Index
141 * 28-31: reserved
142 */
203 143
204typedef struct _PKT_STAT_DESC_t { 144struct pkt_stat_desc {
205 PKT_STAT_DESC_WORD0_t word0; 145 u32 word0;
206 PKT_STAT_DESC_WORD1_t word1; 146 u32 word1;
207} PKT_STAT_DESC_t, *PPKT_STAT_DESC_t; 147};
208 148
209/* Typedefs for the RX DMA status word */ 149/* Typedefs for the RX DMA status word */
210 150
@@ -223,59 +163,38 @@ typedef struct _PKT_STAT_DESC_t {
223 * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine 163 * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine
224 * that get copied out to memory by the ET-1310. Word 3 is a 32 bit word 164 * that get copied out to memory by the ET-1310. Word 3 is a 32 bit word
225 * which contains the Packet Status Ring available offset. 165 * which contains the Packet Status Ring available offset.
166 *
167 * bit 0-15 reserved
168 * bit 16-27 PSRoffset
169 * bit 28 PSRwrap
170 * bit 29-31 unused
226 */ 171 */
227 172
228#define RXSTAT1_OFFSET 16
229#define RXSTAT1_MASK 0xFFF
230#define RXSTAT1_WRAP 0x10000000
231
232typedef union _rxstat_word1_t {
233 u32 value;
234 struct {
235#ifdef _BIT_FIELDS_HTOL
236 u32 PSRunused:3; /* bits 29-31 */
237 u32 PSRwrap:1; /* bit 28 */
238 u32 PSRoffset:12; /* bits 16-27 */
239 u32 reserved:16; /* bits 0-15 */
240#else
241 u32 reserved:16; /* bits 0-15 */
242 u32 PSRoffset:12; /* bits 16-27 */
243 u32 PSRwrap:1; /* bit 28 */
244 u32 PSRunused:3; /* bits 29-31 */
245#endif
246 } bits;
247} RXSTAT_WORD1_t, *PRXSTAT_WORD1_t;
248
249/* 173/*
250 * RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine 174 * struct rx_status_block is a structure representing the status of the Rx
251 * it sits in free memory, and is pointed to by 0x101c / 0x1020 175 * DMA engine it sits in free memory, and is pointed to by 0x101c / 0x1020
252 */ 176 */
253typedef struct _rx_status_block_t { 177struct rx_status_block {
254 u32 Word0; 178 u32 Word0;
255 RXSTAT_WORD1_t Word1; 179 u32 Word1;
256} RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t; 180};
257 181
258/* 182/*
259 * Structure for look-up table holding free buffer ring pointers 183 * Structure for look-up table holding free buffer ring pointers
260 */ 184 */
261typedef struct _FbrLookupTable { 185struct fbr_lookup {
262 void *Va[MAX_DESC_PER_RING_RX]; 186 void *virt[MAX_DESC_PER_RING_RX];
263 void *Buffer1[MAX_DESC_PER_RING_RX]; 187 void *buffer1[MAX_DESC_PER_RING_RX];
264 void *Buffer2[MAX_DESC_PER_RING_RX]; 188 void *buffer2[MAX_DESC_PER_RING_RX];
265 u32 PAHigh[MAX_DESC_PER_RING_RX]; 189 u32 bus_high[MAX_DESC_PER_RING_RX];
266 u32 PALow[MAX_DESC_PER_RING_RX]; 190 u32 bus_low[MAX_DESC_PER_RING_RX];
267} FBRLOOKUPTABLE, *PFBRLOOKUPTABLE; 191};
268
269typedef enum {
270 ONE_PACKET_INTERRUPT,
271 FOUR_PACKET_INTERRUPT
272} eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t;
273 192
274/* 193/*
275 * RX_RING_t is sructure representing the adaptor's local reference(s) to the 194 * struct rx_ring is the ssructure representing the adaptor's local
276 * rings 195 * reference(s) to the rings
277 */ 196 */
278typedef struct _rx_ring_t { 197struct rx_ring {
279#ifdef USE_FBR0 198#ifdef USE_FBR0
280 void *pFbr0RingVa; 199 void *pFbr0RingVa;
281 dma_addr_t pFbr0RingPa; 200 dma_addr_t pFbr0RingPa;
@@ -293,7 +212,7 @@ typedef struct _rx_ring_t {
293 dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; 212 dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
294 uint64_t Fbr1Realpa; 213 uint64_t Fbr1Realpa;
295 uint64_t Fbr1offset; 214 uint64_t Fbr1offset;
296 FBRLOOKUPTABLE *Fbr[2]; 215 struct fbr_lookup *fbr[2]; /* One per ring */
297 u32 local_Fbr1_full; 216 u32 local_Fbr1_full;
298 u32 Fbr1NumEntries; 217 u32 Fbr1NumEntries;
299 u32 Fbr1BufferSize; 218 u32 Fbr1BufferSize;
@@ -303,8 +222,8 @@ typedef struct _rx_ring_t {
303 u32 local_psr_full; 222 u32 local_psr_full;
304 u32 PsrNumEntries; 223 u32 PsrNumEntries;
305 224
306 void *pRxStatusVa; 225 struct rx_status_block *rx_status_block;
307 dma_addr_t pRxStatusPa; 226 dma_addr_t rx_status_bus;
308 227
309 struct list_head RecvBufferPool; 228 struct list_head RecvBufferPool;
310 229
@@ -320,30 +239,6 @@ typedef struct _rx_ring_t {
320 239
321 /* lookaside lists */ 240 /* lookaside lists */
322 struct kmem_cache *RecvLookaside; 241 struct kmem_cache *RecvLookaside;
323} RX_RING_t, *PRX_RING_t; 242};
324
325/* Forward reference of RFD */
326struct _MP_RFD;
327
328/* Forward declaration of the private adapter structure */
329struct et131x_adapter;
330
331/* PROTOTYPES for Initialization */
332int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter);
333void et131x_rx_dma_memory_free(struct et131x_adapter *adapter);
334int et131x_rfd_resources_alloc(struct et131x_adapter *adapter,
335 struct _MP_RFD *pMpRfd);
336void et131x_rfd_resources_free(struct et131x_adapter *adapter,
337 struct _MP_RFD *pMpRfd);
338int et131x_init_recv(struct et131x_adapter *adapter);
339
340void ConfigRxDmaRegs(struct et131x_adapter *adapter);
341void SetRxDmaTimer(struct et131x_adapter *adapter);
342void et131x_rx_dma_disable(struct et131x_adapter *adapter);
343void et131x_rx_dma_enable(struct et131x_adapter *adapter);
344
345void et131x_reset_recv(struct et131x_adapter *adapter);
346
347void et131x_handle_recv_interrupt(struct et131x_adapter *adapter);
348 243
349#endif /* __ET1310_RX_H__ */ 244#endif /* __ET1310_RX_H__ */
diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c
index 977e8b34e7a6..b6ff20f47de4 100644
--- a/drivers/staging/et131x/et1310_tx.c
+++ b/drivers/staging/et131x/et1310_tx.c
@@ -84,15 +84,9 @@
84#include <linux/ioport.h> 84#include <linux/ioport.h>
85 85
86#include "et1310_phy.h" 86#include "et1310_phy.h"
87#include "et1310_pm.h"
88#include "et1310_jagcore.h"
89
90#include "et131x_adapter.h" 87#include "et131x_adapter.h"
91#include "et131x_initpci.h"
92#include "et131x_isr.h"
93
94#include "et1310_tx.h" 88#include "et1310_tx.h"
95 89#include "et131x.h"
96 90
97static inline void et131x_free_send_packet(struct et131x_adapter *etdev, 91static inline void et131x_free_send_packet(struct et131x_adapter *etdev,
98 struct tcb *tcb); 92 struct tcb *tcb);
@@ -200,7 +194,7 @@ void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
200 */ 194 */
201void ConfigTxDmaRegs(struct et131x_adapter *etdev) 195void ConfigTxDmaRegs(struct et131x_adapter *etdev)
202{ 196{
203 struct _TXDMA_t __iomem *txdma = &etdev->regs->txdma; 197 struct txdma_regs __iomem *txdma = &etdev->regs->txdma;
204 198
205 /* Load the hardware with the start of the transmit descriptor ring. */ 199 /* Load the hardware with the start of the transmit descriptor ring. */
206 writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32), 200 writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32),
diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h
index 4f0ea81978f5..82d06e9870de 100644
--- a/drivers/staging/et131x/et1310_tx.h
+++ b/drivers/staging/et131x/et1310_tx.h
@@ -147,18 +147,4 @@ struct tx_ring {
147 int since_irq; 147 int since_irq;
148}; 148};
149 149
150/* Forward declaration of the private adapter structure */
151struct et131x_adapter;
152
153/* PROTOTYPES for et1310_tx.c */
154int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
155void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
156void ConfigTxDmaRegs(struct et131x_adapter *adapter);
157void et131x_init_send(struct et131x_adapter *adapter);
158void et131x_tx_dma_disable(struct et131x_adapter *adapter);
159void et131x_tx_dma_enable(struct et131x_adapter *adapter);
160void et131x_handle_send_interrupt(struct et131x_adapter *adapter);
161void et131x_free_busy_send_packets(struct et131x_adapter *adapter);
162int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
163
164#endif /* __ET1310_TX_H__ */ 150#endif /* __ET1310_TX_H__ */
diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h
new file mode 100644
index 000000000000..a8abfe6ca81f
--- /dev/null
+++ b/drivers/staging/et131x/et131x.h
@@ -0,0 +1,153 @@
1/*
2 * Merged from files
3 *
4 * Copyright © 2005 Agere Systems Inc.
5 * All rights reserved.
6 * http://www.agere.com
7 *
8 * SOFTWARE LICENSE
9 *
10 * This software is provided subject to the following terms and conditions,
11 * which you should read carefully before using the software. Using this
12 * software indicates your acceptance of these terms and conditions. If you do
13 * not agree with these terms and conditions, do not use the software.
14 *
15 * Copyright © 2005 Agere Systems Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source or binary forms, with or without
19 * modifications, are permitted provided that the following conditions are met:
20 *
21 * . Redistributions of source code must retain the above copyright notice, this
22 * list of conditions and the following Disclaimer as comments in the code as
23 * well as in the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * . Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following Disclaimer in the documentation
28 * and/or other materials provided with the distribution.
29 *
30 * . Neither the name of Agere Systems Inc. nor the names of the contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
33 *
34 * Disclaimer
35 *
36 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
37 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
38 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
39 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
40 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
41 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
47 * DAMAGE.
48 *
49 */
50
51/* et131x_eeprom.c */
52int et131x_init_eeprom(struct et131x_adapter *etdev);
53
54/* et131x_initpci.c */
55void ConfigGlobalRegs(struct et131x_adapter *pAdapter);
56void ConfigMMCRegs(struct et131x_adapter *pAdapter);
57void et131x_enable_interrupts(struct et131x_adapter *adapter);
58void et131x_disable_interrupts(struct et131x_adapter *adapter);
59void et131x_align_allocated_memory(struct et131x_adapter *adapter,
60 u64 *phys_addr,
61 u64 *offset, u64 mask);
62
63int et131x_adapter_setup(struct et131x_adapter *adapter);
64int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
65void et131x_adapter_memory_free(struct et131x_adapter *adapter);
66void et131x_hwaddr_init(struct et131x_adapter *adapter);
67void et131x_soft_reset(struct et131x_adapter *adapter);
68
69/* et131x_isr.c */
70irqreturn_t et131x_isr(int irq, void *dev_id);
71void et131x_isr_handler(struct work_struct *work);
72
73/* et1310_mac.c */
74void ConfigMACRegs1(struct et131x_adapter *adapter);
75void ConfigMACRegs2(struct et131x_adapter *adapter);
76void ConfigRxMacRegs(struct et131x_adapter *adapter);
77void ConfigTxMacRegs(struct et131x_adapter *adapter);
78void ConfigMacStatRegs(struct et131x_adapter *adapter);
79void ConfigFlowControl(struct et131x_adapter *adapter);
80void UpdateMacStatHostCounters(struct et131x_adapter *adapter);
81void HandleMacStatInterrupt(struct et131x_adapter *adapter);
82void SetupDeviceForMulticast(struct et131x_adapter *adapter);
83void SetupDeviceForUnicast(struct et131x_adapter *adapter);
84
85/* et131x_netdev.c */
86struct net_device *et131x_device_alloc(void);
87
88/* et131x_pm.c */
89void EnablePhyComa(struct et131x_adapter *adapter);
90void DisablePhyComa(struct et131x_adapter *adapter);
91
92/* et131x_phy.c */
93void ET1310_PhyInit(struct et131x_adapter *adapter);
94void ET1310_PhyReset(struct et131x_adapter *adapter);
95void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
96void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
97 u16 duplex);
98void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
99 u16 action,
100 u16 regnum, u16 bitnum, u8 *value);
101
102int et131x_xcvr_find(struct et131x_adapter *adapter);
103void et131x_setphy_normal(struct et131x_adapter *adapter);
104
105/* static inline function does not work because et131x_adapter is not always
106 * defined
107 */
108int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr,
109 u8 xcvrReg, u16 *value);
110#define MiRead(adapter, xcvrReg, value) \
111 PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
112
113int32_t MiWrite(struct et131x_adapter *adapter,
114 u8 xcvReg, u16 value);
115void et131x_Mii_check(struct et131x_adapter *pAdapter,
116 MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints);
117
118/* This last is not strictly required (the driver could call the TPAL
119 * version instead), but this sets the adapter up correctly, and calls the
120 * access routine indirectly. This protects the driver from changes in TPAL.
121 */
122void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
123
124
125/* et1310_rx.c */
126int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter);
127void et131x_rx_dma_memory_free(struct et131x_adapter *adapter);
128int et131x_rfd_resources_alloc(struct et131x_adapter *adapter,
129 struct _MP_RFD *pMpRfd);
130void et131x_rfd_resources_free(struct et131x_adapter *adapter,
131 struct _MP_RFD *pMpRfd);
132int et131x_init_recv(struct et131x_adapter *adapter);
133
134void ConfigRxDmaRegs(struct et131x_adapter *adapter);
135void SetRxDmaTimer(struct et131x_adapter *adapter);
136void et131x_rx_dma_disable(struct et131x_adapter *adapter);
137void et131x_rx_dma_enable(struct et131x_adapter *adapter);
138
139void et131x_reset_recv(struct et131x_adapter *adapter);
140
141void et131x_handle_recv_interrupt(struct et131x_adapter *adapter);
142
143/* et131x_tx.c */
144int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
145void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
146void ConfigTxDmaRegs(struct et131x_adapter *adapter);
147void et131x_init_send(struct et131x_adapter *adapter);
148void et131x_tx_dma_disable(struct et131x_adapter *adapter);
149void et131x_tx_dma_enable(struct et131x_adapter *adapter);
150void et131x_handle_send_interrupt(struct et131x_adapter *adapter);
151void et131x_free_busy_send_packets(struct et131x_adapter *adapter);
152int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
153
diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h
index 3f7f37a56b6c..64a678fcb60a 100644
--- a/drivers/staging/et131x/et131x_adapter.h
+++ b/drivers/staging/et131x/et131x_adapter.h
@@ -77,38 +77,11 @@
77 */ 77 */
78#define NUM_TRAFFIC_CLASSES 1 78#define NUM_TRAFFIC_CLASSES 1
79 79
80/*
81 * There are three ways of counting errors - if there are more than X errors
82 * in Y packets (represented by the "SAMPLE" macros), if there are more than
83 * N errors in a S mSec time period (the "PERIOD" macros), or if there are
84 * consecutive packets with errors (CONSEC_ERRORED_THRESH). This last covers
85 * for "Bursty" errors, and the errored packets may well not be contiguous,
86 * but several errors where the packet counter has changed by less than a
87 * small amount will cause this count to increment.
88 */
89#define TX_PACKETS_IN_SAMPLE 10000
90#define TX_MAX_ERRORS_IN_SAMPLE 50
91
92#define TX_ERROR_PERIOD 1000 80#define TX_ERROR_PERIOD 1000
93#define TX_MAX_ERRORS_IN_PERIOD 10
94
95#define LINK_DETECTION_TIMER 5000
96
97#define TX_CONSEC_RANGE 5
98#define TX_CONSEC_ERRORED_THRESH 10
99 81
100#define LO_MARK_PERCENT_FOR_PSR 15 82#define LO_MARK_PERCENT_FOR_PSR 15
101#define LO_MARK_PERCENT_FOR_RX 15 83#define LO_MARK_PERCENT_FOR_RX 15
102 84
103/* Counters for error rate monitoring */
104typedef struct _MP_ERR_COUNTERS {
105 u32 PktCountTxPackets;
106 u32 PktCountTxErrors;
107 u32 TimerBasedTxErrors;
108 u32 PktCountLastError;
109 u32 ErredConsecPackets;
110} MP_ERR_COUNTERS, *PMP_ERR_COUNTERS;
111
112/* RFD (Receive Frame Descriptor) */ 85/* RFD (Receive Frame Descriptor) */
113typedef struct _MP_RFD { 86typedef struct _MP_RFD {
114 struct list_head list_node; 87 struct list_head list_node;
@@ -174,6 +147,20 @@ typedef struct _ce_stats_t {
174 u32 InterruptStatus; 147 u32 InterruptStatus;
175} CE_STATS_t, *PCE_STATS_t; 148} CE_STATS_t, *PCE_STATS_t;
176 149
150typedef struct _MP_POWER_MGMT {
151 /* variable putting the phy into coma mode when boot up with no cable
152 * plugged in after 5 seconds
153 */
154 u8 TransPhyComaModeOnBoot;
155
156 /* Next two used to save power information at power down. This
157 * information will be used during power up to set up parts of Power
158 * Management in JAGCore
159 */
160 u16 PowerDownSpeed;
161 u8 PowerDownDuplex;
162} MP_POWER_MGMT, *PMP_POWER_MGMT;
163
177/* The private adapter structure */ 164/* The private adapter structure */
178struct et131x_adapter { 165struct et131x_adapter {
179 struct net_device *netdev; 166 struct net_device *netdev;
@@ -248,7 +235,7 @@ struct et131x_adapter {
248 struct tx_ring tx_ring; 235 struct tx_ring tx_ring;
249 236
250 /* Rx Memory Variables */ 237 /* Rx Memory Variables */
251 RX_RING_t RxRing; 238 struct rx_ring rx_ring;
252 239
253 /* Loopback specifics */ 240 /* Loopback specifics */
254 u8 ReplicaPhyLoopbk; /* Replica Enable */ 241 u8 ReplicaPhyLoopbk; /* Replica Enable */
diff --git a/drivers/staging/et131x/et131x_config.h b/drivers/staging/et131x/et131x_config.h
deleted file mode 100644
index 642c0f6dd6f3..000000000000
--- a/drivers/staging/et131x/et131x_config.h
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et131x_config.h - Defines, structs, enums, prototypes, etc. to support
12 * et131x_config.c
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef __ET131X_CONFIG_H__
60#define __ET131X_CONFIG_H__
61
62/* Forward declaration of the private adapter structure */
63struct et131x_adapter;
64
65void et131x_config_parse(struct et131x_adapter *adapter);
66
67#endif /* __ET131X_CONFIG_H__ */
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
index 0892b6a538db..5ad7e5a6f631 100644
--- a/drivers/staging/et131x/et131x_initpci.c
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -87,20 +87,16 @@
87#include <linux/random.h> 87#include <linux/random.h>
88 88
89#include "et1310_phy.h" 89#include "et1310_phy.h"
90#include "et1310_pm.h"
91#include "et1310_jagcore.h"
92 90
93#include "et131x_adapter.h" 91#include "et131x_adapter.h"
94#include "et131x_netdev.h"
95#include "et131x_config.h"
96#include "et131x_isr.h"
97 92
98#include "et1310_address_map.h" 93#include "et1310_address_map.h"
99#include "et1310_tx.h" 94#include "et1310_tx.h"
100#include "et1310_rx.h" 95#include "et1310_rx.h"
101#include "et1310_mac.h" 96#include "et131x.h"
102#include "et1310_eeprom.h"
103 97
98#define INTERNAL_MEM_SIZE 0x400 /* 1024 of internal memory */
99#define INTERNAL_MEM_RX_OFFSET 0x1FF /* 50% Tx, 50% Rx */
104 100
105/* Defines for Parameter Default/Min/Max vaules */ 101/* Defines for Parameter Default/Min/Max vaules */
106#define PARM_SPEED_DUPLEX_MIN 0 102#define PARM_SPEED_DUPLEX_MIN 0
@@ -327,7 +323,7 @@ void et131x_link_detection_handler(unsigned long data)
327 */ 323 */
328void ConfigGlobalRegs(struct et131x_adapter *etdev) 324void ConfigGlobalRegs(struct et131x_adapter *etdev)
329{ 325{
330 struct _GLOBAL_t __iomem *regs = &etdev->regs->global; 326 struct global_regs __iomem *regs = &etdev->regs->global;
331 327
332 writel(0, &regs->rxq_start_addr); 328 writel(0, &regs->rxq_start_addr);
333 writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr); 329 writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h
deleted file mode 100644
index 7269569a874b..000000000000
--- a/drivers/staging/et131x/et131x_initpci.h
+++ /dev/null
@@ -1,73 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et131x_initpci.h - Header which includes common data and function prototypes
12 * related to the driver's PCI (and PCI Express) information.
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef __ET131X_INITPCI_H__
60#define __ET131X_INITPCI_H__
61
62/* Function Prototypes */
63void et131x_align_allocated_memory(struct et131x_adapter *adapter,
64 u64 *phys_addr,
65 u64 *offset, u64 mask);
66
67int et131x_adapter_setup(struct et131x_adapter *adapter);
68int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
69void et131x_adapter_memory_free(struct et131x_adapter *adapter);
70void et131x_hwaddr_init(struct et131x_adapter *adapter);
71void et131x_soft_reset(struct et131x_adapter *adapter);
72
73#endif /* __ET131X_INITPCI_H__ */
diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c
index f6d452dd14e2..8b6e0b7ec568 100644
--- a/drivers/staging/et131x/et131x_isr.c
+++ b/drivers/staging/et131x/et131x_isr.c
@@ -85,11 +85,27 @@
85#include <linux/ioport.h> 85#include <linux/ioport.h>
86 86
87#include "et1310_phy.h" 87#include "et1310_phy.h"
88#include "et1310_pm.h"
89#include "et1310_jagcore.h"
90#include "et1310_mac.h"
91
92#include "et131x_adapter.h" 88#include "et131x_adapter.h"
89#include "et131x.h"
90
91/*
92 * For interrupts, normal running is:
93 * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt,
94 * watchdog_interrupt & txdma_xfer_done
95 *
96 * In both cases, when flow control is enabled for either Tx or bi-direction,
97 * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the
98 * buffer rings are running low.
99 */
100#define INT_MASK_DISABLE 0xffffffff
101
102/* NOTE: Masking out MAC_STAT Interrupt for now...
103 * #define INT_MASK_ENABLE 0xfff6bf17
104 * #define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7
105 */
106#define INT_MASK_ENABLE 0xfffebf17
107#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7
108
93 109
94/** 110/**
95 * et131x_enable_interrupts - enable interrupt 111 * et131x_enable_interrupts - enable interrupt
@@ -185,7 +201,7 @@ irqreturn_t et131x_isr(int irq, void *dev_id)
185 if (++tcb->stale > 1) 201 if (++tcb->stale > 1)
186 status |= ET_INTR_TXDMA_ISR; 202 status |= ET_INTR_TXDMA_ISR;
187 203
188 if (adapter->RxRing.UnfinishedReceives) 204 if (adapter->rx_ring.UnfinishedReceives)
189 status |= ET_INTR_RXDMA_XFR_DONE; 205 status |= ET_INTR_RXDMA_XFR_DONE;
190 else if (tcb == NULL) 206 else if (tcb == NULL)
191 writel(0, &adapter->regs->global.watchdog_timer); 207 writel(0, &adapter->regs->global.watchdog_timer);
@@ -390,7 +406,7 @@ void et131x_isr_handler(struct work_struct *work)
390 406
391 /* Let's move on to the TxMac */ 407 /* Let's move on to the TxMac */
392 if (status & ET_INTR_TXMAC) { 408 if (status & ET_INTR_TXMAC) {
393 u32 err = readl(&iomem->txmac.err.value); 409 u32 err = readl(&iomem->txmac.err);
394 410
395 /* 411 /*
396 * When any of the errors occur and TXMAC generates 412 * When any of the errors occur and TXMAC generates
@@ -425,12 +441,12 @@ void et131x_isr_handler(struct work_struct *work)
425 441
426 dev_warn(&etdev->pdev->dev, 442 dev_warn(&etdev->pdev->dev,
427 "RXMAC interrupt, error 0x%08x. Requesting reset\n", 443 "RXMAC interrupt, error 0x%08x. Requesting reset\n",
428 readl(&iomem->rxmac.err_reg.value)); 444 readl(&iomem->rxmac.err_reg));
429 445
430 dev_warn(&etdev->pdev->dev, 446 dev_warn(&etdev->pdev->dev,
431 "Enable 0x%08x, Diag 0x%08x\n", 447 "Enable 0x%08x, Diag 0x%08x\n",
432 readl(&iomem->rxmac.ctrl.value), 448 readl(&iomem->rxmac.ctrl),
433 readl(&iomem->rxmac.rxq_diag.value)); 449 readl(&iomem->rxmac.rxq_diag));
434 450
435 /* 451 /*
436 * If we are debugging, we want to see this error, 452 * If we are debugging, we want to see this error,
diff --git a/drivers/staging/et131x/et131x_isr.h b/drivers/staging/et131x/et131x_isr.h
deleted file mode 100644
index 906d57727e20..000000000000
--- a/drivers/staging/et131x/et131x_isr.h
+++ /dev/null
@@ -1,65 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the
12 * ISR processing code.
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef __ET131X_ISR_H__
60#define __ET131X_ISR_H__
61
62irqreturn_t et131x_isr(int irq, void *dev_id);
63void et131x_isr_handler(struct work_struct *work);
64
65#endif /* __ET131X_ISR_H__ */
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c
index edb78ae9e593..40f8954dde47 100644
--- a/drivers/staging/et131x/et131x_netdev.c
+++ b/drivers/staging/et131x/et131x_netdev.c
@@ -85,14 +85,9 @@
85#include <linux/ioport.h> 85#include <linux/ioport.h>
86 86
87#include "et1310_phy.h" 87#include "et1310_phy.h"
88#include "et1310_pm.h"
89#include "et1310_jagcore.h"
90#include "et1310_mac.h"
91#include "et1310_tx.h" 88#include "et1310_tx.h"
92
93#include "et131x_adapter.h" 89#include "et131x_adapter.h"
94#include "et131x_isr.h" 90#include "et131x.h"
95#include "et131x_initpci.h"
96 91
97struct net_device_stats *et131x_stats(struct net_device *netdev); 92struct net_device_stats *et131x_stats(struct net_device *netdev);
98int et131x_open(struct net_device *netdev); 93int et131x_open(struct net_device *netdev);
@@ -339,66 +334,64 @@ int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd)
339 * et131x_set_packet_filter - Configures the Rx Packet filtering on the device 334 * et131x_set_packet_filter - Configures the Rx Packet filtering on the device
340 * @adapter: pointer to our private adapter structure 335 * @adapter: pointer to our private adapter structure
341 * 336 *
337 * FIXME: lot of dups with MAC code
338 *
342 * Returns 0 on success, errno on failure 339 * Returns 0 on success, errno on failure
343 */ 340 */
344int et131x_set_packet_filter(struct et131x_adapter *adapter) 341int et131x_set_packet_filter(struct et131x_adapter *adapter)
345{ 342{
346 int status = 0; 343 int status = 0;
347 uint32_t filter = adapter->PacketFilter; 344 uint32_t filter = adapter->PacketFilter;
348 RXMAC_CTRL_t ctrl; 345 u32 ctrl;
349 RXMAC_PF_CTRL_t pf_ctrl; 346 u32 pf_ctrl;
350 347
351 ctrl.value = readl(&adapter->regs->rxmac.ctrl.value); 348 ctrl = readl(&adapter->regs->rxmac.ctrl);
352 pf_ctrl.value = readl(&adapter->regs->rxmac.pf_ctrl.value); 349 pf_ctrl = readl(&adapter->regs->rxmac.pf_ctrl);
353 350
354 /* Default to disabled packet filtering. Enable it in the individual 351 /* Default to disabled packet filtering. Enable it in the individual
355 * case statements that require the device to filter something 352 * case statements that require the device to filter something
356 */ 353 */
357 ctrl.bits.pkt_filter_disable = 1; 354 ctrl |= 0x04;
358 355
359 /* Set us to be in promiscuous mode so we receive everything, this 356 /* Set us to be in promiscuous mode so we receive everything, this
360 * is also true when we get a packet filter of 0 357 * is also true when we get a packet filter of 0
361 */ 358 */
362 if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0) { 359 if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0)
363 pf_ctrl.bits.filter_broad_en = 0; 360 pf_ctrl &= ~7; /* Clear filter bits */
364 pf_ctrl.bits.filter_multi_en = 0; 361 else {
365 pf_ctrl.bits.filter_uni_en = 0;
366 } else {
367 /* 362 /*
368 * Set us up with Multicast packet filtering. Three cases are 363 * Set us up with Multicast packet filtering. Three cases are
369 * possible - (1) we have a multi-cast list, (2) we receive ALL 364 * possible - (1) we have a multi-cast list, (2) we receive ALL
370 * multicast entries or (3) we receive none. 365 * multicast entries or (3) we receive none.
371 */ 366 */
372 if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) { 367 if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST)
373 pf_ctrl.bits.filter_multi_en = 0; 368 pf_ctrl &= ~2; /* Multicast filter bit */
374 } else { 369 else {
375 SetupDeviceForMulticast(adapter); 370 SetupDeviceForMulticast(adapter);
376 pf_ctrl.bits.filter_multi_en = 1; 371 pf_ctrl |= 2;
377 ctrl.bits.pkt_filter_disable = 0; 372 ctrl &= ~0x04;
378 } 373 }
379 374
380 /* Set us up with Unicast packet filtering */ 375 /* Set us up with Unicast packet filtering */
381 if (filter & ET131X_PACKET_TYPE_DIRECTED) { 376 if (filter & ET131X_PACKET_TYPE_DIRECTED) {
382 SetupDeviceForUnicast(adapter); 377 SetupDeviceForUnicast(adapter);
383 pf_ctrl.bits.filter_uni_en = 1; 378 pf_ctrl |= 4;
384 ctrl.bits.pkt_filter_disable = 0; 379 ctrl &= ~0x04;
385 } 380 }
386 381
387 /* Set us up with Broadcast packet filtering */ 382 /* Set us up with Broadcast packet filtering */
388 if (filter & ET131X_PACKET_TYPE_BROADCAST) { 383 if (filter & ET131X_PACKET_TYPE_BROADCAST) {
389 pf_ctrl.bits.filter_broad_en = 1; 384 pf_ctrl |= 1; /* Broadcast filter bit */
390 ctrl.bits.pkt_filter_disable = 0; 385 ctrl &= ~0x04;
391 } else { 386 } else
392 pf_ctrl.bits.filter_broad_en = 0; 387 pf_ctrl &= ~1;
393 }
394 388
395 /* Setup the receive mac configuration registers - Packet 389 /* Setup the receive mac configuration registers - Packet
396 * Filter control + the enable / disable for packet filter 390 * Filter control + the enable / disable for packet filter
397 * in the control reg. 391 * in the control reg.
398 */ 392 */
399 writel(pf_ctrl.value, 393 writel(pf_ctrl, &adapter->regs->rxmac.pf_ctrl);
400 &adapter->regs->rxmac.pf_ctrl.value); 394 writel(ctrl, &adapter->regs->rxmac.ctrl);
401 writel(ctrl.value, &adapter->regs->rxmac.ctrl.value);
402 } 395 }
403 return status; 396 return status;
404} 397}
@@ -675,12 +668,8 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
675 668
676 memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); 669 memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len);
677 670
678 printk(KERN_INFO 671 printk(KERN_INFO "%s: Setting MAC address to %pM\n",
679 "%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", 672 netdev->name, netdev->dev_addr);
680 netdev->name,
681 netdev->dev_addr[0], netdev->dev_addr[1],
682 netdev->dev_addr[2], netdev->dev_addr[3],
683 netdev->dev_addr[4], netdev->dev_addr[5]);
684 673
685 /* Free Rx DMA memory */ 674 /* Free Rx DMA memory */
686 et131x_adapter_memory_free(adapter); 675 et131x_adapter_memory_free(adapter);
diff --git a/drivers/staging/et131x/et131x_netdev.h b/drivers/staging/et131x/et131x_netdev.h
deleted file mode 100644
index 1eb4a922c01d..000000000000
--- a/drivers/staging/et131x/et131x_netdev.h
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * Agere Systems Inc.
3 * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
4 *
5 * Copyright © 2005 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
8 *
9 *------------------------------------------------------------------------------
10 *
11 * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the
12 * driver's net_device support.
13 *
14 *------------------------------------------------------------------------------
15 *
16 * SOFTWARE LICENSE
17 *
18 * This software is provided subject to the following terms and conditions,
19 * which you should read carefully before using the software. Using this
20 * software indicates your acceptance of these terms and conditions. If you do
21 * not agree with these terms and conditions, do not use the software.
22 *
23 * Copyright © 2005 Agere Systems Inc.
24 * All rights reserved.
25 *
26 * Redistribution and use in source or binary forms, with or without
27 * modifications, are permitted provided that the following conditions are met:
28 *
29 * . Redistributions of source code must retain the above copyright notice, this
30 * list of conditions and the following Disclaimer as comments in the code as
31 * well as in the documentation and/or other materials provided with the
32 * distribution.
33 *
34 * . Redistributions in binary form must reproduce the above copyright notice,
35 * this list of conditions and the following Disclaimer in the documentation
36 * and/or other materials provided with the distribution.
37 *
38 * . Neither the name of Agere Systems Inc. nor the names of the contributors
39 * may be used to endorse or promote products derived from this software
40 * without specific prior written permission.
41 *
42 * Disclaimer
43 *
44 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
45 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
46 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
47 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
48 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
54 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 * DAMAGE.
56 *
57 */
58
59#ifndef __ET131X_NETDEV_H__
60#define __ET131X_NETDEV_H__
61
62struct net_device *et131x_device_alloc(void);
63
64#endif /* __ET131X_NETDEV_H__ */
diff --git a/drivers/staging/et131x/et131x_version.h b/drivers/staging/et131x/et131x_version.h
index 568f6c8c34f5..2aa9bda44ac0 100644
--- a/drivers/staging/et131x/et131x_version.h
+++ b/drivers/staging/et131x/et131x_version.h
@@ -62,20 +62,13 @@
62#define DRIVER_LICENSE "Dual BSD/GPL" 62#define DRIVER_LICENSE "Dual BSD/GPL"
63#define DRIVER_DEVICE_STRING "ET1310" 63#define DRIVER_DEVICE_STRING "ET1310"
64#define DRIVER_NAME "et131x" 64#define DRIVER_NAME "et131x"
65#define DRIVER_MAJOR_VERSION 1 65#define DRIVER_VERSION_STRING "1.2.3-lk"
66#define DRIVER_MINOR_VERSION 2
67#define DRIVER_PATCH_VERSION 3
68#define DRIVER_VERSION_STRING "1.2.3"
69#define DRIVER_VENDOR "Agere Systems, http://www.agere.com" 66#define DRIVER_VENDOR "Agere Systems, http://www.agere.com"
70#define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver" 67#define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver"
71 68
72#define STRUCT_MODULE "net" /* blux: missed by the kernel */
73
74#define DRIVER_INFO DRIVER_DESC " for the "\ 69#define DRIVER_INFO DRIVER_DESC " for the "\
75 DRIVER_DEVICE_STRING ", v" \ 70 DRIVER_DEVICE_STRING ", v" \
76 DRIVER_VERSION_STRING " by " \ 71 DRIVER_VERSION_STRING " by " \
77 DRIVER_VENDOR 72 DRIVER_VENDOR
78 73
79#define DRIVER_NAME_EXT "et131x.ko"
80
81#endif /* __ET131X_VERSION_H__ */ 74#endif /* __ET131X_VERSION_H__ */
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index 15aed87fe1bb..a50a21518a8e 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -58,7 +58,7 @@
58#endif 58#endif
59 59
60/* table of devices that work with this driver */ 60/* table of devices that work with this driver */
61static struct usb_device_id usb_alphatrack_table[] = { 61static const struct usb_device_id usb_alphatrack_table[] = {
62 {USB_DEVICE(VENDOR_ID, PRODUCT_ID)}, 62 {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
63 {} /* Terminating entry */ 63 {} /* Terminating entry */
64}; 64};
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index ef8fcc8c67bd..2f03f43f3a2e 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -55,7 +55,7 @@
55#endif 55#endif
56 56
57/* table of devices that work with this driver */ 57/* table of devices that work with this driver */
58static struct usb_device_id usb_tranzport_table[] = { 58static const struct usb_device_id usb_tranzport_table[] = {
59 {USB_DEVICE(VENDOR_ID, PRODUCT_ID)}, 59 {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
60 {} /* Terminating entry */ 60 {} /* Terminating entry */
61}; 61};
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index fb1345ffb858..d42ba1696999 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -128,6 +128,8 @@ static int go7007_load_encoder(struct go7007 *go)
128 return rv; 128 return rv;
129} 129}
130 130
131MODULE_FIRMWARE("go7007fw.bin");
132
131/* 133/*
132 * Boot the encoder and register the I2C adapter if requested. Do the 134 * Boot the encoder and register the I2C adapter if requested. Do the
133 * minimum initialization necessary, since the board-specific code may 135 * minimum initialization necessary, since the board-specific code may
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index 1e89dc04ec23..ee278f64a16b 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -444,7 +444,9 @@ static struct go7007_usb_board board_sensoray_2250 = {
444 }, 444 },
445}; 445};
446 446
447static struct usb_device_id go7007_usb_id_table[] = { 447MODULE_FIRMWARE("go7007tv.bin");
448
449static const struct usb_device_id go7007_usb_id_table[] = {
448 { 450 {
449 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION | 451 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
450 USB_DEVICE_ID_MATCH_INT_INFO, 452 USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index c324f6ea002b..dc89502ea1b7 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -667,7 +667,7 @@ static int s2250_remove(struct i2c_client *client)
667 return 0; 667 return 0;
668} 668}
669 669
670static struct i2c_device_id s2250_id[] = { 670static const struct i2c_device_id s2250_id[] = {
671 { "s2250", 0 }, 671 { "s2250", 0 },
672 { } 672 { }
673}; 673};
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index c152ab9be2fb..1de2dfb16d3f 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -139,7 +139,7 @@ failed2:
139 139
140static void s2250loader_disconnect(struct usb_interface *interface) 140static void s2250loader_disconnect(struct usb_interface *interface)
141{ 141{
142 pdevice_extension_t s = usb_get_intfdata(interface); 142 pdevice_extension_t s;
143 printk(KERN_INFO "s2250: disconnect\n"); 143 printk(KERN_INFO "s2250: disconnect\n");
144 lock_kernel(); 144 lock_kernel();
145 s = usb_get_intfdata(interface); 145 s = usb_get_intfdata(interface);
@@ -148,7 +148,7 @@ static void s2250loader_disconnect(struct usb_interface *interface)
148 unlock_kernel(); 148 unlock_kernel();
149} 149}
150 150
151static struct usb_device_id s2250loader_ids[] = { 151static const struct usb_device_id s2250loader_ids[] = {
152 {USB_DEVICE(0x1943, 0xa250)}, 152 {USB_DEVICE(0x1943, 0xa250)},
153 {} /* Terminating entry */ 153 {} /* Terminating entry */
154}; 154};
diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c
index 665bbf59d026..b25d7d2090e1 100644
--- a/drivers/staging/go7007/saa7134-go7007.c
+++ b/drivers/staging/go7007/saa7134-go7007.c
@@ -84,6 +84,7 @@ static struct go7007_board_info board_voyager = {
84 }, 84 },
85 }, 85 },
86}; 86};
87MODULE_FIRMWARE("go7007tv.bin");
87 88
88/********************* Driver for GPIO HPI interface *********************/ 89/********************* Driver for GPIO HPI interface *********************/
89 90
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c
index 04d6d3a498a3..4f0cbdde2765 100644
--- a/drivers/staging/go7007/wis-ov7640.c
+++ b/drivers/staging/go7007/wis-ov7640.c
@@ -77,7 +77,7 @@ static int wis_ov7640_remove(struct i2c_client *client)
77 return 0; 77 return 0;
78} 78}
79 79
80static struct i2c_device_id wis_ov7640_id[] = { 80static const struct i2c_device_id wis_ov7640_id[] = {
81 { "wis_ov7640", 0 }, 81 { "wis_ov7640", 0 },
82 { } 82 { }
83}; 83};
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c
index 9ab893bd204e..d196e16fe72b 100644
--- a/drivers/staging/go7007/wis-saa7113.c
+++ b/drivers/staging/go7007/wis-saa7113.c
@@ -304,7 +304,7 @@ static int wis_saa7113_remove(struct i2c_client *client)
304 return 0; 304 return 0;
305} 305}
306 306
307static struct i2c_device_id wis_saa7113_id[] = { 307static const struct i2c_device_id wis_saa7113_id[] = {
308 { "wis_saa7113", 0 }, 308 { "wis_saa7113", 0 },
309 { } 309 { }
310}; 310};
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c
index 8687ad2de761..0f2b4a0ceccf 100644
--- a/drivers/staging/go7007/wis-saa7115.c
+++ b/drivers/staging/go7007/wis-saa7115.c
@@ -437,7 +437,7 @@ static int wis_saa7115_remove(struct i2c_client *client)
437 return 0; 437 return 0;
438} 438}
439 439
440static struct i2c_device_id wis_saa7115_id[] = { 440static const struct i2c_device_id wis_saa7115_id[] = {
441 { "wis_saa7115", 0 }, 441 { "wis_saa7115", 0 },
442 { } 442 { }
443}; 443};
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c
index 086896cec49b..c723e4aa7147 100644
--- a/drivers/staging/go7007/wis-sony-tuner.c
+++ b/drivers/staging/go7007/wis-sony-tuner.c
@@ -688,7 +688,7 @@ static int wis_sony_tuner_remove(struct i2c_client *client)
688 return 0; 688 return 0;
689} 689}
690 690
691static struct i2c_device_id wis_sony_tuner_id[] = { 691static const struct i2c_device_id wis_sony_tuner_id[] = {
692 { "wis_sony_tuner", 0 }, 692 { "wis_sony_tuner", 0 },
693 { } 693 { }
694}; 694};
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c
index e15794a2a0ae..1983839f554d 100644
--- a/drivers/staging/go7007/wis-tw2804.c
+++ b/drivers/staging/go7007/wis-tw2804.c
@@ -327,7 +327,7 @@ static int wis_tw2804_remove(struct i2c_client *client)
327 return 0; 327 return 0;
328} 328}
329 329
330static struct i2c_device_id wis_tw2804_id[] = { 330static const struct i2c_device_id wis_tw2804_id[] = {
331 { "wis_tw2804", 0 }, 331 { "wis_tw2804", 0 },
332 { } 332 { }
333}; 333};
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 506dca6e942e..f97e2be3c0b5 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -309,7 +309,7 @@ static int wis_tw9903_remove(struct i2c_client *client)
309 return 0; 309 return 0;
310} 310}
311 311
312static struct i2c_device_id wis_tw9903_id[] = { 312static const struct i2c_device_id wis_tw9903_id[] = {
313 { "wis_tw9903", 0 }, 313 { "wis_tw9903", 0 },
314 { } 314 { }
315}; 315};
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c
index 739c7ae8913f..5c4eb49d7357 100644
--- a/drivers/staging/go7007/wis-uda1342.c
+++ b/drivers/staging/go7007/wis-uda1342.c
@@ -82,7 +82,7 @@ static int wis_uda1342_remove(struct i2c_client *client)
82 return 0; 82 return 0;
83} 83}
84 84
85static struct i2c_device_id wis_uda1342_id[] = { 85static const struct i2c_device_id wis_uda1342_id[] = {
86 { "wis_uda1342", 0 }, 86 { "wis_uda1342", 0 },
87 { } 87 { }
88}; 88};
diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c
index 746370e82115..d46eb145484f 100644
--- a/drivers/staging/hv/Channel.c
+++ b/drivers/staging/hv/Channel.c
@@ -991,9 +991,8 @@ void VmbusChannelOnTimer(unsigned long data)
991{ 991{
992 struct vmbus_channel *channel = (struct vmbus_channel *)data; 992 struct vmbus_channel *channel = (struct vmbus_channel *)data;
993 993
994 if (channel->OnChannelCallback) { 994 if (channel->OnChannelCallback)
995 channel->OnChannelCallback(channel->ChannelCallbackContext); 995 channel->OnChannelCallback(channel->ChannelCallbackContext);
996 }
997} 996}
998 997
999/** 998/**
diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c
index c2809f2a2ce0..51149e69f3e8 100644
--- a/drivers/staging/hv/Hv.c
+++ b/drivers/staging/hv/Hv.c
@@ -208,50 +208,51 @@ int HvInit(void)
208 /* HvQueryHypervisorFeatures(maxLeaf); */ 208 /* HvQueryHypervisorFeatures(maxLeaf); */
209 209
210 /* 210 /*
211 * Determine if we are running on xenlinux (ie x2v shim) or native 211 * We only support running on top of Hyper-V
212 * linux
213 */ 212 */
214 rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId); 213 rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
215 if (gHvContext.GuestId == 0) { 214
216 /* Write our OS info */ 215 if (gHvContext.GuestId != 0) {
217 wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); 216 DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
218 gHvContext.GuestId = HV_LINUX_GUEST_ID; 217 gHvContext.GuestId);
218 goto Cleanup;
219 } 219 }
220 220
221 /* Write our OS info */
222 wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
223 gHvContext.GuestId = HV_LINUX_GUEST_ID;
224
221 /* See if the hypercall page is already set */ 225 /* See if the hypercall page is already set */
222 rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); 226 rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
223 if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
224 /* Allocate the hypercall page memory */
225 /* virtAddr = osd_PageAlloc(1); */
226 virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
227
228 if (!virtAddr) {
229 DPRINT_ERR(VMBUS,
230 "unable to allocate hypercall page!!");
231 goto Cleanup;
232 }
233 227
234 hypercallMsr.Enable = 1; 228 /*
235 /* hypercallMsr.GuestPhysicalAddress = 229 * Allocate the hypercall page memory
236 * virt_to_phys(virtAddr) >> PAGE_SHIFT; */ 230 * virtAddr = osd_PageAlloc(1);
237 hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr); 231 */
238 wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); 232 virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
239 233
240 /* Confirm that hypercall page did get setup. */ 234 if (!virtAddr) {
241 hypercallMsr.AsUINT64 = 0; 235 DPRINT_ERR(VMBUS,
242 rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); 236 "unable to allocate hypercall page!!");
243 if (!hypercallMsr.Enable) { 237 goto Cleanup;
244 DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); 238 }
245 goto Cleanup;
246 }
247 239
248 gHvContext.HypercallPage = virtAddr; 240 hypercallMsr.Enable = 1;
249 } else { 241
250 DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", 242 hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
251 gHvContext.GuestId); 243 wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
244
245 /* Confirm that hypercall page did get setup. */
246 hypercallMsr.AsUINT64 = 0;
247 rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
248
249 if (!hypercallMsr.Enable) {
250 DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
252 goto Cleanup; 251 goto Cleanup;
253 } 252 }
254 253
254 gHvContext.HypercallPage = virtAddr;
255
255 DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", 256 DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
256 gHvContext.HypercallPage, 257 gHvContext.HypercallPage,
257 (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT); 258 (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
@@ -273,8 +274,6 @@ int HvInit(void)
273 gHvContext.SignalEventParam->FlagNumber = 0; 274 gHvContext.SignalEventParam->FlagNumber = 0;
274 gHvContext.SignalEventParam->RsvdZ = 0; 275 gHvContext.SignalEventParam->RsvdZ = 0;
275 276
276 /* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */
277
278 DPRINT_EXIT(VMBUS); 277 DPRINT_EXIT(VMBUS);
279 278
280 return ret; 279 return ret;
@@ -311,17 +310,14 @@ void HvCleanup(void)
311 kfree(gHvContext.SignalEventBuffer); 310 kfree(gHvContext.SignalEventBuffer);
312 } 311 }
313 312
314 if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { 313 if (gHvContext.HypercallPage) {
315 if (gHvContext.HypercallPage) { 314 hypercallMsr.AsUINT64 = 0;
316 hypercallMsr.AsUINT64 = 0; 315 wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
317 wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); 316 vfree(gHvContext.HypercallPage);
318 vfree(gHvContext.HypercallPage); 317 gHvContext.HypercallPage = NULL;
319 gHvContext.HypercallPage = NULL;
320 }
321 } 318 }
322 319
323 DPRINT_EXIT(VMBUS); 320 DPRINT_EXIT(VMBUS);
324
325} 321}
326 322
327/** 323/**
@@ -393,7 +389,7 @@ void HvSynicInit(void *irqarg)
393 union hv_synic_siefp siefp; 389 union hv_synic_siefp siefp;
394 union hv_synic_sint sharedSint; 390 union hv_synic_sint sharedSint;
395 union hv_synic_scontrol sctrl; 391 union hv_synic_scontrol sctrl;
396 u64 guestID; 392
397 u32 irqVector = *((u32 *)(irqarg)); 393 u32 irqVector = *((u32 *)(irqarg));
398 int cpu = smp_processor_id(); 394 int cpu = smp_processor_id();
399 395
@@ -409,71 +405,41 @@ void HvSynicInit(void *irqarg)
409 405
410 DPRINT_INFO(VMBUS, "SynIC version: %llx", version); 406 DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
411 407
412 /* TODO: Handle SMP */ 408 gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
413 if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID) {
414 DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since "
415 "it is already set.");
416
417 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
418 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
419
420 DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx",
421 simp.AsUINT64, siefp.AsUINT64);
422
423 /*
424 * Determine if we are running on xenlinux (ie x2v shim) or
425 * native linux
426 */
427 rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
428 if (guestID == HV_LINUX_GUEST_ID) {
429 gHvContext.synICMessagePage[cpu] =
430 phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
431 gHvContext.synICEventPage[cpu] =
432 phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
433 } else {
434 DPRINT_ERR(VMBUS, "unknown guest id!!");
435 goto Cleanup;
436 }
437 DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
438 gHvContext.synICMessagePage[cpu],
439 gHvContext.synICEventPage[cpu]);
440 } else {
441 gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
442 if (gHvContext.synICMessagePage[cpu] == NULL) {
443 DPRINT_ERR(VMBUS,
444 "unable to allocate SYNIC message page!!");
445 goto Cleanup;
446 }
447 409
448 gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); 410 if (gHvContext.synICMessagePage[cpu] == NULL) {
449 if (gHvContext.synICEventPage[cpu] == NULL) { 411 DPRINT_ERR(VMBUS,
450 DPRINT_ERR(VMBUS, 412 "unable to allocate SYNIC message page!!");
451 "unable to allocate SYNIC event page!!"); 413 goto Cleanup;
452 goto Cleanup; 414 }
453 }
454 415
455 /* Setup the Synic's message page */ 416 gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
456 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
457 simp.SimpEnabled = 1;
458 simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
459 >> PAGE_SHIFT;
460 417
461 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", 418 if (gHvContext.synICEventPage[cpu] == NULL) {
462 simp.AsUINT64); 419 DPRINT_ERR(VMBUS,
420 "unable to allocate SYNIC event page!!");
421 goto Cleanup;
422 }
463 423
464 wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); 424 /* Setup the Synic's message page */
425 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
426 simp.SimpEnabled = 1;
427 simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
428 >> PAGE_SHIFT;
465 429
466 /* Setup the Synic's event page */ 430 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64);
467 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
468 siefp.SiefpEnabled = 1;
469 siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
470 >> PAGE_SHIFT;
471 431
472 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", 432 wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
473 siefp.AsUINT64);
474 433
475 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); 434 /* Setup the Synic's event page */
476 } 435 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
436 siefp.SiefpEnabled = 1;
437 siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
438 >> PAGE_SHIFT;
439
440 DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64);
441
442 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
477 443
478 /* Setup the interception SINT. */ 444 /* Setup the interception SINT. */
479 /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */ 445 /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
@@ -505,13 +471,11 @@ void HvSynicInit(void *irqarg)
505 return; 471 return;
506 472
507Cleanup: 473Cleanup:
508 if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { 474 if (gHvContext.synICEventPage[cpu])
509 if (gHvContext.synICEventPage[cpu]) 475 osd_PageFree(gHvContext.synICEventPage[cpu], 1);
510 osd_PageFree(gHvContext.synICEventPage[cpu], 1);
511 476
512 if (gHvContext.synICMessagePage[cpu]) 477 if (gHvContext.synICMessagePage[cpu])
513 osd_PageFree(gHvContext.synICMessagePage[cpu], 1); 478 osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
514 }
515 479
516 DPRINT_EXIT(VMBUS); 480 DPRINT_EXIT(VMBUS);
517 return; 481 return;
@@ -542,27 +506,20 @@ void HvSynicCleanup(void *arg)
542 /* Disable the interrupt */ 506 /* Disable the interrupt */
543 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); 507 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
544 508
545 /* 509 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
546 * Disable and free the resources only if we are running as 510 simp.SimpEnabled = 0;
547 * native linux since in xenlinux, we are sharing the 511 simp.BaseSimpGpa = 0;
548 * resources with the x2v shim
549 */
550 if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
551 rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
552 simp.SimpEnabled = 0;
553 simp.BaseSimpGpa = 0;
554 512
555 wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); 513 wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
556 514
557 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); 515 rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
558 siefp.SiefpEnabled = 0; 516 siefp.SiefpEnabled = 0;
559 siefp.BaseSiefpGpa = 0; 517 siefp.BaseSiefpGpa = 0;
560 518
561 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); 519 wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
562 520
563 osd_PageFree(gHvContext.synICMessagePage[cpu], 1); 521 osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
564 osd_PageFree(gHvContext.synICEventPage[cpu], 1); 522 osd_PageFree(gHvContext.synICEventPage[cpu], 1);
565 }
566 523
567 DPRINT_EXIT(VMBUS); 524 DPRINT_EXIT(VMBUS);
568} 525}
diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/Hv.h
index fce4b5cdac30..41f5ebb86e17 100644
--- a/drivers/staging/hv/Hv.h
+++ b/drivers/staging/hv/Hv.h
@@ -41,11 +41,6 @@ enum {
41 41
42#define HV_PRESENT_BIT 0x80000000 42#define HV_PRESENT_BIT 0x80000000
43 43
44#define HV_XENLINUX_GUEST_ID_LO 0x00000000
45#define HV_XENLINUX_GUEST_ID_HI 0x0B00B135
46#define HV_XENLINUX_GUEST_ID (((u64)HV_XENLINUX_GUEST_ID_HI << 32) \
47 | HV_XENLINUX_GUEST_ID_LO)
48
49#define HV_LINUX_GUEST_ID_LO 0x00000000 44#define HV_LINUX_GUEST_ID_LO 0x00000000
50#define HV_LINUX_GUEST_ID_HI 0xB16B00B5 45#define HV_LINUX_GUEST_ID_HI 0xB16B00B5
51#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \ 46#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \
@@ -102,8 +97,9 @@ struct hv_input_signal_event_buffer {
102}; 97};
103 98
104struct hv_context { 99struct hv_context {
105 /* XenLinux or native Linux. If XenLinux, the hypercall and synic pages 100 /* We only support running on top of Hyper-V
106 * has already been initialized */ 101 * So at this point this really can only contain the Hyper-V ID
102 */
107 u64 GuestId; 103 u64 GuestId;
108 104
109 void *HypercallPage; 105 void *HypercallPage;
diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/NetVscApi.h
index 1ce2b74a34a7..95d7a32b12f2 100644
--- a/drivers/staging/hv/NetVscApi.h
+++ b/drivers/staging/hv/NetVscApi.h
@@ -105,8 +105,6 @@ struct netvsc_driver {
105 void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status); 105 void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status);
106 106
107 /* Specific to this driver */ 107 /* Specific to this driver */
108 int (*OnOpen)(struct hv_device *dev);
109 int (*OnClose)(struct hv_device *dev);
110 int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet); 108 int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet);
111 109
112 void *Context; 110 void *Context;
@@ -119,5 +117,7 @@ struct netvsc_device_info {
119 117
120/* Interface */ 118/* Interface */
121int NetVscInitialize(struct hv_driver *drv); 119int NetVscInitialize(struct hv_driver *drv);
120int RndisFilterOnOpen(struct hv_device *Device);
121int RndisFilterOnClose(struct hv_device *Device);
122 122
123#endif /* _NETVSC_API_H_ */ 123#endif /* _NETVSC_API_H_ */
diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c
index f69ae33a91e3..80b8a2c7784f 100644
--- a/drivers/staging/hv/RingBuffer.c
+++ b/drivers/staging/hv/RingBuffer.c
@@ -48,7 +48,7 @@ Description:
48static inline void 48static inline void
49GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write) 49GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write)
50{ 50{
51 u32 read_loc,write_loc; 51 u32 read_loc, write_loc;
52 52
53 /* Capture the read/write indices before they changed */ 53 /* Capture the read/write indices before they changed */
54 read_loc = rbi->RingBuffer->ReadIndex; 54 read_loc = rbi->RingBuffer->ReadIndex;
@@ -68,7 +68,7 @@ Description:
68 68
69--*/ 69--*/
70static inline u32 70static inline u32
71GetNextWriteLocation(RING_BUFFER_INFO* RingInfo) 71GetNextWriteLocation(RING_BUFFER_INFO *RingInfo)
72{ 72{
73 u32 next = RingInfo->RingBuffer->WriteIndex; 73 u32 next = RingInfo->RingBuffer->WriteIndex;
74 74
@@ -87,7 +87,7 @@ Description:
87 87
88--*/ 88--*/
89static inline void 89static inline void
90SetNextWriteLocation(RING_BUFFER_INFO* RingInfo, u32 NextWriteLocation) 90SetNextWriteLocation(RING_BUFFER_INFO *RingInfo, u32 NextWriteLocation)
91{ 91{
92 RingInfo->RingBuffer->WriteIndex = NextWriteLocation; 92 RingInfo->RingBuffer->WriteIndex = NextWriteLocation;
93} 93}
@@ -102,7 +102,7 @@ Description:
102 102
103--*/ 103--*/
104static inline u32 104static inline u32
105GetNextReadLocation(RING_BUFFER_INFO* RingInfo) 105GetNextReadLocation(RING_BUFFER_INFO *RingInfo)
106{ 106{
107 u32 next = RingInfo->RingBuffer->ReadIndex; 107 u32 next = RingInfo->RingBuffer->ReadIndex;
108 108
@@ -122,7 +122,7 @@ Description:
122 122
123--*/ 123--*/
124static inline u32 124static inline u32
125GetNextReadLocationWithOffset(RING_BUFFER_INFO* RingInfo, u32 Offset) 125GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset)
126{ 126{
127 u32 next = RingInfo->RingBuffer->ReadIndex; 127 u32 next = RingInfo->RingBuffer->ReadIndex;
128 128
@@ -143,7 +143,7 @@ Description:
143 143
144--*/ 144--*/
145static inline void 145static inline void
146SetNextReadLocation(RING_BUFFER_INFO* RingInfo, u32 NextReadLocation) 146SetNextReadLocation(RING_BUFFER_INFO *RingInfo, u32 NextReadLocation)
147{ 147{
148 RingInfo->RingBuffer->ReadIndex = NextReadLocation; 148 RingInfo->RingBuffer->ReadIndex = NextReadLocation;
149} 149}
@@ -159,7 +159,7 @@ Description:
159 159
160--*/ 160--*/
161static inline void * 161static inline void *
162GetRingBuffer(RING_BUFFER_INFO* RingInfo) 162GetRingBuffer(RING_BUFFER_INFO *RingInfo)
163{ 163{
164 return (void *)RingInfo->RingBuffer->Buffer; 164 return (void *)RingInfo->RingBuffer->Buffer;
165} 165}
@@ -175,7 +175,7 @@ Description:
175 175
176--*/ 176--*/
177static inline u32 177static inline u32
178GetRingBufferSize(RING_BUFFER_INFO* RingInfo) 178GetRingBufferSize(RING_BUFFER_INFO *RingInfo)
179{ 179{
180 return RingInfo->RingDataSize; 180 return RingInfo->RingDataSize;
181} 181}
@@ -190,9 +190,10 @@ Description:
190 190
191--*/ 191--*/
192static inline u64 192static inline u64
193GetRingBufferIndices(RING_BUFFER_INFO* RingInfo) 193GetRingBufferIndices(RING_BUFFER_INFO *RingInfo)
194{ 194{
195 return ((u64)RingInfo->RingBuffer->WriteIndex << 32) || RingInfo->RingBuffer->ReadIndex; 195 return ((u64)RingInfo->RingBuffer->WriteIndex << 32)
196 || RingInfo->RingBuffer->ReadIndex;
196} 197}
197 198
198 199
@@ -210,9 +211,14 @@ void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix)
210 u32 bytesAvailToWrite; 211 u32 bytesAvailToWrite;
211 u32 bytesAvailToRead; 212 u32 bytesAvailToRead;
212 213
213 GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite); 214 GetRingBufferAvailBytes(RingInfo,
215 &bytesAvailToRead,
216 &bytesAvailToWrite);
214 217
215 DPRINT(VMBUS, DEBUG_RING_LVL, "%s <<ringinfo %p buffer %p avail write %u avail read %u read idx %u write idx %u>>", 218 DPRINT(VMBUS,
219 DEBUG_RING_LVL,
220 "%s <<ringinfo %p buffer %p avail write %u "
221 "avail read %u read idx %u write idx %u>>",
216 Prefix, 222 Prefix,
217 RingInfo, 223 RingInfo,
218 RingInfo->RingBuffer->Buffer, 224 RingInfo->RingBuffer->Buffer,
@@ -229,13 +235,13 @@ static u32
229CopyToRingBuffer( 235CopyToRingBuffer(
230 RING_BUFFER_INFO *RingInfo, 236 RING_BUFFER_INFO *RingInfo,
231 u32 StartWriteOffset, 237 u32 StartWriteOffset,
232 void * Src, 238 void *Src,
233 u32 SrcLen); 239 u32 SrcLen);
234 240
235static u32 241static u32
236CopyFromRingBuffer( 242CopyFromRingBuffer(
237 RING_BUFFER_INFO *RingInfo, 243 RING_BUFFER_INFO *RingInfo,
238 void * Dest, 244 void *Dest,
239 u32 DestLen, 245 u32 DestLen,
240 u32 StartReadOffset); 246 u32 StartReadOffset);
241 247
@@ -256,15 +262,15 @@ void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo,
256 u32 bytesAvailToWrite; 262 u32 bytesAvailToWrite;
257 u32 bytesAvailToRead; 263 u32 bytesAvailToRead;
258 264
259 if (RingInfo->RingBuffer) 265 if (RingInfo->RingBuffer) {
260 { 266 GetRingBufferAvailBytes(RingInfo,
261 GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite); 267 &bytesAvailToRead,
268 &bytesAvailToWrite);
262 269
263 DebugInfo->BytesAvailToRead = bytesAvailToRead; 270 DebugInfo->BytesAvailToRead = bytesAvailToRead;
264 DebugInfo->BytesAvailToWrite = bytesAvailToWrite; 271 DebugInfo->BytesAvailToWrite = bytesAvailToWrite;
265 DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex; 272 DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex;
266 DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex; 273 DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex;
267
268 DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask; 274 DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask;
269 } 275 }
270} 276}
@@ -299,7 +305,7 @@ int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen)
299 305
300 memset(RingInfo, 0, sizeof(RING_BUFFER_INFO)); 306 memset(RingInfo, 0, sizeof(RING_BUFFER_INFO));
301 307
302 RingInfo->RingBuffer = (RING_BUFFER*)Buffer; 308 RingInfo->RingBuffer = (RING_BUFFER *)Buffer;
303 RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0; 309 RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0;
304 310
305 RingInfo->RingSize = BufferLen; 311 RingInfo->RingSize = BufferLen;
@@ -319,7 +325,7 @@ Description:
319 Cleanup the ring buffer 325 Cleanup the ring buffer
320 326
321--*/ 327--*/
322void RingBufferCleanup(RING_BUFFER_INFO* RingInfo) 328void RingBufferCleanup(RING_BUFFER_INFO *RingInfo)
323{ 329{
324} 330}
325 331
@@ -335,14 +341,14 @@ Description:
335int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo, 341int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
336 struct scatterlist *sglist, u32 sgcount) 342 struct scatterlist *sglist, u32 sgcount)
337{ 343{
338 int i=0; 344 int i = 0;
339 u32 byteAvailToWrite; 345 u32 byteAvailToWrite;
340 u32 byteAvailToRead; 346 u32 byteAvailToRead;
341 u32 totalBytesToWrite=0; 347 u32 totalBytesToWrite = 0;
342 348
343 struct scatterlist *sg; 349 struct scatterlist *sg;
344 volatile u32 nextWriteLocation; 350 volatile u32 nextWriteLocation;
345 u64 prevIndices=0; 351 u64 prevIndices = 0;
346 unsigned long flags; 352 unsigned long flags;
347 353
348 DPRINT_ENTER(VMBUS); 354 DPRINT_ENTER(VMBUS);
@@ -356,17 +362,23 @@ int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
356 362
357 spin_lock_irqsave(&OutRingInfo->ring_lock, flags); 363 spin_lock_irqsave(&OutRingInfo->ring_lock, flags);
358 364
359 GetRingBufferAvailBytes(OutRingInfo, &byteAvailToRead, &byteAvailToWrite); 365 GetRingBufferAvailBytes(OutRingInfo,
366 &byteAvailToRead,
367 &byteAvailToWrite);
360 368
361 DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite); 369 DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite);
362 370
363 /* DumpRingInfo(OutRingInfo, "BEFORE "); */ 371 /* DumpRingInfo(OutRingInfo, "BEFORE "); */
364 372
365 /* If there is only room for the packet, assume it is full. Otherwise, the next time around, we think the ring buffer */ 373 /* If there is only room for the packet, assume it is full. */
374 /* Otherwise, the next time around, we think the ring buffer */
366 /* is empty since the read index == write index */ 375 /* is empty since the read index == write index */
367 if (byteAvailToWrite <= totalBytesToWrite) 376 if (byteAvailToWrite <= totalBytesToWrite) {
368 { 377 DPRINT_DBG(VMBUS,
369 DPRINT_DBG(VMBUS, "No more space left on outbound ring buffer (needed %u, avail %u)", totalBytesToWrite, byteAvailToWrite); 378 "No more space left on outbound ring buffer "
379 "(needed %u, avail %u)",
380 totalBytesToWrite,
381 byteAvailToWrite);
370 382
371 spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); 383 spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
372 384
@@ -423,17 +435,22 @@ int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen)
423{ 435{
424 u32 bytesAvailToWrite; 436 u32 bytesAvailToWrite;
425 u32 bytesAvailToRead; 437 u32 bytesAvailToRead;
426 u32 nextReadLocation=0; 438 u32 nextReadLocation = 0;
427 unsigned long flags; 439 unsigned long flags;
428 440
429 spin_lock_irqsave(&InRingInfo->ring_lock, flags); 441 spin_lock_irqsave(&InRingInfo->ring_lock, flags);
430 442
431 GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite); 443 GetRingBufferAvailBytes(InRingInfo,
444 &bytesAvailToRead,
445 &bytesAvailToWrite);
432 446
433 /* Make sure there is something to read */ 447 /* Make sure there is something to read */
434 if (bytesAvailToRead < BufferLen ) 448 if (bytesAvailToRead < BufferLen) {
435 { 449 /* DPRINT_DBG(VMBUS,
436 /* DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); */ 450 "got callback but not enough to read "
451 "<avail to read %d read size %d>!!",
452 bytesAvailToRead,
453 BufferLen); */
437 454
438 spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); 455 spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
439 456
@@ -444,9 +461,9 @@ int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen)
444 nextReadLocation = GetNextReadLocation(InRingInfo); 461 nextReadLocation = GetNextReadLocation(InRingInfo);
445 462
446 nextReadLocation = CopyFromRingBuffer(InRingInfo, 463 nextReadLocation = CopyFromRingBuffer(InRingInfo,
447 Buffer, 464 Buffer,
448 BufferLen, 465 BufferLen,
449 nextReadLocation); 466 nextReadLocation);
450 467
451 spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); 468 spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
452 469
@@ -468,24 +485,29 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer,
468{ 485{
469 u32 bytesAvailToWrite; 486 u32 bytesAvailToWrite;
470 u32 bytesAvailToRead; 487 u32 bytesAvailToRead;
471 u32 nextReadLocation=0; 488 u32 nextReadLocation = 0;
472 u64 prevIndices=0; 489 u64 prevIndices = 0;
473 unsigned long flags; 490 unsigned long flags;
474 491
475 ASSERT(BufferLen > 0); 492 ASSERT(BufferLen > 0);
476 493
477 spin_lock_irqsave(&InRingInfo->ring_lock, flags); 494 spin_lock_irqsave(&InRingInfo->ring_lock, flags);
478 495
479 GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite); 496 GetRingBufferAvailBytes(InRingInfo,
497 &bytesAvailToRead,
498 &bytesAvailToWrite);
480 499
481 DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen); 500 DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen);
482 501
483 /* DumpRingInfo(InRingInfo, "BEFORE "); */ 502 /* DumpRingInfo(InRingInfo, "BEFORE "); */
484 503
485 /* Make sure there is something to read */ 504 /* Make sure there is something to read */
486 if (bytesAvailToRead < BufferLen ) 505 if (bytesAvailToRead < BufferLen) {
487 { 506 DPRINT_DBG(VMBUS,
488 DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); 507 "got callback but not enough to read "
508 "<avail to read %d read size %d>!!",
509 bytesAvailToRead,
510 BufferLen);
489 511
490 spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); 512 spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
491 513
@@ -495,17 +517,18 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer,
495 nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset); 517 nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset);
496 518
497 nextReadLocation = CopyFromRingBuffer(InRingInfo, 519 nextReadLocation = CopyFromRingBuffer(InRingInfo,
498 Buffer, 520 Buffer,
499 BufferLen, 521 BufferLen,
500 nextReadLocation); 522 nextReadLocation);
501 523
502 nextReadLocation = CopyFromRingBuffer(InRingInfo, 524 nextReadLocation = CopyFromRingBuffer(InRingInfo,
503 &prevIndices, 525 &prevIndices,
504 sizeof(u64), 526 sizeof(u64),
505 nextReadLocation); 527 nextReadLocation);
506 528
507 /* Make sure all reads are done before we update the read index since */ 529 /* Make sure all reads are done before we update the read index since */
508 /* the writer may start writing to the read area once the read index is updated */ 530 /* the writer may start writing to the read area once the read index */
531 /*is updated */
509 mb(); 532 mb();
510 533
511 /* Update the read index */ 534 /* Update the read index */
@@ -533,25 +556,22 @@ static u32
533CopyToRingBuffer( 556CopyToRingBuffer(
534 RING_BUFFER_INFO *RingInfo, 557 RING_BUFFER_INFO *RingInfo,
535 u32 StartWriteOffset, 558 u32 StartWriteOffset,
536 void * Src, 559 void *Src,
537 u32 SrcLen) 560 u32 SrcLen)
538{ 561{
539 void * ringBuffer=GetRingBuffer(RingInfo); 562 void *ringBuffer = GetRingBuffer(RingInfo);
540 u32 ringBufferSize=GetRingBufferSize(RingInfo); 563 u32 ringBufferSize = GetRingBufferSize(RingInfo);
541 u32 fragLen; 564 u32 fragLen;
542 565
543 if (SrcLen > ringBufferSize - StartWriteOffset) /* wrap-around detected! */ 566 /* wrap-around detected! */
544 { 567 if (SrcLen > ringBufferSize - StartWriteOffset) {
545 DPRINT_DBG(VMBUS, "wrap-around detected!"); 568 DPRINT_DBG(VMBUS, "wrap-around detected!");
546 569
547 fragLen = ringBufferSize - StartWriteOffset; 570 fragLen = ringBufferSize - StartWriteOffset;
548 memcpy(ringBuffer + StartWriteOffset, Src, fragLen); 571 memcpy(ringBuffer + StartWriteOffset, Src, fragLen);
549 memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen); 572 memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen);
550 } 573 } else
551 else
552 {
553 memcpy(ringBuffer + StartWriteOffset, Src, SrcLen); 574 memcpy(ringBuffer + StartWriteOffset, Src, SrcLen);
554 }
555 575
556 StartWriteOffset += SrcLen; 576 StartWriteOffset += SrcLen;
557 StartWriteOffset %= ringBufferSize; 577 StartWriteOffset %= ringBufferSize;
@@ -573,28 +593,27 @@ Description:
573static u32 593static u32
574CopyFromRingBuffer( 594CopyFromRingBuffer(
575 RING_BUFFER_INFO *RingInfo, 595 RING_BUFFER_INFO *RingInfo,
576 void * Dest, 596 void *Dest,
577 u32 DestLen, 597 u32 DestLen,
578 u32 StartReadOffset) 598 u32 StartReadOffset)
579{ 599{
580 void * ringBuffer=GetRingBuffer(RingInfo); 600 void *ringBuffer = GetRingBuffer(RingInfo);
581 u32 ringBufferSize=GetRingBufferSize(RingInfo); 601 u32 ringBufferSize = GetRingBufferSize(RingInfo);
582 602
583 u32 fragLen; 603 u32 fragLen;
584 604
585 if (DestLen > ringBufferSize - StartReadOffset) /* wrap-around detected at the src */ 605 /* wrap-around detected at the src */
586 { 606 if (DestLen > ringBufferSize - StartReadOffset) {
587 DPRINT_DBG(VMBUS, "src wrap-around detected!"); 607 DPRINT_DBG(VMBUS, "src wrap-around detected!");
588 608
589 fragLen = ringBufferSize - StartReadOffset; 609 fragLen = ringBufferSize - StartReadOffset;
590 610
591 memcpy(Dest, ringBuffer + StartReadOffset, fragLen); 611 memcpy(Dest, ringBuffer + StartReadOffset, fragLen);
592 memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen); 612 memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen);
593 } 613 } else
594 else 614
595 {
596 memcpy(Dest, ringBuffer + StartReadOffset, DestLen); 615 memcpy(Dest, ringBuffer + StartReadOffset, DestLen);
597 } 616
598 617
599 StartReadOffset += DestLen; 618 StartReadOffset += DestLen;
600 StartReadOffset %= ringBufferSize; 619 StartReadOffset %= ringBufferSize;
diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c
index 26d79975387c..1ab7fa97d373 100644
--- a/drivers/staging/hv/RndisFilter.c
+++ b/drivers/staging/hv/RndisFilter.c
@@ -85,10 +85,6 @@ static int RndisFilterOnDeviceRemove(struct hv_device *Device);
85 85
86static void RndisFilterOnCleanup(struct hv_driver *Driver); 86static void RndisFilterOnCleanup(struct hv_driver *Driver);
87 87
88static int RndisFilterOnOpen(struct hv_device *Device);
89
90static int RndisFilterOnClose(struct hv_device *Device);
91
92static int RndisFilterOnSend(struct hv_device *Device, 88static int RndisFilterOnSend(struct hv_device *Device,
93 struct hv_netvsc_packet *Packet); 89 struct hv_netvsc_packet *Packet);
94 90
@@ -654,8 +650,6 @@ int RndisFilterInit(struct netvsc_driver *Driver)
654 Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove; 650 Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
655 Driver->Base.OnCleanup = RndisFilterOnCleanup; 651 Driver->Base.OnCleanup = RndisFilterOnCleanup;
656 Driver->OnSend = RndisFilterOnSend; 652 Driver->OnSend = RndisFilterOnSend;
657 Driver->OnOpen = RndisFilterOnOpen;
658 Driver->OnClose = RndisFilterOnClose;
659 /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ 653 /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */
660 Driver->OnReceiveCallback = RndisFilterOnReceive; 654 Driver->OnReceiveCallback = RndisFilterOnReceive;
661 655
@@ -888,7 +882,7 @@ static void RndisFilterOnCleanup(struct hv_driver *Driver)
888 DPRINT_EXIT(NETVSC); 882 DPRINT_EXIT(NETVSC);
889} 883}
890 884
891static int RndisFilterOnOpen(struct hv_device *Device) 885int RndisFilterOnOpen(struct hv_device *Device)
892{ 886{
893 int ret; 887 int ret;
894 struct netvsc_device *netDevice = Device->Extension; 888 struct netvsc_device *netDevice = Device->Extension;
@@ -903,7 +897,7 @@ static int RndisFilterOnOpen(struct hv_device *Device)
903 return ret; 897 return ret;
904} 898}
905 899
906static int RndisFilterOnClose(struct hv_device *Device) 900int RndisFilterOnClose(struct hv_device *Device)
907{ 901{
908 int ret; 902 int ret;
909 struct netvsc_device *netDevice = Device->Extension; 903 struct netvsc_device *netDevice = Device->Extension;
diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c
index 2f7c425896f7..38ea1407f222 100644
--- a/drivers/staging/hv/StorVsc.c
+++ b/drivers/staging/hv/StorVsc.c
@@ -625,7 +625,7 @@ static int StorVscOnDeviceRemove(struct hv_device *Device)
625 return 0; 625 return 0;
626} 626}
627 627
628static int StorVscOnHostReset(struct hv_device *Device) 628int StorVscOnHostReset(struct hv_device *Device)
629{ 629{
630 struct storvsc_device *storDevice; 630 struct storvsc_device *storDevice;
631 struct storvsc_request_extension *request; 631 struct storvsc_request_extension *request;
@@ -842,7 +842,6 @@ int StorVscInitialize(struct hv_driver *Driver)
842 storDriver->Base.OnCleanup = StorVscOnCleanup; 842 storDriver->Base.OnCleanup = StorVscOnCleanup;
843 843
844 storDriver->OnIORequest = StorVscOnIORequest; 844 storDriver->OnIORequest = StorVscOnIORequest;
845 storDriver->OnHostReset = StorVscOnHostReset;
846 845
847 DPRINT_EXIT(STORVSC); 846 DPRINT_EXIT(STORVSC);
848 847
diff --git a/drivers/staging/hv/StorVscApi.h b/drivers/staging/hv/StorVscApi.h
index 69c14066c479..126a8588edb1 100644
--- a/drivers/staging/hv/StorVscApi.h
+++ b/drivers/staging/hv/StorVscApi.h
@@ -91,13 +91,9 @@ struct storvsc_driver_object {
91 /* Maximum # of requests in flight per channel/device */ 91 /* Maximum # of requests in flight per channel/device */
92 u32 MaxOutstandingRequestsPerChannel; 92 u32 MaxOutstandingRequestsPerChannel;
93 93
94 /* Set by the caller to allow us to re-enumerate the bus on the host */
95 void (*OnHostRescan)(struct hv_device *Device);
96
97 /* Specific to this driver */ 94 /* Specific to this driver */
98 int (*OnIORequest)(struct hv_device *Device, 95 int (*OnIORequest)(struct hv_device *Device,
99 struct hv_storvsc_request *Request); 96 struct hv_storvsc_request *Request);
100 int (*OnHostReset)(struct hv_device *Device);
101}; 97};
102 98
103struct storvsc_device_info { 99struct storvsc_device_info {
@@ -108,6 +104,7 @@ struct storvsc_device_info {
108 104
109/* Interface */ 105/* Interface */
110int StorVscInitialize(struct hv_driver *driver); 106int StorVscInitialize(struct hv_driver *driver);
107int StorVscOnHostReset(struct hv_device *Device);
111int BlkVscInitialize(struct hv_driver *driver); 108int BlkVscInitialize(struct hv_driver *driver);
112 109
113#endif /* _STORVSC_API_H_ */ 110#endif /* _STORVSC_API_H_ */
diff --git a/drivers/staging/hv/VersionInfo.h b/drivers/staging/hv/VersionInfo.h
index 9c3641d99ed8..10d7b19a485f 100644
--- a/drivers/staging/hv/VersionInfo.h
+++ b/drivers/staging/hv/VersionInfo.h
@@ -24,8 +24,24 @@
24#ifndef __HV_VERSION_INFO 24#ifndef __HV_VERSION_INFO
25#define __HV_VERSION_INFO 25#define __HV_VERSION_INFO
26 26
27static const char VersionDate[] = __DATE__; 27/*
28static const char VersionTime[] = __TIME__; 28 * We use the same version numbering for all Hyper-V modules.
29static const char VersionDesc[] = "Version 2.0"; 29 *
30 * Definition of versioning is as follows;
31 *
32 * Major Number Changes for these scenarios;
33 * 1. When a new version of Windows Hyper-V
34 * is released.
35 * 2. A Major change has occurred in the
36 * Linux IC's.
37 * (For example the merge for the first time
38 * into the kernel) Every time the Major Number
39 * changes, the Revision number is reset to 0.
40 * Minor Number Changes when new functionality is added
41 * to the Linux IC's that is not a bug fix.
42 *
43 */
44#define HV_DRV_VERSION "3.0"
45
30 46
31#endif 47#endif
diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c
index 35a023e9f9d1..3d0a240ed664 100644
--- a/drivers/staging/hv/Vmbus.c
+++ b/drivers/staging/hv/Vmbus.c
@@ -273,10 +273,8 @@ int VmbusInitialize(struct hv_driver *drv)
273 273
274 DPRINT_ENTER(VMBUS); 274 DPRINT_ENTER(VMBUS);
275 275
276 DPRINT_INFO(VMBUS, "+++++++ Build Date=%s %s +++++++", 276 DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++",
277 VersionDate, VersionTime); 277 HV_DRV_VERSION);
278 DPRINT_INFO(VMBUS, "+++++++ Build Description=%s +++++++",
279 VersionDesc);
280 DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", 278 DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++",
281 VMBUS_REVISION_NUMBER); 279 VMBUS_REVISION_NUMBER);
282 DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", 280 DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++",
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
index 45d908114d11..abeac12c093d 100644
--- a/drivers/staging/hv/blkvsc_drv.c
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -31,6 +31,7 @@
31#include <scsi/scsi_dbg.h> 31#include <scsi/scsi_dbg.h>
32#include "osd.h" 32#include "osd.h"
33#include "logging.h" 33#include "logging.h"
34#include "VersionInfo.h"
34#include "vmbus.h" 35#include "vmbus.h"
35#include "StorVscApi.h" 36#include "StorVscApi.h"
36 37
@@ -92,7 +93,7 @@ struct blkvsc_request {
92/* Per device structure */ 93/* Per device structure */
93struct block_device_context { 94struct block_device_context {
94 /* point back to our device context */ 95 /* point back to our device context */
95 struct device_context *device_ctx; 96 struct vm_device *device_ctx;
96 struct kmem_cache *request_pool; 97 struct kmem_cache *request_pool;
97 spinlock_t lock; 98 spinlock_t lock;
98 struct gendisk *gd; 99 struct gendisk *gd;
@@ -254,7 +255,7 @@ static int blkvsc_probe(struct device *device)
254 (struct blkvsc_driver_context *)driver_ctx; 255 (struct blkvsc_driver_context *)driver_ctx;
255 struct storvsc_driver_object *storvsc_drv_obj = 256 struct storvsc_driver_object *storvsc_drv_obj =
256 &blkvsc_drv_ctx->drv_obj; 257 &blkvsc_drv_ctx->drv_obj;
257 struct device_context *device_ctx = device_to_device_context(device); 258 struct vm_device *device_ctx = device_to_vm_device(device);
258 struct hv_device *device_obj = &device_ctx->device_obj; 259 struct hv_device *device_obj = &device_ctx->device_obj;
259 260
260 struct block_device_context *blkdev = NULL; 261 struct block_device_context *blkdev = NULL;
@@ -742,7 +743,7 @@ static int blkvsc_remove(struct device *device)
742 (struct blkvsc_driver_context *)driver_ctx; 743 (struct blkvsc_driver_context *)driver_ctx;
743 struct storvsc_driver_object *storvsc_drv_obj = 744 struct storvsc_driver_object *storvsc_drv_obj =
744 &blkvsc_drv_ctx->drv_obj; 745 &blkvsc_drv_ctx->drv_obj;
745 struct device_context *device_ctx = device_to_device_context(device); 746 struct vm_device *device_ctx = device_to_vm_device(device);
746 struct hv_device *device_obj = &device_ctx->device_obj; 747 struct hv_device *device_obj = &device_ctx->device_obj;
747 struct block_device_context *blkdev = dev_get_drvdata(device); 748 struct block_device_context *blkdev = dev_get_drvdata(device);
748 unsigned long flags; 749 unsigned long flags;
@@ -862,7 +863,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
862 void (*request_completion)(struct hv_storvsc_request *)) 863 void (*request_completion)(struct hv_storvsc_request *))
863{ 864{
864 struct block_device_context *blkdev = blkvsc_req->dev; 865 struct block_device_context *blkdev = blkvsc_req->dev;
865 struct device_context *device_ctx = blkdev->device_ctx; 866 struct vm_device *device_ctx = blkdev->device_ctx;
866 struct driver_context *driver_ctx = 867 struct driver_context *driver_ctx =
867 driver_to_driver_context(device_ctx->device.driver); 868 driver_to_driver_context(device_ctx->device.driver);
868 struct blkvsc_driver_context *blkvsc_drv_ctx = 869 struct blkvsc_driver_context *blkvsc_drv_ctx =
@@ -1504,6 +1505,7 @@ static void __exit blkvsc_exit(void)
1504} 1505}
1505 1506
1506MODULE_LICENSE("GPL"); 1507MODULE_LICENSE("GPL");
1508MODULE_VERSION(HV_DRV_VERSION);
1507module_param(blkvsc_ringbuffer_size, int, S_IRUGO); 1509module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
1508module_init(blkvsc_init); 1510module_init(blkvsc_init);
1509module_exit(blkvsc_exit); 1511module_exit(blkvsc_exit);
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index 0d7459e2d036..1af3dcbafd65 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -35,14 +35,13 @@
35#include <net/pkt_sched.h> 35#include <net/pkt_sched.h>
36#include "osd.h" 36#include "osd.h"
37#include "logging.h" 37#include "logging.h"
38#include "VersionInfo.h"
38#include "vmbus.h" 39#include "vmbus.h"
39#include "NetVscApi.h" 40#include "NetVscApi.h"
40 41
41MODULE_LICENSE("GPL");
42
43struct net_device_context { 42struct net_device_context {
44 /* point back to our device context */ 43 /* point back to our device context */
45 struct device_context *device_ctx; 44 struct vm_device *device_ctx;
46 struct net_device_stats stats; 45 struct net_device_stats stats;
47}; 46};
48 47
@@ -72,11 +71,6 @@ static void netvsc_set_multicast_list(struct net_device *net)
72static int netvsc_open(struct net_device *net) 71static int netvsc_open(struct net_device *net)
73{ 72{
74 struct net_device_context *net_device_ctx = netdev_priv(net); 73 struct net_device_context *net_device_ctx = netdev_priv(net);
75 struct driver_context *driver_ctx =
76 driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
77 struct netvsc_driver_context *net_drv_ctx =
78 (struct netvsc_driver_context *)driver_ctx;
79 struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
80 struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj; 74 struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
81 int ret = 0; 75 int ret = 0;
82 76
@@ -87,7 +81,7 @@ static int netvsc_open(struct net_device *net)
87 sizeof(struct net_device_stats)); 81 sizeof(struct net_device_stats));
88 82
89 /* Open up the device */ 83 /* Open up the device */
90 ret = net_drv_obj->OnOpen(device_obj); 84 ret = RndisFilterOnOpen(device_obj);
91 if (ret != 0) { 85 if (ret != 0) {
92 DPRINT_ERR(NETVSC_DRV, 86 DPRINT_ERR(NETVSC_DRV,
93 "unable to open device (ret %d).", ret); 87 "unable to open device (ret %d).", ret);
@@ -106,11 +100,6 @@ static int netvsc_open(struct net_device *net)
106static int netvsc_close(struct net_device *net) 100static int netvsc_close(struct net_device *net)
107{ 101{
108 struct net_device_context *net_device_ctx = netdev_priv(net); 102 struct net_device_context *net_device_ctx = netdev_priv(net);
109 struct driver_context *driver_ctx =
110 driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
111 struct netvsc_driver_context *net_drv_ctx =
112 (struct netvsc_driver_context *)driver_ctx;
113 struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
114 struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj; 103 struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
115 int ret; 104 int ret;
116 105
@@ -118,7 +107,7 @@ static int netvsc_close(struct net_device *net)
118 107
119 netif_stop_queue(net); 108 netif_stop_queue(net);
120 109
121 ret = net_drv_obj->OnClose(device_obj); 110 ret = RndisFilterOnClose(device_obj);
122 if (ret != 0) 111 if (ret != 0)
123 DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret); 112 DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret);
124 113
@@ -282,7 +271,7 @@ retry_send:
282static void netvsc_linkstatus_callback(struct hv_device *device_obj, 271static void netvsc_linkstatus_callback(struct hv_device *device_obj,
283 unsigned int status) 272 unsigned int status)
284{ 273{
285 struct device_context *device_ctx = to_device_context(device_obj); 274 struct vm_device *device_ctx = to_vm_device(device_obj);
286 struct net_device *net = dev_get_drvdata(&device_ctx->device); 275 struct net_device *net = dev_get_drvdata(&device_ctx->device);
287 276
288 DPRINT_ENTER(NETVSC_DRV); 277 DPRINT_ENTER(NETVSC_DRV);
@@ -309,7 +298,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj,
309static int netvsc_recv_callback(struct hv_device *device_obj, 298static int netvsc_recv_callback(struct hv_device *device_obj,
310 struct hv_netvsc_packet *packet) 299 struct hv_netvsc_packet *packet)
311{ 300{
312 struct device_context *device_ctx = to_device_context(device_obj); 301 struct vm_device *device_ctx = to_vm_device(device_obj);
313 struct net_device *net = dev_get_drvdata(&device_ctx->device); 302 struct net_device *net = dev_get_drvdata(&device_ctx->device);
314 struct net_device_context *net_device_ctx; 303 struct net_device_context *net_device_ctx;
315 struct sk_buff *skb; 304 struct sk_buff *skb;
@@ -401,7 +390,7 @@ static int netvsc_probe(struct device *device)
401 struct netvsc_driver_context *net_drv_ctx = 390 struct netvsc_driver_context *net_drv_ctx =
402 (struct netvsc_driver_context *)driver_ctx; 391 (struct netvsc_driver_context *)driver_ctx;
403 struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; 392 struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
404 struct device_context *device_ctx = device_to_device_context(device); 393 struct vm_device *device_ctx = device_to_vm_device(device);
405 struct hv_device *device_obj = &device_ctx->device_obj; 394 struct hv_device *device_obj = &device_ctx->device_obj;
406 struct net_device *net = NULL; 395 struct net_device *net = NULL;
407 struct net_device_context *net_device_ctx; 396 struct net_device_context *net_device_ctx;
@@ -473,7 +462,7 @@ static int netvsc_remove(struct device *device)
473 struct netvsc_driver_context *net_drv_ctx = 462 struct netvsc_driver_context *net_drv_ctx =
474 (struct netvsc_driver_context *)driver_ctx; 463 (struct netvsc_driver_context *)driver_ctx;
475 struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; 464 struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
476 struct device_context *device_ctx = device_to_device_context(device); 465 struct vm_device *device_ctx = device_to_vm_device(device);
477 struct net_device *net = dev_get_drvdata(&device_ctx->device); 466 struct net_device *net = dev_get_drvdata(&device_ctx->device);
478 struct hv_device *device_obj = &device_ctx->device_obj; 467 struct hv_device *device_obj = &device_ctx->device_obj;
479 int ret; 468 int ret;
@@ -613,6 +602,8 @@ static void __exit netvsc_exit(void)
613 DPRINT_EXIT(NETVSC_DRV); 602 DPRINT_EXIT(NETVSC_DRV);
614} 603}
615 604
605MODULE_LICENSE("GPL");
606MODULE_VERSION(HV_DRV_VERSION);
616module_param(netvsc_ringbuffer_size, int, S_IRUGO); 607module_param(netvsc_ringbuffer_size, int, S_IRUGO);
617 608
618module_init(netvsc_init); 609module_init(netvsc_init);
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index d49dc21d4cb4..3988f4bec1ce 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -32,6 +32,7 @@
32#include <scsi/scsi_dbg.h> 32#include <scsi/scsi_dbg.h>
33#include "osd.h" 33#include "osd.h"
34#include "logging.h" 34#include "logging.h"
35#include "VersionInfo.h"
35#include "vmbus.h" 36#include "vmbus.h"
36#include "StorVscApi.h" 37#include "StorVscApi.h"
37 38
@@ -39,10 +40,8 @@
39struct host_device_context { 40struct host_device_context {
40 /* must be 1st field 41 /* must be 1st field
41 * FIXME this is a bug */ 42 * FIXME this is a bug */
42 struct work_struct host_rescan_work;
43
44 /* point back to our device context */ 43 /* point back to our device context */
45 struct device_context *device_ctx; 44 struct vm_device *device_ctx;
46 struct kmem_cache *request_pool; 45 struct kmem_cache *request_pool;
47 unsigned int port; 46 unsigned int port;
48 unsigned char path; 47 unsigned char path;
@@ -77,8 +76,6 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
77static int storvsc_device_alloc(struct scsi_device *); 76static int storvsc_device_alloc(struct scsi_device *);
78static int storvsc_device_configure(struct scsi_device *); 77static int storvsc_device_configure(struct scsi_device *);
79static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd); 78static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd);
80static void storvsc_host_rescan_callback(struct work_struct *work);
81static void storvsc_host_rescan(struct hv_device *device_obj);
82static int storvsc_remove(struct device *dev); 79static int storvsc_remove(struct device *dev);
83 80
84static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl, 81static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
@@ -94,8 +91,6 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
94 struct scatterlist *bounce_sgl, 91 struct scatterlist *bounce_sgl,
95 unsigned int orig_sgl_count); 92 unsigned int orig_sgl_count);
96 93
97static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
98 unsigned int *lun_count);
99static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev, 94static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev,
100 sector_t capacity, int *info); 95 sector_t capacity, int *info);
101 96
@@ -148,7 +143,6 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
148 vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface); 143 vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface);
149 144
150 storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size; 145 storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size;
151 storvsc_drv_obj->OnHostRescan = storvsc_host_rescan;
152 146
153 /* Callback to client driver to complete the initialization */ 147 /* Callback to client driver to complete the initialization */
154 drv_init(&storvsc_drv_obj->Base); 148 drv_init(&storvsc_drv_obj->Base);
@@ -240,7 +234,7 @@ static int storvsc_probe(struct device *device)
240 (struct storvsc_driver_context *)driver_ctx; 234 (struct storvsc_driver_context *)driver_ctx;
241 struct storvsc_driver_object *storvsc_drv_obj = 235 struct storvsc_driver_object *storvsc_drv_obj =
242 &storvsc_drv_ctx->drv_obj; 236 &storvsc_drv_ctx->drv_obj;
243 struct device_context *device_ctx = device_to_device_context(device); 237 struct vm_device *device_ctx = device_to_vm_device(device);
244 struct hv_device *device_obj = &device_ctx->device_obj; 238 struct hv_device *device_obj = &device_ctx->device_obj;
245 struct Scsi_Host *host; 239 struct Scsi_Host *host;
246 struct host_device_context *host_device_ctx; 240 struct host_device_context *host_device_ctx;
@@ -266,9 +260,6 @@ static int storvsc_probe(struct device *device)
266 host_device_ctx->port = host->host_no; 260 host_device_ctx->port = host->host_no;
267 host_device_ctx->device_ctx = device_ctx; 261 host_device_ctx->device_ctx = device_ctx;
268 262
269 INIT_WORK(&host_device_ctx->host_rescan_work,
270 storvsc_host_rescan_callback);
271
272 host_device_ctx->request_pool = 263 host_device_ctx->request_pool =
273 kmem_cache_create(dev_name(&device_ctx->device), 264 kmem_cache_create(dev_name(&device_ctx->device),
274 sizeof(struct storvsc_cmd_request) + 265 sizeof(struct storvsc_cmd_request) +
@@ -339,7 +330,7 @@ static int storvsc_remove(struct device *device)
339 (struct storvsc_driver_context *)driver_ctx; 330 (struct storvsc_driver_context *)driver_ctx;
340 struct storvsc_driver_object *storvsc_drv_obj = 331 struct storvsc_driver_object *storvsc_drv_obj =
341 &storvsc_drv_ctx->drv_obj; 332 &storvsc_drv_ctx->drv_obj;
342 struct device_context *device_ctx = device_to_device_context(device); 333 struct vm_device *device_ctx = device_to_vm_device(device);
343 struct hv_device *device_obj = &device_ctx->device_obj; 334 struct hv_device *device_obj = &device_ctx->device_obj;
344 struct Scsi_Host *host = dev_get_drvdata(device); 335 struct Scsi_Host *host = dev_get_drvdata(device);
345 struct host_device_context *host_device_ctx = 336 struct host_device_context *host_device_ctx =
@@ -640,7 +631,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
640 int ret; 631 int ret;
641 struct host_device_context *host_device_ctx = 632 struct host_device_context *host_device_ctx =
642 (struct host_device_context *)scmnd->device->host->hostdata; 633 (struct host_device_context *)scmnd->device->host->hostdata;
643 struct device_context *device_ctx = host_device_ctx->device_ctx; 634 struct vm_device *device_ctx = host_device_ctx->device_ctx;
644 struct driver_context *driver_ctx = 635 struct driver_context *driver_ctx =
645 driver_to_driver_context(device_ctx->device.driver); 636 driver_to_driver_context(device_ctx->device.driver);
646 struct storvsc_driver_context *storvsc_drv_ctx = 637 struct storvsc_driver_context *storvsc_drv_ctx =
@@ -879,14 +870,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
879 int ret; 870 int ret;
880 struct host_device_context *host_device_ctx = 871 struct host_device_context *host_device_ctx =
881 (struct host_device_context *)scmnd->device->host->hostdata; 872 (struct host_device_context *)scmnd->device->host->hostdata;
882 struct device_context *device_ctx = host_device_ctx->device_ctx; 873 struct vm_device *device_ctx = host_device_ctx->device_ctx;
883 struct driver_context *driver_ctx =
884 driver_to_driver_context(device_ctx->device.driver);
885 struct storvsc_driver_context *storvsc_drv_ctx =
886 (struct storvsc_driver_context *)driver_ctx;
887
888 struct storvsc_driver_object *storvsc_drv_obj =
889 &storvsc_drv_ctx->drv_obj;
890 874
891 DPRINT_ENTER(STORVSC_DRV); 875 DPRINT_ENTER(STORVSC_DRV);
892 876
@@ -894,8 +878,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
894 scmnd->device, &device_ctx->device_obj); 878 scmnd->device, &device_ctx->device_obj);
895 879
896 /* Invokes the vsc to reset the host/bus */ 880 /* Invokes the vsc to reset the host/bus */
897 ASSERT(storvsc_drv_obj->OnHostReset); 881 ret = StorVscOnHostReset(&device_ctx->device_obj);
898 ret = storvsc_drv_obj->OnHostReset(&device_ctx->device_obj);
899 if (ret != 0) { 882 if (ret != 0) {
900 DPRINT_EXIT(STORVSC_DRV); 883 DPRINT_EXIT(STORVSC_DRV);
901 return ret; 884 return ret;
@@ -909,201 +892,6 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
909 return ret; 892 return ret;
910} 893}
911 894
912/**
913 * storvsc_host_rescan - Rescan the scsi HBA
914 */
915static void storvsc_host_rescan_callback(struct work_struct *work)
916{
917 struct hv_device *device_obj =
918 &((struct host_device_context *)work)->device_ctx->device_obj;
919 struct device_context *device_ctx = to_device_context(device_obj);
920 struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
921 struct scsi_device *sdev;
922 struct host_device_context *host_device_ctx;
923 struct scsi_device **sdevs_remove_list;
924 unsigned int sdevs_count = 0;
925 unsigned int found;
926 unsigned int i;
927 unsigned int lun_count = 0;
928 unsigned int *lun_list;
929
930 DPRINT_ENTER(STORVSC_DRV);
931
932 host_device_ctx = (struct host_device_context *)host->hostdata;
933 lun_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET, sizeof(unsigned int),
934 GFP_ATOMIC);
935 if (!lun_list) {
936 DPRINT_ERR(STORVSC_DRV, "unable to allocate lun list");
937 return;
938 }
939
940 sdevs_remove_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET,
941 sizeof(void *), GFP_ATOMIC);
942 if (!sdevs_remove_list) {
943 kfree(lun_list);
944 DPRINT_ERR(STORVSC_DRV, "unable to allocate lun remove list");
945 return;
946 }
947
948 DPRINT_INFO(STORVSC_DRV, "rescanning host for new scsi devices...");
949
950 /* Rescan for new device */
951 scsi_scan_target(&host->shost_gendev, host_device_ctx->path,
952 host_device_ctx->target, SCAN_WILD_CARD, 1);
953
954 DPRINT_INFO(STORVSC_DRV, "rescanning host for removed scsi device...");
955
956 /* Use the 1st device to send the report luns cmd */
957 shost_for_each_device(sdev, host) {
958 lun_count = STORVSC_MAX_LUNS_PER_TARGET;
959 storvsc_report_luns(sdev, lun_list, &lun_count);
960
961 DPRINT_INFO(STORVSC_DRV,
962 "report luns on scsi device (%p) found %u luns ",
963 sdev, lun_count);
964 DPRINT_INFO(STORVSC_DRV,
965 "existing luns on scsi device (%p) host (%d)",
966 sdev, host->host_no);
967
968 scsi_device_put(sdev);
969 break;
970 }
971
972 for (i = 0; i < lun_count; i++)
973 DPRINT_INFO(STORVSC_DRV, "%d) lun %u", i, lun_list[i]);
974
975 /* Rescan for devices that may have been removed.
976 * We do not have to worry that new devices may have been added since
977 * this callback is serialized by the workqueue ie add/remove are done
978 * here.
979 */
980 shost_for_each_device(sdev, host) {
981 /* See if this device is still here */
982 found = 0;
983 for (i = 0; i < lun_count; i++) {
984 if (sdev->lun == lun_list[i]) {
985 found = 1;
986 break;
987 }
988 }
989 if (!found) {
990 DPRINT_INFO(STORVSC_DRV, "lun (%u) does not exists",
991 sdev->lun);
992 sdevs_remove_list[sdevs_count++] = sdev;
993 }
994 }
995
996 /* Now remove the devices */
997 for (i = 0; i < sdevs_count; i++) {
998 DPRINT_INFO(STORVSC_DRV,
999 "removing scsi device (%p) lun (%u)...",
1000 sdevs_remove_list[i], sdevs_remove_list[i]->lun);
1001
1002 /* make sure it is not removed from underneath us */
1003 if (!scsi_device_get(sdevs_remove_list[i])) {
1004 scsi_remove_device(sdevs_remove_list[i]);
1005 scsi_device_put(sdevs_remove_list[i]);
1006 }
1007 }
1008
1009 DPRINT_INFO(STORVSC_DRV, "rescan completed on dev obj (%p) "
1010 "target (%u) bus (%u)", device_obj,
1011 host_device_ctx->target, host_device_ctx->path);
1012
1013 kfree(lun_list);
1014 kfree(sdevs_remove_list);
1015
1016 DPRINT_EXIT(STORVSC_DRV);
1017}
1018
1019static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
1020 unsigned int *lun_count)
1021{
1022 int i, j;
1023 unsigned int lun = 0;
1024 unsigned int num_luns;
1025 int result;
1026 unsigned char *data;
1027 struct scsi_sense_hdr sshdr;
1028 unsigned char cmd[16] = {0};
1029 /* Add 1 to cover the report_lun header */
1030 unsigned int report_len = 8 * (STORVSC_MAX_LUNS_PER_TARGET+1);
1031 unsigned long long *report_luns;
1032 const unsigned int in_lun_count = *lun_count;
1033
1034 *lun_count = 0;
1035
1036 report_luns = kzalloc(report_len, GFP_ATOMIC);
1037 if (!report_luns)
1038 return -ENOMEM;
1039
1040 cmd[0] = REPORT_LUNS;
1041
1042 /* cmd length */
1043 *(unsigned int *)&cmd[6] = cpu_to_be32(report_len);
1044
1045 result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE,
1046 (unsigned char *)report_luns, report_len,
1047 &sshdr, 30 * HZ, 3, NULL);
1048 if (result != 0) {
1049 kfree(report_luns);
1050 return -EBUSY;
1051 }
1052
1053 /* get the length from the first four bytes */
1054 report_len = be32_to_cpu(*(unsigned int *)&report_luns[0]);
1055
1056 num_luns = (report_len / sizeof(unsigned long long));
1057 if (num_luns > in_lun_count) {
1058 kfree(report_luns);
1059 return -EINVAL;
1060 }
1061
1062 *lun_count = num_luns;
1063
1064 DPRINT_DBG(STORVSC_DRV,
1065 "report luns on scsi device (%p) found %u luns ",
1066 sdev, num_luns);
1067
1068 /* lun id starts at 1 */
1069 for (i = 1; i < num_luns + 1; i++) {
1070 lun = 0;
1071 data = (unsigned char *)&report_luns[i];
1072 for (j = 0; j < sizeof(lun); j += 2) {
1073 lun = lun | (((data[j] << 8) | data[j + 1]) <<
1074 (j * 8));
1075 }
1076
1077 luns[i-1] = lun;
1078 }
1079
1080 kfree(report_luns);
1081 return 0;
1082}
1083
1084static void storvsc_host_rescan(struct hv_device *device_obj)
1085{
1086 struct device_context *device_ctx = to_device_context(device_obj);
1087 struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
1088 struct host_device_context *host_device_ctx;
1089
1090 DPRINT_ENTER(STORVSC_DRV);
1091
1092 host_device_ctx = (struct host_device_context *)host->hostdata;
1093
1094 DPRINT_INFO(STORVSC_DRV, "initiating rescan on dev obj (%p) "
1095 "target (%u) bus (%u)...", device_obj,
1096 host_device_ctx->target, host_device_ctx->path);
1097
1098 /*
1099 * We need to queue this since the scanning may block and the caller
1100 * may be in an intr context
1101 */
1102 /* scsi_queue_work(host, &host_device_ctx->host_rescan_work); */
1103 schedule_work(&host_device_ctx->host_rescan_work);
1104 DPRINT_EXIT(STORVSC_DRV);
1105}
1106
1107static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, 895static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
1108 sector_t capacity, int *info) 896 sector_t capacity, int *info)
1109{ 897{
@@ -1203,6 +991,7 @@ static void __exit storvsc_exit(void)
1203} 991}
1204 992
1205MODULE_LICENSE("GPL"); 993MODULE_LICENSE("GPL");
994MODULE_VERSION(HV_DRV_VERSION);
1206module_param(storvsc_ringbuffer_size, int, S_IRUGO); 995module_param(storvsc_ringbuffer_size, int, S_IRUGO);
1207module_init(storvsc_init); 996module_init(storvsc_init);
1208module_exit(storvsc_exit); 997module_exit(storvsc_exit);
diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h
index ae0a896eb392..6404b8424bef 100644
--- a/drivers/staging/hv/vmbus.h
+++ b/drivers/staging/hv/vmbus.h
@@ -43,23 +43,23 @@ struct driver_context {
43 void (*shutdown)(struct device *); 43 void (*shutdown)(struct device *);
44}; 44};
45 45
46struct device_context { 46struct vm_device {
47 struct work_struct probe_failed_work_item; 47 struct work_struct probe_failed_work_item;
48 struct hv_guid class_id; 48 struct hv_guid class_id;
49 struct hv_guid device_id; 49 struct hv_guid device_id;
50 int probe_error; 50 int probe_error;
51 struct device device;
52 struct hv_device device_obj; 51 struct hv_device device_obj;
52 struct device device;
53}; 53};
54 54
55static inline struct device_context *to_device_context(struct hv_device *d) 55static inline struct vm_device *to_vm_device(struct hv_device *d)
56{ 56{
57 return container_of(d, struct device_context, device_obj); 57 return container_of(d, struct vm_device, device_obj);
58} 58}
59 59
60static inline struct device_context *device_to_device_context(struct device *d) 60static inline struct vm_device *device_to_vm_device(struct device *d)
61{ 61{
62 return container_of(d, struct device_context, device); 62 return container_of(d, struct vm_device, device);
63} 63}
64 64
65static inline struct driver_context *driver_to_driver_context(struct device_driver *d) 65static inline struct driver_context *driver_to_driver_context(struct device_driver *d)
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 894eecfc63ca..2c906195b9c8 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -24,6 +24,9 @@
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/sysctl.h> 26#include <linux/sysctl.h>
27#include <linux/pci.h>
28#include <linux/dmi.h>
29#include "VersionInfo.h"
27#include "osd.h" 30#include "osd.h"
28#include "logging.h" 31#include "logging.h"
29#include "vmbus.h" 32#include "vmbus.h"
@@ -47,7 +50,7 @@ struct vmbus_driver_context {
47 struct tasklet_struct event_dpc; 50 struct tasklet_struct event_dpc;
48 51
49 /* The bus root device */ 52 /* The bus root device */
50 struct device_context device_ctx; 53 struct vm_device device_ctx;
51}; 54};
52 55
53static int vmbus_match(struct device *device, struct device_driver *driver); 56static int vmbus_match(struct device *device, struct device_driver *driver);
@@ -135,7 +138,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
135 struct device_attribute *dev_attr, 138 struct device_attribute *dev_attr,
136 char *buf) 139 char *buf)
137{ 140{
138 struct device_context *device_ctx = device_to_device_context(dev); 141 struct vm_device *device_ctx = device_to_vm_device(dev);
139 struct hv_device_info device_info; 142 struct hv_device_info device_info;
140 143
141 memset(&device_info, 0, sizeof(struct hv_device_info)); 144 memset(&device_info, 0, sizeof(struct hv_device_info));
@@ -245,7 +248,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
245{ 248{
246 struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; 249 struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
247 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj; 250 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
248 struct device_context *dev_ctx = &g_vmbus_drv.device_ctx; 251 struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
249 int ret; 252 int ret;
250 unsigned int vector; 253 unsigned int vector;
251 254
@@ -307,7 +310,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
307 DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector); 310 DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
308 311
309 /* Call to bus driver to add the root device */ 312 /* Call to bus driver to add the root device */
310 memset(dev_ctx, 0, sizeof(struct device_context)); 313 memset(dev_ctx, 0, sizeof(struct vm_device));
311 314
312 ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector); 315 ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
313 if (ret != 0) { 316 if (ret != 0) {
@@ -368,7 +371,7 @@ static void vmbus_bus_exit(void)
368 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj; 371 struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
369 struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; 372 struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
370 373
371 struct device_context *dev_ctx = &g_vmbus_drv.device_ctx; 374 struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx;
372 375
373 DPRINT_ENTER(VMBUS_DRV); 376 DPRINT_ENTER(VMBUS_DRV);
374 377
@@ -471,13 +474,13 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
471 struct hv_guid *instance, 474 struct hv_guid *instance,
472 void *context) 475 void *context)
473{ 476{
474 struct device_context *child_device_ctx; 477 struct vm_device *child_device_ctx;
475 struct hv_device *child_device_obj; 478 struct hv_device *child_device_obj;
476 479
477 DPRINT_ENTER(VMBUS_DRV); 480 DPRINT_ENTER(VMBUS_DRV);
478 481
479 /* Allocate the new child device */ 482 /* Allocate the new child device */
480 child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL); 483 child_device_ctx = kzalloc(sizeof(struct vm_device), GFP_KERNEL);
481 if (!child_device_ctx) { 484 if (!child_device_ctx) {
482 DPRINT_ERR(VMBUS_DRV, 485 DPRINT_ERR(VMBUS_DRV,
483 "unable to allocate device_context for child device"); 486 "unable to allocate device_context for child device");
@@ -526,10 +529,10 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
526 struct hv_device *child_device_obj) 529 struct hv_device *child_device_obj)
527{ 530{
528 int ret = 0; 531 int ret = 0;
529 struct device_context *root_device_ctx = 532 struct vm_device *root_device_ctx =
530 to_device_context(root_device_obj); 533 to_vm_device(root_device_obj);
531 struct device_context *child_device_ctx = 534 struct vm_device *child_device_ctx =
532 to_device_context(child_device_obj); 535 to_vm_device(child_device_obj);
533 static atomic_t device_num = ATOMIC_INIT(0); 536 static atomic_t device_num = ATOMIC_INIT(0);
534 537
535 DPRINT_ENTER(VMBUS_DRV); 538 DPRINT_ENTER(VMBUS_DRV);
@@ -572,7 +575,7 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj,
572 */ 575 */
573static void vmbus_child_device_unregister(struct hv_device *device_obj) 576static void vmbus_child_device_unregister(struct hv_device *device_obj)
574{ 577{
575 struct device_context *device_ctx = to_device_context(device_obj); 578 struct vm_device *device_ctx = to_vm_device(device_obj);
576 579
577 DPRINT_ENTER(VMBUS_DRV); 580 DPRINT_ENTER(VMBUS_DRV);
578 581
@@ -610,7 +613,7 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj)
610 */ 613 */
611static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) 614static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
612{ 615{
613 struct device_context *device_ctx = device_to_device_context(device); 616 struct vm_device *device_ctx = device_to_vm_device(device);
614 int ret; 617 int ret;
615 618
616 DPRINT_ENTER(VMBUS_DRV); 619 DPRINT_ENTER(VMBUS_DRV);
@@ -687,7 +690,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
687{ 690{
688 int match = 0; 691 int match = 0;
689 struct driver_context *driver_ctx = driver_to_driver_context(driver); 692 struct driver_context *driver_ctx = driver_to_driver_context(driver);
690 struct device_context *device_ctx = device_to_device_context(device); 693 struct vm_device *device_ctx = device_to_vm_device(device);
691 694
692 DPRINT_ENTER(VMBUS_DRV); 695 DPRINT_ENTER(VMBUS_DRV);
693 696
@@ -724,7 +727,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
724 */ 727 */
725static void vmbus_probe_failed_cb(struct work_struct *context) 728static void vmbus_probe_failed_cb(struct work_struct *context)
726{ 729{
727 struct device_context *device_ctx = (struct device_context *)context; 730 struct vm_device *device_ctx = (struct vm_device *)context;
728 731
729 DPRINT_ENTER(VMBUS_DRV); 732 DPRINT_ENTER(VMBUS_DRV);
730 733
@@ -746,8 +749,8 @@ static int vmbus_probe(struct device *child_device)
746 int ret = 0; 749 int ret = 0;
747 struct driver_context *driver_ctx = 750 struct driver_context *driver_ctx =
748 driver_to_driver_context(child_device->driver); 751 driver_to_driver_context(child_device->driver);
749 struct device_context *device_ctx = 752 struct vm_device *device_ctx =
750 device_to_device_context(child_device); 753 device_to_vm_device(child_device);
751 754
752 DPRINT_ENTER(VMBUS_DRV); 755 DPRINT_ENTER(VMBUS_DRV);
753 756
@@ -871,7 +874,7 @@ static void vmbus_bus_release(struct device *device)
871 */ 874 */
872static void vmbus_device_release(struct device *device) 875static void vmbus_device_release(struct device *device)
873{ 876{
874 struct device_context *device_ctx = device_to_device_context(device); 877 struct vm_device *device_ctx = device_to_vm_device(device);
875 878
876 DPRINT_ENTER(VMBUS_DRV); 879 DPRINT_ENTER(VMBUS_DRV);
877 880
@@ -946,6 +949,19 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id)
946 } 949 }
947} 950}
948 951
952static struct dmi_system_id __initdata microsoft_hv_dmi_table[] = {
953 {
954 .ident = "Hyper-V",
955 .matches = {
956 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
957 DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
958 DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
959 },
960 },
961 { },
962};
963MODULE_DEVICE_TABLE(dmi, microsoft_hv_dmi_table);
964
949static int __init vmbus_init(void) 965static int __init vmbus_init(void)
950{ 966{
951 int ret = 0; 967 int ret = 0;
@@ -957,6 +973,9 @@ static int __init vmbus_init(void)
957 vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel)); 973 vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
958 /* Todo: it is used for loglevel, to be ported to new kernel. */ 974 /* Todo: it is used for loglevel, to be ported to new kernel. */
959 975
976 if (!dmi_check_system(microsoft_hv_dmi_table))
977 return -ENODEV;
978
960 ret = vmbus_bus_init(VmbusInitialize); 979 ret = vmbus_bus_init(VmbusInitialize);
961 980
962 DPRINT_EXIT(VMBUS_DRV); 981 DPRINT_EXIT(VMBUS_DRV);
@@ -973,7 +992,20 @@ static void __exit vmbus_exit(void)
973 return; 992 return;
974} 993}
975 994
995/*
996 * We use a PCI table to determine if we should autoload this driver This is
997 * needed by distro tools to determine if the hyperv drivers should be
998 * installed and/or configured. We don't do anything else with the table, but
999 * it needs to be present.
1000 */
1001const static struct pci_device_id microsoft_hv_pci_table[] = {
1002 { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
1003 { 0 }
1004};
1005MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
1006
976MODULE_LICENSE("GPL"); 1007MODULE_LICENSE("GPL");
1008MODULE_VERSION(HV_DRV_VERSION);
977module_param(vmbus_irq, int, S_IRUGO); 1009module_param(vmbus_irq, int, S_IRUGO);
978module_param(vmbus_loglevel, int, S_IRUGO); 1010module_param(vmbus_loglevel, int, S_IRUGO);
979 1011
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 768f44894d08..b456dfc8fe27 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -79,11 +79,14 @@ EXPORT_SYMBOL(__iio_change_event);
79 /* Does anyone care? */ 79 /* Does anyone care? */
80 mutex_lock(&ev_int->event_list_lock); 80 mutex_lock(&ev_int->event_list_lock);
81 if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) { 81 if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) {
82 if (ev_int->current_events == ev_int->max_events) 82 if (ev_int->current_events == ev_int->max_events) {
83 mutex_unlock(&ev_int->event_list_lock);
83 return 0; 84 return 0;
85 }
84 ev = kmalloc(sizeof(*ev), GFP_KERNEL); 86 ev = kmalloc(sizeof(*ev), GFP_KERNEL);
85 if (ev == NULL) { 87 if (ev == NULL) {
86 ret = -ENOMEM; 88 ret = -ENOMEM;
89 mutex_unlock(&ev_int->event_list_lock);
87 goto error_ret; 90 goto error_ret;
88 } 91 }
89 ev->ev.id = ev_code; 92 ev->ev.id = ev_code;
@@ -115,7 +118,7 @@ int iio_push_event(struct iio_dev *dev_info,
115EXPORT_SYMBOL(iio_push_event); 118EXPORT_SYMBOL(iio_push_event);
116 119
117/* Generic interrupt line interrupt handler */ 120/* Generic interrupt line interrupt handler */
118irqreturn_t iio_interrupt_handler(int irq, void *_int_info) 121static irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
119{ 122{
120 struct iio_interrupt *int_info = _int_info; 123 struct iio_interrupt *int_info = _int_info;
121 struct iio_dev *dev_info = int_info->dev_info; 124 struct iio_dev *dev_info = int_info->dev_info;
@@ -249,10 +252,10 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
249} 252}
250EXPORT_SYMBOL(iio_remove_event_from_list); 253EXPORT_SYMBOL(iio_remove_event_from_list);
251 254
252ssize_t iio_event_chrdev_read(struct file *filep, 255static ssize_t iio_event_chrdev_read(struct file *filep,
253 char *buf, 256 char __user *buf,
254 size_t count, 257 size_t count,
255 loff_t *f_ps) 258 loff_t *f_ps)
256{ 259{
257 struct iio_event_interface *ev_int = filep->private_data; 260 struct iio_event_interface *ev_int = filep->private_data;
258 struct iio_detected_event_list *el; 261 struct iio_detected_event_list *el;
@@ -289,16 +292,16 @@ ssize_t iio_event_chrdev_read(struct file *filep,
289 mutex_unlock(&ev_int->event_list_lock); 292 mutex_unlock(&ev_int->event_list_lock);
290 /* 293 /*
291 * Possible concurency issue if an update of this event is on its way 294 * Possible concurency issue if an update of this event is on its way
292 * through. May lead to new even being removed whilst the reported event 295 * through. May lead to new event being removed whilst the reported
293 * was the unescalated event. In typical use case this is not a problem 296 * event was the unescalated event. In typical use case this is not a
294 * as userspace will say read half the buffer due to a 50% full event 297 * problem as userspace will say read half the buffer due to a 50%
295 * which would make the correct 100% full incorrect anyway. 298 * full event which would make the correct 100% full incorrect anyway.
296 */ 299 */
297 spin_lock(&el->shared_pointer->lock); 300 if (el->shared_pointer) {
298 if (el->shared_pointer) 301 spin_lock(&el->shared_pointer->lock);
299 (el->shared_pointer->ev_p) = NULL; 302 (el->shared_pointer->ev_p) = NULL;
300 spin_unlock(&el->shared_pointer->lock); 303 spin_unlock(&el->shared_pointer->lock);
301 304 }
302 kfree(el); 305 kfree(el);
303 306
304 return len; 307 return len;
@@ -310,7 +313,7 @@ error_ret:
310 return ret; 313 return ret;
311} 314}
312 315
313int iio_event_chrdev_release(struct inode *inode, struct file *filep) 316static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
314{ 317{
315 struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev); 318 struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
316 struct iio_event_interface *ev_int = hand->private; 319 struct iio_event_interface *ev_int = hand->private;
@@ -332,7 +335,7 @@ int iio_event_chrdev_release(struct inode *inode, struct file *filep)
332 return 0; 335 return 0;
333} 336}
334 337
335int iio_event_chrdev_open(struct inode *inode, struct file *filep) 338static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
336{ 339{
337 struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev); 340 struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
338 struct iio_event_interface *ev_int = hand->private; 341 struct iio_event_interface *ev_int = hand->private;
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 93b91b28a02f..09044adf7327 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -146,8 +146,7 @@ static inline void __iio_init_ring_buffer(struct iio_ring_buffer *ring,
146 ring->length = length; 146 ring->length = length;
147 ring->loopcount = 0; 147 ring->loopcount = 0;
148 ring->shared_ev_pointer.ev_p = 0; 148 ring->shared_ev_pointer.ev_p = 0;
149 ring->shared_ev_pointer.lock = 149 spin_lock_init(&ring->shared_ev_pointer.lock);
150 __SPIN_LOCK_UNLOCKED(ring->shared_ev_pointer->loc);
151} 150}
152 151
153/** 152/**
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 359ff9208f36..6f7f4d5a93f3 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -8,7 +8,6 @@
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/device.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/device.h> 12#include <linux/device.h>
14#include <linux/workqueue.h> 13#include <linux/workqueue.h>
@@ -21,7 +20,7 @@ static inline int __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
21 return -EINVAL; 20 return -EINVAL;
22 21
23 __iio_init_ring_buffer(&ring->buf, bytes_per_datum, length); 22 __iio_init_ring_buffer(&ring->buf, bytes_per_datum, length);
24 ring->use_lock = __SPIN_LOCK_UNLOCKED((ring)->use_lock); 23 spin_lock_init(&ring->use_lock);
25 ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL); 24 ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL);
26 ring->read_p = 0; 25 ring->read_p = 0;
27 ring->write_p = 0; 26 ring->write_p = 0;
diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h
index a02d70b0d24a..9d52d9637777 100644
--- a/drivers/staging/iio/trigger_consumer.h
+++ b/drivers/staging/iio/trigger_consumer.h
@@ -27,7 +27,7 @@ int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info);
27 * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers 27 * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
28 * @dev_info: iio_dev associated with the device that will consume the trigger 28 * @dev_info: iio_dev associated with the device that will consume the trigger
29 **/ 29 **/
30int iio_device_register_trigger_consumer(struct iio_dev *dev_info) 30static int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
31{ 31{
32 return 0; 32 return 0;
33}; 33};
@@ -36,7 +36,7 @@ int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
36 * iio_device_unregister_trigger_consumer() - reverse the registration process 36 * iio_device_unregister_trigger_consumer() - reverse the registration process
37 * @dev_info: iio_dev associated with the device that consumed the trigger 37 * @dev_info: iio_dev associated with the device that consumed the trigger
38 **/ 38 **/
39int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) 39static int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
40{ 40{
41 return 0; 41 return 0;
42}; 42};
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index e4078a92d399..0392a4bc8cc8 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -33,7 +33,7 @@
33 33
34 34
35/* table of devices that work with this driver */ 35/* table of devices that work with this driver */
36static struct usb_device_id line6_id_table[] = { 36static const struct usb_device_id line6_id_table[] = {
37 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) }, 37 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
38 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) }, 38 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
39 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) }, 39 { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
index 48d834b0fa1b..58fef82c247d 100644
--- a/drivers/staging/line6/variax.c
+++ b/drivers/staging/line6/variax.c
@@ -254,7 +254,7 @@ static ssize_t variax_set_active(struct device *dev,
254 if (ret) 254 if (ret)
255 return ret; 255 return ret;
256 256
257 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1: 0; 257 variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value ? 1 : 0;
258 line6_send_raw_message_async(&variax->line6, variax->buffer_activate, 258 line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
259 sizeof(variax_activate)); 259 sizeof(variax_activate));
260 return count; 260 return count;
diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig
deleted file mode 100644
index 505dcb275796..000000000000
--- a/drivers/staging/mimio/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config INPUT_MIMIO
2 tristate "Mimio Xi interactive whiteboard support"
3 depends on USB && INPUT
4 default N
5 help
6 Say Y here if you want to use a Mimio Xi interactive
7 whiteboard device.
8
9 To compile this driver as a module, choose M here: the
10 module will be called mimio.
diff --git a/drivers/staging/mimio/Makefile b/drivers/staging/mimio/Makefile
deleted file mode 100644
index 77807ee0450e..000000000000
--- a/drivers/staging/mimio/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_INPUT_MIMIO) += mimio.o
diff --git a/drivers/staging/mimio/mimio.c b/drivers/staging/mimio/mimio.c
deleted file mode 100644
index 1ba8103f5003..000000000000
--- a/drivers/staging/mimio/mimio.c
+++ /dev/null
@@ -1,914 +0,0 @@
1/*
2 * Hardware event => input event mapping:
3 *
4 *
5 *
6 input.h:#define BTN_TOOL_PEN 0x140 black
7 input.h:#define BTN_TOOL_RUBBER 0x141 blue
8 input.h:#define BTN_TOOL_BRUSH 0x142 green
9 input.h:#define BTN_TOOL_PENCIL 0x143 red
10 input.h:#define BTN_TOOL_AIRBRUSH 0x144 eraser
11 input.h:#define BTN_TOOL_FINGER 0x145 small eraser
12 input.h:#define BTN_TOOL_MOUSE 0x146 mimio interactive
13 input.h:#define BTN_TOOL_LENS 0x147 mimio interactive but1
14 input.h:#define LOCALBTN_TOOL_EXTRA1 0x14a mimio interactive but2 == BTN_TOUCH
15 input.h:#define LOCALBTN_TOOL_EXTRA2 0x14b mimio extra pens (orange, brown, yellow, purple) == BTN_STYLUS
16 input.h:#define LOCALBTN_TOOL_EXTRA3 0x14c unused == BTN_STYLUS2
17 input.h:#define BTN_TOOL_DOUBLETAP 0x14d unused
18 input.h:#define BTN_TOOL_TRIPLETAP 0x14e unused
19 *
20 * MIMIO_EV_PENDOWN(MIMIO_PEN_K) => EV_KEY BIT(BTN_TOOL_PEN)
21 * MIMIO_EV_PENDOWN(MIMIO_PEN_B) => EV_KEY BIT(BTN_TOOL_RUBBER)
22 * MIMIO_EV_PENDOWN(MIMIO_PEN_G) => EV_KEY BIT(BTN_TOOL_BRUSH)
23 * MIMIO_EV_PENDOWN(MIMIO_PEN_R) => EV_KEY BIT(BTN_TOOL_PENCIL)
24 * MIMIO_EV_PENDOWN(MIMIO_PEN_E) => EV_KEY BIT(BTN_TOOL_AIRBRUSH)
25 * MIMIO_EV_PENDOWN(MIMIO_PEN_ES) => EV_KEY BIT(BTN_TOOL_FINGER)
26 * MIMIO_EV_PENDOWN(MIMIO_PEN_I) => EV_KEY BIT(BTN_TOOL_MOUSE)
27 * MIMIO_EV_PENDOWN(MIMIO_PEN_IL) => EV_KEY BIT(BTN_TOOL_LENS)
28 * MIMIO_EV_PENDOWN(MIMIO_PEN_IR) => EV_KEY BIT(BTN_TOOL_DOUBLETAP)
29 * MIMIO_EV_PENDOWN(MIMIO_PEN_EX) => EV_KEY BIT(BTN_TOOL_TRIPLETAP)
30 * MIMIO_EV_PENDATA => EV_ABS BIT(ABS_X), BIT(ABS_Y)
31 * MIMIO_EV_MEMRESET => EV_KEY BIT(BTN_0)
32 * MIMIO_EV_ACC(ACC_NEWPAGE) => EV_KEY BIT(BTN_1)
33 * MIMIO_EV_ACC(ACC_TAGPAGE) => EV_KEY BIT(BTN_2)
34 * MIMIO_EV_ACC(ACC_PRINTPAGE) => EV_KEY BIT(BTN_3)
35 * MIMIO_EV_ACC(ACC_MAXIMIZE) => EV_KEY BIT(BTN_4)
36 * MIMIO_EV_ACC(ACC_FINDCTLPNL) => EV_KEY BIT(BTN_5)
37 *
38 *
39 * open issues:
40 * - cold-load of data captured when mimio in standalone mode not yet
41 * supported; need to snoop Win32 box to see datastream for this.
42 * - mimio mouse not yet supported; need to snoop Win32 box to see the
43 * datastream for this.
44 */
45#include <linux/kernel.h>
46#include <linux/init.h>
47#include <linux/slab.h>
48#include <linux/spinlock.h>
49#include <linux/input.h>
50#include <linux/usb.h>
51
52#define DRIVER_VERSION "v0.031"
53#define DRIVER_AUTHOR "mwilder@cs.nmsu.edu"
54#define DRIVER_DESC "USB mimio-xi driver"
55
56enum {UPVALUE, DOWNVALUE, MOVEVALUE};
57
58#define MIMIO_XRANGE_MAX 9600
59#define MIMIO_YRANGE_MAX 4800
60
61#define LOCALBTN_TOOL_EXTRA1 BTN_TOUCH
62#define LOCALBTN_TOOL_EXTRA2 BTN_STYLUS
63#define LOCALBTN_TOOL_EXTRA3 BTN_STYLUS2
64
65#define MIMIO_VENDOR_ID 0x08d3
66#define MIMIO_PRODUCT_ID 0x0001
67#define MIMIO_MAXPAYLOAD (8)
68#define MIMIO_MAXNAMELEN (64)
69#define MIMIO_TXWAIT (1)
70#define MIMIO_TXDONE (2)
71
72#define MIMIO_EV_PENDOWN (0x22)
73#define MIMIO_EV_PENDATA (0x24)
74#define MIMIO_EV_PENUP (0x51)
75#define MIMIO_EV_MEMRESET (0x45)
76#define MIMIO_EV_ACC (0xb2)
77
78#define MIMIO_PEN_K (1) /* black pen */
79#define MIMIO_PEN_B (2) /* blue pen */
80#define MIMIO_PEN_G (3) /* green pen */
81#define MIMIO_PEN_R (4) /* red pen */
82/* 5, 6, 7, 8 are extra pens */
83#define MIMIO_PEN_E (9) /* big eraser */
84#define MIMIO_PEN_ES (10) /* lil eraser */
85#define MIMIO_PENJUMP_START (10)
86#define MIMIO_PENJUMP (6)
87#define MIMIO_PEN_I (17) /* mimio interactive */
88#define MIMIO_PEN_IL (18) /* mimio interactive button 1 */
89#define MIMIO_PEN_IR (19) /* mimio interactive button 2 */
90
91#define MIMIO_PEN_MAX (MIMIO_PEN_IR)
92
93#define ACC_DONE (0)
94#define ACC_NEWPAGE (1)
95#define ACC_TAGPAGE (2)
96#define ACC_PRINTPAGE (4)
97#define ACC_MAXIMIZE (8)
98#define ACC_FINDCTLPNL (16)
99
100#define isvalidtxsize(n) ((n) > 0 && (n) <= MIMIO_MAXPAYLOAD)
101
102
103struct pktbuf {
104 unsigned char instr;
105 unsigned char buf[16];
106 unsigned char *p;
107 unsigned char *q;
108};
109
110struct usbintendpt {
111 dma_addr_t dma;
112 struct urb *urb;
113 unsigned char *buf;
114 struct usb_endpoint_descriptor *desc;
115};
116
117struct mimio {
118 struct input_dev *idev;
119 struct usb_device *udev;
120 struct usb_interface *uifc;
121 int open;
122 int present;
123 int greeted;
124 int txflags;
125 char phys[MIMIO_MAXNAMELEN];
126 struct usbintendpt in;
127 struct usbintendpt out;
128 struct pktbuf pktbuf;
129 unsigned char minor;
130 wait_queue_head_t waitq;
131 spinlock_t txlock;
132 void (*rxhandler)(struct mimio *, unsigned char *, unsigned int);
133 int last_pen_down;
134};
135
136static void mimio_close(struct input_dev *);
137static void mimio_dealloc(struct mimio *);
138static void mimio_disconnect(struct usb_interface *);
139static int mimio_greet(struct mimio *);
140static void mimio_irq_in(struct urb *);
141static void mimio_irq_out(struct urb *);
142static int mimio_open(struct input_dev *);
143static int mimio_probe(struct usb_interface *, const struct usb_device_id *);
144static void mimio_rx_handler(struct mimio *, unsigned char *, unsigned int);
145static int mimio_tx(struct mimio *, const char *, int);
146
147static char mimio_name[] = "VirtualInk mimio-Xi";
148static struct usb_device_id mimio_table [] = {
149 { USB_DEVICE(MIMIO_VENDOR_ID, MIMIO_PRODUCT_ID) },
150 { USB_DEVICE(0x0525, 0xa4a0) }, /* gadget zero firmware */
151 { }
152};
153
154MODULE_DEVICE_TABLE(usb, mimio_table);
155
156static struct usb_driver mimio_driver = {
157 .name = "mimio",
158 .probe = mimio_probe,
159 .disconnect = mimio_disconnect,
160 .id_table = mimio_table,
161};
162
163static DECLARE_MUTEX(disconnect_sem);
164
165static void mimio_close(struct input_dev *idev)
166{
167 struct mimio *mimio;
168
169 mimio = input_get_drvdata(idev);
170 if (!mimio) {
171 dev_err(&idev->dev, "null mimio attached to input device\n");
172 return;
173 }
174
175 if (mimio->open <= 0)
176 dev_err(&idev->dev, "mimio not open.\n");
177 else
178 mimio->open--;
179
180 if (mimio->present == 0 && mimio->open == 0)
181 mimio_dealloc(mimio);
182}
183
184static void mimio_dealloc(struct mimio *mimio)
185{
186 if (mimio == NULL)
187 return;
188
189 usb_kill_urb(mimio->in.urb);
190
191 usb_kill_urb(mimio->out.urb);
192
193 if (mimio->idev) {
194 input_unregister_device(mimio->idev);
195 if (mimio->idev->grab)
196 input_close_device(mimio->idev->grab);
197 else
198 dev_dbg(&mimio->idev->dev, "mimio->idev->grab == NULL"
199 " -- didn't call input_close_device\n");
200 }
201
202 usb_free_urb(mimio->in.urb);
203
204 usb_free_urb(mimio->out.urb);
205
206 if (mimio->in.buf) {
207 usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->in.buf,
208 mimio->in.dma);
209 }
210
211 if (mimio->out.buf)
212 usb_buffer_free(mimio->udev, MIMIO_MAXPAYLOAD, mimio->out.buf,
213 mimio->out.dma);
214
215 if (mimio->idev)
216 input_free_device(mimio->idev);
217
218 kfree(mimio);
219}
220
221static void mimio_disconnect(struct usb_interface *ifc)
222{
223 struct mimio *mimio;
224
225 down(&disconnect_sem);
226
227 mimio = usb_get_intfdata(ifc);
228 usb_set_intfdata(ifc, NULL);
229 dev_dbg(&mimio->idev->dev, "disconnect\n");
230
231 if (mimio) {
232 mimio->present = 0;
233
234 if (mimio->open <= 0)
235 mimio_dealloc(mimio);
236 }
237
238 up(&disconnect_sem);
239}
240
241static int mimio_greet(struct mimio *mimio)
242{
243 const struct grtpkt {
244 int nbytes;
245 unsigned delay;
246 char data[8];
247 } grtpkts[] = {
248 { 3, 0, { 0x11, 0x55, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00 } },
249 { 5, 0, { 0x53, 0x55, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00 } },
250 { 5, 0, { 0x43, 0x55, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00 } },
251 { 5, 0, { 0x33, 0x55, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00 } },
252 { 5, 0, { 0x13, 0x00, 0x5e, 0x02, 0x4f, 0x00, 0x00, 0x00 } },
253 { 5, 0, { 0x13, 0x00, 0x04, 0x03, 0x14, 0x00, 0x00, 0x00 } },
254 { 5, 2, { 0x13, 0x00, 0x00, 0x04, 0x17, 0x00, 0x00, 0x00 } },
255 { 5, 0, { 0x13, 0x00, 0x0d, 0x08, 0x16, 0x00, 0x00, 0x00 } },
256 { 5, 0, { 0x13, 0x00, 0x4d, 0x01, 0x5f, 0x00, 0x00, 0x00 } },
257 { 3, 0, { 0xf1, 0x55, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 } },
258 { 7, 2, { 0x52, 0x55, 0x00, 0x07, 0x31, 0x55, 0x64, 0x00 } },
259 { 0, 0, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
260 };
261 int rslt;
262 const struct grtpkt *pkt;
263
264 for (pkt = grtpkts; pkt->nbytes; pkt++) {
265 rslt = mimio_tx(mimio, pkt->data, pkt->nbytes);
266 if (rslt)
267 return rslt;
268 if (pkt->delay)
269 msleep(pkt->delay);
270 }
271
272 return 0;
273}
274
275static void mimio_irq_in(struct urb *urb)
276{
277 int rslt;
278 char *data;
279 const char *reason = "going down";
280 struct mimio *mimio;
281
282 mimio = urb->context;
283
284 if (mimio == NULL)
285 /* paranoia */
286 return;
287
288 switch (urb->status) {
289 case 0:
290 /* success */
291 break;
292 case -ETIMEDOUT:
293 reason = "timeout -- unplugged?";
294 case -ECONNRESET:
295 case -ENOENT:
296 case -ESHUTDOWN:
297 dev_dbg(&mimio->idev->dev, "%s.\n", reason);
298 return;
299 default:
300 dev_dbg(&mimio->idev->dev, "unknown urb-status: %d.\n",
301 urb->status);
302 goto exit;
303 }
304 data = mimio->in.buf;
305
306 if (mimio->rxhandler)
307 mimio->rxhandler(mimio, data, urb->actual_length);
308exit:
309 /*
310 * Keep listening to device on same urb.
311 */
312 rslt = usb_submit_urb(urb, GFP_ATOMIC);
313 if (rslt)
314 dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
315 rslt);
316}
317
318static void mimio_irq_out(struct urb *urb)
319{
320 unsigned long flags;
321 struct mimio *mimio;
322
323 mimio = urb->context;
324
325 if (urb->status)
326 dev_dbg(&mimio->idev->dev, "urb-status: %d.\n", urb->status);
327
328 spin_lock_irqsave(&mimio->txlock, flags);
329 mimio->txflags |= MIMIO_TXDONE;
330 spin_unlock_irqrestore(&mimio->txlock, flags);
331 wmb();
332 wake_up(&mimio->waitq);
333}
334
335static int mimio_open(struct input_dev *idev)
336{
337 int rslt;
338 struct mimio *mimio;
339
340 rslt = 0;
341 down(&disconnect_sem);
342 mimio = input_get_drvdata(idev);
343 dev_dbg(&idev->dev, "mimio_open\n");
344
345 if (mimio == NULL) {
346 dev_err(&idev->dev, "null mimio.\n");
347 rslt = -ENODEV;
348 goto exit;
349 }
350
351 if (mimio->open++)
352 goto exit;
353
354 if (mimio->present && !mimio->greeted) {
355 struct urb *urb = mimio->in.urb;
356 mimio->in.urb->dev = mimio->udev;
357 rslt = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
358 if (rslt) {
359 dev_err(&idev->dev, "usb_submit_urb failure "
360 "(res = %d: %s). Not greeting.\n",
361 rslt,
362 (!urb ? "urb is NULL" :
363 (urb->hcpriv ? "urb->hcpriv is non-NULL" :
364 (!urb->complete ? "urb is not complete" :
365 (urb->number_of_packets <= 0 ? "urb has no packets" :
366 (urb->interval <= 0 ? "urb interval too small" :
367 "urb interval too large or some other error"))))));
368 rslt = -EIO;
369 goto exit;
370 }
371 rslt = mimio_greet(mimio);
372 if (rslt == 0) {
373 dev_dbg(&idev->dev, "Mimio greeted OK.\n");
374 mimio->greeted = 1;
375 } else {
376 dev_dbg(&idev->dev, "Mimio greet Failure (%d)\n",
377 rslt);
378 }
379 }
380
381exit:
382 up(&disconnect_sem);
383 return rslt;
384}
385
386static int mimio_probe(struct usb_interface *ifc,
387 const struct usb_device_id *id)
388{
389 char path[64];
390 int pipe, maxp;
391 struct mimio *mimio;
392 struct usb_device *udev;
393 struct usb_host_interface *hostifc;
394 struct input_dev *input_dev;
395 int res = 0;
396 int i;
397
398 udev = interface_to_usbdev(ifc);
399
400 mimio = kzalloc(sizeof(struct mimio), GFP_KERNEL);
401 if (!mimio)
402 return -ENOMEM;
403
404 input_dev = input_allocate_device();
405 if (!input_dev) {
406 mimio_dealloc(mimio);
407 return -ENOMEM;
408 }
409
410 mimio->uifc = ifc;
411 mimio->udev = udev;
412 mimio->pktbuf.p = mimio->pktbuf.buf;
413 mimio->pktbuf.q = mimio->pktbuf.buf;
414 /* init_input_dev(mimio->idev); */
415 mimio->idev = input_dev;
416 init_waitqueue_head(&mimio->waitq);
417 spin_lock_init(&mimio->txlock);
418 hostifc = ifc->cur_altsetting;
419
420 if (hostifc->desc.bNumEndpoints != 2) {
421 dev_err(&udev->dev, "Unexpected endpoint count: %d.\n",
422 hostifc->desc.bNumEndpoints);
423 mimio_dealloc(mimio);
424 return -ENODEV;
425 }
426
427 mimio->in.desc = &(hostifc->endpoint[0].desc);
428 mimio->out.desc = &(hostifc->endpoint[1].desc);
429
430 mimio->in.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
431 &mimio->in.dma);
432 mimio->out.buf = usb_buffer_alloc(udev, MIMIO_MAXPAYLOAD, GFP_KERNEL,
433 &mimio->out.dma);
434
435 if (mimio->in.buf == NULL || mimio->out.buf == NULL) {
436 dev_err(&udev->dev, "usb_buffer_alloc failure.\n");
437 mimio_dealloc(mimio);
438 return -ENOMEM;
439 }
440
441 mimio->in.urb = usb_alloc_urb(0, GFP_KERNEL);
442 mimio->out.urb = usb_alloc_urb(0, GFP_KERNEL);
443
444 if (mimio->in.urb == NULL || mimio->out.urb == NULL) {
445 dev_err(&udev->dev, "usb_alloc_urb failure.\n");
446 mimio_dealloc(mimio);
447 return -ENOMEM;
448 }
449
450 /*
451 * Build the input urb.
452 */
453 pipe = usb_rcvintpipe(udev, mimio->in.desc->bEndpointAddress);
454 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
455 if (maxp > MIMIO_MAXPAYLOAD)
456 maxp = MIMIO_MAXPAYLOAD;
457 usb_fill_int_urb(mimio->in.urb, udev, pipe, mimio->in.buf, maxp,
458 mimio_irq_in, mimio, mimio->in.desc->bInterval);
459 mimio->in.urb->transfer_dma = mimio->in.dma;
460 mimio->in.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
461
462 /*
463 * Build the output urb.
464 */
465 pipe = usb_sndintpipe(udev, mimio->out.desc->bEndpointAddress);
466 maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
467 if (maxp > MIMIO_MAXPAYLOAD)
468 maxp = MIMIO_MAXPAYLOAD;
469 usb_fill_int_urb(mimio->out.urb, udev, pipe, mimio->out.buf, maxp,
470 mimio_irq_out, mimio, mimio->out.desc->bInterval);
471 mimio->out.urb->transfer_dma = mimio->out.dma;
472 mimio->out.urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
473
474 /*
475 * Build input device info
476 */
477 usb_make_path(udev, path, 64);
478 snprintf(mimio->phys, MIMIO_MAXNAMELEN, "%s/input0", path);
479 input_set_drvdata(input_dev, mimio);
480 /* input_dev->dev = &ifc->dev; */
481 input_dev->open = mimio_open;
482 input_dev->close = mimio_close;
483 input_dev->name = mimio_name;
484 input_dev->phys = mimio->phys;
485 input_dev->dev.parent = &ifc->dev;
486
487 input_dev->id.bustype = BUS_USB;
488 input_dev->id.vendor = le16_to_cpu(udev->descriptor.idVendor);
489 input_dev->id.product = le16_to_cpu(udev->descriptor.idProduct);
490 input_dev->id.version = le16_to_cpu(udev->descriptor.bcdDevice);
491
492 input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
493 for (i = BTN_TOOL_PEN; i <= LOCALBTN_TOOL_EXTRA2; ++i)
494 set_bit(i, input_dev->keybit);
495
496 input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
497 BIT_MASK(BTN_1) |
498 BIT_MASK(BTN_2) |
499 BIT_MASK(BTN_3) |
500 BIT_MASK(BTN_4) |
501 BIT_MASK(BTN_5);
502 /* input_dev->keybit[BTN_MOUSE] |= BIT(BTN_LEFT); */
503 input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
504 input_set_abs_params(input_dev, ABS_X, 0, MIMIO_XRANGE_MAX, 0, 0);
505 input_set_abs_params(input_dev, ABS_Y, 0, MIMIO_YRANGE_MAX, 0, 0);
506 input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
507
508#if 0
509 input_dev->absmin[ABS_X] = 0;
510 input_dev->absmin[ABS_Y] = 0;
511 input_dev->absmax[ABS_X] = 9600;
512 input_dev->absmax[ABS_Y] = 4800;
513 input_dev->absfuzz[ABS_X] = 0;
514 input_dev->absfuzz[ABS_Y] = 0;
515 input_dev->absflat[ABS_X] = 0;
516 input_dev->absflat[ABS_Y] = 0;
517#endif
518
519#if 0
520 /* this will just reduce the precision */
521 input_dev->absfuzz[ABS_X] = 8; /* experimental; may need to change */
522 input_dev->absfuzz[ABS_Y] = 8; /* experimental; may need to change */
523#endif
524
525 /*
526 * Register the input device.
527 */
528 res = input_register_device(mimio->idev);
529 if (res) {
530 dev_err(&udev->dev, "input_register_device failure (%d)\n",
531 res);
532 mimio_dealloc(mimio);
533 return -EIO;
534 }
535 dev_dbg(&mimio->idev->dev, "input: %s on %s (res = %d).\n",
536 input_dev->name, input_dev->phys, res);
537
538 usb_set_intfdata(ifc, mimio);
539 mimio->present = 1;
540
541 /*
542 * Submit the input urb to the usb subsystem.
543 */
544 mimio->in.urb->dev = mimio->udev;
545 res = usb_submit_urb(mimio->in.urb, GFP_KERNEL);
546 if (res) {
547 dev_err(&mimio->idev->dev, "usb_submit_urb failure (%d)\n",
548 res);
549 mimio_dealloc(mimio);
550 return -EIO;
551 }
552
553 /*
554 * Attempt to greet the mimio after giving
555 * it some post-init settling time.
556 *
557 * note: sometimes this sleep interval isn't
558 * long enough to permit the device to re-init
559 * after a hot-swap; maybe need to bump it up.
560 *
561 * As it is, this probably breaks module unloading support!
562 */
563 msleep(1024);
564
565 res = mimio_greet(mimio);
566 if (res == 0) {
567 dev_dbg(&mimio->idev->dev, "Mimio greeted OK.\n");
568 mimio->greeted = 1;
569 mimio->rxhandler = mimio_rx_handler;
570 } else {
571 dev_dbg(&mimio->idev->dev, "Mimio greet Failure (%d)\n", res);
572 }
573
574 return 0;
575}
576
577static int handle_mimio_rx_penupdown(struct mimio *mimio,
578 int down,
579 const char *const instr[],
580 const int instr_ofst[])
581{
582 int penid, x;
583 if (mimio->pktbuf.q - mimio->pktbuf.p < (down ? 4 : 3))
584 return 1; /* partial pkt */
585
586 if (down) {
587 x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
588 *(mimio->pktbuf.p + 2);
589 if (x != *(mimio->pktbuf.p + 3)) {
590 dev_dbg(&mimio->idev->dev, "EV_PEN%s: bad xsum.\n",
591 down ? "DOWN":"UP");
592 /* skip this event data */
593 mimio->pktbuf.p += 4;
594 /* decode any remaining events */
595 return 0;
596 }
597 penid = mimio->pktbuf.instr = *(mimio->pktbuf.p + 2);
598 if (penid > MIMIO_PEN_MAX) {
599 dev_dbg(&mimio->idev->dev,
600 "Unmapped penID (not in [0, %d]): %d\n",
601 MIMIO_PEN_MAX, (int)mimio->pktbuf.instr);
602 penid = mimio->pktbuf.instr = 0;
603 }
604 mimio->last_pen_down = penid;
605 } else {
606 penid = mimio->last_pen_down;
607 }
608 dev_dbg(&mimio->idev->dev, "%s (id %d, code %d) %s.\n", instr[penid],
609 instr_ofst[penid], penid, down ? "down" : "up");
610
611 if (instr_ofst[penid] >= 0) {
612 int code = BTN_TOOL_PEN + instr_ofst[penid];
613 int value = down ? DOWNVALUE : UPVALUE;
614 if (code > KEY_MAX)
615 dev_dbg(&mimio->idev->dev, "input_event will ignore "
616 "-- code (%d) > KEY_MAX\n", code);
617 if (!test_bit(code, mimio->idev->keybit))
618 dev_dbg(&mimio->idev->dev, "input_event will ignore "
619 "-- bit for code (%d) not enabled\n", code);
620 if (!!test_bit(code, mimio->idev->key) == value)
621 dev_dbg(&mimio->idev->dev, "input_event will ignore "
622 "-- bit for code (%d) already set to %d\n",
623 code, value);
624 if (value != DOWNVALUE) {
625 /* input_regs(mimio->idev, regs); */
626 input_report_key(mimio->idev, code, value);
627 input_sync(mimio->idev);
628 } else {
629 /* wait until we get some coordinates */
630 }
631 } else {
632 dev_dbg(&mimio->idev->dev, "penID offset[%d] == %d is < 0 "
633 "- not sending\n", penid, instr_ofst[penid]);
634 }
635 mimio->pktbuf.p += down ? 4 : 3; /* 3 for up, 4 for down */
636 return 0;
637}
638
639/*
640 * Stay tuned for partial-packet excitement.
641 *
642 * This routine buffers data packets received from the mimio device
643 * in the mimio's data space. This buffering is necessary because
644 * the mimio's in endpoint can serve us partial packets of data, and
645 * we want the driver to support the servicing of multiple mimios.
646 * Empirical evidence gathered so far suggests that the method of
647 * buffering packet data in the mimio's data space works. Previous
648 * versions of this driver did not buffer packet data in each mimio's
649 * data-space, and were therefore not able to service multiple mimios.
650 * Note that since the caller of this routine is running in interrupt
651 * context, care needs to be taken to ensure that this routine does not
652 * become bloated, and it may be that another spinlock is needed in each
653 * mimio to guard the buffered packet data properly.
654 */
655static void mimio_rx_handler(struct mimio *mimio,
656 unsigned char *data,
657 unsigned int nbytes)
658{
659 struct device *dev = &mimio->idev->dev;
660 unsigned int x;
661 unsigned int y;
662 static const char * const instr[] = {
663 "?0",
664 "black pen", "blue pen", "green pen", "red pen",
665 "brown pen", "orange pen", "purple pen", "yellow pen",
666 "big eraser", "lil eraser",
667 "?11", "?12", "?13", "?14", "?15", "?16",
668 "mimio interactive", "interactive button1",
669 "interactive button2"
670 };
671
672 /* Mimio Interactive gives:
673 * down: [0x22 0x01 0x11 0x32 0x24]
674 * b1 : [0x22 0x01 0x12 0x31 0x24]
675 * b2 : [0x22 0x01 0x13 0x30 0x24]
676 */
677 static const int instr_ofst[] = {
678 -1,
679 0, 1, 2, 3,
680 9, 9, 9, 9,
681 4, 5,
682 -1, -1, -1, -1, -1, -1,
683 6, 7, 8,
684 };
685
686 memcpy(mimio->pktbuf.q, data, nbytes);
687 mimio->pktbuf.q += nbytes;
688
689 while (mimio->pktbuf.p < mimio->pktbuf.q) {
690 int t = *mimio->pktbuf.p;
691 switch (t) {
692 case MIMIO_EV_PENUP:
693 case MIMIO_EV_PENDOWN:
694 if (handle_mimio_rx_penupdown(mimio,
695 t == MIMIO_EV_PENDOWN,
696 instr, instr_ofst))
697 return; /* partial packet */
698 break;
699
700 case MIMIO_EV_PENDATA:
701 if (mimio->pktbuf.q - mimio->pktbuf.p < 6)
702 /* partial pkt */
703 return;
704 x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
705 *(mimio->pktbuf.p + 2) ^
706 *(mimio->pktbuf.p + 3) ^
707 *(mimio->pktbuf.p + 4);
708 if (x != *(mimio->pktbuf.p + 5)) {
709 dev_dbg(dev, "EV_PENDATA: bad xsum.\n");
710 mimio->pktbuf.p += 6; /* skip this event data */
711 break; /* decode any remaining events */
712 }
713 x = *(mimio->pktbuf.p + 1);
714 x <<= 8;
715 x |= *(mimio->pktbuf.p + 2);
716 y = *(mimio->pktbuf.p + 3);
717 y <<= 8;
718 y |= *(mimio->pktbuf.p + 4);
719 dev_dbg(dev, "coord: (%d, %d)\n", x, y);
720 if (instr_ofst[mimio->pktbuf.instr] >= 0) {
721 int code = BTN_TOOL_PEN +
722 instr_ofst[mimio->last_pen_down];
723#if 0
724 /* Utter hack to ensure we get forwarded _AND_
725 * so we can identify when a complete signal is
726 * received */
727 mimio->idev->abs[ABS_Y] = -1;
728 mimio->idev->abs[ABS_X] = -1;
729#endif
730 /* input_regs(mimio->idev, regs); */
731 input_report_abs(mimio->idev, ABS_X, x);
732 input_report_abs(mimio->idev, ABS_Y, y);
733 /* fake a penup */
734 change_bit(code, mimio->idev->key);
735 input_report_key(mimio->idev,
736 code,
737 DOWNVALUE);
738 /* always sync here */
739 mimio->idev->sync = 0;
740 input_sync(mimio->idev);
741 }
742 mimio->pktbuf.p += 6;
743 break;
744 case MIMIO_EV_MEMRESET:
745 if (mimio->pktbuf.q - mimio->pktbuf.p < 7)
746 /* partial pkt */
747 return;
748 dev_dbg(dev, "mem-reset.\n");
749 /* input_regs(mimio->idev, regs); */
750 input_event(mimio->idev, EV_KEY, BTN_0, 1);
751 input_event(mimio->idev, EV_KEY, BTN_0, 0);
752 input_sync(mimio->idev);
753 mimio->pktbuf.p += 7;
754 break;
755 case MIMIO_EV_ACC:
756 if (mimio->pktbuf.q - mimio->pktbuf.p < 4)
757 /* partial pkt */
758 return;
759 x = *mimio->pktbuf.p ^ *(mimio->pktbuf.p + 1) ^
760 *(mimio->pktbuf.p + 2);
761 if (x != *(mimio->pktbuf.p + 3)) {
762 dev_dbg(dev, "EV_ACC: bad xsum.\n");
763 mimio->pktbuf.p += 4; /* skip this event data */
764 break; /* decode any remaining events */
765 }
766 switch (*(mimio->pktbuf.p + 2)) {
767 case ACC_NEWPAGE:
768 dev_dbg(&mimio->idev->dev, "new-page.\n");
769 /* input_regs(mimio->idev, regs); */
770 input_event(mimio->idev, EV_KEY, BTN_1, 1);
771 input_event(mimio->idev, EV_KEY, BTN_1, 0);
772 input_sync(mimio->idev);
773 break;
774 case ACC_TAGPAGE:
775 dev_dbg(&mimio->idev->dev, "tag-page.\n");
776 /* input_regs(mimio->idev, regs); */
777 input_event(mimio->idev, EV_KEY, BTN_2, 1);
778 input_event(mimio->idev, EV_KEY, BTN_2, 0);
779 input_sync(mimio->idev);
780 break;
781 case ACC_PRINTPAGE:
782 dev_dbg(&mimio->idev->dev, "print-page.\n");
783 /* input_regs(mimio->idev, regs);*/
784 input_event(mimio->idev, EV_KEY, BTN_3, 1);
785 input_event(mimio->idev, EV_KEY, BTN_3, 0);
786 input_sync(mimio->idev);
787 break;
788 case ACC_MAXIMIZE:
789 dev_dbg(&mimio->idev->dev,
790 "maximize-window.\n");
791 /* input_regs(mimio->idev, regs); */
792 input_event(mimio->idev, EV_KEY, BTN_4, 1);
793 input_event(mimio->idev, EV_KEY, BTN_4, 0);
794 input_sync(mimio->idev);
795 break;
796 case ACC_FINDCTLPNL:
797 dev_dbg(&mimio->idev->dev, "find-ctl-panel.\n");
798 /* input_regs(mimio->idev, regs); */
799 input_event(mimio->idev, EV_KEY, BTN_5, 1);
800 input_event(mimio->idev, EV_KEY, BTN_5, 0);
801 input_sync(mimio->idev);
802 break;
803 case ACC_DONE:
804 dev_dbg(&mimio->idev->dev, "acc-done.\n");
805 /* no event is dispatched to the input
806 * subsystem for this device event.
807 */
808 break;
809 default:
810 dev_dbg(dev, "unknown acc event.\n");
811 break;
812 }
813 mimio->pktbuf.p += 4;
814 break;
815 default:
816 mimio->pktbuf.p++;
817 break;
818 }
819 }
820
821 /*
822 * No partial event was received, so reset mimio's pktbuf ptrs.
823 */
824 mimio->pktbuf.p = mimio->pktbuf.q = mimio->pktbuf.buf;
825}
826
827static int mimio_tx(struct mimio *mimio, const char *buf, int nbytes)
828{
829 int rslt;
830 int timeout;
831 unsigned long flags;
832 DECLARE_WAITQUEUE(wait, current);
833
834 if (!(isvalidtxsize(nbytes))) {
835 dev_err(&mimio->idev->dev, "invalid arg: nbytes: %d.\n",
836 nbytes);
837 return -EINVAL;
838 }
839
840 /*
841 * Init the out urb and copy the data to send.
842 */
843 mimio->out.urb->dev = mimio->udev;
844 mimio->out.urb->transfer_buffer_length = nbytes;
845 memcpy(mimio->out.urb->transfer_buffer, buf, nbytes);
846
847 /*
848 * Send the data.
849 */
850 spin_lock_irqsave(&mimio->txlock, flags);
851 mimio->txflags = MIMIO_TXWAIT;
852 rslt = usb_submit_urb(mimio->out.urb, GFP_ATOMIC);
853 spin_unlock_irqrestore(&mimio->txlock, flags);
854 dev_dbg(&mimio->idev->dev, "rslt: %d.\n", rslt);
855
856 if (rslt) {
857 dev_err(&mimio->idev->dev, "usb_submit_urb failure: %d.\n",
858 rslt);
859 return rslt;
860 }
861
862 /*
863 * Wait for completion to be signalled (the mimio_irq_out
864 * completion routine will or MIMIO_TXDONE in with txflags).
865 */
866 timeout = HZ;
867 set_current_state(TASK_INTERRUPTIBLE);
868 add_wait_queue(&mimio->waitq, &wait);
869
870 while (timeout && ((mimio->txflags & MIMIO_TXDONE) == 0)) {
871 timeout = schedule_timeout(timeout);
872 rmb();
873 }
874
875 if ((mimio->txflags & MIMIO_TXDONE) == 0)
876 dev_dbg(&mimio->idev->dev, "tx timed out.\n");
877
878 /*
879 * Now that completion has been signalled,
880 * unlink the urb so that it can be recycled.
881 */
882 set_current_state(TASK_RUNNING);
883 remove_wait_queue(&mimio->waitq, &wait);
884 usb_unlink_urb(mimio->out.urb);
885
886 return rslt;
887}
888
889static int __init mimio_init(void)
890{
891 int rslt;
892
893 rslt = usb_register(&mimio_driver);
894 if (rslt != 0) {
895 err("%s: usb_register failure: %d", __func__, rslt);
896 return rslt;
897 }
898
899 printk(KERN_INFO KBUILD_MODNAME ":"
900 DRIVER_DESC " " DRIVER_VERSION "\n");
901 return rslt;
902}
903
904static void __exit mimio_exit(void)
905{
906 usb_deregister(&mimio_driver);
907}
908
909module_init(mimio_init);
910module_exit(mimio_exit);
911
912MODULE_AUTHOR(DRIVER_AUTHOR);
913MODULE_DESCRIPTION(DRIVER_DESC);
914MODULE_LICENSE("GPL");
diff --git a/drivers/staging/otus/80211core/cagg.c b/drivers/staging/otus/80211core/cagg.c
index dbd0a5f0fcdf..f9514c06c14c 100644
--- a/drivers/staging/otus/80211core/cagg.c
+++ b/drivers/staging/otus/80211core/cagg.c
@@ -1832,14 +1832,12 @@ u16_t zfAggRxClear(zdev_t* dev, u32_t time)
1832 1832
1833struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf) 1833struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
1834{ 1834{
1835 u16_t dst0, src[3], ac, aid, fragOff; 1835 u16_t dst0, src[3], aid;
1836 u8_t up;
1837 u16_t offset = 0; 1836 u16_t offset = 0;
1838 u16_t seq_no; 1837 u16_t seq_no;
1839 u16_t frameType; 1838 u16_t frameType;
1840 u16_t frameCtrl; 1839 u16_t frameCtrl;
1841 u16_t frameSubtype; 1840 u16_t frameSubtype;
1842 u32_t tcp_seq;
1843 //struct aggSta *agg_sta; 1841 //struct aggSta *agg_sta;
1844#if ZM_AGG_FPGA_REORDERING 1842#if ZM_AGG_FPGA_REORDERING
1845 struct agg_tid_rx *tid_rx; 1843 struct agg_tid_rx *tid_rx;
@@ -1864,13 +1862,17 @@ struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
1864 return NULL; 1862 return NULL;
1865 } 1863 }
1866#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION 1864#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
1867 tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24; 1865 {
1868 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16; 1866 u32_t tcp_seq;
1869 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8; 1867
1870 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39); 1868 tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
1869 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
1870 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
1871 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
1872 ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
1873 }
1871#endif 1874#endif
1872 1875
1873 ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
1874 dst0 = zmw_rx_buf_readh(dev, buf, offset+4); 1876 dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
1875 1877
1876 src[0] = zmw_rx_buf_readh(dev, buf, offset+10); 1878 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
diff --git a/drivers/staging/otus/80211core/ccmd.c b/drivers/staging/otus/80211core/ccmd.c
index 8da28eee7fb0..3e3d9b500f65 100644
--- a/drivers/staging/otus/80211core/ccmd.c
+++ b/drivers/staging/otus/80211core/ccmd.c
@@ -1659,7 +1659,7 @@ void zfiWlanSetPacketTypePromiscuous(zdev_t *dev, u32_t setValue)
1659 if (setValue) { 1659 if (setValue) {
1660 /* write register for sniffer mode */ 1660 /* write register for sniffer mode */
1661 zfHpSetSnifferMode(dev, 1); 1661 zfHpSetSnifferMode(dev, 1);
1662 zm_msg0_mm(ZM_LV_1, "enalbe sniffer mode"); 1662 zm_msg0_mm(ZM_LV_1, "enable sniffer mode");
1663 } else { 1663 } else {
1664 zfHpSetSnifferMode(dev, 0); 1664 zfHpSetSnifferMode(dev, 0);
1665 zm_msg0_mm(ZM_LV_0, "disalbe sniffer mode"); 1665 zm_msg0_mm(ZM_LV_0, "disalbe sniffer mode");
diff --git a/drivers/staging/otus/80211core/cfunc.c b/drivers/staging/otus/80211core/cfunc.c
index d7c49d7523df..e0a9f383c755 100644
--- a/drivers/staging/otus/80211core/cfunc.c
+++ b/drivers/staging/otus/80211core/cfunc.c
@@ -1194,8 +1194,6 @@ u16_t zfFindMinimumUtilizationChannelIndex(zdev_t* dev, u16_t* array, u16_t coun
1194 u8_t i; 1194 u8_t i;
1195 u16_t tempMinIndex, tempMinValue; 1195 u16_t tempMinIndex, tempMinValue;
1196 1196
1197 zmw_get_wlan_dev(dev);
1198
1199 i = 1; 1197 i = 1;
1200 tempMinIndex = 0; 1198 tempMinIndex = 0;
1201 tempMinValue = array[tempMinIndex]; 1199 tempMinValue = array[tempMinIndex];
diff --git a/drivers/staging/otus/80211core/cmm.c b/drivers/staging/otus/80211core/cmm.c
index a6c1b41ba848..484e753df358 100644
--- a/drivers/staging/otus/80211core/cmm.c
+++ b/drivers/staging/otus/80211core/cmm.c
@@ -346,8 +346,6 @@ u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type)
346 u8_t super_feature; 346 u8_t super_feature;
347 u8_t ouiSuperG[6] = {0x00,0x03,0x7f,0x01, 0x01, 0x00}; 347 u8_t ouiSuperG[6] = {0x00,0x03,0x7f,0x01, 0x01, 0x00};
348 348
349 zmw_get_wlan_dev(dev);
350
351 /* Get offset of first element */ 349 /* Get offset of first element */
352 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); 350 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
353 if ((offset = zgElementOffsetTable[subType]) == 0xff) 351 if ((offset = zgElementOffsetTable[subType]) == 0xff)
@@ -411,8 +409,6 @@ u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type)
411 u8_t id; 409 u8_t id;
412 u8_t ouixr[6] = {0x00,0x03,0x7f,0x03, 0x01, 0x00}; 410 u8_t ouixr[6] = {0x00,0x03,0x7f,0x03, 0x01, 0x00};
413 411
414 zmw_get_wlan_dev(dev);
415
416 /* Get offset of first element */ 412 /* Get offset of first element */
417 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); 413 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
418 if ((offset = zgElementOffsetTable[subType]) == 0xff) 414 if ((offset = zgElementOffsetTable[subType]) == 0xff)
diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c
index a11d559167b1..c3fd47529c14 100644
--- a/drivers/staging/otus/80211core/cmmsta.c
+++ b/drivers/staging/otus/80211core/cmmsta.c
@@ -2808,7 +2808,7 @@ void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src)
2808 zmw_get_wlan_dev(dev); 2808 zmw_get_wlan_dev(dev);
2809 2809
2810 /* check mode : AP/IBSS */ 2810 /* check mode : AP/IBSS */
2811 if ((wd->wlanMode != ZM_MODE_AP) || (wd->wlanMode != ZM_MODE_IBSS)) 2811 if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS))
2812 { 2812 {
2813 zm_msg0_mm(ZM_LV_3, "Ignore probe req"); 2813 zm_msg0_mm(ZM_LV_3, "Ignore probe req");
2814 return; 2814 return;
@@ -4848,8 +4848,6 @@ u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset)
4848 u8_t MaxTxPower; 4848 u8_t MaxTxPower;
4849 u8_t MinTxPower; 4849 u8_t MinTxPower;
4850 4850
4851 zmw_get_wlan_dev(dev);
4852
4853 /* Element ID */ 4851 /* Element ID */
4854 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY); 4852 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY);
4855 4853
@@ -5276,7 +5274,6 @@ u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf)
5276 u8_t da0; 5274 u8_t da0;
5277 //u16_t sa[3]; 5275 //u16_t sa[3];
5278 u16_t ret; 5276 u16_t ret;
5279 u16_t i;
5280 //u8_t sa0; 5277 //u8_t sa0;
5281 5278
5282 zmw_get_wlan_dev(dev); 5279 zmw_get_wlan_dev(dev);
@@ -5738,8 +5735,6 @@ u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isH
5738 u8_t weightOfN40BelowThr = 16; 5735 u8_t weightOfN40BelowThr = 16;
5739 u8_t weightOfN40UpThr = 32; 5736 u8_t weightOfN40UpThr = 32;
5740 5737
5741 zmw_get_wlan_dev(dev);
5742
5743 if( isBMode == 0 ) 5738 if( isBMode == 0 )
5744 return (signalStrength + weightOfB); // pure b mode , do not add the weight value for this AP ! 5739 return (signalStrength + weightOfB); // pure b mode , do not add the weight value for this AP !
5745 else 5740 else
diff --git a/drivers/staging/otus/80211core/cpsmgr.c b/drivers/staging/otus/80211core/cpsmgr.c
index cf73caca8e52..98e1f0cc0727 100644
--- a/drivers/staging/otus/80211core/cpsmgr.c
+++ b/drivers/staging/otus/80211core/cpsmgr.c
@@ -381,8 +381,6 @@ static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev)
381 381
382static void zfPowerSavingMgrDisconnectMain(zdev_t* dev) 382static void zfPowerSavingMgrDisconnectMain(zdev_t* dev)
383{ 383{
384 zmw_get_wlan_dev(dev);
385
386#ifdef ZM_ENABLE_DISCONNECT_PS 384#ifdef ZM_ENABLE_DISCONNECT_PS
387 switch(wd->sta.psMgr.state) 385 switch(wd->sta.psMgr.state)
388 { 386 {
diff --git a/drivers/staging/otus/80211core/cscanmgr.c b/drivers/staging/otus/80211core/cscanmgr.c
index b32835c87590..be7d8ebe82ba 100644
--- a/drivers/staging/otus/80211core/cscanmgr.c
+++ b/drivers/staging/otus/80211core/cscanmgr.c
@@ -289,8 +289,6 @@ static void zfScanMgrEventSetFreqCompleteCb(zdev_t* dev)
289 289
290static void zfScanMgrEventScanCompleteCb(zdev_t* dev) 290static void zfScanMgrEventScanCompleteCb(zdev_t* dev)
291{ 291{
292 zmw_get_wlan_dev(dev);
293
294 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev))) 292 if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev)))
295 { 293 {
296 zfSendNullData(dev, 0); 294 zfSendNullData(dev, 0);
diff --git a/drivers/staging/otus/80211core/ctkip.c b/drivers/staging/otus/80211core/ctkip.c
index be42f7aaa37d..ca0740227be4 100644
--- a/drivers/staging/otus/80211core/ctkip.c
+++ b/drivers/staging/otus/80211core/ctkip.c
@@ -255,7 +255,8 @@ void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv)
255 zfMemoryCopy(pSeed->ta, ta, 6); 255 zfMemoryCopy(pSeed->ta, ta, 6);
256 zfMemoryCopy(pSeed->tk, key, 16); 256 zfMemoryCopy(pSeed->tk, key, 16);
257 257
258 iv16 = *initIv++; 258 iv16 = *initIv;
259 initIv++;
259 iv16 += *initIv<<8; 260 iv16 += *initIv<<8;
260 initIv++; 261 initIv++;
261 262
@@ -264,7 +265,7 @@ void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv)
264 for(i=0; i<4; i++) // initiv is little endian 265 for(i=0; i<4; i++) // initiv is little endian
265 { 266 {
266 iv32 += *initIv<<(i*8); 267 iv32 += *initIv<<(i*8);
267 *initIv++; 268 initIv++;
268 } 269 }
269 270
270 pSeed->iv32 = iv32+1; // Force Recalculating on Tkip Phase1 271 pSeed->iv32 = iv32+1; // Force Recalculating on Tkip Phase1
diff --git a/drivers/staging/otus/80211core/ctxrx.c b/drivers/staging/otus/80211core/ctxrx.c
index ac54d5a636b0..4e7f4bd86f47 100644
--- a/drivers/staging/otus/80211core/ctxrx.c
+++ b/drivers/staging/otus/80211core/ctxrx.c
@@ -536,8 +536,7 @@ void zfProtRspSim(zdev_t* dev, zbuf_t* buf)
536 zm_msg2_rx(ZM_LV_2, "ip1=", dip[1]); 536 zm_msg2_rx(ZM_LV_2, "ip1=", dip[1]);
537 537
538 //ARP request to 192.168.1.15 538 //ARP request to 192.168.1.15
539 if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)); 539 if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)) {
540 {
541 zm_msg0_rx(ZM_LV_2, "ARP"); 540 zm_msg0_rx(ZM_LV_2, "ARP");
542 /* ARP response */ 541 /* ARP response */
543 zmw_rx_buf_writeh(dev, buf, 20, 0x0200); 542 zmw_rx_buf_writeh(dev, buf, 20, 0x0200);
@@ -883,7 +882,6 @@ zlError:
883/************************************************************************/ 882/************************************************************************/
884u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t flag) 883u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t flag)
885{ 884{
886 u16_t err;
887 //u16_t addrTblSize; 885 //u16_t addrTblSize;
888 //struct zsAddrTbl addrTbl; 886 //struct zsAddrTbl addrTbl;
889 u16_t removeLen; 887 u16_t removeLen;
@@ -905,7 +903,6 @@ u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t fla
905 u8_t qosType, keyIdx = 0; 903 u8_t qosType, keyIdx = 0;
906 u16_t fragOff; 904 u16_t fragOff;
907 u16_t newFlag; 905 u16_t newFlag;
908 struct zsMicVar* pMicKey;
909 u8_t tkipFrameOffset = 0; 906 u8_t tkipFrameOffset = 0;
910 907
911 zmw_get_wlan_dev(dev); 908 zmw_get_wlan_dev(dev);
@@ -1693,8 +1690,6 @@ void zfShowTxEAPOL(zdev_t* dev, zbuf_t* buf, u16_t offset)
1693 u16_t packetLen, keyInfo, keyLen, keyDataLen, length, Op_Code; 1690 u16_t packetLen, keyInfo, keyLen, keyDataLen, length, Op_Code;
1694 u32_t replayCounterH, replayCounterL, vendorId, VendorType; 1691 u32_t replayCounterH, replayCounterL, vendorId, VendorType;
1695 1692
1696 zmw_get_wlan_dev(dev);
1697
1698 zm_debug_msg1("EAPOL Packet size = ", zfwBufGetSize(dev, buf)); 1693 zm_debug_msg1("EAPOL Packet size = ", zfwBufGetSize(dev, buf));
1699 1694
1700 /* EAPOL packet type */ 1695 /* EAPOL packet type */
@@ -2437,7 +2432,6 @@ void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo)
2437 u16_t IvOffset; 2432 u16_t IvOffset;
2438 u8_t keyLen = 5; 2433 u8_t keyLen = 5;
2439 u8_t iv[3]; 2434 u8_t iv[3];
2440 u8_t *wepKey;
2441 u8_t keyIdx; 2435 u8_t keyIdx;
2442 2436
2443 IvOffset = offset + ZM_SIZE_OF_WLAN_DATA_HEADER; 2437 IvOffset = offset + ZM_SIZE_OF_WLAN_DATA_HEADER;
diff --git a/drivers/staging/otus/80211core/ledmgr.c b/drivers/staging/otus/80211core/ledmgr.c
index 1e104a928ca4..eafce0b1204f 100644
--- a/drivers/staging/otus/80211core/ledmgr.c
+++ b/drivers/staging/otus/80211core/ledmgr.c
@@ -187,7 +187,6 @@ void zfLedCtrlType2_scan(zdev_t* dev);
187 187
188void zfLedCtrlType2(zdev_t* dev) 188void zfLedCtrlType2(zdev_t* dev)
189{ 189{
190 u32_t ton, toff, tmp, period;
191 u16_t OperateLED; 190 u16_t OperateLED;
192 zmw_get_wlan_dev(dev); 191 zmw_get_wlan_dev(dev);
193 192
diff --git a/drivers/staging/otus/80211core/pub_zfi.h b/drivers/staging/otus/80211core/pub_zfi.h
index b7b7f455f357..5202e5a645d5 100644
--- a/drivers/staging/otus/80211core/pub_zfi.h
+++ b/drivers/staging/otus/80211core/pub_zfi.h
@@ -814,7 +814,6 @@ extern void zfiRxPerformanceReg(zdev_t* dev, u32_t reg, u32_t rsp);
814#define ZM_PERFORMANCE_RX_AMSDU(dev, buf, len) 814#define ZM_PERFORMANCE_RX_AMSDU(dev, buf, len)
815#define ZM_PERFORMANCE_RX_FLUSH(dev) 815#define ZM_PERFORMANCE_RX_FLUSH(dev)
816#define ZM_PERFORMANCE_RX_CLEAR(dev) 816#define ZM_PERFORMANCE_RX_CLEAR(dev)
817#define ZM_SEQ_DEBUG
818#define ZM_PERFORMANCE_RX_REORDER(dev) 817#define ZM_PERFORMANCE_RX_REORDER(dev)
819#endif 818#endif
820/***** End of section 3 *****/ 819/***** End of section 3 *****/
diff --git a/drivers/staging/otus/Kconfig b/drivers/staging/otus/Kconfig
index f6cc2625e341..e9181340bef1 100644
--- a/drivers/staging/otus/Kconfig
+++ b/drivers/staging/otus/Kconfig
@@ -1,6 +1,8 @@
1config OTUS 1config OTUS
2 tristate "Atheros OTUS 802.11n USB wireless support" 2 tristate "Atheros OTUS 802.11n USB wireless support"
3 depends on USB && WLAN && MAC80211 3 depends on USB && WLAN && MAC80211
4 select WIRELESS_EXT
5 select WEXT_PRIV
4 default N 6 default N
5 ---help--- 7 ---help---
6 Enable support for Atheros 802.11n USB hardware: 8 Enable support for Atheros 802.11n USB hardware:
diff --git a/drivers/staging/otus/apdbg.c b/drivers/staging/otus/apdbg.c
index 0eb93f19958a..b59028e7e33c 100644
--- a/drivers/staging/otus/apdbg.c
+++ b/drivers/staging/otus/apdbg.c
@@ -90,8 +90,27 @@ struct zdap_ioctl {
90 90
91#endif 91#endif
92 92
93char hex(char); 93static char hex(char v)
94unsigned char asctohex(char *str); 94{
95 if (isdigit(v))
96 return v - '0';
97 else if (isxdigit(v))
98 return tolower(v) - 'a' + 10;
99 else
100 return 0;
101}
102
103static unsigned char asctohex(char *str)
104{
105 unsigned char value;
106
107 value = hex(*str) & 0x0f;
108 value = value << 4;
109 str++;
110 value |= hex(*str) & 0x0f;
111
112 return value;
113}
95 114
96char *prgname; 115char *prgname;
97 116
@@ -109,10 +128,10 @@ int set_ioctl(int sock, struct ifreq *req)
109 128
110int read_reg(int sock, struct ifreq *req) 129int read_reg(int sock, struct ifreq *req)
111{ 130{
112 struct zdap_ioctl *zdreq = 0; 131 struct zdap_ioctl *zdreq = NULL;
113 132
114 if (!set_ioctl(sock, req)) 133 if (!set_ioctl(sock, req))
115 return -1; 134 return -1;
116 135
117 /* 136 /*
118 * zdreq = (struct zdap_ioctl *)req->ifr_data; 137 * zdreq = (struct zdap_ioctl *)req->ifr_data;
@@ -125,7 +144,7 @@ int read_reg(int sock, struct ifreq *req)
125 144
126int read_mem(int sock, struct ifreq *req) 145int read_mem(int sock, struct ifreq *req)
127{ 146{
128 struct zdap_ioctl *zdreq = 0; 147 struct zdap_ioctl *zdreq = NULL;
129 int i; 148 int i;
130 149
131 if (!set_ioctl(sock, req)) 150 if (!set_ioctl(sock, req))
@@ -368,7 +387,7 @@ int main(int argc, char **argv)
368 387
369 zdreq.addr = addr; 388 zdreq.addr = addr;
370 zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE; 389 zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE;
371 } else { 390 } else {
372 fprintf(stderr, "error action\n"); 391 fprintf(stderr, "error action\n");
373 exit(1); 392 exit(1);
374 } 393 }
@@ -380,25 +399,3 @@ fail:
380 exit(0); 399 exit(0);
381} 400}
382 401
383unsigned char asctohex(char *str)
384{
385 unsigned char value;
386
387 value = hex(*str) & 0x0f;
388 value = value << 4;
389 str++;
390 value |= hex(*str) & 0x0f;
391
392 return value;
393}
394
395char hex(char v)
396{
397 if (isdigit(v))
398 return v - '0';
399 else if (isxdigit(v))
400 return tolower(v) - 'a' + 10;
401 else
402 return 0;
403}
404
diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c
index 94f9cbbbdefc..8dff5b97dfe3 100644
--- a/drivers/staging/otus/hal/hpmain.c
+++ b/drivers/staging/otus/hal/hpmain.c
@@ -1316,7 +1316,6 @@ void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40,
1316 u8_t extOffset, u8_t initRF) 1316 u8_t extOffset, u8_t initRF)
1317{ 1317{
1318 u32_t cmd[9]; 1318 u32_t cmd[9];
1319 u32_t cmdB[3];
1320 u16_t ret; 1319 u16_t ret;
1321 u8_t old_band; 1320 u8_t old_band;
1322 u8_t new_band; 1321 u8_t new_band;
@@ -3434,7 +3433,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset)
3434 /* Write PHY regs 672-703 */ 3433 /* Write PHY regs 672-703 */
3435 for (i=0; i<128; i+=4) 3434 for (i=0; i<128; i+=4)
3436 { 3435 {
3437 u32_t regAddr = 0x9800 + (672 * 4);
3438 u32_t val; 3436 u32_t val;
3439 3437
3440 val = ((u32_t)vpd_chain1[i+3]<<24) | 3438 val = ((u32_t)vpd_chain1[i+3]<<24) |
@@ -3485,7 +3483,6 @@ void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset)
3485 /* Write PHY regs 672-703 + 0x1000 */ 3483 /* Write PHY regs 672-703 + 0x1000 */
3486 for (i=0; i<128; i+=4) 3484 for (i=0; i<128; i+=4)
3487 { 3485 {
3488 u32_t regAddr = 0x9800 + (672 * 4) + 0x1000;
3489 u32_t val; 3486 u32_t val;
3490 3487
3491 val = ((u32_t)vpd_chain3[i+3]<<24) | 3488 val = ((u32_t)vpd_chain3[i+3]<<24) |
@@ -4584,7 +4581,6 @@ void zfHpSetRollCallTable(zdev_t* dev)
4584void zfHpSetTTSIFSTime(zdev_t* dev, u8_t sifs_time) 4581void zfHpSetTTSIFSTime(zdev_t* dev, u8_t sifs_time)
4585{ 4582{
4586 u32_t reg_value = 0; 4583 u32_t reg_value = 0;
4587 zmw_get_wlan_dev(dev);
4588 4584
4589 sifs_time &= 0x3f; 4585 sifs_time &= 0x3f;
4590 reg_value = 0x14400b | (((u32_t)sifs_time)<<24); 4586 reg_value = 0x14400b | (((u32_t)sifs_time)<<24);
diff --git a/drivers/staging/otus/hal/hpreg.c b/drivers/staging/otus/hal/hpreg.c
index d9894fe5f4ec..178777c09dbd 100644
--- a/drivers/staging/otus/hal/hpreg.c
+++ b/drivers/staging/otus/hal/hpreg.c
@@ -786,45 +786,6 @@ enum {
786 WT1_5760_5800, 786 WT1_5760_5800,
787}; 787};
788 788
789static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
790 { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5130_5210 */
791 { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5250_5330 */
792 { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5370_5490 */
793 { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5530_5650 */
794
795 { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5150_5190 */
796 { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5230_5310 */
797 { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5350_5470 */
798 { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5510_5670 */
799
800 { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5200_5240 */
801 { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5200_5240 */
802 { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5210_5210 */
803 { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5210_5210 */
804
805 { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5280_5280 */
806 { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5280_5280 */
807 { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5250 */
808 { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5290_5290 */
809 { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5290 */
810 { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5250_5290 */
811
812 { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5540_5660 */
813 { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5760_5800 */
814 { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5760_5800 */
815
816 { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5765_5805 */
817
818 /*
819 * Below are the WWR frequencies
820 */
821
822 { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5210_5250 */
823 { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5290_5290 */
824 { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5540_5660 */
825 { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* WT1_5760_5800 */
826};
827
828/* 789/*
829 * 2GHz 11b channel tags 790 * 2GHz 11b channel tags
830 */ 791 */
@@ -864,45 +825,6 @@ enum {
864 W2_2484_2484, 825 W2_2484_2484,
865}; 826};
866 827
867static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
868 { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2312_2372 */
869 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F2_2312_2372 */
870
871 { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2472 */
872 { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2472 */
873 { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F3_2412_2472 */
874
875 { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2462 */
876 { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2462 */
877 { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2432_2442 */
878
879 { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2457_2472 */
880
881 { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0, 0}, /* F1_2467_2472 */
882
883 { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2484_2484 */
884 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0, 0}, /* F2_2484_2484 */
885
886 { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2512_2732 */
887
888 /*
889 * WWR have powers opened up to 20dBm. Limits should often come from CTL/Max powers
890 */
891
892 { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2312_2372 */
893 { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2412_2412 */
894 { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2417_2432 */
895 { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2437_2442 */
896 { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2447_2457 */
897 { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2462_2462 */
898 { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2467_2467 */
899 { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2467_2467 */
900 { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2472_2472 */
901 { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2472_2472 */
902 { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2484_2484 */
903 { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2484_2484 */
904};
905
906 828
907/* 829/*
908 * 2GHz 11g channel tags 830 * 2GHz 11g channel tags
@@ -984,16 +906,6 @@ enum {
984 T1_2512_2732 906 T1_2512_2732
985}; 907};
986 908
987static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
988 { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2312_2372 */
989 { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2437_2437 */
990 { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_2437_2437 */
991 { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* T3_2437_2437 */
992 { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2512_2732 */
993};
994
995
996
997/* 909/*
998 * 2GHz 11n frequency tags 910 * 2GHz 11n frequency tags
999 */ 911 */
@@ -1005,15 +917,6 @@ enum {
1005 NG_DEMO_ALL_CHANNELS, 917 NG_DEMO_ALL_CHANNELS,
1006}; 918};
1007 919
1008static REG_DMN_FREQ_BAND regDmn2Ghz11ngFreq[] = {
1009 { 2422, 2452, 20, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG1_2422_2452 */
1010 { 2422, 2452, 27, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG2_2422_2452 */
1011 { 2422, 2452, 30, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG3_2422_2452 */
1012
1013 { 2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG_DEMO_ALL_CHANNELS */
1014};
1015
1016
1017/* 920/*
1018 * 5GHz 11n frequency tags 921 * 5GHz 11n frequency tags
1019 */ 922 */
@@ -1050,42 +953,6 @@ enum {
1050 NA_DEMO_ALL_CHANNELS, 953 NA_DEMO_ALL_CHANNELS,
1051}; 954};
1052 955
1053static REG_DMN_FREQ_BAND regDmn5Ghz11naFreq[] = {
1054 /*
1055 * ToDo: This table needs to be completely populated with 5GHz 11n properties
1056 */
1057 { 5190, 5230, 15, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5190_5230 */
1058 { 5190, 5230, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA2_5190_5230 */
1059 { 5190, 5230, 18, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5190_5230 */
1060 { 5190, 5230, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5190_5230 */
1061 { 5190, 5230, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5190_5230 */
1062
1063 { 5270, 5270, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5270 */
1064
1065 { 5270, 5310, 18, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5310 */
1066 { 5270, 5310, 20, 0, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA2_5270_5310 */
1067 { 5270, 5310, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA3_5270_5310 */
1068 { 5270, 5310, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA4_5270_5310 */
1069
1070 { 5310, 5310, 17, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5310_5310 */
1071
1072 { 5510, 5630, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5510_5630 */
1073
1074 { 5510, 5670, 20, 6, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA1_5510_5670 */
1075 { 5510, 5670, 27, 0, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA2_5510_5670 */
1076 { 5510, 5670, 30, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 1}, /* NA3_5510_5670 */
1077
1078 { 5755, 5795, 17, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5755_5795 */
1079 { 5755, 5795, 20, 6, 40, 40, DFS_ETSI, NO_PSCAN, 0, 0}, /* NA2_5755_5795 */
1080 { 5755, 5795, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5755_5795 */
1081 { 5755, 5795, 30, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5755_5795 */
1082 { 5755, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5755_5795 */
1083
1084 { 5795, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5795_5795 */
1085
1086 { 4920, 6100, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA_DEMO_ALL_CHANNELS */
1087};
1088
1089typedef struct regDomain { 956typedef struct regDomain {
1090 u16_t regDmnEnum; /* value from EnumRd table */ 957 u16_t regDmnEnum; /* value from EnumRd table */
1091 u8_t conformanceTestLimit; 958 u8_t conformanceTestLimit;
diff --git a/drivers/staging/otus/hal/hprw.c b/drivers/staging/otus/hal/hprw.c
index d9fad47d5d59..4dbd5fb44b0a 100644
--- a/drivers/staging/otus/hal/hprw.c
+++ b/drivers/staging/otus/hal/hprw.c
@@ -282,7 +282,6 @@ void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen)
282 else if (src == ZM_OID_FLASH_READ) 282 else if (src == ZM_OID_FLASH_READ)
283 { 283 {
284 u32_t datalen; 284 u32_t datalen;
285 u16_t i;
286 285
287 datalen = (rsp[0] & 255); 286 datalen = (rsp[0] & 255);
288 287
diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c
index 6808e69fb354..8c47b1a68627 100644
--- a/drivers/staging/otus/ioctl.c
+++ b/drivers/staging/otus/ioctl.c
@@ -866,15 +866,15 @@ int usbdrvwext_giwscan(struct net_device *dev,
866 char *current_ev = extra; 866 char *current_ev = extra;
867 char *end_buf; 867 char *end_buf;
868 int i; 868 int i;
869 /* struct zsBssList BssList; */
870 struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
871 GFP_KERNEL);
872 /* BssList = wd->sta.pBssList; */ 869 /* BssList = wd->sta.pBssList; */
873 /* zmw_get_wlan_dev(dev); */ 870 /* zmw_get_wlan_dev(dev); */
874 871
875 if (macp->DeviceOpened != 1) 872 if (macp->DeviceOpened != 1)
876 return 0; 873 return 0;
877 874
875 /* struct zsBssList BssList; */
876 struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
877 GFP_KERNEL);
878 if (data->length == 0) 878 if (data->length == 0)
879 end_buf = extra + IW_SCAN_MAX_DATA; 879 end_buf = extra + IW_SCAN_MAX_DATA;
880 else 880 else
@@ -930,7 +930,7 @@ int usbdrvwext_siwessid(struct net_device *dev,
930 return -EINVAL; 930 return -EINVAL;
931 931
932 if (essid->flags == 1) { 932 if (essid->flags == 1) {
933 if (essid->length > (IW_ESSID_MAX_SIZE + 1)) 933 if (essid->length > IW_ESSID_MAX_SIZE)
934 return -E2BIG; 934 return -E2BIG;
935 935
936 if (copy_from_user(&EssidBuf, essid->pointer, essid->length)) 936 if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
@@ -2227,7 +2227,8 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
2227 case ZD_CMD_SCAN_REQ: 2227 case ZD_CMD_SCAN_REQ:
2228 printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n"); 2228 printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
2229 break; 2229 break;
2230 case ZD_CMD_SET_GENERIC_ELEMENT: 2230 case ZD_CMD_SET_GENERIC_ELEMENT: {
2231 u8_t len, *wpaie;
2231 printk(KERN_ERR "usbdrv_wpa_ioctl:" 2232 printk(KERN_ERR "usbdrv_wpa_ioctl:"
2232 " ZD_CMD_SET_GENERIC_ELEMENT\n"); 2233 " ZD_CMD_SET_GENERIC_ELEMENT\n");
2233 2234
@@ -2250,8 +2251,8 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
2250 /* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, 2251 /* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
2251 * zdparm->u.generic_elem.len); 2252 * zdparm->u.generic_elem.len);
2252 */ 2253 */
2253 u8_t len = zdparm->u.generic_elem.len; 2254 len = zdparm->u.generic_elem.len;
2254 u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data; 2255 wpaie = zdparm->u.generic_elem.data;
2255 2256
2256 printk(KERN_ERR "wd->ap.wpaLen : % d\n", len); 2257 printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);
2257 2258
@@ -2273,6 +2274,7 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
2273 * #endif 2274 * #endif
2274 */ 2275 */
2275 break; 2276 break;
2277 }
2276 2278
2277 /* #ifdef ZM_HOSTAPD_SUPPORT */ 2279 /* #ifdef ZM_HOSTAPD_SUPPORT */
2278 case ZD_CMD_GET_TSC: 2280 case ZD_CMD_GET_TSC:
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index b0adbc8b2dc2..5e6a12037b12 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -829,7 +829,7 @@ int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId)
829{ 829{
830 /* Allocate net device structure */ 830 /* Allocate net device structure */
831 vap[vapId].dev = alloc_etherdev(0); 831 vap[vapId].dev = alloc_etherdev(0);
832 printk("Register vap dev=%x\n", (u32_t)vap[vapId].dev); 832 printk("Register vap dev=%p\n", vap[vapId].dev);
833 833
834 if(vap[vapId].dev == NULL) { 834 if(vap[vapId].dev == NULL) {
835 printk("alloc_etherdev fail\n"); 835 printk("alloc_etherdev fail\n");
@@ -883,7 +883,7 @@ int zfLnxUnregisterVapDev(struct net_device* parentDev, u16_t vapId)
883 printk("Unregister VAP dev : %s\n", vap[vapId].dev->name); 883 printk("Unregister VAP dev : %s\n", vap[vapId].dev->name);
884 884
885 if(vap[vapId].dev != NULL) { 885 if(vap[vapId].dev != NULL) {
886 printk("Unregister vap dev=%x\n", (u32_t)vap[vapId].dev); 886 printk("Unregister vap dev=%p\n", vap[vapId].dev);
887 // 887 //
888 //unregister_netdevice(wds[wdsId].dev); 888 //unregister_netdevice(wds[wdsId].dev);
889 unregister_netdev(vap[vapId].dev); 889 unregister_netdev(vap[vapId].dev);
diff --git a/drivers/staging/otus/wrap_pkt.c b/drivers/staging/otus/wrap_pkt.c
index 75bb952fd0a5..a2f5cb1f5298 100644
--- a/drivers/staging/otus/wrap_pkt.c
+++ b/drivers/staging/otus/wrap_pkt.c
@@ -58,7 +58,7 @@ void zfLnxRecv80211(zdev_t *dev, zbuf_t *buf, struct zsAdditionInfo *addInfo)
58 skb1 = skb_copy(buf, GFP_ATOMIC); 58 skb1 = skb_copy(buf, GFP_ATOMIC);
59 if (skb1 != NULL) { 59 if (skb1 != NULL) {
60 skb1->dev = dev; 60 skb1->dev = dev;
61 skb1->mac_header = skb1->data; 61 skb_reset_mac_header(skb1);
62 skb1->ip_summed = CHECKSUM_NONE; 62 skb1->ip_summed = CHECKSUM_NONE;
63 skb1->pkt_type = PACKET_OTHERHOST; 63 skb1->pkt_type = PACKET_OTHERHOST;
64 /* ETH_P_80211_RAW */ 64 /* ETH_P_80211_RAW */
@@ -85,13 +85,7 @@ void zfLnxRecvEth(zdev_t *dev, zbuf_t *buf, u16_t port)
85 /* new_buf = dev_alloc_skb(2048); */ 85 /* new_buf = dev_alloc_skb(2048); */
86 new_buf = dev_alloc_skb(buf->len); 86 new_buf = dev_alloc_skb(buf->len);
87 87
88#ifdef NET_SKBUFF_DATA_USES_OFFSET 88 skb_reset_tail_pointer(new_buf);
89 new_buf->tail = 0;
90 new_buf->len = 0;
91#else
92 new_buf->tail = new_buf->data;
93 new_buf->len = 0;
94#endif
95 89
96 skb_put(new_buf, buf->len); 90 skb_put(new_buf, buf->len);
97 memcpy(new_buf->data, buf->data, buf->len); 91 memcpy(new_buf->data, buf->data, buf->len);
diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c
index 2a6d937ba5e8..4cd9b7f5a887 100644
--- a/drivers/staging/otus/zdusb.c
+++ b/drivers/staging/otus/zdusb.c
@@ -45,7 +45,7 @@ MODULE_LICENSE("Dual BSD/GPL");
45static const char driver_name[] = "Otus"; 45static const char driver_name[] = "Otus";
46 46
47/* table of devices that work with this driver */ 47/* table of devices that work with this driver */
48static struct usb_device_id zd1221_ids [] = { 48static const struct usb_device_id zd1221_ids[] = {
49 { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, 49 { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) },
50 { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, 50 { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) },
51 { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) }, 51 { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) },
diff --git a/drivers/staging/p9auth/Kconfig b/drivers/staging/p9auth/Kconfig
deleted file mode 100644
index d1c66d262020..000000000000
--- a/drivers/staging/p9auth/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
1config PLAN9AUTH
2 tristate "Plan 9 style capability device implementation"
3 default n
4 depends on CRYPTO
5 help
6 This module implements the Plan 9 style capability device.
7
8 To compile this driver as a module, choose
9 M here: the module will be called p9auth.
diff --git a/drivers/staging/p9auth/Makefile b/drivers/staging/p9auth/Makefile
deleted file mode 100644
index 3ebf6ff0eef2..000000000000
--- a/drivers/staging/p9auth/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_PLAN9AUTH) += p9auth.o
diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c
deleted file mode 100644
index db7962621210..000000000000
--- a/drivers/staging/p9auth/p9auth.c
+++ /dev/null
@@ -1,408 +0,0 @@
1/*
2 * Plan 9 style capability device implementation for the Linux Kernel
3 *
4 * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com>
5 *
6 * Released under the GPLv2
7 *
8 */
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/moduleparam.h>
12#include <linux/slab.h>
13#include <linux/fs.h>
14#include <linux/errno.h>
15#include <linux/fcntl.h>
16#include <linux/cdev.h>
17#include <linux/uaccess.h>
18#include <linux/list.h>
19#include <linux/mm.h>
20#include <linux/string.h>
21#include <linux/crypto.h>
22#include <linux/highmem.h>
23#include <linux/scatterlist.h>
24#include <linux/sched.h>
25#include <linux/cred.h>
26
27#ifndef CAP_MAJOR
28#define CAP_MAJOR 0
29#endif
30
31#ifndef CAP_NR_DEVS
32#define CAP_NR_DEVS 2 /* caphash and capuse */
33#endif
34
35#ifndef CAP_NODE_SIZE
36#define CAP_NODE_SIZE 20
37#endif
38
39#define MAX_DIGEST_SIZE 20
40
41struct cap_node {
42 char data[CAP_NODE_SIZE];
43 struct list_head list;
44};
45
46struct cap_dev {
47 struct cap_node *head;
48 int node_size;
49 unsigned long size;
50 struct semaphore sem;
51 struct cdev cdev;
52};
53
54static int cap_major = CAP_MAJOR;
55static int cap_minor;
56static int cap_nr_devs = CAP_NR_DEVS;
57static int cap_node_size = CAP_NODE_SIZE;
58
59module_param(cap_major, int, S_IRUGO);
60module_param(cap_minor, int, S_IRUGO);
61module_param(cap_nr_devs, int, S_IRUGO);
62
63MODULE_AUTHOR("Ashwin Ganti");
64MODULE_LICENSE("GPL");
65
66static struct cap_dev *cap_devices;
67
68static void hexdump(unsigned char *buf, unsigned int len)
69{
70 while (len--)
71 printk("%02x", *buf++);
72 printk("\n");
73}
74
75static char *cap_hash(char *plain_text, unsigned int plain_text_size,
76 char *key, unsigned int key_size)
77{
78 struct scatterlist sg;
79 char *result;
80 struct crypto_hash *tfm;
81 struct hash_desc desc;
82 int ret;
83
84 tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
85 if (IS_ERR(tfm)) {
86 printk(KERN_ERR
87 "failed to load transform for hmac(sha1): %ld\n",
88 PTR_ERR(tfm));
89 return NULL;
90 }
91
92 desc.tfm = tfm;
93 desc.flags = 0;
94
95 result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
96 if (!result) {
97 printk(KERN_ERR "out of memory!\n");
98 goto out;
99 }
100
101 sg_set_buf(&sg, plain_text, plain_text_size);
102
103 ret = crypto_hash_setkey(tfm, key, key_size);
104 if (ret) {
105 printk(KERN_ERR "setkey() failed ret=%d\n", ret);
106 kfree(result);
107 result = NULL;
108 goto out;
109 }
110
111 ret = crypto_hash_digest(&desc, &sg, plain_text_size, result);
112 if (ret) {
113 printk(KERN_ERR "digest () failed ret=%d\n", ret);
114 kfree(result);
115 result = NULL;
116 goto out;
117 }
118
119 printk(KERN_DEBUG "crypto hash digest size %d\n",
120 crypto_hash_digestsize(tfm));
121 hexdump(result, MAX_DIGEST_SIZE);
122
123out:
124 crypto_free_hash(tfm);
125 return result;
126}
127
128static int cap_trim(struct cap_dev *dev)
129{
130 struct cap_node *tmp;
131 struct list_head *pos, *q;
132 if (dev->head != NULL) {
133 list_for_each_safe(pos, q, &(dev->head->list)) {
134 tmp = list_entry(pos, struct cap_node, list);
135 list_del(pos);
136 kfree(tmp);
137 }
138 }
139 return 0;
140}
141
142static int cap_open(struct inode *inode, struct file *filp)
143{
144 struct cap_dev *dev;
145 dev = container_of(inode->i_cdev, struct cap_dev, cdev);
146 filp->private_data = dev;
147
148 /* trim to 0 the length of the device if open was write-only */
149 if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
150 if (down_interruptible(&dev->sem))
151 return -ERESTARTSYS;
152 cap_trim(dev);
153 up(&dev->sem);
154 }
155 /* initialise the head if it is NULL */
156 if (dev->head == NULL) {
157 dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
158 INIT_LIST_HEAD(&(dev->head->list));
159 }
160 return 0;
161}
162
163static int cap_release(struct inode *inode, struct file *filp)
164{
165 return 0;
166}
167
168static ssize_t cap_write(struct file *filp, const char __user *buf,
169 size_t count, loff_t *f_pos)
170{
171 struct cap_node *node_ptr, *tmp;
172 struct list_head *pos;
173 struct cap_dev *dev = filp->private_data;
174 ssize_t retval = -ENOMEM;
175 struct cred *new;
176 int len, target_int, source_int, flag = 0;
177 char *user_buf, *user_buf_running, *source_user, *target_user,
178 *rand_str, *hash_str, *result;
179
180 if (down_interruptible(&dev->sem))
181 return -ERESTARTSYS;
182
183 user_buf_running = NULL;
184 hash_str = NULL;
185 node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
186 user_buf = kzalloc(count+1, GFP_KERNEL);
187 if (!node_ptr || !user_buf)
188 goto out;
189
190 if (copy_from_user(user_buf, buf, count)) {
191 retval = -EFAULT;
192 goto out;
193 }
194
195 /*
196 * If the minor number is 0 ( /dev/caphash ) then simply add the
197 * hashed capability supplied by the user to the list of hashes
198 */
199 if (0 == iminor(filp->f_dentry->d_inode)) {
200 if (count > CAP_NODE_SIZE) {
201 retval = -EINVAL;
202 goto out;
203 }
204 printk(KERN_INFO "Capability being written to /dev/caphash : \n");
205 hexdump(user_buf, count);
206 memcpy(node_ptr->data, user_buf, count);
207 list_add(&(node_ptr->list), &(dev->head->list));
208 node_ptr = NULL;
209 } else {
210 char *tmpu;
211 if (!cap_devices[0].head ||
212 list_empty(&(cap_devices[0].head->list))) {
213 retval = -EINVAL;
214 goto out;
215 }
216 /*
217 * break the supplied string into tokens with @ as the
218 * delimiter If the string is "user1@user2@randomstring" we
219 * need to split it and hash 'user1@user2' using 'randomstring'
220 * as the key.
221 */
222 tmpu = user_buf_running = kstrdup(user_buf, GFP_KERNEL);
223 source_user = strsep(&tmpu, "@");
224 target_user = strsep(&tmpu, "@");
225 rand_str = tmpu;
226 if (!source_user || !target_user || !rand_str) {
227 retval = -EINVAL;
228 goto out;
229 }
230
231 /* hash the string user1@user2 with rand_str as the key */
232 len = strlen(source_user) + strlen(target_user) + 1;
233 /* src, @, len, \0 */
234 hash_str = kzalloc(len+1, GFP_KERNEL);
235 strcat(hash_str, source_user);
236 strcat(hash_str, "@");
237 strcat(hash_str, target_user);
238
239 printk(KERN_ALERT "the source user is %s \n", source_user);
240 printk(KERN_ALERT "the target user is %s \n", target_user);
241
242 result = cap_hash(hash_str, len, rand_str, strlen(rand_str));
243 if (NULL == result) {
244 retval = -EFAULT;
245 goto out;
246 }
247 memcpy(node_ptr->data, result, CAP_NODE_SIZE); /* why? */
248 /* Change the process's uid if the hash is present in the
249 * list of hashes
250 */
251 list_for_each(pos, &(cap_devices->head->list)) {
252 /*
253 * Change the user id of the process if the hashes
254 * match
255 */
256 if (0 ==
257 memcmp(result,
258 list_entry(pos, struct cap_node,
259 list)->data,
260 CAP_NODE_SIZE)) {
261 target_int = (unsigned int)
262 simple_strtol(target_user, NULL, 0);
263 source_int = (unsigned int)
264 simple_strtol(source_user, NULL, 0);
265 flag = 1;
266
267 /*
268 * Check whether the process writing to capuse
269 * is actually owned by the source owner
270 */
271 if (source_int != current_uid()) {
272 printk(KERN_ALERT
273 "Process is not owned by the source user of the capability.\n");
274 retval = -EFAULT;
275 goto out;
276 }
277 /*
278 * What all id's need to be changed here? uid,
279 * euid, fsid, savedids ?? Currently I am
280 * changing the effective user id since most of
281 * the authorisation decisions are based on it
282 */
283 new = prepare_creds();
284 if (!new) {
285 retval = -ENOMEM;
286 goto out;
287 }
288 new->uid = (uid_t) target_int;
289 new->euid = (uid_t) target_int;
290 retval = commit_creds(new);
291 if (retval)
292 goto out;
293
294 /*
295 * Remove the capability from the list and
296 * break
297 */
298 tmp = list_entry(pos, struct cap_node, list);
299 list_del(pos);
300 kfree(tmp);
301 break;
302 }
303 }
304 if (0 == flag) {
305 /*
306 * The capability is not present in the list of the
307 * hashes stored, hence return failure
308 */
309 printk(KERN_ALERT
310 "Invalid capabiliy written to /dev/capuse \n");
311 retval = -EFAULT;
312 goto out;
313 }
314 }
315 *f_pos += count;
316 retval = count;
317 /* update the size */
318 if (dev->size < *f_pos)
319 dev->size = *f_pos;
320
321out:
322 kfree(node_ptr);
323 kfree(user_buf);
324 kfree(user_buf_running);
325 kfree(hash_str);
326 up(&dev->sem);
327 return retval;
328}
329
330static const struct file_operations cap_fops = {
331 .owner = THIS_MODULE,
332 .write = cap_write,
333 .open = cap_open,
334 .release = cap_release,
335};
336
337/* no __exit here because it can be called by the init function */
338static void cap_cleanup_module(void)
339{
340 int i;
341 dev_t devno = MKDEV(cap_major, cap_minor);
342 if (cap_devices) {
343 for (i = 0; i < cap_nr_devs; i++) {
344 cap_trim(cap_devices + i);
345 cdev_del(&cap_devices[i].cdev);
346 }
347 kfree(cap_devices);
348 }
349 unregister_chrdev_region(devno, cap_nr_devs);
350
351}
352
353static void cap_setup_cdev(struct cap_dev *dev, int index)
354{
355 int err, devno = MKDEV(cap_major, cap_minor + index);
356 cdev_init(&dev->cdev, &cap_fops);
357 dev->cdev.owner = THIS_MODULE;
358 dev->cdev.ops = &cap_fops;
359 err = cdev_add(&dev->cdev, devno, 1);
360 if (err)
361 printk(KERN_NOTICE "Error %d adding cap%d", err, index);
362}
363
364static int __init cap_init_module(void)
365{
366 int result, i;
367 dev_t dev = 0;
368
369 if (cap_major) {
370 dev = MKDEV(cap_major, cap_minor);
371 result = register_chrdev_region(dev, cap_nr_devs, "cap");
372 } else {
373 result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs,
374 "cap");
375 cap_major = MAJOR(dev);
376 }
377
378 if (result < 0) {
379 printk(KERN_WARNING "cap: can't get major %d\n",
380 cap_major);
381 return result;
382 }
383
384 cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev),
385 GFP_KERNEL);
386 if (!cap_devices) {
387 result = -ENOMEM;
388 goto fail;
389 }
390
391 /* Initialize each device. */
392 for (i = 0; i < cap_nr_devs; i++) {
393 cap_devices[i].node_size = cap_node_size;
394 init_MUTEX(&cap_devices[i].sem);
395 cap_setup_cdev(&cap_devices[i], i);
396 }
397
398 return 0;
399
400fail:
401 cap_cleanup_module();
402 return result;
403}
404
405module_init(cap_init_module);
406module_exit(cap_cleanup_module);
407
408
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 95c93e82ccec..377884f3480d 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -41,7 +41,6 @@
41#include <linux/signal.h> 41#include <linux/signal.h>
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/spinlock.h> 43#include <linux/spinlock.h>
44#include <linux/smp_lock.h>
45#include <linux/interrupt.h> 44#include <linux/interrupt.h>
46#include <linux/miscdevice.h> 45#include <linux/miscdevice.h>
47#include <linux/slab.h> 46#include <linux/slab.h>
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
index fcba78d21636..0c495eacb75b 100644
--- a/drivers/staging/phison/phison.c
+++ b/drivers/staging/phison/phison.c
@@ -69,7 +69,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
69 return ret; 69 return ret;
70} 70}
71 71
72static struct pci_device_id phison_pci_tbl[] = { 72static const struct pci_device_id phison_pci_tbl[] = {
73 { PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID, 73 { PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID,
74 PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 }, 74 PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
75 { 0, }, 75 { 0, },
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index 11fc4d5c43e1..63275529ff55 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -36,6 +36,7 @@
36#define POHMELFS_MAGIC_NUM 0x504f482e 36#define POHMELFS_MAGIC_NUM 0x504f482e
37 37
38static struct kmem_cache *pohmelfs_inode_cache; 38static struct kmem_cache *pohmelfs_inode_cache;
39static atomic_t psb_bdi_num = ATOMIC_INIT(0);
39 40
40/* 41/*
41 * Removes inode from all trees, drops local name cache and removes all queued 42 * Removes inode from all trees, drops local name cache and removes all queued
@@ -322,7 +323,7 @@ int pohmelfs_write_create_inode(struct pohmelfs_inode *pi)
322 t = netfs_trans_alloc(psb, err + 1, 0, 0); 323 t = netfs_trans_alloc(psb, err + 1, 0, 0);
323 if (!t) { 324 if (!t) {
324 err = -ENOMEM; 325 err = -ENOMEM;
325 goto err_out_put; 326 goto err_out_exit;
326 } 327 }
327 t->complete = pohmelfs_write_inode_complete; 328 t->complete = pohmelfs_write_inode_complete;
328 t->private = igrab(inode); 329 t->private = igrab(inode);
@@ -395,7 +396,8 @@ int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n)
395/* 396/*
396 * Writeback for given inode. 397 * Writeback for given inode.
397 */ 398 */
398static int pohmelfs_write_inode(struct inode *inode, int sync) 399static int pohmelfs_write_inode(struct inode *inode,
400 struct writeback_control *wbc)
399{ 401{
400 struct pohmelfs_inode *pi = POHMELFS_I(inode); 402 struct pohmelfs_inode *pi = POHMELFS_I(inode);
401 403
@@ -1331,6 +1333,8 @@ static void pohmelfs_put_super(struct super_block *sb)
1331 pohmelfs_crypto_exit(psb); 1333 pohmelfs_crypto_exit(psb);
1332 pohmelfs_state_exit(psb); 1334 pohmelfs_state_exit(psb);
1333 1335
1336 bdi_destroy(&psb->bdi);
1337
1334 kfree(psb); 1338 kfree(psb);
1335 sb->s_fs_info = NULL; 1339 sb->s_fs_info = NULL;
1336} 1340}
@@ -1767,8 +1771,7 @@ static int pohmelfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
1767 seq_printf(m, "%u ", ctl->idx); 1771 seq_printf(m, "%u ", ctl->idx);
1768 if (ctl->addr.sa_family == AF_INET) { 1772 if (ctl->addr.sa_family == AF_INET) {
1769 struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr; 1773 struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
1770 /* seq_printf(m, "%pi4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port)); */ 1774 seq_printf(m, "%pI4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port));
1771 seq_printf(m, "%u.%u.%u.%u:%u", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
1772 } else if (ctl->addr.sa_family == AF_INET6) { 1775 } else if (ctl->addr.sa_family == AF_INET6) {
1773 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr; 1776 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
1774 seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port)); 1777 seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port));
@@ -1815,11 +1818,22 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
1815 if (!psb) 1818 if (!psb)
1816 goto err_out_exit; 1819 goto err_out_exit;
1817 1820
1821 err = bdi_init(&psb->bdi);
1822 if (err)
1823 goto err_out_free_sb;
1824
1825 err = bdi_register(&psb->bdi, NULL, "pfs-%d", atomic_inc_return(&psb_bdi_num));
1826 if (err) {
1827 bdi_destroy(&psb->bdi);
1828 goto err_out_free_sb;
1829 }
1830
1818 sb->s_fs_info = psb; 1831 sb->s_fs_info = psb;
1819 sb->s_op = &pohmelfs_sb_ops; 1832 sb->s_op = &pohmelfs_sb_ops;
1820 sb->s_magic = POHMELFS_MAGIC_NUM; 1833 sb->s_magic = POHMELFS_MAGIC_NUM;
1821 sb->s_maxbytes = MAX_LFS_FILESIZE; 1834 sb->s_maxbytes = MAX_LFS_FILESIZE;
1822 sb->s_blocksize = PAGE_SIZE; 1835 sb->s_blocksize = PAGE_SIZE;
1836 sb->s_bdi = &psb->bdi;
1823 1837
1824 psb->sb = sb; 1838 psb->sb = sb;
1825 1839
@@ -1863,11 +1877,11 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
1863 1877
1864 err = pohmelfs_parse_options((char *) data, psb, 0); 1878 err = pohmelfs_parse_options((char *) data, psb, 0);
1865 if (err) 1879 if (err)
1866 goto err_out_free_sb; 1880 goto err_out_free_bdi;
1867 1881
1868 err = pohmelfs_copy_crypto(psb); 1882 err = pohmelfs_copy_crypto(psb);
1869 if (err) 1883 if (err)
1870 goto err_out_free_sb; 1884 goto err_out_free_bdi;
1871 1885
1872 err = pohmelfs_state_init(psb); 1886 err = pohmelfs_state_init(psb);
1873 if (err) 1887 if (err)
@@ -1916,6 +1930,8 @@ err_out_state_exit:
1916err_out_free_strings: 1930err_out_free_strings:
1917 kfree(psb->cipher_string); 1931 kfree(psb->cipher_string);
1918 kfree(psb->hash_string); 1932 kfree(psb->hash_string);
1933err_out_free_bdi:
1934 bdi_destroy(&psb->bdi);
1919err_out_free_sb: 1935err_out_free_sb:
1920 kfree(psb); 1936 kfree(psb);
1921err_out_exit: 1937err_out_exit:
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
index 623a07d29dea..01cba006e07a 100644
--- a/drivers/staging/pohmelfs/netfs.h
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -18,6 +18,7 @@
18 18
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/connector.h> 20#include <linux/connector.h>
21#include <linux/backing-dev.h>
21 22
22#define POHMELFS_CN_IDX 5 23#define POHMELFS_CN_IDX 5
23#define POHMELFS_CN_VAL 0 24#define POHMELFS_CN_VAL 0
@@ -624,6 +625,8 @@ struct pohmelfs_sb {
624 625
625 struct super_block *sb; 626 struct super_block *sb;
626 627
628 struct backing_dev_info bdi;
629
627 /* 630 /*
628 * Algorithm strings. 631 * Algorithm strings.
629 */ 632 */
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
index f7726f1d3641..1561f74a413b 100644
--- a/drivers/staging/quatech_usb2/quatech_usb2.c
+++ b/drivers/staging/quatech_usb2/quatech_usb2.c
@@ -116,7 +116,7 @@ static int debug;
116#define FOURTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 3] 116#define FOURTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 3]
117#define FIFTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 4] 117#define FIFTHCHAR ((unsigned char *)(urb->transfer_buffer))[i + 4]
118 118
119static struct usb_device_id quausb2_id_table[] = { 119static const struct usb_device_id quausb2_id_table[] = {
120 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)}, 120 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)},
121 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)}, 121 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)},
122 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)}, 122 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)},
diff --git a/drivers/staging/ramzswap/Kconfig b/drivers/staging/ramzswap/Kconfig
index 24e25691fae2..127b3c6c9596 100644
--- a/drivers/staging/ramzswap/Kconfig
+++ b/drivers/staging/ramzswap/Kconfig
@@ -5,7 +5,7 @@ config RAMZSWAP
5 select LZO_DECOMPRESS 5 select LZO_DECOMPRESS
6 default n 6 default n
7 help 7 help
8 Creates virtual block devices which can be used (only) as a swap 8 Creates virtual block devices which can (only) be used as swap
9 disks. Pages swapped to these disks are compressed and stored in 9 disks. Pages swapped to these disks are compressed and stored in
10 memory itself. 10 memory itself.
11 11
diff --git a/drivers/staging/ramzswap/ramzswap.txt b/drivers/staging/ramzswap/ramzswap.txt
index e9f1619505a0..9694acfeb43f 100644
--- a/drivers/staging/ramzswap/ramzswap.txt
+++ b/drivers/staging/ramzswap/ramzswap.txt
@@ -5,9 +5,9 @@ Project home: http://compcache.googlecode.com/
5 5
6* Introduction 6* Introduction
7 7
8It creates RAM based block devices which can be used (only) as swap disks. 8The ramzswap module creates RAM based block devices which can (only) be used as
9Pages swapped to these devices are compressed and stored in memory itself. 9swap disks. Pages swapped to these devices are compressed and stored in memory
10See project home for use cases, performance numbers and a lot more. 10itself. See project home for use cases, performance numbers and a lot more.
11 11
12Individual ramzswap devices are configured and initialized using rzscontrol 12Individual ramzswap devices are configured and initialized using rzscontrol
13userspace utility as shown in examples below. See rzscontrol man page for more 13userspace utility as shown in examples below. See rzscontrol man page for more
diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c
index 989fac5b01b3..5e422e254ee8 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.c
+++ b/drivers/staging/ramzswap/ramzswap_drv.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Compressed RAM based swap device 2 * Compressed RAM based swap device
3 * 3 *
4 * Copyright (C) 2008, 2009 Nitin Gupta 4 * Copyright (C) 2008, 2009, 2010 Nitin Gupta
5 * 5 *
6 * This code is released using a dual license strategy: BSD/GPL 6 * This code is released using a dual license strategy: BSD/GPL
7 * You can choose the licence that better fits your requirements. 7 * You can choose the licence that better fits your requirements.
@@ -24,12 +24,10 @@
24#include <linux/genhd.h> 24#include <linux/genhd.h>
25#include <linux/highmem.h> 25#include <linux/highmem.h>
26#include <linux/lzo.h> 26#include <linux/lzo.h>
27#include <linux/mutex.h>
28#include <linux/string.h> 27#include <linux/string.h>
29#include <linux/swap.h> 28#include <linux/swap.h>
30#include <linux/swapops.h> 29#include <linux/swapops.h>
31#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
32#include <linux/version.h>
33 31
34#include "ramzswap_drv.h" 32#include "ramzswap_drv.h"
35 33
@@ -222,7 +220,7 @@ out:
222 return ret; 220 return ret;
223} 221}
224 222
225void ramzswap_ioctl_get_stats(struct ramzswap *rzs, 223static void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
226 struct ramzswap_ioctl_stats *s) 224 struct ramzswap_ioctl_stats *s)
227{ 225{
228 strncpy(s->backing_swap_name, rzs->backing_swap_name, 226 strncpy(s->backing_swap_name, rzs->backing_swap_name,
@@ -240,7 +238,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
240 238
241 mem_used = xv_get_total_size_bytes(rzs->mem_pool) 239 mem_used = xv_get_total_size_bytes(rzs->mem_pool)
242 + (rs->pages_expand << PAGE_SHIFT); 240 + (rs->pages_expand << PAGE_SHIFT);
243 succ_writes = rs->num_writes - rs->failed_writes; 241 succ_writes = rzs_stat64_read(rzs, &rs->num_writes) -
242 rzs_stat64_read(rzs, &rs->failed_writes);
244 243
245 if (succ_writes && rs->pages_stored) { 244 if (succ_writes && rs->pages_stored) {
246 good_compress_perc = rs->good_compress * 100 245 good_compress_perc = rs->good_compress * 100
@@ -249,11 +248,12 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
249 / rs->pages_stored; 248 / rs->pages_stored;
250 } 249 }
251 250
252 s->num_reads = rs->num_reads; 251 s->num_reads = rzs_stat64_read(rzs, &rs->num_reads);
253 s->num_writes = rs->num_writes; 252 s->num_writes = rzs_stat64_read(rzs, &rs->num_writes);
254 s->failed_reads = rs->failed_reads; 253 s->failed_reads = rzs_stat64_read(rzs, &rs->failed_reads);
255 s->failed_writes = rs->failed_writes; 254 s->failed_writes = rzs_stat64_read(rzs, &rs->failed_writes);
256 s->invalid_io = rs->invalid_io; 255 s->invalid_io = rzs_stat64_read(rzs, &rs->invalid_io);
256 s->notify_free = rzs_stat64_read(rzs, &rs->notify_free);
257 s->pages_zero = rs->pages_zero; 257 s->pages_zero = rs->pages_zero;
258 258
259 s->good_compress_pct = good_compress_perc; 259 s->good_compress_pct = good_compress_perc;
@@ -265,8 +265,8 @@ void ramzswap_ioctl_get_stats(struct ramzswap *rzs,
265 s->compr_data_size = rs->compr_size; 265 s->compr_data_size = rs->compr_size;
266 s->mem_used_total = mem_used; 266 s->mem_used_total = mem_used;
267 267
268 s->bdev_num_reads = rs->bdev_num_reads; 268 s->bdev_num_reads = rzs_stat64_read(rzs, &rs->bdev_num_reads);
269 s->bdev_num_writes = rs->bdev_num_writes; 269 s->bdev_num_writes = rzs_stat64_read(rzs, &rs->bdev_num_writes);
270 } 270 }
271#endif /* CONFIG_RAMZSWAP_STATS */ 271#endif /* CONFIG_RAMZSWAP_STATS */
272} 272}
@@ -502,6 +502,14 @@ static int setup_backing_swap(struct ramzswap *rzs)
502 goto bad_param; 502 goto bad_param;
503 } 503 }
504 disksize = i_size_read(inode); 504 disksize = i_size_read(inode);
505 /*
506 * Can happen if user gives an extended partition as
507 * backing swap or simply a bad disk.
508 */
509 if (!disksize) {
510 pr_err("Error reading backing swap size.\n");
511 goto bad_param;
512 }
505 } else if (S_ISREG(inode->i_mode)) { 513 } else if (S_ISREG(inode->i_mode)) {
506 bdev = inode->i_sb->s_bdev; 514 bdev = inode->i_sb->s_bdev;
507 if (IS_SWAPFILE(inode)) { 515 if (IS_SWAPFILE(inode)) {
@@ -519,7 +527,6 @@ static int setup_backing_swap(struct ramzswap *rzs)
519 rzs->swap_file = swap_file; 527 rzs->swap_file = swap_file;
520 rzs->backing_swap = bdev; 528 rzs->backing_swap = bdev;
521 rzs->disksize = disksize; 529 rzs->disksize = disksize;
522 BUG_ON(!rzs->disksize);
523 530
524 return 0; 531 return 0;
525 532
@@ -537,7 +544,7 @@ out:
537 * Map logical page number 'pagenum' to physical page number 544 * Map logical page number 'pagenum' to physical page number
538 * on backing swap device. For block device, this is a nop. 545 * on backing swap device. For block device, this is a nop.
539 */ 546 */
540u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum) 547static u32 map_backing_swap_page(struct ramzswap *rzs, u32 pagenum)
541{ 548{
542 u32 skip_pages, entries_per_page; 549 u32 skip_pages, entries_per_page;
543 size_t delta, se_offset, skipped; 550 size_t delta, se_offset, skipped;
@@ -593,9 +600,13 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
593 u32 offset = rzs->table[index].offset; 600 u32 offset = rzs->table[index].offset;
594 601
595 if (unlikely(!page)) { 602 if (unlikely(!page)) {
603 /*
604 * No memory is allocated for zero filled pages.
605 * Simply clear zero page flag.
606 */
596 if (rzs_test_flag(rzs, index, RZS_ZERO)) { 607 if (rzs_test_flag(rzs, index, RZS_ZERO)) {
597 rzs_clear_flag(rzs, index, RZS_ZERO); 608 rzs_clear_flag(rzs, index, RZS_ZERO);
598 stat_dec(rzs->stats.pages_zero); 609 rzs_stat_dec(&rzs->stats.pages_zero);
599 } 610 }
600 return; 611 return;
601 } 612 }
@@ -604,7 +615,7 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
604 clen = PAGE_SIZE; 615 clen = PAGE_SIZE;
605 __free_page(page); 616 __free_page(page);
606 rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED); 617 rzs_clear_flag(rzs, index, RZS_UNCOMPRESSED);
607 stat_dec(rzs->stats.pages_expand); 618 rzs_stat_dec(&rzs->stats.pages_expand);
608 goto out; 619 goto out;
609 } 620 }
610 621
@@ -614,11 +625,11 @@ static void ramzswap_free_page(struct ramzswap *rzs, size_t index)
614 625
615 xv_free(rzs->mem_pool, page, offset); 626 xv_free(rzs->mem_pool, page, offset);
616 if (clen <= PAGE_SIZE / 2) 627 if (clen <= PAGE_SIZE / 2)
617 stat_dec(rzs->stats.good_compress); 628 rzs_stat_dec(&rzs->stats.good_compress);
618 629
619out: 630out:
620 rzs->stats.compr_size -= clen; 631 rzs->stats.compr_size -= clen;
621 stat_dec(rzs->stats.pages_stored); 632 rzs_stat_dec(&rzs->stats.pages_stored);
622 633
623 rzs->table[index].page = NULL; 634 rzs->table[index].page = NULL;
624 rzs->table[index].offset = 0; 635 rzs->table[index].offset = 0;
@@ -664,7 +675,6 @@ static int handle_uncompressed_page(struct ramzswap *rzs, struct bio *bio)
664 return 0; 675 return 0;
665} 676}
666 677
667
668/* 678/*
669 * Called when request page is not present in ramzswap. 679 * Called when request page is not present in ramzswap.
670 * Its either in backing swap device (if present) or 680 * Its either in backing swap device (if present) or
@@ -680,8 +690,8 @@ static int handle_ramzswap_fault(struct ramzswap *rzs, struct bio *bio)
680 */ 690 */
681 if (rzs->backing_swap) { 691 if (rzs->backing_swap) {
682 u32 pagenum; 692 u32 pagenum;
683 stat_dec(rzs->stats.num_reads); 693 rzs_stat64_dec(rzs, &rzs->stats.num_reads);
684 stat_inc(rzs->stats.bdev_num_reads); 694 rzs_stat64_inc(rzs, &rzs->stats.bdev_num_reads);
685 bio->bi_bdev = rzs->backing_swap; 695 bio->bi_bdev = rzs->backing_swap;
686 696
687 /* 697 /*
@@ -719,7 +729,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
719 struct zobj_header *zheader; 729 struct zobj_header *zheader;
720 unsigned char *user_mem, *cmem; 730 unsigned char *user_mem, *cmem;
721 731
722 stat_inc(rzs->stats.num_reads); 732 rzs_stat64_inc(rzs, &rzs->stats.num_reads);
723 733
724 page = bio->bi_io_vec[0].bv_page; 734 page = bio->bi_io_vec[0].bv_page;
725 index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; 735 index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -731,7 +741,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
731 if (!rzs->table[index].page) 741 if (!rzs->table[index].page)
732 return handle_ramzswap_fault(rzs, bio); 742 return handle_ramzswap_fault(rzs, bio);
733 743
734 /* Page is stored uncompressed since its incompressible */ 744 /* Page is stored uncompressed since it's incompressible */
735 if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED))) 745 if (unlikely(rzs_test_flag(rzs, index, RZS_UNCOMPRESSED)))
736 return handle_uncompressed_page(rzs, bio); 746 return handle_uncompressed_page(rzs, bio);
737 747
@@ -753,7 +763,7 @@ static int ramzswap_read(struct ramzswap *rzs, struct bio *bio)
753 if (unlikely(ret != LZO_E_OK)) { 763 if (unlikely(ret != LZO_E_OK)) {
754 pr_err("Decompression failed! err=%d, page=%u\n", 764 pr_err("Decompression failed! err=%d, page=%u\n",
755 ret, index); 765 ret, index);
756 stat_inc(rzs->stats.failed_reads); 766 rzs_stat64_inc(rzs, &rzs->stats.failed_reads);
757 goto out; 767 goto out;
758 } 768 }
759 769
@@ -777,7 +787,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
777 struct page *page, *page_store; 787 struct page *page, *page_store;
778 unsigned char *user_mem, *cmem, *src; 788 unsigned char *user_mem, *cmem, *src;
779 789
780 stat_inc(rzs->stats.num_writes); 790 rzs_stat64_inc(rzs, &rzs->stats.num_writes);
781 791
782 page = bio->bi_io_vec[0].bv_page; 792 page = bio->bi_io_vec[0].bv_page;
783 index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; 793 index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT;
@@ -789,25 +799,16 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
789 * is no longer referenced by any process. So, its now safe 799 * is no longer referenced by any process. So, its now safe
790 * to free the memory that was allocated for this page. 800 * to free the memory that was allocated for this page.
791 */ 801 */
792 if (rzs->table[index].page) 802 if (rzs->table[index].page || rzs_test_flag(rzs, index, RZS_ZERO))
793 ramzswap_free_page(rzs, index); 803 ramzswap_free_page(rzs, index);
794 804
795 /*
796 * No memory ia allocated for zero filled pages.
797 * Simply clear zero page flag.
798 */
799 if (rzs_test_flag(rzs, index, RZS_ZERO)) {
800 stat_dec(rzs->stats.pages_zero);
801 rzs_clear_flag(rzs, index, RZS_ZERO);
802 }
803
804 mutex_lock(&rzs->lock); 805 mutex_lock(&rzs->lock);
805 806
806 user_mem = kmap_atomic(page, KM_USER0); 807 user_mem = kmap_atomic(page, KM_USER0);
807 if (page_zero_filled(user_mem)) { 808 if (page_zero_filled(user_mem)) {
808 kunmap_atomic(user_mem, KM_USER0); 809 kunmap_atomic(user_mem, KM_USER0);
809 mutex_unlock(&rzs->lock); 810 mutex_unlock(&rzs->lock);
810 stat_inc(rzs->stats.pages_zero); 811 rzs_stat_inc(&rzs->stats.pages_zero);
811 rzs_set_flag(rzs, index, RZS_ZERO); 812 rzs_set_flag(rzs, index, RZS_ZERO);
812 813
813 set_bit(BIO_UPTODATE, &bio->bi_flags); 814 set_bit(BIO_UPTODATE, &bio->bi_flags);
@@ -831,7 +832,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
831 if (unlikely(ret != LZO_E_OK)) { 832 if (unlikely(ret != LZO_E_OK)) {
832 mutex_unlock(&rzs->lock); 833 mutex_unlock(&rzs->lock);
833 pr_err("Compression failed! err=%d\n", ret); 834 pr_err("Compression failed! err=%d\n", ret);
834 stat_inc(rzs->stats.failed_writes); 835 rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
835 goto out; 836 goto out;
836 } 837 }
837 838
@@ -854,13 +855,13 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
854 mutex_unlock(&rzs->lock); 855 mutex_unlock(&rzs->lock);
855 pr_info("Error allocating memory for incompressible " 856 pr_info("Error allocating memory for incompressible "
856 "page: %u\n", index); 857 "page: %u\n", index);
857 stat_inc(rzs->stats.failed_writes); 858 rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
858 goto out; 859 goto out;
859 } 860 }
860 861
861 offset = 0; 862 offset = 0;
862 rzs_set_flag(rzs, index, RZS_UNCOMPRESSED); 863 rzs_set_flag(rzs, index, RZS_UNCOMPRESSED);
863 stat_inc(rzs->stats.pages_expand); 864 rzs_stat_inc(&rzs->stats.pages_expand);
864 rzs->table[index].page = page_store; 865 rzs->table[index].page = page_store;
865 src = kmap_atomic(page, KM_USER0); 866 src = kmap_atomic(page, KM_USER0);
866 goto memstore; 867 goto memstore;
@@ -872,7 +873,7 @@ static int ramzswap_write(struct ramzswap *rzs, struct bio *bio)
872 mutex_unlock(&rzs->lock); 873 mutex_unlock(&rzs->lock);
873 pr_info("Error allocating memory for compressed " 874 pr_info("Error allocating memory for compressed "
874 "page: %u, size=%zu\n", index, clen); 875 "page: %u, size=%zu\n", index, clen);
875 stat_inc(rzs->stats.failed_writes); 876 rzs_stat64_inc(rzs, &rzs->stats.failed_writes);
876 if (rzs->backing_swap) 877 if (rzs->backing_swap)
877 fwd_write_request = 1; 878 fwd_write_request = 1;
878 goto out; 879 goto out;
@@ -901,9 +902,9 @@ memstore:
901 902
902 /* Update stats */ 903 /* Update stats */
903 rzs->stats.compr_size += clen; 904 rzs->stats.compr_size += clen;
904 stat_inc(rzs->stats.pages_stored); 905 rzs_stat_inc(&rzs->stats.pages_stored);
905 if (clen <= PAGE_SIZE / 2) 906 if (clen <= PAGE_SIZE / 2)
906 stat_inc(rzs->stats.good_compress); 907 rzs_stat_inc(&rzs->stats.good_compress);
907 908
908 mutex_unlock(&rzs->lock); 909 mutex_unlock(&rzs->lock);
909 910
@@ -913,7 +914,7 @@ memstore:
913 914
914out: 915out:
915 if (fwd_write_request) { 916 if (fwd_write_request) {
916 stat_inc(rzs->stats.bdev_num_writes); 917 rzs_stat64_inc(rzs, &rzs->stats.bdev_num_writes);
917 bio->bi_bdev = rzs->backing_swap; 918 bio->bi_bdev = rzs->backing_swap;
918#if 0 919#if 0
919 /* 920 /*
@@ -941,7 +942,6 @@ out:
941 return 0; 942 return 0;
942} 943}
943 944
944
945/* 945/*
946 * Check if request is within bounds and page aligned. 946 * Check if request is within bounds and page aligned.
947 */ 947 */
@@ -975,7 +975,7 @@ static int ramzswap_make_request(struct request_queue *queue, struct bio *bio)
975 } 975 }
976 976
977 if (!valid_swap_request(rzs, bio)) { 977 if (!valid_swap_request(rzs, bio)) {
978 stat_inc(rzs->stats.invalid_io); 978 rzs_stat64_inc(rzs, &rzs->stats.invalid_io);
979 bio_io_error(bio); 979 bio_io_error(bio);
980 return 0; 980 return 0;
981 } 981 }
@@ -1000,6 +1000,9 @@ static void reset_device(struct ramzswap *rzs)
1000 unsigned entries_per_page; 1000 unsigned entries_per_page;
1001 unsigned long num_table_pages, entry = 0; 1001 unsigned long num_table_pages, entry = 0;
1002 1002
1003 /* Do not accept any new I/O request */
1004 rzs->init_done = 0;
1005
1003 if (rzs->backing_swap && !rzs->num_extents) 1006 if (rzs->backing_swap && !rzs->num_extents)
1004 is_backing_blkdev = 1; 1007 is_backing_blkdev = 1;
1005 1008
@@ -1066,6 +1069,7 @@ static void reset_device(struct ramzswap *rzs)
1066 bd_release(rzs->backing_swap); 1069 bd_release(rzs->backing_swap);
1067 filp_close(rzs->swap_file, NULL); 1070 filp_close(rzs->swap_file, NULL);
1068 rzs->backing_swap = NULL; 1071 rzs->backing_swap = NULL;
1072 memset(rzs->backing_swap_name, 0, MAX_SWAP_NAME_LEN);
1069 } 1073 }
1070 1074
1071 /* Reset stats */ 1075 /* Reset stats */
@@ -1073,9 +1077,6 @@ static void reset_device(struct ramzswap *rzs)
1073 1077
1074 rzs->disksize = 0; 1078 rzs->disksize = 0;
1075 rzs->memlimit = 0; 1079 rzs->memlimit = 0;
1076
1077 /* Back to uninitialized state */
1078 rzs->init_done = 0;
1079} 1080}
1080 1081
1081static int ramzswap_ioctl_init_device(struct ramzswap *rzs) 1082static int ramzswap_ioctl_init_device(struct ramzswap *rzs)
@@ -1276,6 +1277,11 @@ static int ramzswap_ioctl(struct block_device *bdev, fmode_t mode,
1276 ret = -EBUSY; 1277 ret = -EBUSY;
1277 goto out; 1278 goto out;
1278 } 1279 }
1280
1281 /* Make sure all pending I/O is finished */
1282 if (bdev)
1283 fsync_bdev(bdev);
1284
1279 ret = ramzswap_ioctl_reset_device(rzs); 1285 ret = ramzswap_ioctl_reset_device(rzs);
1280 break; 1286 break;
1281 1287
@@ -1293,16 +1299,20 @@ static struct block_device_operations ramzswap_devops = {
1293 .owner = THIS_MODULE, 1299 .owner = THIS_MODULE,
1294}; 1300};
1295 1301
1296static void create_device(struct ramzswap *rzs, int device_id) 1302static int create_device(struct ramzswap *rzs, int device_id)
1297{ 1303{
1304 int ret = 0;
1305
1298 mutex_init(&rzs->lock); 1306 mutex_init(&rzs->lock);
1307 spin_lock_init(&rzs->stat64_lock);
1299 INIT_LIST_HEAD(&rzs->backing_swap_extent_list); 1308 INIT_LIST_HEAD(&rzs->backing_swap_extent_list);
1300 1309
1301 rzs->queue = blk_alloc_queue(GFP_KERNEL); 1310 rzs->queue = blk_alloc_queue(GFP_KERNEL);
1302 if (!rzs->queue) { 1311 if (!rzs->queue) {
1303 pr_err("Error allocating disk queue for device %d\n", 1312 pr_err("Error allocating disk queue for device %d\n",
1304 device_id); 1313 device_id);
1305 return; 1314 ret = -ENOMEM;
1315 goto out;
1306 } 1316 }
1307 1317
1308 blk_queue_make_request(rzs->queue, ramzswap_make_request); 1318 blk_queue_make_request(rzs->queue, ramzswap_make_request);
@@ -1314,7 +1324,8 @@ static void create_device(struct ramzswap *rzs, int device_id)
1314 blk_cleanup_queue(rzs->queue); 1324 blk_cleanup_queue(rzs->queue);
1315 pr_warning("Error allocating disk structure for device %d\n", 1325 pr_warning("Error allocating disk structure for device %d\n",
1316 device_id); 1326 device_id);
1317 return; 1327 ret = -ENOMEM;
1328 goto out;
1318 } 1329 }
1319 1330
1320 rzs->disk->major = ramzswap_major; 1331 rzs->disk->major = ramzswap_major;
@@ -1329,9 +1340,16 @@ static void create_device(struct ramzswap *rzs, int device_id)
1329 * or set equal to backing swap device (if provided) 1340 * or set equal to backing swap device (if provided)
1330 */ 1341 */
1331 set_capacity(rzs->disk, 0); 1342 set_capacity(rzs->disk, 0);
1343
1344 blk_queue_physical_block_size(rzs->disk->queue, PAGE_SIZE);
1345 blk_queue_logical_block_size(rzs->disk->queue, PAGE_SIZE);
1346
1332 add_disk(rzs->disk); 1347 add_disk(rzs->disk);
1333 1348
1334 rzs->init_done = 0; 1349 rzs->init_done = 0;
1350
1351out:
1352 return ret;
1335} 1353}
1336 1354
1337static void destroy_device(struct ramzswap *rzs) 1355static void destroy_device(struct ramzswap *rzs)
@@ -1347,18 +1365,20 @@ static void destroy_device(struct ramzswap *rzs)
1347 1365
1348static int __init ramzswap_init(void) 1366static int __init ramzswap_init(void)
1349{ 1367{
1350 int i, ret; 1368 int ret, dev_id;
1351 1369
1352 if (num_devices > max_num_devices) { 1370 if (num_devices > max_num_devices) {
1353 pr_warning("Invalid value for num_devices: %u\n", 1371 pr_warning("Invalid value for num_devices: %u\n",
1354 num_devices); 1372 num_devices);
1355 return -EINVAL; 1373 ret = -EINVAL;
1374 goto out;
1356 } 1375 }
1357 1376
1358 ramzswap_major = register_blkdev(0, "ramzswap"); 1377 ramzswap_major = register_blkdev(0, "ramzswap");
1359 if (ramzswap_major <= 0) { 1378 if (ramzswap_major <= 0) {
1360 pr_warning("Unable to get major number\n"); 1379 pr_warning("Unable to get major number\n");
1361 return -EBUSY; 1380 ret = -EBUSY;
1381 goto out;
1362 } 1382 }
1363 1383
1364 if (!num_devices) { 1384 if (!num_devices) {
@@ -1371,15 +1391,23 @@ static int __init ramzswap_init(void)
1371 devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL); 1391 devices = kzalloc(num_devices * sizeof(struct ramzswap), GFP_KERNEL);
1372 if (!devices) { 1392 if (!devices) {
1373 ret = -ENOMEM; 1393 ret = -ENOMEM;
1374 goto out; 1394 goto unregister;
1375 } 1395 }
1376 1396
1377 for (i = 0; i < num_devices; i++) 1397 for (dev_id = 0; dev_id < num_devices; dev_id++) {
1378 create_device(&devices[i], i); 1398 ret = create_device(&devices[dev_id], dev_id);
1399 if (ret)
1400 goto free_devices;
1401 }
1379 1402
1380 return 0; 1403 return 0;
1381out: 1404
1405free_devices:
1406 while (dev_id)
1407 destroy_device(&devices[--dev_id]);
1408unregister:
1382 unregister_blkdev(ramzswap_major, "ramzswap"); 1409 unregister_blkdev(ramzswap_major, "ramzswap");
1410out:
1383 return ret; 1411 return ret;
1384} 1412}
1385 1413
diff --git a/drivers/staging/ramzswap/ramzswap_drv.h b/drivers/staging/ramzswap/ramzswap_drv.h
index a6ea240935b6..c7e0e767c223 100644
--- a/drivers/staging/ramzswap/ramzswap_drv.h
+++ b/drivers/staging/ramzswap/ramzswap_drv.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Compressed RAM based swap device 2 * Compressed RAM based swap device
3 * 3 *
4 * Copyright (C) 2008, 2009 Nitin Gupta 4 * Copyright (C) 2008, 2009, 2010 Nitin Gupta
5 * 5 *
6 * This code is released using a dual license strategy: BSD/GPL 6 * This code is released using a dual license strategy: BSD/GPL
7 * You can choose the licence that better fits your requirements. 7 * You can choose the licence that better fits your requirements.
@@ -15,6 +15,9 @@
15#ifndef _RAMZSWAP_DRV_H_ 15#ifndef _RAMZSWAP_DRV_H_
16#define _RAMZSWAP_DRV_H_ 16#define _RAMZSWAP_DRV_H_
17 17
18#include <linux/spinlock.h>
19#include <linux/mutex.h>
20
18#include "ramzswap_ioctl.h" 21#include "ramzswap_ioctl.h"
19#include "xvmalloc.h" 22#include "xvmalloc.h"
20 23
@@ -71,15 +74,6 @@ static const unsigned max_zpage_size_nobdev = PAGE_SIZE / 4 * 3;
71#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) 74#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
72#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT) 75#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT)
73 76
74/* Debugging and Stats */
75#if defined(CONFIG_RAMZSWAP_STATS)
76#define stat_inc(stat) ((stat)++)
77#define stat_dec(stat) ((stat)--)
78#else
79#define stat_inc(x)
80#define stat_dec(x)
81#endif
82
83/* Flags for ramzswap pages (table[page_no].flags) */ 77/* Flags for ramzswap pages (table[page_no].flags) */
84enum rzs_pageflags { 78enum rzs_pageflags {
85 /* Page is stored uncompressed */ 79 /* Page is stored uncompressed */
@@ -102,7 +96,7 @@ struct table {
102 u16 offset; 96 u16 offset;
103 u8 count; /* object ref count (not yet used) */ 97 u8 count; /* object ref count (not yet used) */
104 u8 flags; 98 u8 flags;
105} __attribute__((aligned(4)));; 99} __attribute__((aligned(4)));
106 100
107/* 101/*
108 * Swap extent information in case backing swap is a regular 102 * Swap extent information in case backing swap is a regular
@@ -121,9 +115,10 @@ struct ramzswap_stats {
121#if defined(CONFIG_RAMZSWAP_STATS) 115#if defined(CONFIG_RAMZSWAP_STATS)
122 u64 num_reads; /* failed + successful */ 116 u64 num_reads; /* failed + successful */
123 u64 num_writes; /* --do-- */ 117 u64 num_writes; /* --do-- */
124 u64 failed_reads; /* can happen when memory is too low */ 118 u64 failed_reads; /* should NEVER! happen */
125 u64 failed_writes; /* should NEVER! happen */ 119 u64 failed_writes; /* can happen when memory is too low */
126 u64 invalid_io; /* non-swap I/O requests */ 120 u64 invalid_io; /* non-swap I/O requests */
121 u64 notify_free; /* no. of swap slot free notifications */
127 u32 pages_zero; /* no. of zero filled pages */ 122 u32 pages_zero; /* no. of zero filled pages */
128 u32 pages_stored; /* no. of pages currently stored */ 123 u32 pages_stored; /* no. of pages currently stored */
129 u32 good_compress; /* % of pages with compression ratio<=50% */ 124 u32 good_compress; /* % of pages with compression ratio<=50% */
@@ -138,6 +133,7 @@ struct ramzswap {
138 void *compress_workmem; 133 void *compress_workmem;
139 void *compress_buffer; 134 void *compress_buffer;
140 struct table *table; 135 struct table *table;
136 spinlock_t stat64_lock; /* protect 64-bit stats */
141 struct mutex lock; 137 struct mutex lock;
142 struct request_queue *queue; 138 struct request_queue *queue;
143 struct gendisk *disk; 139 struct gendisk *disk;
@@ -167,5 +163,48 @@ struct ramzswap {
167 163
168/*-- */ 164/*-- */
169 165
170#endif 166/* Debugging and Stats */
167#if defined(CONFIG_RAMZSWAP_STATS)
168static void rzs_stat_inc(u32 *v)
169{
170 *v = *v + 1;
171}
172
173static void rzs_stat_dec(u32 *v)
174{
175 *v = *v - 1;
176}
177
178static void rzs_stat64_inc(struct ramzswap *rzs, u64 *v)
179{
180 spin_lock(&rzs->stat64_lock);
181 *v = *v + 1;
182 spin_unlock(&rzs->stat64_lock);
183}
184
185static void rzs_stat64_dec(struct ramzswap *rzs, u64 *v)
186{
187 spin_lock(&rzs->stat64_lock);
188 *v = *v - 1;
189 spin_unlock(&rzs->stat64_lock);
190}
191
192static u64 rzs_stat64_read(struct ramzswap *rzs, u64 *v)
193{
194 u64 val;
195
196 spin_lock(&rzs->stat64_lock);
197 val = *v;
198 spin_unlock(&rzs->stat64_lock);
199
200 return val;
201}
202#else
203#define rzs_stat_inc(v)
204#define rzs_stat_dec(v)
205#define rzs_stat64_inc(r, v)
206#define rzs_stat64_dec(r, v)
207#define rzs_stat64_read(r, v)
208#endif /* CONFIG_RAMZSWAP_STATS */
171 209
210#endif
diff --git a/drivers/staging/ramzswap/ramzswap_ioctl.h b/drivers/staging/ramzswap/ramzswap_ioctl.h
index c713a09af580..d26076d41bde 100644
--- a/drivers/staging/ramzswap/ramzswap_ioctl.h
+++ b/drivers/staging/ramzswap/ramzswap_ioctl.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Compressed RAM based swap device 2 * Compressed RAM based swap device
3 * 3 *
4 * Copyright (C) 2008, 2009 Nitin Gupta 4 * Copyright (C) 2008, 2009, 2010 Nitin Gupta
5 * 5 *
6 * This code is released using a dual license strategy: BSD/GPL 6 * This code is released using a dual license strategy: BSD/GPL
7 * You can choose the licence that better fits your requirements. 7 * You can choose the licence that better fits your requirements.
@@ -24,9 +24,10 @@ struct ramzswap_ioctl_stats {
24 * size (if present) */ 24 * size (if present) */
25 u64 num_reads; /* failed + successful */ 25 u64 num_reads; /* failed + successful */
26 u64 num_writes; /* --do-- */ 26 u64 num_writes; /* --do-- */
27 u64 failed_reads; /* can happen when memory is too low */ 27 u64 failed_reads; /* should NEVER! happen */
28 u64 failed_writes; /* should NEVER! happen */ 28 u64 failed_writes; /* can happen when memory is too low */
29 u64 invalid_io; /* non-swap I/O requests */ 29 u64 invalid_io; /* non-swap I/O requests */
30 u64 notify_free; /* no. of swap slot free notifications */
30 u32 pages_zero; /* no. of zero filled pages */ 31 u32 pages_zero; /* no. of zero filled pages */
31 u32 good_compress_pct; /* no. of pages with compression ratio<=50% */ 32 u32 good_compress_pct; /* no. of pages with compression ratio<=50% */
32 u32 pages_expand_pct; /* no. of incompressible pages */ 33 u32 pages_expand_pct; /* no. of incompressible pages */
diff --git a/drivers/staging/ramzswap/xvmalloc.c b/drivers/staging/ramzswap/xvmalloc.c
index b3e986c33141..3fdbb8ada827 100644
--- a/drivers/staging/ramzswap/xvmalloc.c
+++ b/drivers/staging/ramzswap/xvmalloc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * xvmalloc memory allocator 2 * xvmalloc memory allocator
3 * 3 *
4 * Copyright (C) 2008, 2009 Nitin Gupta 4 * Copyright (C) 2008, 2009, 2010 Nitin Gupta
5 * 5 *
6 * This code is released using a dual license strategy: BSD/GPL 6 * This code is released using a dual license strategy: BSD/GPL
7 * You can choose the licence that better fits your requirements. 7 * You can choose the licence that better fits your requirements.
@@ -273,7 +273,7 @@ static void remove_block(struct xv_pool *pool, struct page *page, u32 offset,
273} 273}
274 274
275/* 275/*
276 * Allocate a page and add it freelist of given pool. 276 * Allocate a page and add it to freelist of given pool.
277 */ 277 */
278static int grow_pool(struct xv_pool *pool, gfp_t flags) 278static int grow_pool(struct xv_pool *pool, gfp_t flags)
279{ 279{
diff --git a/drivers/staging/ramzswap/xvmalloc.h b/drivers/staging/ramzswap/xvmalloc.h
index 010c6fe5e173..5b1a81aa5faf 100644
--- a/drivers/staging/ramzswap/xvmalloc.h
+++ b/drivers/staging/ramzswap/xvmalloc.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * xvmalloc memory allocator 2 * xvmalloc memory allocator
3 * 3 *
4 * Copyright (C) 2008, 2009 Nitin Gupta 4 * Copyright (C) 2008, 2009, 2010 Nitin Gupta
5 * 5 *
6 * This code is released using a dual license strategy: BSD/GPL 6 * This code is released using a dual license strategy: BSD/GPL
7 * You can choose the licence that better fits your requirements. 7 * You can choose the licence that better fits your requirements.
diff --git a/drivers/staging/ramzswap/xvmalloc_int.h b/drivers/staging/ramzswap/xvmalloc_int.h
index 03c1a652a3aa..e23ed5c8b8e4 100644
--- a/drivers/staging/ramzswap/xvmalloc_int.h
+++ b/drivers/staging/ramzswap/xvmalloc_int.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * xvmalloc memory allocator 2 * xvmalloc memory allocator
3 * 3 *
4 * Copyright (C) 2008, 2009 Nitin Gupta 4 * Copyright (C) 2008, 2009, 2010 Nitin Gupta
5 * 5 *
6 * This code is released using a dual license strategy: BSD/GPL 6 * This code is released using a dual license strategy: BSD/GPL
7 * You can choose the licence that better fits your requirements. 7 * You can choose the licence that better fits your requirements.
@@ -62,7 +62,7 @@ struct link_free {
62 62
63struct block_header { 63struct block_header {
64 union { 64 union {
65 /* This common header must be ALIGN bytes */ 65 /* This common header must be XV_ALIGN bytes */
66 u8 common[XV_ALIGN]; 66 u8 common[XV_ALIGN];
67 struct { 67 struct {
68 u16 size; 68 u16 size;
diff --git a/drivers/staging/rar/Kconfig b/drivers/staging/rar/Kconfig
deleted file mode 100644
index 17f8bf3bb41a..000000000000
--- a/drivers/staging/rar/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
1#
2# RAR device configuration
3#
4
5menu "RAR Register Driver"
6#
7# Restricted Access Register Manager
8#
9config RAR_REGISTER
10 tristate "Restricted Access Region Register Driver"
11 default n
12 ---help---
13 This driver allows other kernel drivers access to the
14 contents of the restricted access region control
15 registers.
16
17endmenu
diff --git a/drivers/staging/rar/Makefile b/drivers/staging/rar/Makefile
deleted file mode 100644
index 5422ed04ccf1..000000000000
--- a/drivers/staging/rar/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1EXTRA_CFLAGS += -DLITTLE__ENDIAN
2obj-$(CONFIG_RAR_REGISTER) += rar_driver.o
diff --git a/drivers/staging/rar/rar_driver.c b/drivers/staging/rar/rar_driver.c
deleted file mode 100644
index d85d1890e81e..000000000000
--- a/drivers/staging/rar/rar_driver.c
+++ /dev/null
@@ -1,444 +0,0 @@
1#include <linux/init.h>
2#include <linux/module.h>
3#include <linux/fs.h>
4#include <linux/cdev.h>
5#include <linux/kdev_t.h>
6#include <linux/semaphore.h>
7#include <linux/mm.h>
8#include <linux/poll.h>
9#include <linux/wait.h>
10#include <linux/ioctl.h>
11#include <linux/ioport.h>
12#include <linux/io.h>
13#include <linux/interrupt.h>
14#include <linux/pagemap.h>
15#include <linux/pci.h>
16#include <linux/firmware.h>
17#include <linux/sched.h>
18#include "rar_driver.h"
19
20/* The following defines are for the IPC process to retrieve RAR in */
21
22/* === Lincroft Message Bus Interface === */
23/* Message Control Register */
24#define LNC_MCR_OFFSET 0xD0
25
26/* Message Data Register */
27#define LNC_MDR_OFFSET 0xD4
28
29/* Message Opcodes */
30#define LNC_MESSAGE_READ_OPCODE 0xD0
31#define LNC_MESSAGE_WRITE_OPCODE 0xE0
32
33/* Message Write Byte Enables */
34#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
35
36/* B-unit Port */
37#define LNC_BUNIT_PORT 0x3
38
39/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
40#define LNC_BRAR0L 0x10
41#define LNC_BRAR0H 0x11
42#define LNC_BRAR1L 0x12
43#define LNC_BRAR1H 0x13
44
45/* Reserved for SeP */
46#define LNC_BRAR2L 0x14
47#define LNC_BRAR2H 0x15
48
49
50/* This structure is only used during module initialization. */
51struct RAR_offsets {
52 int low; /* Register offset for low RAR physical address. */
53 int high; /* Register offset for high RAR physical address. */
54};
55
56struct pci_dev *rar_dev;
57static uint32_t registered;
58
59/* Moorestown supports three restricted access regions. */
60#define MRST_NUM_RAR 3
61
62struct RAR_address_struct rar_addr[MRST_NUM_RAR];
63
64/* prototype for init */
65static int __init rar_init_handler(void);
66static void __exit rar_exit_handler(void);
67
68/*
69 function that is activated on the successfull probe of the RAR device
70*/
71static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
72
73static struct pci_device_id rar_pci_id_tbl[] = {
74 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) },
75 { 0 }
76};
77
78MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
79
80/* field for registering driver to PCI device */
81static struct pci_driver rar_pci_driver = {
82 .name = "rar_driver",
83 .id_table = rar_pci_id_tbl,
84 .probe = rar_probe
85};
86
87/* This function is used to retrieved RAR info using the IPC message
88 bus interface */
89static int memrar_get_rar_addr(struct pci_dev* pdev,
90 int offset,
91 u32 *addr)
92{
93 /*
94 * ======== The Lincroft Message Bus Interface ========
95 * Lincroft registers may be obtained from the PCI
96 * (the Host Bridge) using the Lincroft Message Bus
97 * Interface. That message bus interface is generally
98 * comprised of two registers: a control register (MCR, 0xDO)
99 * and a data register (MDR, 0xD4).
100 *
101 * The MCR (message control register) format is the following:
102 * 1. [31:24]: Opcode
103 * 2. [23:16]: Port
104 * 3. [15:8]: Register Offset
105 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
106 * to 1)
107 * 5. [3:0]: reserved
108 *
109 * Read (0xD0) and write (0xE0) opcodes are written to the
110 * control register when reading and writing to Lincroft
111 * registers, respectively.
112 *
113 * We're interested in registers found in the Lincroft
114 * B-unit. The B-unit port is 0x3.
115 *
116 * The six B-unit RAR register offsets we use are listed
117 * earlier in this file.
118 *
119 * Lastly writing to the MCR register requires the "Byte
120 * enables" bits to be set to 1. This may be achieved by
121 * writing 0xF at bit 4.
122 *
123 * The MDR (message data register) format is the following:
124 * 1. [31:0]: Read/Write Data
125 *
126 * Data being read from this register is only available after
127 * writing the appropriate control message to the MCR
128 * register.
129 *
130 * Data being written to this register must be written before
131 * writing the appropriate control message to the MCR
132 * register.
133 */
134
135 int result = 0; /* result */
136 /* Construct control message */
137 u32 const message =
138 (LNC_MESSAGE_READ_OPCODE << 24)
139 | (LNC_BUNIT_PORT << 16)
140 | (offset << 8)
141 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
142
143 printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
144
145 if (addr == 0)
146 return -EINVAL;
147
148 /* Send the control message */
149 result = pci_write_config_dword(pdev,
150 LNC_MCR_OFFSET,
151 message);
152
153 printk(KERN_WARNING "rar- result from send ctl register is %x\n"
154 ,result);
155
156 if (!result)
157 result = pci_read_config_dword(pdev,
158 LNC_MDR_OFFSET,
159 addr);
160
161 printk(KERN_WARNING "rar- result from read data register is %x\n",
162 result);
163
164 printk(KERN_WARNING "rar- value read from data register is %x\n",
165 *addr);
166
167 if (result)
168 return -1;
169 else
170 return 0;
171}
172
173static int memrar_set_rar_addr(struct pci_dev* pdev,
174 int offset,
175 u32 addr)
176{
177 /*
178 * ======== The Lincroft Message Bus Interface ========
179 * Lincroft registers may be obtained from the PCI
180 * (the Host Bridge) using the Lincroft Message Bus
181 * Interface. That message bus interface is generally
182 * comprised of two registers: a control register (MCR, 0xDO)
183 * and a data register (MDR, 0xD4).
184 *
185 * The MCR (message control register) format is the following:
186 * 1. [31:24]: Opcode
187 * 2. [23:16]: Port
188 * 3. [15:8]: Register Offset
189 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
190 * to 1)
191 * 5. [3:0]: reserved
192 *
193 * Read (0xD0) and write (0xE0) opcodes are written to the
194 * control register when reading and writing to Lincroft
195 * registers, respectively.
196 *
197 * We're interested in registers found in the Lincroft
198 * B-unit. The B-unit port is 0x3.
199 *
200 * The six B-unit RAR register offsets we use are listed
201 * earlier in this file.
202 *
203 * Lastly writing to the MCR register requires the "Byte
204 * enables" bits to be set to 1. This may be achieved by
205 * writing 0xF at bit 4.
206 *
207 * The MDR (message data register) format is the following:
208 * 1. [31:0]: Read/Write Data
209 *
210 * Data being read from this register is only available after
211 * writing the appropriate control message to the MCR
212 * register.
213 *
214 * Data being written to this register must be written before
215 * writing the appropriate control message to the MCR
216 * register.
217 */
218
219 int result = 0; /* result */
220
221 /* Construct control message */
222 u32 const message =
223 (LNC_MESSAGE_WRITE_OPCODE << 24)
224 | (LNC_BUNIT_PORT << 16)
225 | (offset << 8)
226 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
227
228 printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
229
230 if (addr == 0)
231 return -EINVAL;
232
233 /* Send the control message */
234 result = pci_write_config_dword(pdev,
235 LNC_MDR_OFFSET,
236 addr);
237
238 printk(KERN_WARNING "rar- result from send ctl register is %x\n"
239 ,result);
240
241 if (!result)
242 result = pci_write_config_dword(pdev,
243 LNC_MCR_OFFSET,
244 message);
245
246 printk(KERN_WARNING "rar- result from write data register is %x\n",
247 result);
248
249 printk(KERN_WARNING "rar- value read to data register is %x\n",
250 addr);
251
252 if (result)
253 return -1;
254 else
255 return 0;
256}
257
258/*
259
260 * Initialize RAR parameters, such as physical addresses, etc.
261
262 */
263static int memrar_init_rar_params(struct pci_dev *pdev)
264{
265 struct RAR_offsets const offsets[] = {
266 { LNC_BRAR0L, LNC_BRAR0H },
267 { LNC_BRAR1L, LNC_BRAR1H },
268 { LNC_BRAR2L, LNC_BRAR2H }
269 };
270
271 size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]);
272 struct RAR_offsets const *end = offsets + num_offsets;
273 struct RAR_offsets const *i;
274 unsigned int n = 0;
275 int result = 0;
276
277 /* Retrieve RAR start and end physical addresses. */
278
279 /*
280 * Access the RAR registers through the Lincroft Message Bus
281 * Interface on PCI device: 00:00.0 Host bridge.
282 */
283
284 /* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */
285
286 if (pdev == NULL)
287 return -ENODEV;
288
289 for (i = offsets; i != end; ++i, ++n) {
290 if (memrar_get_rar_addr (pdev,
291 (*i).low,
292 &(rar_addr[n].low)) != 0
293 || memrar_get_rar_addr (pdev,
294 (*i).high,
295 &(rar_addr[n].high)) != 0) {
296 result = -1;
297 break;
298 }
299 }
300
301 /* Done accessing the device. */
302 /* pci_dev_put(pdev); */
303
304 if (result == 0) {
305 if(1) {
306 size_t z;
307 for (z = 0; z != MRST_NUM_RAR; ++z) {
308 printk(KERN_WARNING "rar - BRAR[%Zd] physical address low\n"
309 "\tlow: 0x%08x\n"
310 "\thigh: 0x%08x\n",
311 z,
312 rar_addr[z].low,
313 rar_addr[z].high);
314 }
315 }
316 }
317
318 return result;
319}
320
321/*
322 function that is activated on the successfull probe of the RAR device
323*/
324static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
325{
326 /* error */
327 int error;
328
329 /*------------------------
330 CODE
331 ---------------------------*/
332
333 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
334 "Rar pci probe starting\n");
335 error = 0;
336
337 /* enable the device */
338 error = pci_enable_device(pdev);
339 if (error) {
340 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
341 "error enabling pci device\n");
342 goto end_function;
343 }
344
345 rar_dev = pdev;
346 registered = 1;
347
348 /* Initialize the RAR parameters, which have to be retrieved */
349 /* via the message bus service */
350 error=memrar_init_rar_params(rar_dev);
351
352 if (error) {
353 DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
354 "error getting RAR addresses device\n");
355 registered = 0;
356 goto end_function;
357 }
358
359end_function:
360
361 return error;
362}
363
364/*
365 this function registers th driver to
366 the device subsystem( either PCI, USB, etc)
367*/
368static int __init rar_init_handler(void)
369{
370 return pci_register_driver(&rar_pci_driver);
371}
372
373static void __exit rar_exit_handler(void)
374{
375 pci_unregister_driver(&rar_pci_driver);
376}
377
378module_init(rar_init_handler);
379module_exit(rar_exit_handler);
380
381MODULE_LICENSE("GPL");
382
383
384/* The get_rar_address function is used by other device drivers
385 * to obtain RAR address information on a RAR. It takes two
386 * parameter:
387 *
388 * int rar_index
389 * The rar_index is an index to the rar for which you wish to retrieve
390 * the address information.
391 * Values can be 0,1, or 2.
392 *
393 * struct RAR_address_struct is a pointer to a place to which the function
394 * can return the address structure for the RAR.
395 *
396 * The function returns a 0 upon success or a -1 if there is no RAR
397 * facility on this system.
398 */
399int get_rar_address(int rar_index,struct RAR_address_struct *addresses)
400{
401 if (registered && (rar_index < 3) && (rar_index >= 0)) {
402 *addresses=rar_addr[rar_index];
403 /* strip off lock bit information */
404 addresses->low = addresses->low & 0xfffffff0;
405 addresses->high = addresses->high & 0xfffffff0;
406 return 0;
407 }
408
409 else {
410 return -ENODEV;
411 }
412}
413
414
415EXPORT_SYMBOL(get_rar_address);
416
417/* The lock_rar function is ued by other device drivers to lock an RAR.
418 * once an RAR is locked, it stays locked until the next system reboot.
419 * The function takes one parameter:
420 *
421 * int rar_index
422 * The rar_index is an index to the rar that you want to lock.
423 * Values can be 0,1, or 2.
424 *
425 * The function returns a 0 upon success or a -1 if there is no RAR
426 * facility on this system.
427 */
428int lock_rar(int rar_index)
429{
430 u32 working_addr;
431 int result;
432if (registered && (rar_index < 3) && (rar_index >= 0)) {
433 /* first make sure that lock bits are clear (this does lock) */
434 working_addr=rar_addr[rar_index].low & 0xfffffff0;
435
436 /* now send that value to the register using the IPC */
437 result=memrar_set_rar_addr(rar_dev,rar_index,working_addr);
438 return result;
439 }
440
441else {
442 return -ENODEV;
443 }
444}
diff --git a/drivers/staging/rar/rar_driver.h b/drivers/staging/rar/rar_driver.h
deleted file mode 100644
index 3690f984ff55..000000000000
--- a/drivers/staging/rar/rar_driver.h
+++ /dev/null
@@ -1,99 +0,0 @@
1/* === RAR Physical Addresses === */
2struct RAR_address_struct {
3 u32 low;
4 u32 high;
5};
6
7/* The get_rar_address function is used by other device drivers
8 * to obtain RAR address information on a RAR. It takes two
9 * parameter:
10 *
11 * int rar_index
12 * The rar_index is an index to the rar for which you wish to retrieve
13 * the address information.
14 * Values can be 0,1, or 2.
15 *
16 * struct RAR_address_struct is a pointer to a place to which the function
17 * can return the address structure for the RAR.
18 *
19 * The function returns a 0 upon success or a -1 if there is no RAR
20 * facility on this system.
21 */
22int get_rar_address(int rar_index,struct RAR_address_struct *addresses);
23
24
25/* The lock_rar function is ued by other device drivers to lock an RAR.
26 * once an RAR is locked, it stays locked until the next system reboot.
27 * The function takes one parameter:
28 *
29 * int rar_index
30 * The rar_index is an index to the rar that you want to lock.
31 * Values can be 0,1, or 2.
32 *
33 * The function returns a 0 upon success or a -1 if there is no RAR
34 * facility on this system.
35 */
36int lock_rar(int rar_index);
37
38
39/* DEBUG LEVEL MASKS */
40#define RAR_DEBUG_LEVEL_BASIC 0x1
41
42#define RAR_DEBUG_LEVEL_REGISTERS 0x2
43
44#define RAR_DEBUG_LEVEL_EXTENDED 0x4
45
46#define DEBUG_LEVEL 0x7
47
48/* FUNCTIONAL MACROS */
49
50/* debug macro without paramaters */
51#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \
52do \
53{ \
54 if(DEBUG_LEVEL) \
55 { \
56 printk(KERN_WARNING info); \
57 } \
58}while(0)
59
60/* debug macro with 1 paramater */
61#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \
62do \
63{ \
64 if(DEBUG_LEVEL) \
65 { \
66 printk(KERN_WARNING info , param1); \
67 } \
68}while(0)
69
70/* debug macro with 2 paramaters */
71#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \
72do \
73{ \
74 if(DEBUG_LEVEL) \
75 { \
76 printk(KERN_WARNING info , param1, param2); \
77 } \
78}while(0)
79
80/* debug macro with 3 paramaters */
81#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \
82do \
83{ \
84 if(DEBUG_LEVEL) \
85 { \
86 printk(KERN_WARNING info , param1, param2 , param3); \
87 } \
88}while(0)
89
90/* debug macro with 4 paramaters */
91#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \
92do \
93{ \
94 if(DEBUG_LEVEL) \
95 { \
96 printk(KERN_WARNING info , param1, param2 , param3 , param4); \
97 } \
98}while(0)
99
diff --git a/drivers/staging/rar_register/Kconfig b/drivers/staging/rar_register/Kconfig
new file mode 100644
index 000000000000..3f73839643e9
--- /dev/null
+++ b/drivers/staging/rar_register/Kconfig
@@ -0,0 +1,30 @@
1#
2# RAR device configuration
3#
4
5menu "RAR Register Driver"
6#
7# Restricted Access Register Manager
8#
9config RAR_REGISTER
10 tristate "Restricted Access Region Register Driver"
11 default n
12 ---help---
13 This driver allows other kernel drivers access to the
14 contents of the restricted access region control
15 registers.
16
17 The restricted access region control registers
18 (rar_registers) are used to pass address and
19 locking information on restricted access regions
20 to other drivers that use restricted access regions
21
22 The restricted access regions are regions of memory
23 on the Intel MID Platform that are not accessible to
24 the x86 processor, but are accessible to dedicated
25 processors on board peripheral devices.
26
27 The purpose of the restricted access regions is to
28 protect sensitive data from compromise by unauthorized
29 programs running on the x86 processor.
30endmenu
diff --git a/drivers/staging/rar_register/Makefile b/drivers/staging/rar_register/Makefile
new file mode 100644
index 000000000000..d5954ccc16c9
--- /dev/null
+++ b/drivers/staging/rar_register/Makefile
@@ -0,0 +1,2 @@
1EXTRA_CFLAGS += -DLITTLE__ENDIAN
2obj-$(CONFIG_RAR_REGISTER) += rar_register.o
diff --git a/drivers/staging/rar_register/rar_register.c b/drivers/staging/rar_register/rar_register.c
new file mode 100644
index 000000000000..bfc0e31f1a6f
--- /dev/null
+++ b/drivers/staging/rar_register/rar_register.c
@@ -0,0 +1,615 @@
1/*
2 * rar_register.c - An Intel Restricted Access Region register driver
3 *
4 * Copyright(c) 2009 Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 *
21 * -------------------------------------------------------------------
22 * 20091204 Mark Allyn <mark.a.allyn@intel.com>
23 * Ossama Othman <ossama.othman@intel.com>
24 * Cleanup per feedback from Alan Cox and Arjan Van De Ven
25 *
26 * 20090806 Ossama Othman <ossama.othman@intel.com>
27 * Return zero high address if upper 22 bits is zero.
28 * Cleaned up checkpatch errors.
29 * Clarified that driver is dealing with bus addresses.
30 *
31 * 20090702 Ossama Othman <ossama.othman@intel.com>
32 * Removed unnecessary include directives
33 * Cleaned up spinlocks.
34 * Cleaned up logging.
35 * Improved invalid parameter checks.
36 * Fixed and simplified RAR address retrieval and RAR locking
37 * code.
38 *
39 * 20090626 Mark Allyn <mark.a.allyn@intel.com>
40 * Initial publish
41 */
42
43#define DEBUG 1
44
45#include "rar_register.h"
46
47#include <linux/module.h>
48#include <linux/pci.h>
49#include <linux/spinlock.h>
50#include <linux/device.h>
51#include <linux/kernel.h>
52
53/* === Lincroft Message Bus Interface === */
54/* Message Control Register */
55#define LNC_MCR_OFFSET 0xD0
56
57/* Maximum number of clients (other drivers using this driver) */
58#define MAX_RAR_CLIENTS 10
59
60/* Message Data Register */
61#define LNC_MDR_OFFSET 0xD4
62
63/* Message Opcodes */
64#define LNC_MESSAGE_READ_OPCODE 0xD0
65#define LNC_MESSAGE_WRITE_OPCODE 0xE0
66
67/* Message Write Byte Enables */
68#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
69
70/* B-unit Port */
71#define LNC_BUNIT_PORT 0x3
72
73/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
74#define LNC_BRAR0L 0x10
75#define LNC_BRAR0H 0x11
76#define LNC_BRAR1L 0x12
77#define LNC_BRAR1H 0x13
78
79/* Reserved for SeP */
80#define LNC_BRAR2L 0x14
81#define LNC_BRAR2H 0x15
82
83/* Moorestown supports three restricted access regions. */
84#define MRST_NUM_RAR 3
85
86
87/* RAR Bus Address Range */
88struct RAR_address_range {
89 dma_addr_t low;
90 dma_addr_t high;
91};
92
93/* Structure containing low and high RAR register offsets. */
94struct RAR_offsets {
95 u32 low; /* Register offset for low RAR bus address. */
96 u32 high; /* Register offset for high RAR bus address. */
97};
98
99struct client {
100 int (*client_callback)(void *client_data);
101 void *customer_data;
102 int client_called;
103 };
104
105static DEFINE_MUTEX(rar_mutex);
106static DEFINE_MUTEX(lnc_reg_mutex);
107
108struct RAR_device {
109 struct RAR_offsets const rar_offsets[MRST_NUM_RAR];
110 struct RAR_address_range rar_addr[MRST_NUM_RAR];
111 struct pci_dev *rar_dev;
112 bool registered;
113 };
114
115/* this platform has only one rar_device for 3 rar regions */
116static struct RAR_device my_rar_device = {
117 .rar_offsets = {
118 [0].low = LNC_BRAR0L,
119 [0].high = LNC_BRAR0H,
120 [1].low = LNC_BRAR1L,
121 [1].high = LNC_BRAR1H,
122 [2].low = LNC_BRAR2L,
123 [2].high = LNC_BRAR2H
124 }
125};
126
127/* this data is for handling requests from other drivers which arrive
128 * prior to this driver initializing
129 */
130
131static struct client clients[MAX_RAR_CLIENTS];
132static int num_clients;
133
134/*
135 * This function is used to retrieved RAR info using the Lincroft
136 * message bus interface.
137 */
138static int retrieve_rar_addr(struct pci_dev *pdev,
139 int offset,
140 dma_addr_t *addr)
141{
142 /*
143 * ======== The Lincroft Message Bus Interface ========
144 * Lincroft registers may be obtained from the PCI
145 * (the Host Bridge) using the Lincroft Message Bus
146 * Interface. That message bus interface is generally
147 * comprised of two registers: a control register (MCR, 0xDO)
148 * and a data register (MDR, 0xD4).
149 *
150 * The MCR (message control register) format is the following:
151 * 1. [31:24]: Opcode
152 * 2. [23:16]: Port
153 * 3. [15:8]: Register Offset
154 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
155 * to 1)
156 * 5. [3:0]: reserved
157 *
158 * Read (0xD0) and write (0xE0) opcodes are written to the
159 * control register when reading and writing to Lincroft
160 * registers, respectively.
161 *
162 * We're interested in registers found in the Lincroft
163 * B-unit. The B-unit port is 0x3.
164 *
165 * The six B-unit RAR register offsets we use are listed
166 * earlier in this file.
167 *
168 * Lastly writing to the MCR register requires the "Byte
169 * enables" bits to be set to 1. This may be achieved by
170 * writing 0xF at bit 4.
171 *
172 * The MDR (message data register) format is the following:
173 * 1. [31:0]: Read/Write Data
174 *
175 * Data being read from this register is only available after
176 * writing the appropriate control message to the MCR
177 * register.
178 *
179 * Data being written to this register must be written before
180 * writing the appropriate control message to the MCR
181 * register.
182 */
183
184 int result;
185
186 /* Construct control message */
187 u32 const message =
188 (LNC_MESSAGE_READ_OPCODE << 24)
189 | (LNC_BUNIT_PORT << 16)
190 | (offset << 8)
191 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
192
193 dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset);
194
195 if (addr == 0) {
196 WARN_ON(1);
197 return -EINVAL;
198 }
199
200 /*
201 * We synchronize access to the Lincroft MCR and MDR registers
202 * until BOTH the command is issued through the MCR register
203 * and the corresponding data is read from the MDR register.
204 * Otherwise a race condition would exist between accesses to
205 * both registers.
206 */
207
208 mutex_lock(&lnc_reg_mutex);
209
210 /* Send the control message */
211 result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
212
213 dev_dbg(&pdev->dev, "Result from send ctl register is %x\n", result);
214
215 if (!result) {
216 result = pci_read_config_dword(pdev, LNC_MDR_OFFSET,
217 (u32 *)addr);
218 dev_dbg(&pdev->dev,
219 "Result from read data register is %x\n", result);
220
221 dev_dbg(&pdev->dev,
222 "Value read from data register is %lx\n",
223 (unsigned long)*addr);
224 }
225
226 mutex_unlock(&lnc_reg_mutex);
227
228 return result;
229}
230
231static int set_rar_address(struct pci_dev *pdev,
232 int offset,
233 dma_addr_t addr)
234{
235 /*
236 * Data being written to this register must be written before
237 * writing the appropriate control message to the MCR
238 * register.
239 * @note See rar_get_address() for a description of the
240 * message bus interface being used here.
241 */
242
243 int result = 0;
244
245 /* Construct control message */
246 u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24)
247 | (LNC_BUNIT_PORT << 16)
248 | (offset << 8)
249 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
250
251 if (addr == 0) {
252 WARN_ON(1);
253 return -EINVAL;
254 }
255
256 dev_dbg(&pdev->dev, "Offset for 'set' LNC MSG is %x\n", offset);
257
258 /*
259 * We synchronize access to the Lincroft MCR and MDR registers
260 * until BOTH the command is issued through the MCR register
261 * and the corresponding data is read from the MDR register.
262 * Otherwise a race condition would exist between accesses to
263 * both registers.
264 */
265
266 mutex_lock(&lnc_reg_mutex);
267
268 /* Send the control message */
269 result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr);
270
271 dev_dbg(&pdev->dev, "Result from write data register is %x\n", result);
272
273 if (!result) {
274 dev_dbg(&pdev->dev,
275 "Value written to data register is %lx\n",
276 (unsigned long)addr);
277
278 result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
279
280 dev_dbg(&pdev->dev, "Result from send ctl register is %x\n",
281 result);
282 }
283
284 mutex_unlock(&lnc_reg_mutex);
285
286 return result;
287}
288
289/*
290* Initialize RAR parameters, such as bus addresses, etc.
291*/
292static int init_rar_params(struct pci_dev *pdev)
293{
294 unsigned int i;
295 int result = 0;
296
297 /* Retrieve RAR start and end bus addresses.
298 * Access the RAR registers through the Lincroft Message Bus
299 * Interface on PCI device: 00:00.0 Host bridge.
300 */
301
302 for (i = 0; i < MRST_NUM_RAR; ++i) {
303 struct RAR_offsets const *offset =
304 &my_rar_device.rar_offsets[i];
305 struct RAR_address_range *addr = &my_rar_device.rar_addr[i];
306
307 if ((retrieve_rar_addr(pdev, offset->low, &addr->low) != 0)
308 || (retrieve_rar_addr(pdev, offset->high, &addr->high) != 0)) {
309 result = -1;
310 break;
311 }
312
313 /*
314 * Only the upper 22 bits of the RAR addresses are
315 * stored in their corresponding RAR registers so we
316 * must set the lower 10 bits accordingly.
317
318 * The low address has its lower 10 bits cleared, and
319 * the high address has all its lower 10 bits set,
320 * e.g.:
321 * low = 0x2ffffc00
322 */
323
324 addr->low &= (dma_addr_t)0xfffffc00u;
325
326 /*
327 * Set bits 9:0 on uppser address if bits 31:10 are non
328 * zero; otherwize clear all bits
329 */
330
331 if ((addr->high & 0xfffffc00u) == 0)
332 addr->high = 0;
333 else
334 addr->high |= 0x3ffu;
335 }
336 /* Done accessing the device. */
337
338 if (result == 0) {
339 int z;
340 for (z = 0; z != MRST_NUM_RAR; ++z) {
341 /*
342 * "BRAR" refers to the RAR registers in the
343 * Lincroft B-unit.
344 */
345 dev_info(&pdev->dev, "BRAR[%u] bus address range = "
346 "[%lx, %lx]\n", z,
347 (unsigned long)my_rar_device.rar_addr[z].low,
348 (unsigned long)my_rar_device.rar_addr[z].high);
349 }
350 }
351
352 return result;
353}
354
355/*
356 * The rar_get_address function is used by other device drivers
357 * to obtain RAR address information on a RAR. It takes three
358 * parameters:
359 *
360 * int rar_index
361 * The rar_index is an index to the rar for which you wish to retrieve
362 * the address information.
363 * Values can be 0,1, or 2.
364 *
365 * The function returns a 0 upon success or a -1 if there is no RAR
366 * facility on this system.
367 */
368int rar_get_address(int rar_index,
369 dma_addr_t *start_address,
370 dma_addr_t *end_address)
371{
372 int result = -ENODEV;
373
374 if (my_rar_device.registered) {
375 if (start_address == 0 || end_address == 0
376 || rar_index >= MRST_NUM_RAR || rar_index < 0) {
377 result = -EINVAL;
378 } else {
379 *start_address =
380 my_rar_device.rar_addr[rar_index].low;
381 *end_address =
382 my_rar_device.rar_addr[rar_index].high;
383
384 result = 0;
385 }
386 }
387
388 return result;
389}
390EXPORT_SYMBOL(rar_get_address);
391
392/*
393 * The rar_lock function is ued by other device drivers to lock an RAR.
394 * once an RAR is locked, it stays locked until the next system reboot.
395 * The function takes one parameter:
396 *
397 * int rar_index
398 * The rar_index is an index to the rar that you want to lock.
399 * Values can be 0,1, or 2.
400 *
401 * The function returns a 0 upon success or a -1 if there is no RAR
402 * facility on this system.
403 */
404int rar_lock(int rar_index)
405{
406 int result = -ENODEV;
407
408 if (rar_index >= MRST_NUM_RAR || rar_index < 0) {
409 result = -EINVAL;
410 return result;
411 }
412
413 dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex locking\n");
414 mutex_lock(&rar_mutex);
415
416 if (my_rar_device.registered) {
417
418 dma_addr_t low = my_rar_device.rar_addr[rar_index].low &
419 0xfffffc00u;
420
421 dma_addr_t high = my_rar_device.rar_addr[rar_index].high &
422 0xfffffc00u;
423
424 /*
425 * Only allow I/O from the graphics and Langwell;
426 * Not from the x96 processor
427 */
428 if (rar_index == (int)RAR_TYPE_VIDEO) {
429 low |= 0x00000009;
430 high |= 0x00000015;
431 }
432
433 else if (rar_index == (int)RAR_TYPE_AUDIO) {
434 /* Only allow I/O from Langwell; nothing from x86 */
435 low |= 0x00000008;
436 high |= 0x00000018;
437 }
438
439 else
440 /* Read-only from all agents */
441 high |= 0x00000018;
442
443 /*
444 * Now program the register using the Lincroft message
445 * bus interface.
446 */
447 result = set_rar_address(my_rar_device.rar_dev,
448 my_rar_device.rar_offsets[rar_index].low,
449 low);
450
451 if (result == 0)
452 result = set_rar_address(
453 my_rar_device.rar_dev,
454 my_rar_device.rar_offsets[rar_index].high,
455 high);
456 }
457
458 dev_dbg(&my_rar_device.rar_dev->dev, "rar_lock mutex unlocking\n");
459 mutex_unlock(&rar_mutex);
460 return result;
461}
462EXPORT_SYMBOL(rar_lock);
463
464/* The register_rar function is to used by other device drivers
465 * to ensure that this driver is ready. As we cannot be sure of
466 * the compile/execute order of dirvers in ther kernel, it is
467 * best to give this driver a callback function to call when
468 * it is ready to give out addresses. The callback function
469 * would have those steps that continue the initialization of
470 * a driver that do require a valid RAR address. One of those
471 * steps would be to call rar_get_address()
472 * This function return 0 on success an -1 on failure.
473*/
474int register_rar(int (*callback)(void *yourparameter), void *yourparameter)
475{
476
477 int result = -ENODEV;
478
479 if (callback == NULL)
480 return -EINVAL;
481
482 mutex_lock(&rar_mutex);
483
484 if (my_rar_device.registered) {
485
486 mutex_unlock(&rar_mutex);
487 /*
488 * if the driver already registered, then we can simply
489 * call the callback right now
490 */
491
492 return (*callback)(yourparameter);
493 }
494
495 if (num_clients < MRST_NUM_RAR) {
496
497 clients[num_clients].client_callback = callback;
498 clients[num_clients].customer_data = yourparameter;
499 num_clients += 1;
500 result = 0;
501 }
502
503 mutex_unlock(&rar_mutex);
504 return result;
505
506}
507EXPORT_SYMBOL(register_rar);
508
509/* Suspend - returns -ENOSYS */
510static int rar_suspend(struct pci_dev *dev, pm_message_t state)
511{
512 return -ENOSYS;
513}
514
515static int rar_resume(struct pci_dev *dev)
516{
517 return -ENOSYS;
518}
519
520/*
521 * This function registers the driver with the device subsystem (
522 * either PCI, USB, etc).
523 * Function that is activaed on the succesful probe of the RAR device
524 * (Moorestown host controller).
525 */
526static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id)
527{
528 int error;
529 int counter;
530
531 dev_dbg(&dev->dev, "PCI probe starting\n");
532
533 /* enable the device */
534 error = pci_enable_device(dev);
535 if (error) {
536 dev_err(&dev->dev,
537 "Error enabling RAR register PCI device\n");
538 goto end_function;
539 }
540
541 /* we have only one device; fill in the rar_device structure */
542 my_rar_device.rar_dev = dev;
543
544 /*
545 * Initialize the RAR parameters, which have to be retrieved
546 * via the message bus interface.
547 */
548 error = init_rar_params(dev);
549 if (error) {
550 pci_disable_device(dev);
551
552 dev_err(&dev->dev,
553 "Error retrieving RAR addresses\n");
554
555 goto end_function;
556 }
557
558 dev_dbg(&dev->dev, "PCI probe locking\n");
559 mutex_lock(&rar_mutex);
560 my_rar_device.registered = 1;
561
562 /* now call anyone who has registered (using callbacks) */
563 for (counter = 0; counter < num_clients; counter += 1) {
564 if (clients[counter].client_callback) {
565 error = (*clients[counter].client_callback)(
566 clients[counter].customer_data);
567 /* set callback to NULL to indicate it has been done */
568 clients[counter].client_callback = NULL;
569 dev_dbg(&my_rar_device.rar_dev->dev,
570 "Callback called for %d\n",
571 counter);
572 }
573 }
574
575 dev_dbg(&dev->dev, "PCI probe unlocking\n");
576 mutex_unlock(&rar_mutex);
577
578end_function:
579
580 return error;
581}
582
583const struct pci_device_id rar_pci_id_tbl[] = {
584 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_RAR_DEVICE_ID) },
585 { 0 }
586};
587
588MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
589
590const struct pci_device_id *my_id_table = rar_pci_id_tbl;
591
592/* field for registering driver to PCI device */
593static struct pci_driver rar_pci_driver = {
594 .name = "rar_register_driver",
595 .id_table = rar_pci_id_tbl,
596 .probe = rar_probe,
597 .suspend = rar_suspend,
598 .resume = rar_resume
599};
600
601static int __init rar_init_handler(void)
602{
603 return pci_register_driver(&rar_pci_driver);
604}
605
606static void __exit rar_exit_handler(void)
607{
608 pci_unregister_driver(&rar_pci_driver);
609}
610
611module_init(rar_init_handler);
612module_exit(rar_exit_handler);
613
614MODULE_LICENSE("GPL");
615MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver");
diff --git a/drivers/staging/rar_register/rar_register.h b/drivers/staging/rar_register/rar_register.h
new file mode 100644
index 000000000000..29ade0f361d2
--- /dev/null
+++ b/drivers/staging/rar_register/rar_register.h
@@ -0,0 +1,84 @@
1/*
2 * Copyright (C) 2010 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General
6 * Public License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be
9 * useful, but WITHOUT ANY WARRANTY; without even the implied
10 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public
13 * License along with this program; if not, write to the Free
14 * Software Foundation, Inc., 59 Temple Place - Suite 330,
15 * Boston, MA 02111-1307, USA.
16 * The full GNU General Public License is included in this
17 * distribution in the file called COPYING.
18 */
19
20
21#ifndef _RAR_REGISTER_H
22#define _RAR_REGISTER_H
23
24# include <linux/types.h>
25
26/* following are used both in drivers as well as user space apps */
27enum RAR_type {
28 RAR_TYPE_VIDEO = 0,
29 RAR_TYPE_AUDIO,
30 RAR_TYPE_IMAGE,
31 RAR_TYPE_DATA
32};
33
34#ifdef __KERNEL__
35
36/* PCI device id for controller */
37#define PCI_RAR_DEVICE_ID 0x4110
38
39/* The register_rar function is to used by other device drivers
40 * to ensure that this driver is ready. As we cannot be sure of
41 * the compile/execute order of dirvers in ther kernel, it is
42 * best to give this driver a callback function to call when
43 * it is ready to give out addresses. The callback function
44 * would have those steps that continue the initialization of
45 * a driver that do require a valid RAR address. One of those
46 * steps would be to call get_rar_address()
47 * This function return 0 on success an -1 on failure.
48 */
49int register_rar(int (*callback)(void *yourparameter), void *yourparameter);
50
51/* The get_rar_address function is used by other device drivers
52 * to obtain RAR address information on a RAR. It takes two
53 * parameter:
54 *
55 * int rar_index
56 * The rar_index is an index to the rar for which you wish to retrieve
57 * the address information.
58 * Values can be 0,1, or 2.
59 *
60 * struct RAR_address_struct is a pointer to a place to which the function
61 * can return the address structure for the RAR.
62 *
63 * The function returns a 0 upon success or a -1 if there is no RAR
64 * facility on this system.
65 */
66int rar_get_address(int rar_index,
67 dma_addr_t *start_address,
68 dma_addr_t *end_address);
69
70/* The lock_rar function is ued by other device drivers to lock an RAR.
71 * once an RAR is locked, it stays locked until the next system reboot.
72 * The function takes one parameter:
73 *
74 * int rar_index
75 * The rar_index is an index to the rar that you want to lock.
76 * Values can be 0,1, or 2.
77 *
78 * The function returns a 0 upon success or a -1 if there is no RAR
79 * facility on this system.
80 */
81int rar_lock(int rar_index);
82
83#endif /* __KERNEL__ */
84#endif /* _RAR_REGISTER_H */
diff --git a/drivers/staging/rt2860/Kconfig b/drivers/staging/rt2860/Kconfig
index f9962b693128..f3a7e47df5e9 100644
--- a/drivers/staging/rt2860/Kconfig
+++ b/drivers/staging/rt2860/Kconfig
@@ -3,6 +3,8 @@ config RT2860
3 depends on PCI && X86 && WLAN 3 depends on PCI && X86 && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV 5 select WEXT_PRIV
6 select CRC_CCITT
7 select FW_LOADER
6 ---help--- 8 ---help---
7 This is an experimental driver for the Ralink 2860 and 3090 9 This is an experimental driver for the Ralink 2860 and 3090
8 wireless chips. 10 wireless chips.
diff --git a/drivers/staging/rt2860/common/firmware.h b/drivers/staging/rt2860/common/firmware.h
deleted file mode 100644
index 2fecd32f7600..000000000000
--- a/drivers/staging/rt2860/common/firmware.h
+++ /dev/null
@@ -1,558 +0,0 @@
1/*
2 Copyright (c) 2007, Ralink Technology Corporation
3 All rights reserved.
4
5 Redistribution. Redistribution and use in binary form, without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions must reproduce the above copyright notice and the
10 following disclaimer in the documentation and/or other materials
11 provided with the distribution.
12 * Neither the name of Ralink Technology Corporation nor the names of its
13 suppliers may be used to endorse or promote products derived from this
14 software without specific prior written permission.
15 * No reverse engineering, decompilation, or disassembly of this software
16 is permitted.
17
18 Limited patent license. Ralink Technology Corporation grants a world-wide,
19 royalty-free, non-exclusive license under patents it now or hereafter
20 owns or controls to make, have made, use, import, offer to sell and
21 sell ("Utilize") this software, but solely to the extent that any
22 such patent is necessary to Utilize the software alone, or in
23 combination with an operating system licensed under an approved Open
24 Source license as listed by the Open Source Initiative at
25 http://opensource.org/licenses. The patent license shall not apply to
26 any other combinations which include this software. No hardware per
27 se is licensed hereunder.
28
29 DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
31 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
32 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
36 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
39 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
40 DAMAGE.
41*/
42/* AUTO GEN PLEASE DO NOT MODIFY IT */
43/* AUTO GEN PLEASE DO NOT MODIFY IT */
44
45
46u8 FirmwareImage_2860 [] = {
470x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff,
480xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0,
490xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
500x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
510xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x2f,
520x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
530x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
540x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
550x50, 0x85, 0x2f, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
560x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x2f, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
570x2f, 0x12, 0x02, 0x8d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
580xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
590x2f, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
600x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x53, 0xc2,
610xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d,
620xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x30, 0x90,
630x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10,
640x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a,
650x0d, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0xc2, 0x05,
660xd2, 0xaf, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0xe8, 0xc0, 0xe0,
670xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0, 0xe0, 0xed, 0xc0, 0xe0, 0xee,
680xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x12, 0xd2, 0xaf, 0xd0,
690xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc, 0xd0, 0xe0, 0xfb, 0xd0, 0xe0,
700xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0,
710xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0xc2,
720xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5, 0x54, 0x60, 0x04, 0x15, 0x54,
730x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04, 0x15, 0x50, 0x80, 0x02, 0xc2,
740x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04, 0x30, 0x45, 0x03, 0x12, 0x10,
750x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32,
760x12, 0x02, 0xd3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12,
770x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b,
780x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09,
790x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12,
800x02, 0xec, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5,
810x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18,
820x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x19, 0xc2, 0x18, 0xc2, 0x1a, 0x22,
830xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16,
840x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8,
850xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12,
860x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
870xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60,
880x1f, 0xe4, 0xfe, 0x12, 0x03, 0x6a, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x6a, 0xef, 0xf0, 0x74,
890x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3,
900x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
910x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0,
920xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x14, 0x12, 0x03, 0x1c, 0xe4, 0xf5,
930x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x30, 0x45, 0x03, 0x12,
940x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
950xc0, 0x2a, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x0a, 0x22, 0xc0, 0x2a,
960x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x18, 0x22, 0x75, 0x89, 0x02, 0xe4,
970xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75,
980xa8, 0x05, 0x22, 0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x80, 0x1e, 0x80,
990xf5, 0x22, 0xc8, 0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22,
1000xc8, 0xef, 0xc8, 0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x78, 0x7f,
1010xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xd0, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4,
1020x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x7e, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a, 0x18,
1030xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1040xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1050xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1060xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1070xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1080xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1100xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1110xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1120xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1130xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1140xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1150xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1160xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1170xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1180xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1190xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1200xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1210xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1220xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1230xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1240xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1250xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1260xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1270xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1280xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1290xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1300xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1310xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1320xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1330xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1340xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1350xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1360xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1370xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1380xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1390xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1400xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1410xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1420xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1430xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1440xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1450xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1460xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1470xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1480xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1490xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1500xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1510xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1520xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1530xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1540xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1550xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1560xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1570xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1580xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1590xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1600xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1610xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1620xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1630xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1640xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1650xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1660xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1670xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1680xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1690xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1700xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1710xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1720xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1730xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1740xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1750xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1760xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1770xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1780xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1790xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1800xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1810xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1820xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1830xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1840xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1850xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1860xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1870xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1880xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1890xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1900xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1910xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1920xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1930xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1940xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1950xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1960xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1970xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1980xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1990xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2000xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2010xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2020xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2030xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2040xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2050xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2060xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2070xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2080xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2100xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2110xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2120xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2130xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2140xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2150xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2160xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2170xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2180xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2190xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2200xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2210xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2220xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2230xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2240xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2250xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2260xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2270xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2280xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2290xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2300xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2310xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2320xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2330xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2340xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2350xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2360xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2370xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2380xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2390xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2400xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2410xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2420xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2430xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2440xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2450xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2460xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2470xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2480xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2490xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2500xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2510xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2520xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2530xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2540xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2550xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2560xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2570xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2580xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2590xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2600xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2610xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2620xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2630xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2640xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2650xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2660xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2670xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2680xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2690xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2700xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2710xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2720xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2730xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2740xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2750xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2760xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2770xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2780xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2790xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2800xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2810xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2820xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2830xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2840xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2850xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2860xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2870xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2880xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2890xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2900xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2910xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2920xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2930xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2940xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2950xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2960xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2970xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2980xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2990xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3000xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3010xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3020xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3030xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x12, 0xb8, 0x02,
3040x12, 0xb9, 0x02, 0x13, 0x3e, 0x02, 0x13, 0x3f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x16, 0x56, 0x02,
3050x17, 0x6b, 0x02, 0x14, 0x2a, 0x02, 0x13, 0x40, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x00,
3060xd8, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x18, 0x5e, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
3070x20, 0xe7, 0x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
3080x12, 0x02, 0x67, 0x11, 0x4e, 0x30, 0x11, 0x25, 0x31, 0x10, 0x87, 0x33, 0x10, 0xaa, 0x34, 0x10,
3090xc3, 0x35, 0x11, 0x57, 0x50, 0x11, 0x7b, 0x51, 0x11, 0x84, 0x52, 0x11, 0x84, 0x53, 0x11, 0x84,
3100x54, 0x11, 0xc5, 0x55, 0x11, 0xdc, 0x70, 0x12, 0x07, 0x71, 0x12, 0x34, 0x72, 0x12, 0x5e, 0x80,
3110x12, 0x81, 0x83, 0x00, 0x00, 0x12, 0xb7, 0x75, 0x24, 0x05, 0x75, 0x25, 0xdc, 0x90, 0x70, 0x9f,
3120x74, 0x12, 0xf0, 0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x0d, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
3130x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0,
3140x54, 0xfd, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7,
3150x02, 0x12, 0xaa, 0xe5, 0x55, 0x64, 0x02, 0x70, 0x37, 0x90, 0x70, 0x10, 0xe0, 0x60, 0x08, 0x90,
3160x01, 0x0d, 0x74, 0x09, 0xf0, 0x80, 0x25, 0xe5, 0x34, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14,
3170x60, 0x14, 0x24, 0x03, 0x70, 0x16, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x80, 0x0e, 0x90, 0x01,
3180x0d, 0x74, 0x0b, 0xf0, 0x80, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x1b, 0xf0, 0x7d, 0x01, 0x80, 0x02,
3190x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x90,
3200x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
3210x12, 0xb7, 0x02, 0x12, 0xaa, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, 0x56, 0x12,
3220x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4,
3230x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, 0x90, 0x70,
3240x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60,
3250x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60,
3260x03, 0x02, 0x12, 0xb7, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24,
3270xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70,
3280x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff,
3290x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
3300x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
3310x12, 0xb7, 0x02, 0x12, 0xaa, 0xe5, 0x47, 0xb4, 0x07, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x07,
3320xf5, 0x26, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x22, 0x90, 0x70, 0x10, 0xe0,
3330xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02,
3340x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
3350x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0,
3360xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
3370x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
3380x12, 0xb7, 0x80, 0x76, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x26, 0xff, 0xc2, 0x19, 0xc2, 0x18,
3390xc2, 0x1a, 0x75, 0x34, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74,
3400x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x5b, 0x80, 0x4c, 0x90, 0x70,
3410x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
3420x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x38, 0x80,
3430x29, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x34, 0xd3, 0x94, 0x00, 0x40, 0x07, 0x90, 0x01, 0x0d, 0xe0,
3440x54, 0xfb, 0xf0, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
3450xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x0d, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01,
3460xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x13, 0x3d,
3470xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0xa2, 0x19,
3480xe4, 0x33, 0x90, 0x70, 0x90, 0xf0, 0xa2, 0x18, 0xe4, 0x33, 0xa3, 0xf0, 0x30, 0x19, 0x4d, 0x90,
3490x70, 0x98, 0x74, 0x23, 0xf0, 0xa3, 0xe5, 0x25, 0xf0, 0xe5, 0x24, 0xa3, 0xf0, 0x7f, 0x35, 0x7d,
3500x32, 0x12, 0x03, 0x42, 0x50, 0x09, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5,
3510x35, 0xd3, 0x94, 0x10, 0x40, 0x1e, 0x30, 0x1a, 0x1b, 0xc2, 0x1a, 0xa2, 0x18, 0x92, 0x19, 0x20,
3520x19, 0x12, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0,
3530xc2, 0x61, 0xd2, 0x03, 0xe5, 0x35, 0xb4, 0x0b, 0x14, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2,
3540x18, 0x92, 0x19, 0x30, 0x19, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22,
3550xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x67, 0x13, 0x62, 0x00, 0x13, 0xf5, 0x04, 0x13,
3560xf1, 0x08, 0x13, 0xcc, 0x10, 0x13, 0x76, 0x20, 0x13, 0x96, 0x60, 0x13, 0xa7, 0xa0, 0x00, 0x00,
3570x13, 0xf7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60,
3580x03, 0x02, 0x13, 0xf7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4,
3590x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
3600x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5,
3610x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b,
3620xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06,
3630x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04,
3640x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75,
3650x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80,
3660x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x38, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff,
3670xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3,
3680xe5, 0x4a, 0xf0, 0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3,
3690xe5, 0x42, 0xf0, 0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0,
3700x70, 0x03, 0x12, 0x16, 0x36, 0x12, 0x14, 0x3f, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
3710xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45,
3720x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74,
3730x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x38, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5,
3740x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
3750x38, 0x70, 0x05, 0x75, 0x38, 0x0c, 0x80, 0x02, 0x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
3760xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
3770x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x38,
3780x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x38, 0x70, 0x05, 0x75, 0x38, 0x07, 0x80, 0x02,
3790x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5, 0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5,
3800x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a,
3810x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0,
3820x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x15, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2,
3830xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3840x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x15, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2,
3850xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3860x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x15, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2,
3870xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3880x71, 0x92, 0x70, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x46, 0x90,
3890x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe,
3900x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x35, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0d,
3910x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22, 0x44, 0x01, 0xf0,
3920x22, 0xe5, 0x46, 0x30, 0xe3, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, 0x28, 0xe0,
3930x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x03, 0x02, 0x16, 0x35, 0xf5, 0x27,
3940x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x26, 0x14, 0x60, 0x26, 0x14, 0x60, 0x2e, 0x14,
3950x60, 0x36, 0x24, 0x03, 0x70, 0x5f, 0xe5, 0x46, 0x13, 0x13, 0x13, 0x54, 0x1f, 0x75, 0xf0, 0x03,
3960x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff,
3970x80, 0x02, 0xa2, 0x47, 0x92, 0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x3f, 0xe5, 0x46, 0x30,
3980xe3, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe3, 0x0d, 0x54, 0x70, 0xc3,
3990x94, 0x60, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47,
4000x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47,
4010xb3, 0x92, 0x39, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02, 0x28, 0xe0,
4020x54, 0xfc, 0x45, 0x27, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45,
4030x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59,
4040x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x30, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a,
4050x14, 0x60, 0x6a, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x4c, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20,
4060x19, 0x1c, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34,
4070xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20,
4080x12, 0x16, 0x4c, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x17, 0x4c,
4090xe5, 0x50, 0x70, 0x06, 0x75, 0x30, 0x03, 0x02, 0x17, 0x4c, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03,
4100x70, 0x15, 0x7f, 0x20, 0x12, 0x16, 0x4c, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb,
4110xf0, 0x75, 0x51, 0x02, 0x02, 0x17, 0x4c, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x7a, 0x20, 0x19, 0x0f,
4120x90, 0x02, 0x08, 0xe0, 0x20, 0xe3, 0x6c, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x64, 0x90,
4130x12, 0x04, 0x74, 0x0a, 0xf0, 0x30, 0x1b, 0x11, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3,
4140xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x04, 0x01, 0xe0,
4150x44, 0x10, 0xf0, 0xe5, 0x34, 0xf4, 0x90, 0x04, 0x01, 0x60, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80,
4160x04, 0xe0, 0x54, 0xf9, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5,
4170x34, 0xf4, 0x60, 0x14, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x33, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40,
4180x07, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x30, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5,
4190x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x30, 0x03, 0xf5, 0x51, 0xe5, 0x30, 0x60, 0x18,
4200xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x19, 0x0e, 0xad, 0x30, 0xaf, 0x40, 0x12, 0x18,
4210x2a, 0xe5, 0x30, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e,
4220xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x18, 0x2a, 0xe5, 0x52,
4230x14, 0x60, 0x55, 0x14, 0x60, 0x2f, 0x24, 0x02, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe5, 0x34, 0xf4,
4240x60, 0x23, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40, 0x16, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x02, 0xf0,
4250x90, 0x01, 0x0d, 0xe0, 0x20, 0xe3, 0x03, 0x02, 0x18, 0x27, 0x7f, 0x50, 0x12, 0x16, 0x51, 0x75,
4260x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x34, 0xf4, 0x60, 0x0a, 0xe5, 0x54, 0x70, 0x69, 0x90, 0x01,
4270x0d, 0xe5, 0x33, 0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x16, 0x51,
4280x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x80, 0x4f, 0xe5, 0x54, 0x70, 0x4b, 0x90, 0x04, 0x01, 0xe0,
4290x44, 0x0e, 0xf0, 0x20, 0x19, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f,
4300xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03,
4310xf0, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44,
4320x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41,
4330x12, 0x18, 0x2a, 0x80, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe,
4340x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14,
4350x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4,
4360x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x20, 0x19,
4370x03, 0x02, 0x19, 0x0f, 0x90, 0x70, 0x80, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x37, 0xe0, 0x30, 0xe5,
4380x03, 0x02, 0x19, 0x0b, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x31, 0xa3, 0xe0, 0xf5, 0x30, 0xf5, 0x32,
4390xe4, 0xf5, 0x37, 0x90, 0x70, 0x81, 0xe0, 0x04, 0xf0, 0x90, 0x70, 0x82, 0xe0, 0x04, 0xf0, 0xe5,
4400x32, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00, 0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x30, 0x65,
4410x32, 0x70, 0x05, 0xfc, 0x7d, 0x18, 0x80, 0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee,
4420x3c, 0xfe, 0x12, 0x19, 0x10, 0x50, 0x25, 0x90, 0x70, 0x83, 0xe0, 0x04, 0xf0, 0x90, 0x01, 0x14,
4430xe0, 0x44, 0x02, 0xf0, 0xe0, 0x30, 0xe1, 0x06, 0x90, 0x70, 0x92, 0x74, 0x45, 0xf0, 0x90, 0x70,
4440x93, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x90, 0x70, 0x94, 0xf0, 0xe5, 0x32, 0x65, 0x31,
4450x60, 0x10, 0xe4, 0x25, 0x32, 0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x32,
4460x80, 0x97, 0x90, 0x04, 0x10, 0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x31, 0xf0, 0xa3, 0xe5,
4470x30, 0xf0, 0x90, 0x04, 0x11, 0x74, 0x01, 0xf0, 0x02, 0x18, 0x6a, 0xc2, 0x06, 0xd2, 0x1a, 0x22,
4480x90, 0x70, 0x84, 0xe5, 0x37, 0xf0, 0xc3, 0x94, 0x06, 0x50, 0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0,
4490xb4, 0xff, 0x07, 0x05, 0x37, 0xe4, 0xf5, 0x36, 0x80, 0x59, 0xe4, 0xf5, 0x37, 0x8f, 0x82, 0x8e,
4500x83, 0xf0, 0x80, 0x4f, 0xe5, 0x36, 0x75, 0xf0, 0x06, 0x84, 0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82,
4510xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0x6d, 0x70, 0x30,
4520x90, 0x70, 0x88, 0xe0, 0x04, 0xf0, 0xa3, 0xe0, 0xfd, 0xd3, 0x95, 0x37, 0x40, 0x02, 0x80, 0x02,
4530xad, 0x37, 0x90, 0x70, 0x89, 0xed, 0xf0, 0x05, 0x37, 0x05, 0x36, 0xe5, 0x36, 0x75, 0xf0, 0x06,
4540x84, 0x74, 0x8a, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x03,
4550xe4, 0xf5, 0x37, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x0a, 0xe5, 0x37, 0xc3,
4560x94, 0x4e, 0x50, 0x03, 0x02, 0x19, 0x10, 0xe5, 0x37, 0xb4, 0x4e, 0x03, 0xd3, 0x80, 0x01, 0xc3,
4570x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x94, 0xeb, } ;
diff --git a/drivers/staging/rt2860/common/firmware_3070.h b/drivers/staging/rt2860/common/firmware_3070.h
deleted file mode 100644
index b710d40bc046..000000000000
--- a/drivers/staging/rt2860/common/firmware_3070.h
+++ /dev/null
@@ -1,517 +0,0 @@
1/* AUTO GEN PLEASE DO NOT MODIFY IT */
2/* AUTO GEN PLEASE DO NOT MODIFY IT */
3
4
5u8 FirmwareImage_3070 [] = {
60xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
70x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
80x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
90x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
100x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
110x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
120x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
130x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
140x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
150xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
160x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
170x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
180xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
190xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
200x02, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
210xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
220x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
230xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
240xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
250x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
260x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
270xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
280x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14,
290x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
300x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
310x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
320x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
330xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
340xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2,
350x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
360x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
370xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
380x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
390x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
400x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
410xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
420xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
430x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
440xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
450x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
460x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
470xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
480x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
490xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
500x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
510xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
520x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
530x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
540xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
550x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
560xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
570xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
580xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
590x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
600x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
610x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
620x9d, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
630x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
640x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
650xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
660x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
670x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
680x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
690x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
700xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
710x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
720xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
730x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
740x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
750x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
760xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
770x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
780x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
790x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
800x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
810xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
820x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
830x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
840x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
850xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
860x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
870x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
880x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
890x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
900x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
910x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
920x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
930x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
940x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
950x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
960x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
970xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
980x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
990x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
1000xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
1010x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
1020x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
1030x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
1040x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
1050x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
1060x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
1070x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
1080x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
1090x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
1100x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
1110xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
1120xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
1130x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
1140x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
1150x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
1160xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
1170x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
1180x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
1190x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
1200x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
1210x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
1220x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
1230x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
1240x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
1250x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
1260x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
1270x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
1280x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
1290x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
1300x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
1310x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
1320xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
1330x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
1340x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
1350xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
1360xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
1370x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
1380x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
1390x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
1400x0d, 0x2a, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
1410xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
1420x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
1430x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
1440xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
1450x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
1460x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
1470xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
1480xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
1490x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
1500x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
1510x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
1520x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
1530x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
1540x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
1550x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
1560x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
1570x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
1580xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
1590x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
1600x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
1610x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
1620x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
1630x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
1640x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
1650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x7b, 0xc4,
2620xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
2630x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
2640x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
2650x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
2660x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
2670x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
2680x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
2690x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
2700x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
2710xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
2720x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
2730x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
2740xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
2750xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
2760x02, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
2770xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
2780x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
2790xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
2800xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
2810x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
2820x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
2830xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
2840x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14,
2850x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
2860x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
2870x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
2880x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
2890xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
2900xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2,
2910x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
2920x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
2930xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
2940x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
2950x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
2960x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
2970xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
2980xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
2990x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
3000xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
3010x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
3020x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
3030xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
3040x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
3050xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
3060x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
3070xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
3080x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
3090x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
3100xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
3110x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
3120xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
3130xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
3140xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
3150x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
3160x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
3170x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
3180xb6, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
3190x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
3200x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
3210xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
3220x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
3230x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
3240x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
3250x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
3260xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
3270x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
3280xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
3290x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
3300x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
3310x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
3320xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
3330x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
3340x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
3350x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
3360x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
3370xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
3380x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
3390x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
3400x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
3410xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
3420x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
3430x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
3440x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
3450x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
3460x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
3470x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
3480x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
3490x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
3500x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
3510x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
3520x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
3530xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
3540x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
3550x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
3560xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
3570x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
3580x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
3590x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
3600x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
3610x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
3620x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
3630x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
3640x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
3650x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
3660x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
3670xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
3680xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
3690x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
3700x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
3710x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
3720xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
3730x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
3740x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
3750x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
3760x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
3770x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
3780x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
3790x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
3800x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
3810x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
3820x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
3830x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
3840x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
3850x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
3860x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
3870x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
3880xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
3890x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
3900x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
3910xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
3920xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
3930x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
3940x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
3950x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
3960x0d, 0x48, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
3970xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
3980x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
3990x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
4000xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
4010x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
4020x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
4030xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
4040xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
4050x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
4060x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
4070x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
4080x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
4090x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
4100x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
4110x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
4120x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
4130x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
4140xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
4150x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
4160x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
4170x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
4180x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
4190x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
4200x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
4210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x65, 0xd3, } ;
diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c
index 9f03901433bb..844d4b987b78 100644
--- a/drivers/staging/rt2860/common/rtmp_mcu.c
+++ b/drivers/staging/rt2860/common/rtmp_mcu.c
@@ -37,35 +37,38 @@
37 37
38#include "../rt_config.h" 38#include "../rt_config.h"
39 39
40#if defined(RT2860) || defined(RT3090) 40#include <linux/crc-ccitt.h>
41#include "firmware.h" 41#include <linux/firmware.h>
42#include "../../rt3090/firmware.h"
43#endif
44#ifdef RT2870
45#include "../../rt3070/firmware.h"
46#include "firmware_3070.h"
47#endif
48
49#include <linux/bitrev.h>
50 42
51#ifdef RTMP_MAC_USB 43#ifdef RTMP_MAC_USB
52/* */
53/* RT2870 Firmware Spec only used 1 oct for version expression */
54/* */
55#define FIRMWARE_MINOR_VERSION 7
56#endif /* RTMP_MAC_USB // */
57 44
58/* New 8k byte firmware size for RT3071/RT3072 */ 45#define FIRMWAREIMAGE_LENGTH 0x1000
59#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
60#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(u8))
61#define FIRMWARE_MAJOR_VERSION 0
62 46
63#define FIRMWAREIMAGEV1_LENGTH 0x1000 47#define FIRMWARE_2870_MIN_VERSION 12
64#define FIRMWAREIMAGEV2_LENGTH 0x1000 48#define FIRMWARE_2870_FILENAME "rt2870.bin"
49MODULE_FIRMWARE(FIRMWARE_2870_FILENAME);
65 50
66#ifdef RTMP_MAC_PCI 51#define FIRMWARE_3070_MIN_VERSION 17
67#define FIRMWARE_MINOR_VERSION 2 52#define FIRMWARE_3070_FILENAME "rt3070.bin"
68#endif /* RTMP_MAC_PCI // */ 53MODULE_FIRMWARE(FIRMWARE_3070_FILENAME);
54
55#define FIRMWARE_3071_MIN_VERSION 17
56#define FIRMWARE_3071_FILENAME "rt3071.bin" /* for RT3071/RT3072 */
57MODULE_FIRMWARE(FIRMWARE_3071_FILENAME);
58
59#else /* RTMP_MAC_PCI */
60
61#define FIRMWAREIMAGE_LENGTH 0x2000
62
63#define FIRMWARE_2860_MIN_VERSION 11
64#define FIRMWARE_2860_FILENAME "rt2860.bin"
65MODULE_FIRMWARE(FIRMWARE_2860_FILENAME);
66
67#define FIRMWARE_3090_MIN_VERSION 19
68#define FIRMWARE_3090_FILENAME "rt3090.bin" /* for RT3090/RT3390 */
69MODULE_FIRMWARE(FIRMWARE_3090_FILENAME);
70
71#endif
69 72
70/* 73/*
71 ======================================================================== 74 ========================================================================
@@ -90,6 +93,78 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
90 return 0; 93 return 0;
91} 94}
92 95
96static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter)
97{
98 const char *name;
99 const struct firmware *fw = NULL;
100 u8 min_version;
101 struct device *dev;
102 int err;
103
104 if (adapter->firmware)
105 return adapter->firmware;
106
107#ifdef RTMP_MAC_USB
108 if (IS_RT3071(adapter)) {
109 name = FIRMWARE_3071_FILENAME;
110 min_version = FIRMWARE_3071_MIN_VERSION;
111 } else if (IS_RT3070(adapter)) {
112 name = FIRMWARE_3070_FILENAME;
113 min_version = FIRMWARE_3070_MIN_VERSION;
114 } else {
115 name = FIRMWARE_2870_FILENAME;
116 min_version = FIRMWARE_2870_MIN_VERSION;
117 }
118 dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev;
119#else /* RTMP_MAC_PCI */
120 if (IS_RT3090(adapter) || IS_RT3390(adapter)) {
121 name = FIRMWARE_3090_FILENAME;
122 min_version = FIRMWARE_3090_MIN_VERSION;
123 } else {
124 name = FIRMWARE_2860_FILENAME;
125 min_version = FIRMWARE_2860_MIN_VERSION;
126 }
127 dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev;
128#endif
129
130 err = request_firmware(&fw, name, dev);
131 if (err) {
132 dev_err(dev, "firmware file %s request failed (%d)\n",
133 name, err);
134 return NULL;
135 }
136
137 if (fw->size < FIRMWAREIMAGE_LENGTH) {
138 dev_err(dev, "firmware file %s size is invalid\n", name);
139 goto invalid;
140 }
141
142 /* is it new enough? */
143 adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3];
144 if (adapter->FirmwareVersion < min_version) {
145 dev_err(dev,
146 "firmware file %s is too old;"
147 " driver requires v%d or later\n",
148 name, min_version);
149 goto invalid;
150 }
151
152 /* is the internal CRC correct? */
153 if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) !=
154 (fw->data[FIRMWAREIMAGE_LENGTH - 2] |
155 (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) {
156 dev_err(dev, "firmware file %s failed internal CRC\n", name);
157 goto invalid;
158 }
159
160 adapter->firmware = fw;
161 return fw;
162
163invalid:
164 release_firmware(fw);
165 return NULL;
166}
167
93/* 168/*
94 ======================================================================== 169 ========================================================================
95 170
@@ -109,46 +184,16 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
109*/ 184*/
110int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd) 185int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
111{ 186{
112 187 const struct firmware *fw;
113 int Status = NDIS_STATUS_SUCCESS; 188 int Status = NDIS_STATUS_SUCCESS;
114 u8 *pFirmwareImage = NULL; 189 unsigned long Index;
115 unsigned long FileLength, Index;
116 u32 MacReg = 0; 190 u32 MacReg = 0;
117#ifdef RTMP_MAC_USB
118 u32 Version = (pAd->MACVersion >> 16);
119#endif
120 191
121 /* New 8k byte firmware size for RT3071/RT3072 */ 192 fw = rtmp_get_firmware(pAd);
122 { 193 if (!fw)
123#ifdef RTMP_MAC_PCI 194 return NDIS_STATUS_FAILURE;
124 if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
125 pFirmwareImage = FirmwareImage_3090;
126 FileLength = FIRMWAREIMAGE_MAX_LENGTH;
127 } else {
128 pFirmwareImage = FirmwareImage_2860;
129 FileLength = FIRMWAREIMAGE_MAX_LENGTH;
130 }
131#endif /* RTMP_MAC_PCI // */
132#ifdef RTMP_MAC_USB
133 /* the firmware image consists of two parts */
134 if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) { /* use the second part */
135 /*printk("KH:Use New Version,part2\n"); */
136 pFirmwareImage =
137 (u8 *)&
138 FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH];
139 FileLength = FIRMWAREIMAGEV2_LENGTH;
140 } else {
141 /*printk("KH:Use New Version,part1\n"); */
142 if (Version == 0x3070)
143 pFirmwareImage = FirmwareImage_3070;
144 else
145 pFirmwareImage = FirmwareImage_2870;
146 FileLength = FIRMWAREIMAGEV1_LENGTH;
147 }
148#endif /* RTMP_MAC_USB // */
149 }
150 195
151 RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength); 196 RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH);
152 197
153 /* check if MCU is ready */ 198 /* check if MCU is ready */
154 Index = 0; 199 Index = 0;
@@ -221,7 +266,7 @@ int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
221 ("AsicSendCommanToMcu::Mail box is busy\n")); 266 ("AsicSendCommanToMcu::Mail box is busy\n"));
222 } while (i++ < 100); 267 } while (i++ < 100);
223 268
224 if (i >= 100) { 269 if (i > 100) {
225 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); 270 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
226 return FALSE; 271 return FALSE;
227 } 272 }
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index 9357fb26cc2a..b5c78aecf5e3 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -25,6 +25,7 @@
25 ************************************************************************* 25 *************************************************************************
26 */ 26 */
27 27
28#include <linux/firmware.h>
28#include <linux/sched.h> 29#include <linux/sched.h>
29#include "rt_config.h" 30#include "rt_config.h"
30 31
@@ -260,6 +261,8 @@ void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
260 261
261 NdisFreeSpinLock(&pAd->irq_lock); 262 NdisFreeSpinLock(&pAd->irq_lock);
262 263
264 release_firmware(pAd->firmware);
265
263 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */ 266 vfree(pAd); /* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
264 if (os_cookie) 267 if (os_cookie)
265 kfree(os_cookie); 268 kfree(os_cookie);
@@ -462,9 +465,9 @@ void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
462 if ((skb = 465 if ((skb =
463 __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) { 466 __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) {
464 skb_reserve(skb, 2); 467 skb_reserve(skb, 2);
465 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen); 468 NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
466 skb_put(skb, HdrLen); 469 skb_put(skb, HdrLen);
467 NdisMoveMemory(skb->tail, pData, DataSize); 470 NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
468 skb_put(skb, DataSize); 471 skb_put(skb, DataSize);
469 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); 472 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
470 pPacket = OSPKT_TO_RTPKT(skb); 473 pPacket = OSPKT_TO_RTPKT(skb);
@@ -515,7 +518,7 @@ void *ClonePacket(struct rt_rtmp_adapter *pAd,
515 pClonedPkt->dev = pRxPkt->dev; 518 pClonedPkt->dev = pRxPkt->dev;
516 pClonedPkt->data = pData; 519 pClonedPkt->data = pData;
517 pClonedPkt->len = DataSize; 520 pClonedPkt->len = DataSize;
518 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len; 521 skb_set_tail_pointer(pClonedPkt, DataSize)
519 ASSERT(DataSize < 1530); 522 ASSERT(DataSize < 1530);
520 } 523 }
521 return pClonedPkt; 524 return pClonedPkt;
@@ -535,7 +538,7 @@ void update_os_packet_info(struct rt_rtmp_adapter *pAd,
535 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); 538 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
536 pOSPkt->data = pRxBlk->pData; 539 pOSPkt->data = pRxBlk->pData;
537 pOSPkt->len = pRxBlk->DataSize; 540 pOSPkt->len = pRxBlk->DataSize;
538 pOSPkt->tail = pOSPkt->data + pOSPkt->len; 541 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
539} 542}
540 543
541void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd, 544void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
@@ -553,7 +556,7 @@ void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
553 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); 556 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
554 pOSPkt->data = pRxBlk->pData; 557 pOSPkt->data = pRxBlk->pData;
555 pOSPkt->len = pRxBlk->DataSize; 558 pOSPkt->len = pRxBlk->DataSize;
556 pOSPkt->tail = pOSPkt->data + pOSPkt->len; 559 skb_set_tail_pointer(pOSPkt, pOSPkt->len);
557 560
558 /* */ 561 /* */
559 /* copy 802.3 header */ 562 /* copy 802.3 header */
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index f85508d9d5a9..a7c540f8e3e3 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -658,9 +658,9 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size,
658 (RTPKT_TO_OSPKT(_pkt)->len) = (_len) 658 (RTPKT_TO_OSPKT(_pkt)->len) = (_len)
659 659
660#define GET_OS_PKT_DATATAIL(_pkt) \ 660#define GET_OS_PKT_DATATAIL(_pkt) \
661 (RTPKT_TO_OSPKT(_pkt)->tail) 661 (skb_tail_pointer(RTPKT_TO_OSPKT(_pkt))
662#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \ 662#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \
663 ((RTPKT_TO_OSPKT(_pkt))->tail) = (u8 *)((_start) + (_len)) 663 (skb_set_tail_pointer(RTPKT_TO_OSPKT(_pkt), _len))
664 664
665#define GET_OS_PKT_HEAD(_pkt) \ 665#define GET_OS_PKT_HEAD(_pkt) \
666 (RTPKT_TO_OSPKT(_pkt)->head) 666 (RTPKT_TO_OSPKT(_pkt)->head)
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index c3d92802d0c9..fbddb00cfedd 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -216,7 +216,7 @@ int rt28xx_close(struct net_device *dev)
216 u32 i = 0; 216 u32 i = 0;
217 217
218#ifdef RTMP_MAC_USB 218#ifdef RTMP_MAC_USB
219 DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup); 219 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
220 DECLARE_WAITQUEUE(wait, current); 220 DECLARE_WAITQUEUE(wait, current);
221#endif /* RTMP_MAC_USB // */ 221#endif /* RTMP_MAC_USB // */
222 222
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index c50abf4b8068..4401a55bda67 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -1719,6 +1719,7 @@ struct rt_rtmp_adapter {
1719 void *OS_Cookie; /* save specific structure relative to OS */ 1719 void *OS_Cookie; /* save specific structure relative to OS */
1720 struct net_device *net_dev; 1720 struct net_device *net_dev;
1721 unsigned long VirtualIfCnt; 1721 unsigned long VirtualIfCnt;
1722 const struct firmware *firmware;
1722 1723
1723 struct rt_rtmp_chip_op chipOps; 1724 struct rt_rtmp_chip_op chipOps;
1724 u16 ThisTbttNumToNextWakeUp; 1725 u16 ThisTbttNumToNextWakeUp;
@@ -4043,10 +4044,10 @@ int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
4043 u16 Offset, u8 *pData, u16 length); 4044 u16 Offset, u8 *pData, u16 length);
4044 4045
4045int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd, 4046int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
4046 u16 Offset, u8 *pData, u16 length); 4047 u16 Offset, const u8 *pData, u16 length);
4047 4048
4048int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd, 4049int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
4049 u16 Offset, u8 *pData); 4050 u16 Offset, const u8 *pData);
4050 4051
4051int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd, 4052int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
4052 u8 Id, u8 *pValue); 4053 u8 Id, u8 *pValue);
@@ -4112,7 +4113,7 @@ int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd,
4112 u16 Offset, u16 Value); 4113 u16 Offset, u16 Value);
4113 4114
4114int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd, 4115int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
4115 u8 *pFwImage, unsigned long FwLen); 4116 const u8 *pFwImage, unsigned long FwLen);
4116 4117
4117int RTUSBVenderReset(struct rt_rtmp_adapter *pAd); 4118int RTUSBVenderReset(struct rt_rtmp_adapter *pAd);
4118 4119
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index 17e59ba3d807..55732b10062d 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -62,8 +62,8 @@ u8 CipherSuiteWpaNoneAes[] = {
62u8 CipherSuiteWpaNoneAesLen = 62u8 CipherSuiteWpaNoneAesLen =
63 (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8)); 63 (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
64 64
65/* The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS, */ 65/* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */
66/* or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */ 66/* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */
67/* All settings successfuly negotiated furing MLME state machines become final settings */ 67/* All settings successfuly negotiated furing MLME state machines become final settings */
68/* and are copied to pAd->StaActive */ 68/* and are copied to pAd->StaActive */
69#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ 69#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index d8fbe6cc6941..de4b6277baee 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -975,10 +975,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
975 /*================================ */ 975 /*================================ */
976 memset(&iwe, 0, sizeof(iwe)); 976 memset(&iwe, 0, sizeof(iwe));
977 iwe.cmd = SIOCGIWFREQ; 977 iwe.cmd = SIOCGIWFREQ;
978 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) 978 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
979 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
980 else
981 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
982 iwe.u.freq.e = 0; 979 iwe.u.freq.e = 0;
983 iwe.u.freq.i = 0; 980 iwe.u.freq.i = 0;
984 981
diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c
index 925a236e1044..1873a79bb033 100644
--- a/drivers/staging/rt2860/usb_main_dev.c
+++ b/drivers/staging/rt2860/usb_main_dev.c
@@ -216,10 +216,6 @@ static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
216static int rt2870_resume(struct usb_interface *intf); 216static int rt2870_resume(struct usb_interface *intf);
217#endif /* CONFIG_PM // */ 217#endif /* CONFIG_PM // */
218 218
219static int rtusb_probe(struct usb_interface *intf,
220 const struct usb_device_id *id);
221static void rtusb_disconnect(struct usb_interface *intf);
222
223static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, 219static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
224 IN struct usb_interface *intf, 220 IN struct usb_interface *intf,
225 struct rt_rtmp_adapter *pAd) 221 struct rt_rtmp_adapter *pAd)
@@ -296,7 +292,7 @@ static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
296 292
297} 293}
298 294
299static int rtusb_probe(struct usb_interface *intf, 295static int __devinit rtusb_probe(struct usb_interface *intf,
300 const struct usb_device_id *id) 296 const struct usb_device_id *id)
301{ 297{
302 struct rt_rtmp_adapter *pAd; 298 struct rt_rtmp_adapter *pAd;
diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig
index fd3ba3a3b127..6ea172b433e9 100644
--- a/drivers/staging/rt2870/Kconfig
+++ b/drivers/staging/rt2870/Kconfig
@@ -3,5 +3,7 @@ config RT2870
3 depends on USB && X86 && WLAN 3 depends on USB && X86 && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV 5 select WEXT_PRIV
6 select CRC_CCITT
7 select FW_LOADER
6 ---help--- 8 ---help---
7 This is an experimental driver for the Ralink xx70 wireless chips. 9 This is an experimental driver for the Ralink xx70 wireless chips.
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
index 34443f2243f1..cf0d2f5dbc6c 100644
--- a/drivers/staging/rt2870/common/rtusb_io.c
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -84,7 +84,7 @@ static int RTUSBFirmwareRun(struct rt_rtmp_adapter *pAd)
84 ======================================================================== 84 ========================================================================
85*/ 85*/
86int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd, 86int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
87 u8 *pFwImage, unsigned long FwLen) 87 const u8 *pFwImage, unsigned long FwLen)
88{ 88{
89 u32 MacReg; 89 u32 MacReg;
90 int Status; 90 int Status;
@@ -167,7 +167,7 @@ int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
167 ======================================================================== 167 ========================================================================
168*/ 168*/
169int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd, 169int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
170 u16 Offset, u8 *pData) 170 u16 Offset, const u8 *pData)
171{ 171{
172 int Status; 172 int Status;
173 173
@@ -175,18 +175,18 @@ int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
175 Status = RTUSB_VendorRequest(pAd, 175 Status = RTUSB_VendorRequest(pAd,
176 USBD_TRANSFER_DIRECTION_OUT, 176 USBD_TRANSFER_DIRECTION_OUT,
177 DEVICE_VENDOR_REQUEST_OUT, 177 DEVICE_VENDOR_REQUEST_OUT,
178 0x6, 0, Offset, pData, 1); 178 0x6, 0, Offset, (u8 *)pData, 1);
179 179
180 return Status; 180 return Status;
181} 181}
182 182
183int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd, 183int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
184 u16 Offset, u8 *pData, u16 length) 184 u16 Offset, const u8 *pData, u16 length)
185{ 185{
186 int Status; 186 int Status;
187 187
188 u16 index = 0, Value; 188 u16 index = 0, Value;
189 u8 *pSrc = pData; 189 const u8 *pSrc = pData;
190 u16 resude = 0; 190 u16 resude = 0;
191 191
192 resude = length % 2; 192 resude = length % 2;
diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h
deleted file mode 100644
index 5cf9cbcf4ab6..000000000000
--- a/drivers/staging/rt3070/firmware.h
+++ /dev/null
@@ -1,558 +0,0 @@
1/*
2 Copyright (c) 2007, Ralink Technology Corporation
3 All rights reserved.
4
5 Redistribution. Redistribution and use in binary form, without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions must reproduce the above copyright notice and the
10 following disclaimer in the documentation and/or other materials
11 provided with the distribution.
12 * Neither the name of Ralink Technology Corporation nor the names of its
13 suppliers may be used to endorse or promote products derived from this
14 software without specific prior written permission.
15 * No reverse engineering, decompilation, or disassembly of this software
16 is permitted.
17
18 Limited patent license. Ralink Technology Corporation grants a world-wide,
19 royalty-free, non-exclusive license under patents it now or hereafter
20 owns or controls to make, have made, use, import, offer to sell and
21 sell ("Utilize") this software, but solely to the extent that any
22 such patent is necessary to Utilize the software alone, or in
23 combination with an operating system licensed under an approved Open
24 Source license as listed by the Open Source Initiative at
25 http://opensource.org/licenses. The patent license shall not apply to
26 any other combinations which include this software. No hardware per
27 se is licensed hereunder.
28
29 DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
31 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
32 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
36 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
38 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
39 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
40 DAMAGE.
41*/
42/* AUTO GEN PLEASE DO NOT MODIFY IT */
43/* AUTO GEN PLEASE DO NOT MODIFY IT */
44
45
46u8 FirmwareImage_2870 [] = {
470xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
480x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
490x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
500xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
510x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
520x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
530x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
540x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
550x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
560xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
570x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
580x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
590x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
600x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
610x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
620xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
630x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
640xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
650xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
660xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
670x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
680x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
690x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
700x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70,
710x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
720x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
730xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
740x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
750x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
760x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
770xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
780xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
790x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80,
800xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
810xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74,
820x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
830x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90,
840x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
850x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
860x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
870x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
880x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
890x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
900x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
910x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
920x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
930x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
940x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
950xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
960x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
970xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
980x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
990x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
1000x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
1010xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
1020xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
1030x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
1040x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
1050x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
1060x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
1070x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
1080x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
1090xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
1100x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
1110x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
1120x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
1130x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
1140x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
1150x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
1160x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
1170x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
1180x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
1190x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
1200x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
1210x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
1220x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
1230x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
1240x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
1250x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
1260x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
1270x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
1280x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
1290xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
1300x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
1310x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
1320x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
1330x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
1340x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
1350x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
1360x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
1370x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
1380x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
1390x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
1400xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
1410x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
1420x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
1430x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
1440x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
1450x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
1460x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
1470x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
1480x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
1490x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
1500x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
1510x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
1520xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
1530x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
1540x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
1550x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
1560xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
1570x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
1580x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
1590x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
1600xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
1610xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
1620x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
1630x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
1640x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
1650x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
1660xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
1670x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
1680x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
1690x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
1700xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
1710x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
1720x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
1730x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
1740x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
1750x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
1760xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x94, 0x3f,
3030xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
3040x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
3050x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
3060xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
3070x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
3080x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
3090x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
3100x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
3110x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
3120xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
3130x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
3140x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
3150x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
3160x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
3170x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
3180xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
3190x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
3200xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
3210xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
3220xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
3230x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
3240x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
3250x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
3260x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70,
3270x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
3280x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
3290xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
3300x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
3310xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
3320x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
3330xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
3340xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
3350x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80,
3360xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
3370xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74,
3380x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
3390x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90,
3400x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
3410x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
3420x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
3430x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
3440x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
3450x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
3460x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
3470x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
3480x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
3490x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
3500x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
3510xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
3520x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
3530xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
3540x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
3550x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
3560x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
3570xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
3580xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
3590x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
3600x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
3610x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
3620x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
3630x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
3640x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
3650xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
3660x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
3670x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
3680x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
3690x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
3700x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
3710x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
3720x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
3730x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
3740x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
3750x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
3760x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
3770x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
3780x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
3790x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
3800x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
3810x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
3820x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
3830x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
3840x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
3850xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
3860x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
3870x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
3880x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
3890x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
3900x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
3910x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
3920x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
3930x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
3940x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
3950x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
3960xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
3970x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
3980x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3990x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
4000x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
4010x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
4020x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
4030x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
4040x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
4050x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
4060x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
4070x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
4080xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
4090x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
4100x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
4110x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
4120xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
4130x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
4140x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
4150x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
4160xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
4170xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
4180x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
4190x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
4200x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
4210x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
4220xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
4230x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
4240x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
4250x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
4260xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
4270x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
4280x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
4290x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
4300x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
4310x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
4320xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b, 0xc0, } ;
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
index a9cc7b0f3ee3..b3fb63726182 100644
--- a/drivers/staging/rt3070/md4.h
+++ b/drivers/staging/rt3070/md4.h
@@ -35,8 +35,8 @@ typedef struct _MD4_CTX_ {
35 u8 buffer[64]; /* input buffer */ 35 u8 buffer[64]; /* input buffer */
36} MD4_CTX; 36} MD4_CTX;
37 37
38void MD4Init (MD4_CTX *); 38void MD4Init(MD4_CTX *);
39void MD4Update (MD4_CTX *, u8 *, UINT); 39void MD4Update(MD4_CTX *, u8 *, UINT);
40void MD4Final (u8 [16], MD4_CTX *); 40void MD4Final(u8 [16], MD4_CTX *);
41 41
42#endif //__MD4_H__ \ No newline at end of file 42#endif /*__MD4_H__*/
diff --git a/drivers/staging/rt3090/firmware.h b/drivers/staging/rt3090/firmware.h
deleted file mode 100644
index 17056e26795b..000000000000
--- a/drivers/staging/rt3090/firmware.h
+++ /dev/null
@@ -1,517 +0,0 @@
1/* AUTO GEN PLEASE DO NOT MODIFY IT */
2/* AUTO GEN PLEASE DO NOT MODIFY IT */
3
4
5u8 FirmwareImage_3090 [] = {
60x02, 0x02, 0xf3, 0x02, 0x02, 0xa1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x27, 0xff, 0xff,
70xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xd8, 0xc0, 0xe0,
80xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
90x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
100xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x36,
110x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
120x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
130x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
140x50, 0x85, 0x36, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
150x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x36, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
160x36, 0x12, 0x02, 0x7d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
170xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
180x36, 0x12, 0x02, 0x7d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
190x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82,
200xc0, 0xd0, 0xe8, 0xc0, 0xe0, 0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0,
210xe0, 0xed, 0xc0, 0xe0, 0xee, 0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12,
220x10, 0x12, 0xd2, 0xaf, 0xd0, 0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc,
230xd0, 0xe0, 0xfb, 0xd0, 0xe0, 0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82,
240xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0,
250xd0, 0x75, 0xd0, 0x10, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5,
260x54, 0x60, 0x04, 0x15, 0x54, 0x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04,
270x15, 0x50, 0x80, 0x02, 0xc2, 0x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04,
280x30, 0x45, 0x03, 0x12, 0x10, 0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83,
290xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x43, 0xc2, 0xaf, 0x90, 0x70,
300x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
310x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x37, 0x90, 0x10, 0x1e, 0xe0,
320x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
330x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22,
340x12, 0x02, 0xc3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12,
350x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b,
360x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09,
370x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12,
380x03, 0x1c, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5,
390x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18,
400x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x1a, 0xc2, 0x18, 0xc2, 0x1b, 0x22,
410xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16,
420x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8,
430xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12,
440x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
450xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60,
460x1f, 0xe4, 0xfe, 0x12, 0x03, 0x5b, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x5b, 0xef, 0xf0, 0x74,
470x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3,
480x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
490x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0,
500xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x04, 0x12, 0x02, 0xdc, 0xe4, 0xf5,
510x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x75, 0x89, 0x02, 0xe4,
520xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75,
530xa8, 0x05, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xc0, 0xff,
540xc0, 0x26, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x0a, 0x22, 0xc0, 0x26,
550x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x18, 0x22, 0x30, 0x45, 0x03, 0x12,
560x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
570xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x71, 0x1e, 0x80, 0xf5, 0x22, 0xc8,
580xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22, 0xc8, 0xef, 0xc8,
590xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x74, 0x14, 0x2e, 0xf5, 0x82,
600xe4, 0x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x6f, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a,
610x18, 0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
620xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
630xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
640xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
650xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
660xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
670xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
680xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
690xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
700xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
710xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
720xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
730xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
740xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
750xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
760xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
770xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
780xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
790xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
800xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
810xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
820xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
830xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
840xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
850xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
860xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
870xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
880xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
890xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
900xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
910xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
920xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
930xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
940xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
950xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
960xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
970xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
980xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
990xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1000xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1010xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1020xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1030xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1040xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1050xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1060xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1070xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1080xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1100xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1110xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1120xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1130xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1140xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1150xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1160xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1170xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1180xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1190xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1200xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1210xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1220xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1230xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1240xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1250xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1260xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1270xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1280xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1290xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1300xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1310xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1320xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1330xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1340xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1350xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1360xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1370xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1380xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1390xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1400xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1410xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1420xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1430xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1440xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1450xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1460xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1470xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1480xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1490xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1500xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1510xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1520xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1530xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1540xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1550xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1560xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1570xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1580xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1590xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1600xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1610xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1620xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1630xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1640xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1650xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1660xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1670xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1680xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1690xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1700xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1710xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1720xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1730xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1740xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1750xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1760xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1770xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1780xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1790xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1800xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1810xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1820xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1830xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1840xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1850xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1860xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1870xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1880xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1890xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1900xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1910xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1920xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1930xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1940xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1950xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1960xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1970xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1980xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1990xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2000xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2010xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2020xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2030xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2040xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2050xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2060xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2070xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2080xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2100xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2110xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2120xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2130xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2140xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2150xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2160xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2170xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2180xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2190xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2200xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2210xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2220xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2230xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2240xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2250xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2260xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2270xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2280xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2290xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2300xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2310xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2320xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2330xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2340xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2350xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2360xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2370xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2380xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2390xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2400xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2410xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2420xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2430xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2440xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2450xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2460xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2470xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2480xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2490xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2500xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2510xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2520xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2530xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2540xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2550xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2560xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2570xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2580xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2590xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2600xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2610xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2620xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x13, 0x68, 0x02,
2630x13, 0x69, 0x02, 0x14, 0x1e, 0x02, 0x14, 0x1f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x19, 0xa1, 0x02,
2640x1b, 0x31, 0x02, 0x14, 0xea, 0x02, 0x14, 0x20, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x01,
2650x75, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x1c, 0x4f, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
2660x20, 0xe7, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
2670x12, 0x02, 0x57, 0x11, 0x11, 0x30, 0x10, 0xe2, 0x31, 0x10, 0x90, 0x33, 0x10, 0xa0, 0x34, 0x10,
2680xbe, 0x35, 0x10, 0xac, 0x36, 0x11, 0x1f, 0x50, 0x11, 0x68, 0x51, 0x11, 0x71, 0x52, 0x11, 0x71,
2690x53, 0x11, 0x71, 0x54, 0x11, 0xb3, 0x55, 0x12, 0x16, 0x70, 0x12, 0x42, 0x71, 0x12, 0x71, 0x72,
2700x12, 0xda, 0x73, 0x12, 0xfe, 0x80, 0x13, 0x29, 0x83, 0x13, 0x47, 0x84, 0x00, 0x00, 0x13, 0x67,
2710xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x2a, 0x75, 0x32, 0x0b, 0x75, 0x33, 0xb8, 0x02, 0x13, 0x62,
2720xc2, 0x18, 0x90, 0x01, 0x14, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x13, 0x62, 0x90, 0x70, 0x11, 0xe0,
2730xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x22, 0xe5, 0x55,
2740xb4, 0x02, 0x0f, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x7d, 0x01,
2750x80, 0x02, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
2760x13, 0x62, 0x20, 0x02, 0x03, 0x30, 0x03, 0x10, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
2770x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90,
2780x01, 0x0c, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x85, 0x56, 0x41, 0xd2, 0x02,
2790x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x67, 0xe0, 0xf5, 0x30, 0x22, 0xe5,
2800x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x10,
2810xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e,
2820x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x13,
2830x67, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x13,
2840x67, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47,
2850x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09, 0x90,
2860x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47,
2870x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8,
2880xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
2890x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13,
2900x09, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x23, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x1d, 0xe5, 0x47, 0x64,
2910x09, 0x60, 0x17, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x0b, 0xe5,
2920x47, 0x64, 0x0d, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x0d, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f,
2930xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5,
2940x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56,
2950x12, 0x02, 0x7d, 0xd2, 0x04, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60,
2960x03, 0x02, 0x13, 0x09, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8,
2970xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
2980x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09,
2990x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
3000xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13,
3010x62, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5,
3020x59, 0xe5, 0x58, 0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44,
3030x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe,
3040x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0xc2, 0x1a, 0xc2, 0x18,
3050xc2, 0x1b, 0xf5, 0x34, 0x90, 0x05, 0xa4, 0x74, 0x11, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0xa3, 0x74,
3060x03, 0xf0, 0xe4, 0xf5, 0x30, 0xc2, 0x19, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
3070x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40,
3080x06, 0xe5, 0x55, 0x60, 0x02, 0x80, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4,
3090xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x64, 0xe5, 0x34,
3100xc3, 0x94, 0x03, 0x40, 0x0b, 0xe5, 0x55, 0x60, 0x07, 0x7d, 0x03, 0xaf, 0x56, 0x02, 0x02, 0x7d,
3110x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
3120x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x39, 0xe4, 0xf5, 0x34, 0xf5, 0x30, 0x90, 0x70,
3130x10, 0xe0, 0xf4, 0x60, 0x03, 0xe0, 0xf5, 0x34, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
3140x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x1b, 0xd2, 0x19, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x1a, 0x03,
3150xe4, 0xf5, 0x2f, 0xd2, 0x04, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74,
3160x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x22, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x17,
3170xe5, 0x55, 0xb4, 0x02, 0x12, 0xe5, 0x30, 0x60, 0x0e, 0x30, 0x60, 0x0b, 0x74, 0xfd, 0x25, 0x46,
3180xf5, 0x46, 0xd2, 0x04, 0xe4, 0xf5, 0x53, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x14, 0x1d, 0x30, 0x60,
3190x21, 0xb2, 0x4d, 0x30, 0x4d, 0x1c, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x11, 0xe5, 0x55, 0xb4,
3200x02, 0x0c, 0xe5, 0x30, 0x60, 0x08, 0x74, 0x03, 0x25, 0x46, 0xf5, 0x46, 0x80, 0x02, 0x05, 0x46,
3210xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e,
3220x30, 0x1a, 0x49, 0x7f, 0x32, 0x7d, 0xb8, 0x7c, 0x0b, 0x12, 0x02, 0x30, 0x50, 0x06, 0x90, 0x04,
3230x10, 0x74, 0x40, 0xf0, 0x7f, 0x35, 0x7d, 0x32, 0x12, 0x03, 0x3f, 0x50, 0x09, 0x90, 0x10, 0x04,
3240xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5, 0x35, 0xd3, 0x94, 0x2d, 0x40, 0x30, 0x30, 0x1b, 0x2d,
3250xc2, 0x1b, 0xa2, 0x18, 0x92, 0x1a, 0x20, 0x1a, 0x24, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0,
3260x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0, 0xc2, 0x61, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2,
3270x18, 0x92, 0x1a, 0x30, 0x1a, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22,
3280xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x57, 0x14, 0x42, 0x00, 0x14, 0xd5, 0x04, 0x14,
3290xd1, 0x08, 0x14, 0xac, 0x10, 0x14, 0x56, 0x20, 0x14, 0x76, 0x60, 0x14, 0x87, 0xa0, 0x00, 0x00,
3300x14, 0xd7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60,
3310x03, 0x02, 0x14, 0xd7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4,
3320x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
3330x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5,
3340x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b,
3350xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06,
3360x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04,
3370x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75,
3380x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80,
3390x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x2a, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff,
3400xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x1a, 0x24, 0xc0,
3410x60, 0x0a, 0x24, 0x35, 0x70, 0x09, 0x12, 0x19, 0x5f, 0x12, 0x15, 0x09, 0x12, 0x19, 0x5f, 0x12,
3420x15, 0x09, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54,
3430x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2,
3440xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74, 0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f,
3450xf5, 0x2d, 0xe5, 0x2a, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5, 0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d,
3460x29, 0xe5, 0x5f, 0x54, 0x30, 0x64, 0x30, 0x70, 0x21, 0xe5, 0x2a, 0x70, 0x15, 0xe5, 0x34, 0xc3,
3470x94, 0x03, 0x40, 0x09, 0xe5, 0x30, 0x60, 0x05, 0x75, 0x2a, 0x05, 0x80, 0x07, 0x75, 0x2a, 0x0c,
3480x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2,
3490x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03, 0x70, 0x21, 0x30,
3500x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x2a, 0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2,
3510x4c, 0xe5, 0x2a, 0x70, 0x05, 0x75, 0x2a, 0x07, 0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d,
3520xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05,
3530xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a,
3540xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2,
3550x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e,
3560x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75,
3570x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x45, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
3580x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
3590xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80,
3600x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0,
3610xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73,
3620x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x45, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
3630x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
3640xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80,
3650x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0,
3660xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75,
3670x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x64, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x19, 0xe5,
3680x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x53, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30,
3690xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x45, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80,
3700x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5,
3710x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80, 0x1d,
3720xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe,
3730xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92,
3740x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30,
3750x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f,
3760xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06,
3770x70, 0x46, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60,
3780x14, 0x24, 0xfe, 0x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x19, 0x5e, 0x90, 0x02, 0x28, 0xe0,
3790x30, 0x47, 0x0d, 0x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22,
3800x44, 0x01, 0xf0, 0x22, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90,
3810x02, 0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47,
3820x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe4, 0xf5, 0x27,
3830x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e, 0x14,
3840x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5, 0x46,
3850x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80,
3860x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46, 0x30,
3870xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3,
3880x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47,
3890x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47,
3900xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39,
3910xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02,
3920x28, 0xe0, 0x54, 0xfc, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64,
3930x0b, 0x60, 0x03, 0x02, 0x18, 0xc6, 0xe4, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd, 0xf0,
3940xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24,
3950xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03,
3960x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35,
3970xa2, 0x47, 0x92, 0x39, 0x80, 0x47, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3980x39, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e,
3990x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02,
4000x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x39, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03,
4010xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x05, 0xa2, 0x47, 0xb3, 0x92, 0x39, 0x90, 0x02, 0x28,
4020xe0, 0x54, 0xfd, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0d, 0x60, 0x03, 0x02, 0x19, 0x5e, 0xf5,
4030x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xef, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e,
4040x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24, 0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5,
4050x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
4060x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35, 0xa2, 0x47, 0x92, 0x3c, 0x80, 0x47, 0xe5, 0x46,
4070x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
4080x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
4090x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92,
4100x3c, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x05,
4110xa2, 0x47, 0xb3, 0x92, 0x3c, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xef, 0x45, 0x27, 0xf0, 0x22, 0xe5,
4120x47, 0x64, 0x0b, 0x70, 0x1c, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, 0xf0, 0x30, 0x47, 0x04, 0xaf,
4130x45, 0x80, 0x05, 0xe5, 0x45, 0x64, 0x14, 0xff, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xeb, 0x4f, 0xf0,
4140x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4,
4150xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58,
4160x22, 0xe4, 0xf5, 0x37, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a, 0x14, 0x60, 0x6b, 0x24, 0x02,
4170x60, 0x03, 0x02, 0x1b, 0x12, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20, 0x1a, 0x1c, 0x90, 0x02, 0x08,
4180xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3,
4190xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x19, 0x97, 0x90, 0x10,
4200x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x1b, 0x12, 0xe5, 0x50, 0x70, 0x06, 0x75,
4210x37, 0x03, 0x02, 0x1b, 0x12, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x15, 0x7f, 0x20, 0x12,
4220x19, 0x97, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb, 0xf0, 0x75, 0x51, 0x02, 0x02,
4230x1b, 0x12, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x1b, 0x0d, 0x20, 0x1a, 0x15, 0x90, 0x02, 0x08, 0xe0,
4240x30, 0xe3, 0x03, 0x02, 0x1b, 0x09, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x1b,
4250x09, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35,
4260x10, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03,
4270xf0, 0x7f, 0x01, 0x12, 0x03, 0x30, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54,
4280xf0, 0xf0, 0xe5, 0x59, 0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3,
4290x80, 0x14, 0x90, 0x13, 0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13,
4300x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x20,
4310x1a, 0x07, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x10, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x09,
4320xe5, 0x30, 0x70, 0x05, 0x75, 0x8c, 0x40, 0x80, 0x03, 0x75, 0x8c, 0x80, 0x90, 0x04, 0x01, 0xe0,
4330x54, 0xfd, 0xf0, 0x20, 0x1a, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x59, 0xb4,
4340x28, 0x06, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x31, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x14, 0x90,
4350x01, 0x0d, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x59, 0x64, 0x35, 0x60, 0x07, 0x90, 0x12, 0x04, 0xe0,
4360x54, 0xfd, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x14, 0x20, 0x02, 0x11, 0x20, 0x03, 0x0e,
4370x90, 0x01, 0x0d, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x37,
4380x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x37, 0x03,
4390xf5, 0x51, 0xe5, 0x37, 0x60, 0x18, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x1a, 0x0e,
4400xad, 0x37, 0xaf, 0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x37, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf,
4410x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf,
4420x40, 0x12, 0x1c, 0x1b, 0xe5, 0x52, 0x14, 0x60, 0x5c, 0x14, 0x60, 0x3a, 0x24, 0x02, 0x60, 0x03,
4430x02, 0x1c, 0x18, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x02,
4440xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x13, 0x90, 0x12, 0x04,
4450xe0, 0x44, 0x02, 0xf0, 0x7f, 0x32, 0x12, 0x03, 0x30, 0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfe, 0xf0,
4460x75, 0x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0xe5, 0x31,
4470xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x19, 0x9c, 0x75, 0x52, 0x01,
4480x75, 0x55, 0x03, 0x80, 0x73, 0xe5, 0x54, 0x70, 0x6f, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0,
4490x20, 0x1a, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0xf5, 0x8c, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f,
4500xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03,
4510xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90, 0x05, 0x00, 0x74, 0xe2,
4520xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x03,
4530x30, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44,
4540x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41,
4550x12, 0x1c, 0x1b, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4,
4560xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74,
4570x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82,
4580xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x30,
4590x1a, 0x77, 0x90, 0x04, 0x37, 0xe0, 0x20, 0xe5, 0x6c, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x38, 0xa3,
4600xe0, 0xf5, 0x37, 0xf5, 0x39, 0xe4, 0xf5, 0x25, 0xe5, 0x39, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00,
4610xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x37, 0x65, 0x39, 0x70, 0x05, 0xfc, 0x7d, 0x28, 0x80,
4620x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee, 0x3c, 0xfe, 0x12, 0x1c, 0xca, 0x50, 0x07,
4630x90, 0x01, 0x14, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x39, 0x65, 0x38, 0x60, 0x10, 0xe4, 0x25, 0x39,
4640xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x39, 0x80, 0xbb, 0x90, 0x04, 0x10,
4650x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x38, 0xf0, 0xa3, 0xe5, 0x37, 0xf0, 0x90, 0x04, 0x11,
4660x74, 0x01, 0xf0, 0x80, 0x8d, 0xc2, 0x06, 0xd2, 0x1b, 0x22, 0xe5, 0x25, 0xc3, 0x94, 0x06, 0x50,
4670x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xb4, 0xff, 0x07, 0x05, 0x25, 0xe4, 0xf5, 0x24, 0x80, 0x2e,
4680xe4, 0xf5, 0x25, 0x8f, 0x82, 0x8e, 0x83, 0xf0, 0x80, 0x24, 0xe5, 0x24, 0x75, 0xf0, 0x06, 0x84,
4690x74, 0x08, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e,
4700x83, 0xe0, 0x6d, 0x70, 0x06, 0x05, 0x25, 0x05, 0x24, 0x80, 0x03, 0xe4, 0xf5, 0x25, 0x0f, 0xbf,
4710x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x07, 0xe5, 0x25, 0xc3, 0x94, 0x2a, 0x40, 0xab, 0xe5,
4720x25, 0xb4, 0x2a, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xe3, 0x34, } ;
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
index e24a6f7a0d85..155a78e07405 100644
--- a/drivers/staging/rtl8187se/Kconfig
+++ b/drivers/staging/rtl8187se/Kconfig
@@ -3,6 +3,7 @@ config R8187SE
3 depends on PCI && WLAN 3 depends on PCI && WLAN
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV 5 select WEXT_PRIV
6 select EEPROM_93CX6
6 default N 7 default N
7 ---help--- 8 ---help---
8 If built as a module, it will be called r8187se.ko. 9 If built as a module, it will be called r8187se.ko.
diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile
index b395acf5a38e..e6adf91cdd2c 100644
--- a/drivers/staging/rtl8187se/Makefile
+++ b/drivers/staging/rtl8187se/Makefile
@@ -18,7 +18,6 @@ EXTRA_CFLAGS += -DENABLE_LPS
18 18
19r8187se-objs := \ 19r8187se-objs := \
20 r8180_core.o \ 20 r8180_core.o \
21 r8180_93cx6.o \
22 r8180_wx.o \ 21 r8180_wx.o \
23 r8180_rtl8225z2.o \ 22 r8180_rtl8225z2.o \
24 r8185b_init.o \ 23 r8185b_init.o \
diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO
index a762e79873e9..704949a9da0d 100644
--- a/drivers/staging/rtl8187se/TODO
+++ b/drivers/staging/rtl8187se/TODO
@@ -5,7 +5,6 @@ TODO:
5- switch to use shared "librtl" instead of private ieee80211 stack 5- switch to use shared "librtl" instead of private ieee80211 stack
6- switch to use LIB80211 6- switch to use LIB80211
7- switch to use MAC80211 7- switch to use MAC80211
8- switch to use EEPROM_93CX6
9- use kernel coding style 8- use kernel coding style
10- checkpatch.pl fixes 9- checkpatch.pl fixes
11- sparse fixes 10- sparse fixes
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
index 9086047c32d4..4cd95c3dc947 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -29,6 +29,7 @@
29#include <linux/jiffies.h> 29#include <linux/jiffies.h>
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/semaphore.h>
32#include <linux/wireless.h> 33#include <linux/wireless.h>
33#include <linux/ieee80211.h> 34#include <linux/ieee80211.h>
34 35
@@ -161,10 +162,6 @@ do { if (ieee80211_debug_level & (level)) \
161#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) 162#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
162#endif /* CONFIG_IEEE80211_DEBUG */ 163#endif /* CONFIG_IEEE80211_DEBUG */
163 164
164#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
165#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
166 ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
167
168/* 165/*
169 * To use the debug system; 166 * To use the debug system;
170 * 167 *
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
index 172e8f3ae6c1..40f1b99faad2 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
@@ -285,7 +285,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
285 if (!(keyidx & (1 << 5))) { 285 if (!(keyidx & (1 << 5))) {
286 if (net_ratelimit()) { 286 if (net_ratelimit()) {
287 printk(KERN_DEBUG "CCMP: received packet without ExtIV" 287 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
288 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 288 " flag from %pM\n", hdr->addr2);
289 } 289 }
290 key->dot11RSNAStatsCCMPFormatErrors++; 290 key->dot11RSNAStatsCCMPFormatErrors++;
291 return -2; 291 return -2;
@@ -298,9 +298,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
298 } 298 }
299 if (!key->key_set) { 299 if (!key->key_set) {
300 if (net_ratelimit()) { 300 if (net_ratelimit()) {
301 printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT 301 printk(KERN_DEBUG "CCMP: received packet from %pM"
302 " with keyid=%d that does not have a configured" 302 " with keyid=%d that does not have a configured"
303 " key\n", MAC_ARG(hdr->addr2), keyidx); 303 " key\n", hdr->addr2, keyidx);
304 } 304 }
305 return -3; 305 return -3;
306 } 306 }
@@ -315,11 +315,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
315 315
316 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { 316 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
317 if (net_ratelimit()) { 317 if (net_ratelimit()) {
318 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT 318 printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
319 " previous PN %02x%02x%02x%02x%02x%02x " 319 " previous PN %pm received PN %pm\n",
320 "received PN %02x%02x%02x%02x%02x%02x\n", 320 hdr->addr2, key->rx_pn, pn);
321 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
322 MAC_ARG(pn));
323 } 321 }
324 key->dot11RSNAStatsCCMPReplays++; 322 key->dot11RSNAStatsCCMPReplays++;
325 return -4; 323 return -4;
@@ -347,7 +345,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
347 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { 345 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
348 if (net_ratelimit()) { 346 if (net_ratelimit()) {
349 printk(KERN_DEBUG "CCMP: decrypt failed: STA=" 347 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
350 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 348 "%pM\n", hdr->addr2);
351 } 349 }
352 key->dot11RSNAStatsCCMPDecryptErrors++; 350 key->dot11RSNAStatsCCMPDecryptErrors++;
353 return -5; 351 return -5;
@@ -423,11 +421,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
423{ 421{
424 struct ieee80211_ccmp_data *ccmp = priv; 422 struct ieee80211_ccmp_data *ccmp = priv;
425 p += sprintf(p, "key[%d] alg=CCMP key_set=%d " 423 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
426 "tx_pn=%02x%02x%02x%02x%02x%02x " 424 "tx_pn=%pm rx_pn=%pm "
427 "rx_pn=%02x%02x%02x%02x%02x%02x "
428 "format_errors=%d replays=%d decrypt_errors=%d\n", 425 "format_errors=%d replays=%d decrypt_errors=%d\n",
429 ccmp->key_idx, ccmp->key_set, 426 ccmp->key_idx, ccmp->key_set,
430 MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), 427 ccmp->tx_pn, ccmp->rx_pn,
431 ccmp->dot11RSNAStatsCCMPFormatErrors, 428 ccmp->dot11RSNAStatsCCMPFormatErrors,
432 ccmp->dot11RSNAStatsCCMPReplays, 429 ccmp->dot11RSNAStatsCCMPReplays,
433 ccmp->dot11RSNAStatsCCMPDecryptErrors); 430 ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
index e6d8385e1d88..a5254111d9a1 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
@@ -385,7 +385,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
385 if (!(keyidx & (1 << 5))) { 385 if (!(keyidx & (1 << 5))) {
386 if (net_ratelimit()) { 386 if (net_ratelimit()) {
387 printk(KERN_DEBUG "TKIP: received packet without ExtIV" 387 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
388 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 388 " flag from %pM\n", hdr->addr2);
389 } 389 }
390 return -2; 390 return -2;
391 } 391 }
@@ -397,9 +397,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
397 } 397 }
398 if (!tkey->key_set) { 398 if (!tkey->key_set) {
399 if (net_ratelimit()) { 399 if (net_ratelimit()) {
400 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT 400 printk(KERN_DEBUG "TKIP: received packet from %pM"
401 " with keyid=%d that does not have a configured" 401 " with keyid=%d that does not have a configured"
402 " key\n", MAC_ARG(hdr->addr2), keyidx); 402 " key\n", hdr->addr2, keyidx);
403 } 403 }
404 return -3; 404 return -3;
405 } 405 }
@@ -410,9 +410,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
410 if (iv32 < tkey->rx_iv32 || 410 if (iv32 < tkey->rx_iv32 ||
411 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { 411 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
412 if (net_ratelimit()) { 412 if (net_ratelimit()) {
413 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT 413 printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
414 " previous TSC %08x%04x received TSC " 414 " previous TSC %08x%04x received TSC "
415 "%08x%04x\n", MAC_ARG(hdr->addr2), 415 "%08x%04x\n", hdr->addr2,
416 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); 416 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
417 } 417 }
418 tkey->dot11RSNAStatsTKIPReplays++; 418 tkey->dot11RSNAStatsTKIPReplays++;
@@ -431,8 +431,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
431 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { 431 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
432 if (net_ratelimit()) { 432 if (net_ratelimit()) {
433 printk(KERN_DEBUG ": TKIP: failed to decrypt " 433 printk(KERN_DEBUG ": TKIP: failed to decrypt "
434 "received packet from " MAC_FMT "\n", 434 "received packet from %pM\n",
435 MAC_ARG(hdr->addr2)); 435 hdr->addr2);
436 } 436 }
437 return -7; 437 return -7;
438 } 438 }
@@ -450,7 +450,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
450 } 450 }
451 if (net_ratelimit()) { 451 if (net_ratelimit()) {
452 printk(KERN_DEBUG "TKIP: ICV error detected: STA=" 452 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
453 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 453 "%pM\n", hdr->addr2);
454 } 454 }
455 tkey->dot11RSNAStatsTKIPICVErrors++; 455 tkey->dot11RSNAStatsTKIPICVErrors++;
456 return -5; 456 return -5;
@@ -604,8 +604,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
604 struct ieee80211_hdr_4addr *hdr; 604 struct ieee80211_hdr_4addr *hdr;
605 hdr = (struct ieee80211_hdr_4addr *)skb->data; 605 hdr = (struct ieee80211_hdr_4addr *)skb->data;
606 printk(KERN_DEBUG "%s: Michael MIC verification failed for " 606 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
607 "MSDU from " MAC_FMT " keyidx=%d\n", 607 "MSDU from %pM keyidx=%d\n",
608 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), 608 skb->dev ? skb->dev->name : "N/A", hdr->addr2,
609 keyidx); 609 keyidx);
610 if (skb->dev) 610 if (skb->dev)
611 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); 611 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
index 9128c181bc7d..2b7080cc2c05 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -311,8 +311,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
311 strcmp(crypt->ops->name, "TKIP") == 0) { 311 strcmp(crypt->ops->name, "TKIP") == 0) {
312 if (net_ratelimit()) { 312 if (net_ratelimit()) {
313 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 313 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
314 "received packet from " MAC_FMT "\n", 314 "received packet from %pM\n",
315 ieee->dev->name, MAC_ARG(hdr->addr2)); 315 ieee->dev->name, hdr->addr2);
316 } 316 }
317 return -1; 317 return -1;
318 } 318 }
@@ -323,8 +323,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
323 atomic_dec(&crypt->refcnt); 323 atomic_dec(&crypt->refcnt);
324 if (res < 0) { 324 if (res < 0) {
325 IEEE80211_DEBUG_DROP( 325 IEEE80211_DEBUG_DROP(
326 "decryption failed (SA=" MAC_FMT 326 "decryption failed (SA=%pM"
327 ") res=%d\n", MAC_ARG(hdr->addr2), res); 327 ") res=%d\n", hdr->addr2, res);
328 if (res == -2) 328 if (res == -2)
329 IEEE80211_DEBUG_DROP("Decryption failed ICV " 329 IEEE80211_DEBUG_DROP("Decryption failed ICV "
330 "mismatch (key %d)\n", 330 "mismatch (key %d)\n",
@@ -356,8 +356,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
356 atomic_dec(&crypt->refcnt); 356 atomic_dec(&crypt->refcnt);
357 if (res < 0) { 357 if (res < 0) {
358 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" 358 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
359 " (SA=" MAC_FMT " keyidx=%d)\n", 359 " (SA=%pM keyidx=%d)\n",
360 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); 360 ieee->dev->name, hdr->addr2, keyidx);
361 return -1; 361 return -1;
362 } 362 }
363 363
@@ -550,8 +550,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
550 * frames silently instead of filling system log with 550 * frames silently instead of filling system log with
551 * these reports. */ 551 * these reports. */
552 IEEE80211_DEBUG_DROP("Decryption failed (not set)" 552 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
553 " (SA=" MAC_FMT ")\n", 553 " (SA=%pM)\n",
554 MAC_ARG(hdr->addr2)); 554 hdr->addr2);
555 ieee->ieee_stats.rx_discards_undecryptable++; 555 ieee->ieee_stats.rx_discards_undecryptable++;
556 goto rx_dropped; 556 goto rx_dropped;
557 } 557 }
@@ -709,8 +709,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
709 } else { 709 } else {
710 IEEE80211_DEBUG_DROP( 710 IEEE80211_DEBUG_DROP(
711 "encryption configured, but RX " 711 "encryption configured, but RX "
712 "frame not encrypted (SA=" MAC_FMT ")\n", 712 "frame not encrypted (SA=%pM)\n",
713 MAC_ARG(hdr->addr2)); 713 hdr->addr2);
714 goto rx_dropped; 714 goto rx_dropped;
715 } 715 }
716 } 716 }
@@ -729,9 +729,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
729 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { 729 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
730 IEEE80211_DEBUG_DROP( 730 IEEE80211_DEBUG_DROP(
731 "dropped unencrypted RX data " 731 "dropped unencrypted RX data "
732 "frame from " MAC_FMT 732 "frame from %pM"
733 " (drop_unencrypted=1)\n", 733 " (drop_unencrypted=1)\n",
734 MAC_ARG(hdr->addr2)); 734 hdr->addr2);
735 goto rx_dropped; 735 goto rx_dropped;
736 } 736 }
737/* 737/*
@@ -1196,11 +1196,11 @@ inline int ieee80211_network_init(
1196 } 1196 }
1197 1197
1198 if (network->mode == 0) { 1198 if (network->mode == 0) {
1199 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " 1199 IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
1200 "network.\n", 1200 "network.\n",
1201 escape_essid(network->ssid, 1201 escape_essid(network->ssid,
1202 network->ssid_len), 1202 network->ssid_len),
1203 MAC_ARG(network->bssid)); 1203 network->bssid);
1204 return 1; 1204 return 1;
1205 } 1205 }
1206 1206
@@ -1341,9 +1341,9 @@ inline void ieee80211_process_probe_response(
1341 memset(&network, 0, sizeof(struct ieee80211_network)); 1341 memset(&network, 0, sizeof(struct ieee80211_network));
1342 1342
1343 IEEE80211_DEBUG_SCAN( 1343 IEEE80211_DEBUG_SCAN(
1344 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", 1344 "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1345 escape_essid(info_element->data, info_element->len), 1345 escape_essid(info_element->data, info_element->len),
1346 MAC_ARG(beacon->header.addr3), 1346 beacon->header.addr3,
1347 (beacon->capability & (1<<0xf)) ? '1' : '0', 1347 (beacon->capability & (1<<0xf)) ? '1' : '0',
1348 (beacon->capability & (1<<0xe)) ? '1' : '0', 1348 (beacon->capability & (1<<0xe)) ? '1' : '0',
1349 (beacon->capability & (1<<0xd)) ? '1' : '0', 1349 (beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -1362,10 +1362,10 @@ inline void ieee80211_process_probe_response(
1362 (beacon->capability & (1<<0x0)) ? '1' : '0'); 1362 (beacon->capability & (1<<0x0)) ? '1' : '0');
1363 1363
1364 if (ieee80211_network_init(ieee, beacon, &network, stats)) { 1364 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
1365 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", 1365 IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
1366 escape_essid(info_element->data, 1366 escape_essid(info_element->data,
1367 info_element->len), 1367 info_element->len),
1368 MAC_ARG(beacon->header.addr3), 1368 beacon->header.addr3,
1369 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 1369 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1370 IEEE80211_STYPE_PROBE_RESP ? 1370 IEEE80211_STYPE_PROBE_RESP ?
1371 "PROBE RESPONSE" : "BEACON"); 1371 "PROBE RESPONSE" : "BEACON");
@@ -1464,11 +1464,11 @@ inline void ieee80211_process_probe_response(
1464 /* If there are no more slots, expire the oldest */ 1464 /* If there are no more slots, expire the oldest */
1465 list_del(&oldest->list); 1465 list_del(&oldest->list);
1466 target = oldest; 1466 target = oldest;
1467 IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " 1467 IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
1468 "network list.\n", 1468 "network list.\n",
1469 escape_essid(target->ssid, 1469 escape_essid(target->ssid,
1470 target->ssid_len), 1470 target->ssid_len),
1471 MAC_ARG(target->bssid)); 1471 target->bssid);
1472 } else { 1472 } else {
1473 /* Otherwise just pull from the free list */ 1473 /* Otherwise just pull from the free list */
1474 target = list_entry(ieee->network_free_list.next, 1474 target = list_entry(ieee->network_free_list.next,
@@ -1478,10 +1478,10 @@ inline void ieee80211_process_probe_response(
1478 1478
1479 1479
1480#ifdef CONFIG_IEEE80211_DEBUG 1480#ifdef CONFIG_IEEE80211_DEBUG
1481 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", 1481 IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
1482 escape_essid(network.ssid, 1482 escape_essid(network.ssid,
1483 network.ssid_len), 1483 network.ssid_len),
1484 MAC_ARG(network.bssid), 1484 network.bssid,
1485 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 1485 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1486 IEEE80211_STYPE_PROBE_RESP ? 1486 IEEE80211_STYPE_PROBE_RESP ?
1487 "PROBE RESPONSE" : "BEACON"); 1487 "PROBE RESPONSE" : "BEACON");
@@ -1492,10 +1492,10 @@ inline void ieee80211_process_probe_response(
1492 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) 1492 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
1493 ieee80211_softmac_new_net(ieee,&network); 1493 ieee80211_softmac_new_net(ieee,&network);
1494 } else { 1494 } else {
1495 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", 1495 IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
1496 escape_essid(target->ssid, 1496 escape_essid(target->ssid,
1497 target->ssid_len), 1497 target->ssid_len),
1498 MAC_ARG(target->bssid), 1498 target->bssid,
1499 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 1499 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1500 IEEE80211_STYPE_PROBE_RESP ? 1500 IEEE80211_STYPE_PROBE_RESP ?
1501 "PROBE RESPONSE" : "BEACON"); 1501 "PROBE RESPONSE" : "BEACON");
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index a2150670ef56..c2f472ee6eb6 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -1573,7 +1573,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1573 ieee80211_resp_to_assoc_rq(ieee, dest); 1573 ieee80211_resp_to_assoc_rq(ieee, dest);
1574 } 1574 }
1575 1575
1576 printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); 1576 printk(KERN_INFO"New client associated: %pM\n", dest);
1577} 1577}
1578 1578
1579 1579
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
index f1d6cb452563..ad42bcdc9374 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
@@ -482,8 +482,7 @@ int ieee80211_wx_set_power(struct ieee80211_device *ieee,
482 (!ieee->enter_sleep_state) || 482 (!ieee->enter_sleep_state) ||
483 (!ieee->ps_is_queue_empty)){ 483 (!ieee->ps_is_queue_empty)){
484 484
485 printk("ERROR. PS mode is tryied to be use but\ 485 printk("ERROR. PS mode tried to be use but driver missed a callback\n\n");
486driver missed a callback\n\n");
487 486
488 return -1; 487 return -1;
489 } 488 }
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
index 69bd02164b0c..6cb31e1760ac 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
@@ -198,8 +198,8 @@ int ieee80211_encrypt_fragment(
198 header = (struct ieee80211_hdr_4addr *)frag->data; 198 header = (struct ieee80211_hdr_4addr *)frag->data;
199 if (net_ratelimit()) { 199 if (net_ratelimit()) {
200 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 200 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
201 "TX packet to " MAC_FMT "\n", 201 "TX packet to %pM\n",
202 ieee->dev->name, MAC_ARG(header->addr1)); 202 ieee->dev->name, header->addr1);
203 } 203 }
204 return -1; 204 return -1;
205 } 205 }
@@ -407,7 +407,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb,
407 memcpy(&header.addr2, src, ETH_ALEN); 407 memcpy(&header.addr2, src, ETH_ALEN);
408 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); 408 memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
409 } 409 }
410 // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1)); 410 // printk(KERN_WARNING "essid MAC address is %pM", &header.addr1);
411 header.frame_ctl = cpu_to_le16(fc); 411 header.frame_ctl = cpu_to_le16(fc);
412 //hdr_len = IEEE80211_3ADDR_LEN; 412 //hdr_len = IEEE80211_3ADDR_LEN;
413 413
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index 6aad48fe2e18..bd5e77bf7162 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -234,10 +234,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
234 else 234 else
235 IEEE80211_DEBUG_SCAN( 235 IEEE80211_DEBUG_SCAN(
236 "Not showing network '%s (" 236 "Not showing network '%s ("
237 MAC_FMT ")' due to age (%lums).\n", 237 "%pM)' due to age (%lums).\n",
238 escape_essid(network->ssid, 238 escape_essid(network->ssid,
239 network->ssid_len), 239 network->ssid_len),
240 MAC_ARG(network->bssid), 240 network->bssid,
241 (jiffies - network->last_scanned) / (HZ / 100)); 241 (jiffies - network->last_scanned) / (HZ / 100));
242 } 242 }
243 } 243 }
@@ -694,7 +694,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
694#if 1 694#if 1
695 case IW_AUTH_WPA_ENABLED: 695 case IW_AUTH_WPA_ENABLED:
696 ieee->wpa_enabled = (data->value)?1:0; 696 ieee->wpa_enabled = (data->value)?1:0;
697 //printk("enalbe wpa:%d\n", ieee->wpa_enabled); 697 //printk("enable wpa:%d\n", ieee->wpa_enabled);
698 break; 698 break;
699 699
700#endif 700#endif
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
index ce828885b64f..d15bdf64efd0 100644
--- a/drivers/staging/rtl8187se/r8180.h
+++ b/drivers/staging/rtl8187se/r8180.h
@@ -366,7 +366,6 @@ typedef struct r8180_priv
366 short diversity; 366 short diversity;
367 u8 cs_treshold; 367 u8 cs_treshold;
368 short rcr_csense; 368 short rcr_csense;
369 short rf_chip;
370 u32 key0[4]; 369 u32 key0[4];
371 short (*rf_set_sens)(struct net_device *dev,short sens); 370 short (*rf_set_sens)(struct net_device *dev,short sens);
372 void (*rf_set_chan)(struct net_device *dev,short ch); 371 void (*rf_set_chan)(struct net_device *dev,short ch);
@@ -479,9 +478,6 @@ typedef struct r8180_priv
479 u8 retry_rts; 478 u8 retry_rts;
480 u16 rts; 479 u16 rts;
481 480
482//add for RF power on power off by lizhaoming 080512
483 u8 RegThreeWireMode; // See "Three wire mode" defined above, 2006.05.31, by rcnjko.
484
485//by amy for led 481//by amy for led
486 LED_STRATEGY_8185 LedStrategy; 482 LED_STRATEGY_8185 LedStrategy;
487//by amy for led 483//by amy for led
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.c b/drivers/staging/rtl8187se/r8180_93cx6.c
deleted file mode 100644
index 7e4711fb930c..000000000000
--- a/drivers/staging/rtl8187se/r8180_93cx6.c
+++ /dev/null
@@ -1,146 +0,0 @@
1/*
2 This files contains card eeprom (93c46 or 93c56) programming routines,
3 memory is addressed by 16 bits words.
4
5 This is part of rtl8180 OpenSource driver.
6 Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
7 Released under the terms of GPL (General Public Licence)
8
9 Parts of this driver are based on the GPL part of the
10 official realtek driver.
11
12 Parts of this driver are based on the rtl8180 driver skeleton
13 from Patric Schenke & Andres Salomon.
14
15 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
16
17 We want to tanks the Authors of those projects and the Ndiswrapper
18 project Authors.
19*/
20
21#include "r8180_93cx6.h"
22
23void eprom_cs(struct net_device *dev, short bit)
24{
25 if(bit)
26 write_nic_byte(dev, EPROM_CMD,
27 (1<<EPROM_CS_SHIFT) | \
28 read_nic_byte(dev, EPROM_CMD)); //enable EPROM
29 else
30 write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
31 &~(1<<EPROM_CS_SHIFT)); //disable EPROM
32
33 force_pci_posting(dev);
34 udelay(EPROM_DELAY);
35}
36
37
38void eprom_ck_cycle(struct net_device *dev)
39{
40 write_nic_byte(dev, EPROM_CMD,
41 (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
42 force_pci_posting(dev);
43 udelay(EPROM_DELAY);
44 write_nic_byte(dev, EPROM_CMD,
45 read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
46 force_pci_posting(dev);
47 udelay(EPROM_DELAY);
48}
49
50
51void eprom_w(struct net_device *dev,short bit)
52{
53 if(bit)
54 write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
55 read_nic_byte(dev,EPROM_CMD));
56 else
57 write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
58 &~(1<<EPROM_W_SHIFT));
59
60 force_pci_posting(dev);
61 udelay(EPROM_DELAY);
62}
63
64
65short eprom_r(struct net_device *dev)
66{
67 short bit;
68
69 bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
70 udelay(EPROM_DELAY);
71
72 if(bit) return 1;
73 return 0;
74}
75
76
77void eprom_send_bits_string(struct net_device *dev, short b[], int len)
78{
79 int i;
80
81 for(i=0; i<len; i++){
82 eprom_w(dev, b[i]);
83 eprom_ck_cycle(dev);
84 }
85}
86
87
88u32 eprom_read(struct net_device *dev, u32 addr)
89{
90 struct r8180_priv *priv = ieee80211_priv(dev);
91 short read_cmd[]={1,1,0};
92 short addr_str[8];
93 int i;
94 int addr_len;
95 u32 ret;
96
97 ret=0;
98 //enable EPROM programming
99 write_nic_byte(dev, EPROM_CMD,
100 (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
101 force_pci_posting(dev);
102 udelay(EPROM_DELAY);
103
104 if (priv->epromtype==EPROM_93c56){
105 addr_str[7]=addr & 1;
106 addr_str[6]=addr & (1<<1);
107 addr_str[5]=addr & (1<<2);
108 addr_str[4]=addr & (1<<3);
109 addr_str[3]=addr & (1<<4);
110 addr_str[2]=addr & (1<<5);
111 addr_str[1]=addr & (1<<6);
112 addr_str[0]=addr & (1<<7);
113 addr_len=8;
114 }else{
115 addr_str[5]=addr & 1;
116 addr_str[4]=addr & (1<<1);
117 addr_str[3]=addr & (1<<2);
118 addr_str[2]=addr & (1<<3);
119 addr_str[1]=addr & (1<<4);
120 addr_str[0]=addr & (1<<5);
121 addr_len=6;
122 }
123 eprom_cs(dev, 1);
124 eprom_ck_cycle(dev);
125 eprom_send_bits_string(dev, read_cmd, 3);
126 eprom_send_bits_string(dev, addr_str, addr_len);
127
128 //keep chip pin D to low state while reading.
129 //I'm unsure if it is necessary, but anyway shouldn't hurt
130 eprom_w(dev, 0);
131
132 for(i=0;i<16;i++){
133 //eeprom needs a clk cycle between writing opcode&adr
134 //and reading data. (eeprom outs a dummy 0)
135 eprom_ck_cycle(dev);
136 ret |= (eprom_r(dev)<<(15-i));
137 }
138
139 eprom_cs(dev, 0);
140 eprom_ck_cycle(dev);
141
142 //disable EPROM programming
143 write_nic_byte(dev, EPROM_CMD,
144 (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
145 return ret;
146}
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h
index 36ae100f3f16..79e7391ac881 100644
--- a/drivers/staging/rtl8187se/r8180_93cx6.h
+++ b/drivers/staging/rtl8187se/r8180_93cx6.h
@@ -45,13 +45,10 @@
45 45
46#define EPROM_TXPW_OFDM_CH1_2 0x20 46#define EPROM_TXPW_OFDM_CH1_2 0x20
47 47
48//#define EPROM_TXPW_CH1_2 0x10 48#define EPROM_TXPW_CH1_2 0x30
49#define EPROM_TXPW_CH1_2 0x30 49
50#define EPROM_TXPW_CH3_4 0x11 50#define RTL818X_EEPROM_CMD_READ (1 << 0)
51#define EPROM_TXPW_CH5_6 0x12 51#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
52#define EPROM_TXPW_CH7_8 0x13 52#define RTL818X_EEPROM_CMD_CK (1 << 2)
53#define EPROM_TXPW_CH9_10 0x14 53#define RTL818X_EEPROM_CMD_CS (1 << 3)
54#define EPROM_TXPW_CH11_12 0x15 54
55#define EPROM_TXPW_CH13_14 0x16
56
57u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 1847f38b9f22..b1757acabedc 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -31,6 +31,7 @@
31#undef DUMMY_RX 31#undef DUMMY_RX
32 32
33#include <linux/syscalls.h> 33#include <linux/syscalls.h>
34#include <linux/eeprom_93cx6.h>
34 35
35#include "r8180_hw.h" 36#include "r8180_hw.h"
36#include "r8180.h" 37#include "r8180.h"
@@ -41,13 +42,6 @@
41 42
42#include "ieee80211/dot11d.h" 43#include "ieee80211/dot11d.h"
43 44
44#ifndef PCI_VENDOR_ID_BELKIN
45 #define PCI_VENDOR_ID_BELKIN 0x1799
46#endif
47#ifndef PCI_VENDOR_ID_DLINK
48 #define PCI_VENDOR_ID_DLINK 0x1186
49#endif
50
51static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = { 45static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
52 { 46 {
53 .vendor = PCI_VENDOR_ID_REALTEK, 47 .vendor = PCI_VENDOR_ID_REALTEK,
@@ -669,11 +663,8 @@ unsigned char STRENGTH_MAP[] = {
669 663
670void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual) 664void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual)
671{ 665{
672 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
673 u32 temp; 666 u32 temp;
674 u32 temp2; 667 u32 temp2;
675 u32 temp3;
676 u32 lsb;
677 u32 q; 668 u32 q;
678 u32 orig_qual; 669 u32 orig_qual;
679 u8 _rssi; 670 u8 _rssi;
@@ -695,88 +686,6 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual)
695 *qual = temp; 686 *qual = temp;
696 temp2 = *rssi; 687 temp2 = *rssi;
697 688
698 switch(priv->rf_chip){
699 case RFCHIPID_RFMD:
700 lsb = temp2 & 1;
701 temp2 &= 0x7e;
702 if ( !lsb || !(temp2 <= 0x3c) ) {
703 temp2 = 0x64;
704 } else {
705 temp2 = 100 * temp2 / 0x3c;
706 }
707 *rssi = temp2 & 0xff;
708 _rssi = temp2 & 0xff;
709 break;
710 case RFCHIPID_INTERSIL:
711 lsb = temp2;
712 temp2 &= 0xfffffffe;
713 temp2 *= 251;
714 temp3 = temp2;
715 temp2 <<= 6;
716 temp3 += temp2;
717 temp3 <<= 1;
718 temp2 = 0x4950df;
719 temp2 -= temp3;
720 lsb &= 1;
721 if ( temp2 <= 0x3e0000 ) {
722 if ( temp2 < 0xffef0000 )
723 temp2 = 0xffef0000;
724 } else {
725 temp2 = 0x3e0000;
726 }
727 if ( !lsb ) {
728 temp2 -= 0xf0000;
729 } else {
730 temp2 += 0xf0000;
731 }
732
733 temp3 = 0x4d0000;
734 temp3 -= temp2;
735 temp3 *= 100;
736 temp3 = temp3 / 0x6d;
737 temp3 >>= 0x10;
738 _rssi = temp3 & 0xff;
739 *rssi = temp3 & 0xff;
740 break;
741 case RFCHIPID_GCT:
742 lsb = temp2 & 1;
743 temp2 &= 0x7e;
744 if ( ! lsb || !(temp2 <= 0x3c) ){
745 temp2 = 0x64;
746 } else {
747 temp2 = (100 * temp2) / 0x3c;
748 }
749 *rssi = temp2 & 0xff;
750 _rssi = temp2 & 0xff;
751 break;
752 case RFCHIPID_PHILIPS:
753 if( orig_qual <= 0x4e ){
754 _rssi = STRENGTH_MAP[orig_qual];
755 *rssi = _rssi;
756 } else {
757 orig_qual -= 0x80;
758 if ( !orig_qual ){
759 _rssi = 1;
760 *rssi = 1;
761 } else {
762 _rssi = 0x32;
763 *rssi = 0x32;
764 }
765 }
766 break;
767 case RFCHIPID_MAXIM:
768 lsb = temp2 & 1;
769 temp2 &= 0x7e;
770 temp2 >>= 1;
771 temp2 += 0x42;
772 if( lsb != 0 ){
773 temp2 += 0xa;
774 }
775 *rssi = temp2 & 0xff;
776 _rssi = temp2 & 0xff;
777 break;
778 }
779
780 if ( _rssi < 0x64 ){ 689 if ( _rssi < 0x64 ){
781 if ( _rssi == 0 ) { 690 if ( _rssi == 0 ) {
782 *rssi = 1; 691 *rssi = 1;
@@ -1421,11 +1330,9 @@ u16 N_DBPSOfRate(u16 DataRate)
1421 return N_DBPS; 1330 return N_DBPS;
1422} 1331}
1423 1332
1424//{by amy 080312
1425// 1333//
1426// Description: 1334// Description:
1427// For Netgear case, they want good-looking singal strength. 1335// For Netgear case, they want good-looking singal strength.
1428// 2004.12.05, by rcnjko.
1429// 1336//
1430long NetgearSignalStrengthTranslate(long LastSS, long CurrSS) 1337long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
1431{ 1338{
@@ -1481,7 +1388,6 @@ long TranslateToDbm8185(u8 SignalStrengthIndex)
1481// This is different with PerformSignalSmoothing8185 in smoothing fomula. 1388// This is different with PerformSignalSmoothing8185 in smoothing fomula.
1482// No dramatic adjustion is apply because dynamic mechanism need some degree 1389// No dramatic adjustion is apply because dynamic mechanism need some degree
1483// of correctness. Ported from 8187B. 1390// of correctness. Ported from 8187B.
1484// 2007-02-26, by Bruce.
1485// 1391//
1486void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv, 1392void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
1487 bool bCckRate) 1393 bool bCckRate)
@@ -1502,7 +1408,6 @@ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
1502 priv->CurCCKRSSI = 0; 1408 priv->CurCCKRSSI = 0;
1503} 1409}
1504 1410
1505//by amy 080312}
1506 1411
1507/* This is rough RX isr handling routine*/ 1412/* This is rough RX isr handling routine*/
1508void rtl8180_rx(struct net_device *dev) 1413void rtl8180_rx(struct net_device *dev)
@@ -1638,7 +1543,7 @@ void rtl8180_rx(struct net_device *dev)
1638 } 1543 }
1639 1544
1640 signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16); 1545 signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16);
1641 signal=(signal&0xfe)>>1; // Modify by hikaru 6.6 1546 signal = (signal & 0xfe) >> 1;
1642 1547
1643 quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff)); 1548 quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff));
1644 1549
@@ -1652,7 +1557,6 @@ void rtl8180_rx(struct net_device *dev)
1652 1557
1653 stats.rate = rtl8180_rate2rate(rate); 1558 stats.rate = rtl8180_rate2rate(rate);
1654 Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ; 1559 Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ;
1655//by amy for antenna
1656 if(!rtl8180_IsWirelessBMode(stats.rate)) 1560 if(!rtl8180_IsWirelessBMode(stats.rate))
1657 { // OFDM rate. 1561 { // OFDM rate.
1658 1562
@@ -1691,11 +1595,10 @@ void rtl8180_rx(struct net_device *dev)
1691 RXAGC=(95-RXAGC)*100/65; 1595 RXAGC=(95-RXAGC)*100/65;
1692 } 1596 }
1693 priv->SignalStrength = (u8)RXAGC; 1597 priv->SignalStrength = (u8)RXAGC;
1694 priv->RecvSignalPower = RxAGC_dBm ; // It can use directly by SD3 CMLin 1598 priv->RecvSignalPower = RxAGC_dBm;
1695 priv->RxPower = rxpower; 1599 priv->RxPower = rxpower;
1696 priv->RSSI = RSSI; 1600 priv->RSSI = RSSI;
1697//{by amy 080312 1601 /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */
1698 // SQ translation formular is provided by SD3 DZ. 2006.06.27, by rcnjko.
1699 if(quality >= 127) 1602 if(quality >= 127)
1700 quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now; 1603 quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now;
1701 else if(quality < 27) 1604 else if(quality < 27)
@@ -1712,7 +1615,6 @@ void rtl8180_rx(struct net_device *dev)
1712 // printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength); 1615 // printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength);
1713 stats.rssi = priv->wstats.qual.qual = priv->SignalQuality; 1616 stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
1714 stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual; 1617 stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
1715//by amy 080312}
1716 bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 ) 1618 bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 )
1717 | (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 ); 1619 | (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 );
1718 bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13; 1620 bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
@@ -1725,11 +1627,12 @@ void rtl8180_rx(struct net_device *dev)
1725 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) 1627 (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
1726 && (!bHwError) && (!bCRC)&& (!bICV)) 1628 && (!bHwError) && (!bCRC)&& (!bICV))
1727 { 1629 {
1728//by amy 080312 1630 /* Perform signal smoothing for dynamic
1729 // Perform signal smoothing for dynamic mechanism on demand. 1631 * mechanism on demand. This is different
1730 // This is different with PerformSignalSmoothing8185 in smoothing fomula. 1632 * with PerformSignalSmoothing8185 in smoothing
1731 // No dramatic adjustion is apply because dynamic mechanism need some degree 1633 * fomula. No dramatic adjustion is apply
1732 // of correctness. 2007.01.23, by shien chang. 1634 * because dynamic mechanism need some degree
1635 * of correctness. */
1733 PerformUndecoratedSignalSmoothing8185(priv,bCckRate); 1636 PerformUndecoratedSignalSmoothing8185(priv,bCckRate);
1734 // 1637 //
1735 // For good-looking singal strength. 1638 // For good-looking singal strength.
@@ -1749,12 +1652,9 @@ void rtl8180_rx(struct net_device *dev)
1749 1652
1750 // Figure out which antenna that received the lasted packet. 1653 // Figure out which antenna that received the lasted packet.
1751 priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main. 1654 priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main.
1752//by amy 080312
1753 SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); 1655 SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
1754 } 1656 }
1755 1657
1756//by amy for antenna
1757#ifndef DUMMY_RX
1758 if(first){ 1658 if(first){
1759 if(!priv->rx_skb_complete){ 1659 if(!priv->rx_skb_complete){
1760 /* seems that HW sometimes fails to reiceve and 1660 /* seems that HW sometimes fails to reiceve and
@@ -1810,19 +1710,12 @@ void rtl8180_rx(struct net_device *dev)
1810 if(last && !priv->rx_skb_complete){ 1710 if(last && !priv->rx_skb_complete){
1811 if(priv->rx_skb->len > 4) 1711 if(priv->rx_skb->len > 4)
1812 skb_trim(priv->rx_skb,priv->rx_skb->len-4); 1712 skb_trim(priv->rx_skb,priv->rx_skb->len-4);
1813#ifndef RX_DONT_PASS_UL
1814 if(!ieee80211_rtl_rx(priv->ieee80211, 1713 if(!ieee80211_rtl_rx(priv->ieee80211,
1815 priv->rx_skb, &stats)){ 1714 priv->rx_skb, &stats))
1816#endif // RX_DONT_PASS_UL
1817
1818 dev_kfree_skb_any(priv->rx_skb); 1715 dev_kfree_skb_any(priv->rx_skb);
1819#ifndef RX_DONT_PASS_UL
1820 }
1821#endif
1822 priv->rx_skb_complete=1; 1716 priv->rx_skb_complete=1;
1823 } 1717 }
1824 1718
1825#endif //DUMMY_RX
1826 pci_dma_sync_single_for_device(priv->pdev, 1719 pci_dma_sync_single_for_device(priv->pdev,
1827 priv->rxbuffer->dma, 1720 priv->rxbuffer->dma,
1828 priv->rxbuffersize * \ 1721 priv->rxbuffersize * \
@@ -2056,7 +1949,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
2056 u16 RtsDur = 0; 1949 u16 RtsDur = 0;
2057 u16 ThisFrameTime = 0; 1950 u16 ThisFrameTime = 0;
2058 u16 TxDescDuration = 0; 1951 u16 TxDescDuration = 0;
2059 u8 ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14 1952 u8 ownbit_flag = false;
2060 1953
2061 switch(priority) { 1954 switch(priority) {
2062 case MANAGE_PRIORITY: 1955 case MANAGE_PRIORITY:
@@ -2123,7 +2016,8 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
2123 //YJ,add,080828,for Keep alive 2016 //YJ,add,080828,for Keep alive
2124 priv->NumTxUnicast++; 2017 priv->NumTxUnicast++;
2125 2018
2126 // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko. 2019 /* Figure out ACK rate according to BSS basic rate
2020 * and Tx rate. */
2127 AckTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send 2021 AckTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
2128 2022
2129 if ( ((len + sCrcLng) > priv->rts) && priv->rts ) 2023 if ( ((len + sCrcLng) > priv->rts) && priv->rts )
@@ -2206,7 +2100,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
2206 *tail |= (1<<15); /* no encrypt */ 2100 *tail |= (1<<15); /* no encrypt */
2207 2101
2208 if(remain==len && !descfrag) { 2102 if(remain==len && !descfrag) {
2209 ownbit_flag = false; //added by david woo,2007.12.14 2103 ownbit_flag = false;
2210 *tail = *tail| (1<<29) ; //fist segment of the packet 2104 *tail = *tail| (1<<29) ; //fist segment of the packet
2211 *tail = *tail |(len); 2105 *tail = *tail |(len);
2212 } else { 2106 } else {
@@ -2556,27 +2450,16 @@ void watch_dog_adaptive(unsigned long data)
2556 } 2450 }
2557 2451
2558 // Tx High Power Mechanism. 2452 // Tx High Power Mechanism.
2559#ifdef HIGH_POWER
2560 if(CheckHighPower((struct net_device *)data)) 2453 if(CheckHighPower((struct net_device *)data))
2561 {
2562 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq); 2454 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq);
2563 }
2564#endif
2565 2455
2566 // Tx Power Tracking on 87SE. 2456 // Tx Power Tracking on 87SE.
2567#ifdef TX_TRACK 2457 if (CheckTxPwrTracking((struct net_device *)data))
2568 //if( priv->bTxPowerTrack ) //lzm mod 080826
2569 if( CheckTxPwrTracking((struct net_device *)data));
2570 TxPwrTracking87SE((struct net_device *)data); 2458 TxPwrTracking87SE((struct net_device *)data);
2571#endif
2572 2459
2573 // Perform DIG immediately. 2460 // Perform DIG immediately.
2574#ifdef SW_DIG
2575 if(CheckDig((struct net_device *)data) == true) 2461 if(CheckDig((struct net_device *)data) == true)
2576 {
2577 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq); 2462 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
2578 }
2579#endif
2580 rtl8180_watch_dog((struct net_device *)data); 2463 rtl8180_watch_dog((struct net_device *)data);
2581 2464
2582 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem); 2465 queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
@@ -2675,6 +2558,36 @@ static void rtl8180_link_detect_init(plink_detect_t plink_detect)
2675} 2558}
2676//YJ,add,080828,end 2559//YJ,add,080828,end
2677 2560
2561static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom)
2562{
2563 struct net_device *dev = eeprom->data;
2564 u8 reg = read_nic_byte(dev, EPROM_CMD);
2565
2566 eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
2567 eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
2568 eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
2569 eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
2570}
2571
2572static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom)
2573{
2574 struct net_device *dev = eeprom->data;
2575 u8 reg = 2 << 6;
2576
2577 if (eeprom->reg_data_in)
2578 reg |= RTL818X_EEPROM_CMD_WRITE;
2579 if (eeprom->reg_data_out)
2580 reg |= RTL818X_EEPROM_CMD_READ;
2581 if (eeprom->reg_data_clock)
2582 reg |= RTL818X_EEPROM_CMD_CK;
2583 if (eeprom->reg_chip_select)
2584 reg |= RTL818X_EEPROM_CMD_CS;
2585
2586 write_nic_byte(dev, EPROM_CMD, reg);
2587 read_nic_byte(dev, EPROM_CMD);
2588 udelay(10);
2589}
2590
2678short rtl8180_init(struct net_device *dev) 2591short rtl8180_init(struct net_device *dev)
2679{ 2592{
2680 struct r8180_priv *priv = ieee80211_priv(dev); 2593 struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2683,8 +2596,16 @@ short rtl8180_init(struct net_device *dev)
2683 u32 usValue; 2596 u32 usValue;
2684 u16 tmpu16; 2597 u16 tmpu16;
2685 int i, j; 2598 int i, j;
2599 struct eeprom_93cx6 eeprom;
2600 u16 eeprom_val;
2601
2602 eeprom.data = dev;
2603 eeprom.register_read = rtl8187se_eeprom_register_read;
2604 eeprom.register_write = rtl8187se_eeprom_register_write;
2605 eeprom.width = PCI_EEPROM_WIDTH_93C46;
2686 2606
2687 priv->channel_plan = eprom_read(dev, EEPROM_COUNTRY_CODE>>1) & 0xFF; 2607 eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val);
2608 priv->channel_plan = eeprom_val & 0xFF;
2688 if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){ 2609 if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
2689 printk("rtl8180_init:Error channel plan! Set to default.\n"); 2610 printk("rtl8180_init:Error channel plan! Set to default.\n");
2690 priv->channel_plan = 0; 2611 priv->channel_plan = 0;
@@ -2701,8 +2622,6 @@ short rtl8180_init(struct net_device *dev)
2701 priv->txbeaconcount = 2; 2622 priv->txbeaconcount = 2;
2702 priv->rx_skb_complete = 1; 2623 priv->rx_skb_complete = 1;
2703 2624
2704 priv->RegThreeWireMode = HW_THREE_WIRE_SI;
2705
2706 priv->RFChangeInProgress = false; 2625 priv->RFChangeInProgress = false;
2707 priv->SetRFPowerStateInProgress = false; 2626 priv->SetRFPowerStateInProgress = false;
2708 priv->RFProgType = 0; 2627 priv->RFProgType = 0;
@@ -2747,10 +2666,8 @@ short rtl8180_init(struct net_device *dev)
2747 priv->TxPollingTimes = 0;//lzm add 080826 2666 priv->TxPollingTimes = 0;//lzm add 080826
2748 priv->bLeisurePs = true; 2667 priv->bLeisurePs = true;
2749 priv->dot11PowerSaveMode = eActive; 2668 priv->dot11PowerSaveMode = eActive;
2750//by amy for antenna
2751 priv->AdMinCheckPeriod = 5; 2669 priv->AdMinCheckPeriod = 5;
2752 priv->AdMaxCheckPeriod = 10; 2670 priv->AdMaxCheckPeriod = 10;
2753// Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
2754 priv->AdMaxRxSsThreshold = 30;//60->30 2671 priv->AdMaxRxSsThreshold = 30;//60->30
2755 priv->AdRxSsThreshold = 20;//50->20 2672 priv->AdRxSsThreshold = 20;//50->20
2756 priv->AdCheckPeriod = priv->AdMinCheckPeriod; 2673 priv->AdCheckPeriod = priv->AdMinCheckPeriod;
@@ -2765,8 +2682,6 @@ short rtl8180_init(struct net_device *dev)
2765 init_timer(&priv->SwAntennaDiversityTimer); 2682 init_timer(&priv->SwAntennaDiversityTimer);
2766 priv->SwAntennaDiversityTimer.data = (unsigned long)dev; 2683 priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
2767 priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback; 2684 priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
2768//by amy for antenna
2769//{by amy 080312
2770 priv->bDigMechanism = 1; 2685 priv->bDigMechanism = 1;
2771 priv->InitialGain = 6; 2686 priv->InitialGain = 6;
2772 priv->bXtalCalibration = false; 2687 priv->bXtalCalibration = false;
@@ -2803,58 +2718,63 @@ short rtl8180_init(struct net_device *dev)
2803 priv->NumTxUnicast = 0; 2718 priv->NumTxUnicast = 0;
2804 priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL; 2719 priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
2805 priv->PowerProfile = POWER_PROFILE_AC; 2720 priv->PowerProfile = POWER_PROFILE_AC;
2806 priv->CurrRetryCnt=0; 2721 priv->CurrRetryCnt = 0;
2807 priv->LastRetryCnt=0; 2722 priv->LastRetryCnt = 0;
2808 priv->LastTxokCnt=0; 2723 priv->LastTxokCnt = 0;
2809 priv->LastRxokCnt=0; 2724 priv->LastRxokCnt = 0;
2810 priv->LastRetryRate=0; 2725 priv->LastRetryRate = 0;
2811 priv->bTryuping=0; 2726 priv->bTryuping = 0;
2812 priv->CurrTxRate=0; 2727 priv->CurrTxRate = 0;
2813 priv->CurrRetryRate=0; 2728 priv->CurrRetryRate = 0;
2814 priv->TryupingCount=0; 2729 priv->TryupingCount = 0;
2815 priv->TryupingCountNoData=0; 2730 priv->TryupingCountNoData = 0;
2816 priv->TryDownCountLowData=0; 2731 priv->TryDownCountLowData = 0;
2817 priv->LastTxOKBytes=0; 2732 priv->LastTxOKBytes = 0;
2818 priv->LastFailTxRate=0; 2733 priv->LastFailTxRate = 0;
2819 priv->LastFailTxRateSS=0; 2734 priv->LastFailTxRateSS = 0;
2820 priv->FailTxRateCount=0; 2735 priv->FailTxRateCount = 0;
2821 priv->LastTxThroughput=0; 2736 priv->LastTxThroughput = 0;
2822 priv->NumTxOkBytesTotal=0; 2737 priv->NumTxOkBytesTotal = 0;
2823 priv->ForcedDataRate = 0; 2738 priv->ForcedDataRate = 0;
2824 priv->RegBModeGainStage = 1; 2739 priv->RegBModeGainStage = 1;
2825 2740
2826 priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0; 2741 priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
2827 spin_lock_init(&priv->irq_lock); 2742 spin_lock_init(&priv->irq_lock);
2828 spin_lock_init(&priv->irq_th_lock); 2743 spin_lock_init(&priv->irq_th_lock);
2829 spin_lock_init(&priv->tx_lock); 2744 spin_lock_init(&priv->tx_lock);
2830 spin_lock_init(&priv->ps_lock); 2745 spin_lock_init(&priv->ps_lock);
2831 spin_lock_init(&priv->rf_ps_lock); 2746 spin_lock_init(&priv->rf_ps_lock);
2832 sema_init(&priv->wx_sem,1); 2747 sema_init(&priv->wx_sem, 1);
2833 sema_init(&priv->rf_state,1); 2748 sema_init(&priv->rf_state, 1);
2834 INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq); 2749 INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq);
2835 INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq); 2750 INIT_WORK(&priv->tx_irq_wq, (void *)rtl8180_tx_irq_wq);
2836 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq); 2751 INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,
2837 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq); 2752 (void *)rtl8180_hw_wakeup_wq);
2838 INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update); 2753 INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,
2839 INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);//+by amy 080312 2754 (void *)rtl8180_hw_sleep_wq);
2840 INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);//+by amy 080312 2755 INIT_WORK(&priv->ieee80211->wmm_param_update_wq,
2841 INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);//+by amy 080312 2756 (void *)rtl8180_wmm_param_update);
2842 2757 INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,
2843 INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack); 2758 (void *)rtl8180_rate_adapter);
2844 2759 INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,
2760 (void *)rtl8180_hw_dig_wq);
2761 INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,
2762 (void *)rtl8180_tx_pw_wq);
2763 INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,
2764 (void *) GPIOChangeRFWorkItemCallBack);
2845 tasklet_init(&priv->irq_rx_tasklet, 2765 tasklet_init(&priv->irq_rx_tasklet,
2846 (void(*)(unsigned long)) rtl8180_irq_rx_tasklet, 2766 (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
2847 (unsigned long)priv); 2767 (unsigned long)priv);
2848 2768
2849 init_timer(&priv->watch_dog_timer); 2769 init_timer(&priv->watch_dog_timer);
2850 priv->watch_dog_timer.data = (unsigned long)dev; 2770 priv->watch_dog_timer.data = (unsigned long)dev;
2851 priv->watch_dog_timer.function = watch_dog_adaptive; 2771 priv->watch_dog_timer.function = watch_dog_adaptive;
2852 2772
2853 init_timer(&priv->rateadapter_timer); 2773 init_timer(&priv->rateadapter_timer);
2854 priv->rateadapter_timer.data = (unsigned long)dev; 2774 priv->rateadapter_timer.data = (unsigned long)dev;
2855 priv->rateadapter_timer.function = timer_rate_adaptive; 2775 priv->rateadapter_timer.function = timer_rate_adaptive;
2856 priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD; 2776 priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
2857 priv->bEnhanceTxPwr=false; 2777 priv->bEnhanceTxPwr = false;
2858 2778
2859 priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit; 2779 priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
2860 priv->ieee80211->set_chan = rtl8180_set_chan; 2780 priv->ieee80211->set_chan = rtl8180_set_chan;
@@ -2877,30 +2797,28 @@ short rtl8180_init(struct net_device *dev)
2877 2797
2878 priv->CSMethod = (0x01 << 29); 2798 priv->CSMethod = (0x01 << 29);
2879 2799
2880 priv->TransmitConfig = 2800 priv->TransmitConfig = TCR_DurProcMode_OFFSET |
2881 1<<TCR_DurProcMode_OFFSET | //for RTL8185B, duration setting by HW 2801 (7<<TCR_MXDMA_OFFSET) |
2882 (7<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied. 2802 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) |
2883 (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit 2803 (priv->LongRetryLimit<<TCR_LRL_OFFSET) |
2884 (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit 2804 (0 ? TCR_SAT : 0);
2885 (0 ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them 2805
2886 2806 priv->ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF |
2887 priv->ReceiveConfig = 2807 RCR_AB | RCR_AM | RCR_APM |
2888 RCR_AMF | RCR_ADF | //accept management/data 2808 (7<<RCR_MXDMA_OFFSET) |
2889 RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko. 2809 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) |
2890 RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC 2810 (priv->EarlyRxThreshold == 7 ?
2891 (7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited. 2811 RCR_ONLYERLPKT : 0);
2892 (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2893 (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2894 2812
2895 priv->IntrMask = IMR_TMGDOK | IMR_TBDER | IMR_THPDER | 2813 priv->IntrMask = IMR_TMGDOK | IMR_TBDER | IMR_THPDER |
2896 IMR_THPDER | IMR_THPDOK | 2814 IMR_THPDER | IMR_THPDOK |
2897 IMR_TVODER | IMR_TVODOK | 2815 IMR_TVODER | IMR_TVODOK |
2898 IMR_TVIDER | IMR_TVIDOK | 2816 IMR_TVIDER | IMR_TVIDOK |
2899 IMR_TBEDER | IMR_TBEDOK | 2817 IMR_TBEDER | IMR_TBEDOK |
2900 IMR_TBKDER | IMR_TBKDOK | 2818 IMR_TBKDER | IMR_TBKDOK |
2901 IMR_RDU | // To handle the defragmentation not enough Rx descriptors case. Annie, 2006-03-27. 2819 IMR_RDU |
2902 IMR_RER | IMR_ROK | 2820 IMR_RER | IMR_ROK |
2903 IMR_RQoSOK; // <NOTE> ROK and RQoSOK are mutually exclusive, so, we must handle RQoSOK interrupt to receive QoS frames, 2005.12.09, by rcnjko. 2821 IMR_RQoSOK;
2904 2822
2905 priv->InitialGain = 6; 2823 priv->InitialGain = 6;
2906 2824
@@ -2913,7 +2831,8 @@ short rtl8180_init(struct net_device *dev)
2913 // just for sync 85 2831 // just for sync 85
2914 priv->enable_gpio0 = 0; 2832 priv->enable_gpio0 = 0;
2915 2833
2916 usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET); 2834 eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val);
2835 usValue = eeprom_val;
2917 DMESG("usValue is 0x%x\n",usValue); 2836 DMESG("usValue is 0x%x\n",usValue);
2918 //3Read AntennaDiversity 2837 //3Read AntennaDiversity
2919 2838
@@ -2953,54 +2872,46 @@ short rtl8180_init(struct net_device *dev)
2953 else 2872 else
2954 priv->epromtype=EPROM_93c46; 2873 priv->epromtype=EPROM_93c46;
2955 2874
2956 dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff; 2875 eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)
2957 dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8; 2876 dev->dev_addr, 3);
2958 dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
2959 dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
2960 dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
2961 dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8;
2962 2877
2963 for(i=1,j=0; i<14; i+=2,j++){ 2878 for(i=1,j=0; i<14; i+=2,j++){
2964 word = eprom_read(dev,EPROM_TXPW_CH1_2 + j); 2879 eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word);
2965 priv->chtxpwr[i]=word & 0xff; 2880 priv->chtxpwr[i]=word & 0xff;
2966 priv->chtxpwr[i+1]=(word & 0xff00)>>8; 2881 priv->chtxpwr[i+1]=(word & 0xff00)>>8;
2967 } 2882 }
2968 for (i = 1, j = 0; i < 14; i += 2, j++) { 2883 for (i = 1, j = 0; i < 14; i += 2, j++) {
2969 word = eprom_read(dev, EPROM_TXPW_OFDM_CH1_2 + j); 2884 eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word);
2970 priv->chtxpwr_ofdm[i] = word & 0xff; 2885 priv->chtxpwr_ofdm[i] = word & 0xff;
2971 priv->chtxpwr_ofdm[i+1] = (word & 0xff00)>>8; 2886 priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8;
2972 } 2887 }
2973 2888
2974 //3Read crystal calibtration and thermal meter indication on 87SE. 2889 /* 3Read crystal calibtration and thermal meter indication on 87SE. */
2975 2890 eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16);
2976 // By SD3 SY's request. Added by Roger, 2007.12.11.
2977 2891
2978 tmpu16 = eprom_read(dev, EEPROM_RSV>>1); 2892 /* Crystal calibration for Xin and Xout resp. */
2893 priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK;
2894 priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4;
2895 if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12)
2896 priv->bXtalCalibration = true;
2979 2897
2980 // Crystal calibration for Xin and Xout resp. 2898 /* Thermal meter reference indication. */
2981 priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; // 0~7.5pF 2899 priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8);
2982 priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK)>>4; // 0~7.5pF 2900 if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13)
2983 if((tmpu16 & EEPROM_XTAL_CAL_ENABLE)>>12) 2901 priv->bTxPowerTrack = true;
2984 priv->bXtalCalibration = true;
2985 2902
2986 // Thermal meter reference indication. 2903 eeprom_93cx6_read(&eeprom, EPROM_TXPW_BASE, &word);
2987 priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK)>>8);
2988 if((tmpu16 & EEPROM_THERMAL_METER_ENABLE)>>13)
2989 priv->bTxPowerTrack = true;
2990
2991 word = eprom_read(dev,EPROM_TXPW_BASE);
2992 priv->cck_txpwr_base = word & 0xf; 2904 priv->cck_txpwr_base = word & 0xf;
2993 priv->ofdm_txpwr_base = (word>>4) & 0xf; 2905 priv->ofdm_txpwr_base = (word>>4) & 0xf;
2994 2906
2995 version = eprom_read(dev,EPROM_VERSION); 2907 eeprom_93cx6_read(&eeprom, EPROM_VERSION, &version);
2996 DMESG("EEPROM version %x",version); 2908 DMESG("EEPROM version %x",version);
2997 priv->rcr_csense = 3; 2909 priv->rcr_csense = 3;
2998 2910
2999 priv->cs_treshold = (eprom_read(dev, ENERGY_TRESHOLD) & 0xff00) >> 8; 2911 eeprom_93cx6_read(&eeprom, ENERGY_TRESHOLD, &eeprom_val);
3000 2912 priv->cs_treshold = (eeprom_val & 0xff00) >> 8;
3001 priv->rf_chip = 0xff & eprom_read(dev, RFCHIPID);
3002 2913
3003 priv->rf_chip = RF_ZEBRA4; 2914 eeprom_93cx6_read(&eeprom, RFCHIPID, &eeprom_val);
3004 priv->rf_sleep = rtl8225z4_rf_sleep; 2915 priv->rf_sleep = rtl8225z4_rf_sleep;
3005 priv->rf_wakeup = rtl8225z4_rf_wakeup; 2916 priv->rf_wakeup = rtl8225z4_rf_wakeup;
3006 DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!"); 2917 DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
@@ -3010,7 +2921,6 @@ short rtl8180_init(struct net_device *dev)
3010 priv->rf_set_chan = rtl8225z2_rf_set_chan; 2921 priv->rf_set_chan = rtl8225z2_rf_set_chan;
3011 priv->rf_set_sens = NULL; 2922 priv->rf_set_sens = NULL;
3012 2923
3013
3014 if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount)) 2924 if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
3015 return -ENOMEM; 2925 return -ENOMEM;
3016 2926
@@ -3042,11 +2952,7 @@ short rtl8180_init(struct net_device *dev)
3042 TX_BEACON_RING_ADDR)) 2952 TX_BEACON_RING_ADDR))
3043 return -ENOMEM; 2953 return -ENOMEM;
3044 2954
3045#if !defined(SA_SHIRQ)
3046 if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){ 2955 if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){
3047#else
3048 if(request_irq(dev->irq, (void *)rtl8180_interrupt, SA_SHIRQ, dev->name, dev)){
3049#endif
3050 DMESGE("Error allocating IRQ %d",dev->irq); 2956 DMESGE("Error allocating IRQ %d",dev->irq);
3051 return -1; 2957 return -1;
3052 }else{ 2958 }else{
@@ -3169,43 +3075,6 @@ void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
3169 rtl8185_write_phy(dev, adr, data | 0x10000); 3075 rtl8185_write_phy(dev, adr, data | 0x10000);
3170} 3076}
3171 3077
3172/* 70*3 = 210 ms
3173 * I hope this is enougth
3174 */
3175#define MAX_PHY 70
3176void write_phy(struct net_device *dev, u8 adr, u8 data)
3177{
3178 u32 phy;
3179 int i;
3180
3181 phy = 0xff0000;
3182 phy |= adr;
3183 phy |= 0x80; /* this should enable writing */
3184 phy |= (data<<8);
3185
3186 //PHY_ADR, PHY_R and PHY_W are contig and treated as one dword
3187 write_nic_dword(dev,PHY_ADR, phy);
3188
3189 phy= 0xffff00;
3190 phy |= adr;
3191
3192 write_nic_dword(dev,PHY_ADR, phy);
3193 for(i=0;i<MAX_PHY;i++){
3194 phy=read_nic_dword(dev,PHY_ADR);
3195 phy= phy & 0xff0000;
3196 phy= phy >> 16;
3197 if(phy == data){ //SUCCESS!
3198 force_pci_posting(dev);
3199 mdelay(3); //random value
3200 return;
3201 }else{
3202 force_pci_posting(dev);
3203 mdelay(3); //random value
3204 }
3205 }
3206 DMESGW ("Phy writing %x %x failed!", adr,data);
3207}
3208
3209void rtl8185_set_rate(struct net_device *dev) 3078void rtl8185_set_rate(struct net_device *dev)
3210{ 3079{
3211 int i; 3080 int i;
@@ -3335,7 +3204,6 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev)
3335} 3204}
3336// 3205//
3337// Change current and default preamble mode. 3206// Change current and default preamble mode.
3338// 2005.01.06, by rcnjko.
3339// 3207//
3340bool 3208bool
3341MgntActSet_802_11_PowerSaveMode( 3209MgntActSet_802_11_PowerSaveMode(
@@ -3454,7 +3322,6 @@ void rtl8180_watch_dog(struct net_device *dev)
3454 MgntLinkKeepAlive(priv); 3322 MgntLinkKeepAlive(priv);
3455 3323
3456 //YJ,add,080828,for LPS 3324 //YJ,add,080828,for LPS
3457#ifdef ENABLE_LPS
3458 if (priv->PowerProfile == POWER_PROFILE_BATTERY) 3325 if (priv->PowerProfile == POWER_PROFILE_BATTERY)
3459 priv->bLeisurePs = true; 3326 priv->bLeisurePs = true;
3460 else if (priv->PowerProfile == POWER_PROFILE_AC) { 3327 else if (priv->PowerProfile == POWER_PROFILE_AC) {
@@ -3464,7 +3331,6 @@ void rtl8180_watch_dog(struct net_device *dev)
3464 3331
3465 if(priv->ieee80211->state == IEEE80211_LINKED){ 3332 if(priv->ieee80211->state == IEEE80211_LINKED){
3466 priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod; 3333 priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod;
3467 //printk("TxOk=%d RxOk=%d\n", priv->link_detect.NumTxOkInPeriod, priv->link_detect.NumRxOkInPeriod);
3468 if( priv->link_detect.NumRxOkInPeriod> 666 || 3334 if( priv->link_detect.NumRxOkInPeriod> 666 ||
3469 priv->link_detect.NumTxOkInPeriod> 666 ) { 3335 priv->link_detect.NumTxOkInPeriod> 666 ) {
3470 bBusyTraffic = true; 3336 bBusyTraffic = true;
@@ -3481,7 +3347,6 @@ void rtl8180_watch_dog(struct net_device *dev)
3481 LeisurePSLeave(priv); 3347 LeisurePSLeave(priv);
3482 } else 3348 } else
3483 LeisurePSLeave(priv); 3349 LeisurePSLeave(priv);
3484#endif
3485 priv->link_detect.bBusyTraffic = bBusyTraffic; 3350 priv->link_detect.bBusyTraffic = bBusyTraffic;
3486 priv->link_detect.NumRxOkInPeriod = 0; 3351 priv->link_detect.NumRxOkInPeriod = 0;
3487 priv->link_detect.NumTxOkInPeriod = 0; 3352 priv->link_detect.NumTxOkInPeriod = 0;
@@ -3503,16 +3368,11 @@ int _rtl8180_up(struct net_device *dev)
3503 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) 3368 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3504 IPSLeave(dev); 3369 IPSLeave(dev);
3505 } 3370 }
3506#ifdef RATE_ADAPT
3507 timer_rate_adaptive((unsigned long)dev); 3371 timer_rate_adaptive((unsigned long)dev);
3508#endif
3509 watch_dog_adaptive((unsigned long)dev); 3372 watch_dog_adaptive((unsigned long)dev);
3510#ifdef SW_ANTE
3511 if(priv->bSwAntennaDiverity) 3373 if(priv->bSwAntennaDiverity)
3512 SwAntennaDiversityTimerCallback(dev); 3374 SwAntennaDiversityTimerCallback(dev);
3513#endif
3514 ieee80211_softmac_start_protocol(priv->ieee80211); 3375 ieee80211_softmac_start_protocol(priv->ieee80211);
3515
3516 return 0; 3376 return 0;
3517} 3377}
3518 3378
@@ -3748,7 +3608,7 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
3748 dev->wireless_handlers = &r8180_wx_handlers_def; 3608 dev->wireless_handlers = &r8180_wx_handlers_def;
3749 3609
3750 dev->type=ARPHRD_ETHER; 3610 dev->type=ARPHRD_ETHER;
3751 dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13 3611 dev->watchdog_timeo = HZ*3;
3752 3612
3753 if (dev_alloc_name(dev, ifname) < 0){ 3613 if (dev_alloc_name(dev, ifname) < 0){
3754 DMESG("Oops: devname already taken! Trying wlan%%d...\n"); 3614 DMESG("Oops: devname already taken! Trying wlan%%d...\n");
@@ -3864,8 +3724,7 @@ static int __init rtl8180_pci_module_init(void)
3864 return ret; 3724 return ret;
3865 } 3725 }
3866 3726
3867 printk(KERN_INFO "\nLinux kernel driver for RTL8180 \ 3727 printk(KERN_INFO "\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
3868/ RTL8185 based WLAN cards\n");
3869 printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n"); 3728 printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n");
3870 DMESG("Initializing module"); 3729 DMESG("Initializing module");
3871 DMESG("Wireless extensions version %d", WIRELESS_EXT); 3730 DMESG("Wireless extensions version %d", WIRELESS_EXT);
@@ -4236,60 +4095,51 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
4236 static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; 4095 static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
4237 static int readf_count = 0; 4096 static int readf_count = 0;
4238 4097
4239#ifdef ENABLE_LPS
4240 if(readf_count % 10 == 0) 4098 if(readf_count % 10 == 0)
4241 priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state"); 4099 priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state");
4242 4100
4243 readf_count = (readf_count+1)%0xffff; 4101 readf_count = (readf_count+1)%0xffff;
4244#endif 4102 /* We should turn off LED before polling FF51[4]. */
4245 {
4246 // We should turn off LED before polling FF51[4].
4247 4103
4248 //Turn off LED. 4104 /* Turn off LED. */
4249 btPSR = read_nic_byte(dev, PSR); 4105 btPSR = read_nic_byte(dev, PSR);
4250 write_nic_byte(dev, PSR, (btPSR & ~BIT3)); 4106 write_nic_byte(dev, PSR, (btPSR & ~BIT3));
4251 4107
4252 //It need to delay 4us suggested by Jong, 2008-01-16 4108 /* It need to delay 4us suggested by Jong, 2008-01-16 */
4253 udelay(4); 4109 udelay(4);
4254 4110
4255 //HW radio On/Off according to the value of FF51[4](config0) 4111 /* HW radio On/Off according to the value of FF51[4](config0) */
4256 btConfig0 = btPSR = read_nic_byte(dev, CONFIG0); 4112 btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
4257 4113
4258 //Turn on LED. 4114 eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff;
4259 write_nic_byte(dev, PSR, btPSR| BIT3);
4260 4115
4261 eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff; 4116 /* Turn LED back on when radio enabled */
4117 if (eRfPowerStateToSet == eRfOn)
4118 write_nic_byte(dev, PSR, btPSR | BIT3);
4262 4119
4263 if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn)) 4120 if ((priv->ieee80211->bHwRadioOff == true) &&
4264 { 4121 (eRfPowerStateToSet == eRfOn)) {
4265 priv->ieee80211->bHwRadioOff = false; 4122 priv->ieee80211->bHwRadioOff = false;
4266 bActuallySet = true; 4123 bActuallySet = true;
4267 } 4124 } else if ((priv->ieee80211->bHwRadioOff == false) &&
4268 else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff)) 4125 (eRfPowerStateToSet == eRfOff)) {
4269 { 4126 priv->ieee80211->bHwRadioOff = true;
4270 priv->ieee80211->bHwRadioOff = true; 4127 bActuallySet = true;
4271 bActuallySet = true; 4128 }
4272 }
4273 4129
4274 if(bActuallySet) 4130 if (bActuallySet) {
4275 { 4131 MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
4276 MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); 4132
4277 4133 /* To update the UI status for Power status changed */
4278 /* To update the UI status for Power status changed */ 4134 if (priv->ieee80211->bHwRadioOff == true)
4279 if(priv->ieee80211->bHwRadioOff == true) 4135 argv[1] = "RFOFF";
4280 argv[1] = "RFOFF"; 4136 else
4281 else{ 4137 argv[1] = "RFON";
4282 //if(!priv->RfOffReason) 4138 argv[0] = RadioPowerPath;
4283 argv[1] = "RFON"; 4139 argv[2] = NULL;
4284 //else 4140
4285 // argv[1] = "RFOFF"; 4141 call_usermodehelper(RadioPowerPath, argv, envp, 1);
4286 } 4142 }
4287 argv[0] = RadioPowerPath;
4288 argv[2] = NULL;
4289
4290 call_usermodehelper(RadioPowerPath,argv,envp,1);
4291 }
4292 }
4293} 4143}
4294 4144
4295static u8 read_acadapter_file(char *filename) 4145static u8 read_acadapter_file(char *filename)
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
index cbca58db85e1..fc4907839c58 100644
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -282,30 +282,13 @@ DIG_Zebra(
282// Dispatch DIG implementation according to RF. 282// Dispatch DIG implementation according to RF.
283// 283//
284void 284void
285DynamicInitGain( 285DynamicInitGain(struct net_device *dev)
286 struct net_device *dev
287 )
288{ 286{
289 struct r8180_priv *priv = ieee80211_priv(dev); 287 DIG_Zebra(dev);
290
291 switch(priv->rf_chip)
292 {
293 case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
294 case RF_ZEBRA4:
295 DIG_Zebra( dev );
296 break;
297
298 default:
299 printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
300 break;
301 }
302} 288}
303 289
304void rtl8180_hw_dig_wq (struct work_struct *work) 290void rtl8180_hw_dig_wq (struct work_struct *work)
305{ 291{
306// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
307// struct ieee80211_device * ieee = (struct ieee80211_device*)
308// container_of(work, struct ieee80211_device, watch_dog_wq);
309 struct delayed_work *dwork = to_delayed_work(work); 292 struct delayed_work *dwork = to_delayed_work(work);
310 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq); 293 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
311 struct net_device *dev = ieee->dev; 294 struct net_device *dev = ieee->dev;
@@ -1310,44 +1293,24 @@ SetAntenna8185(
1310 switch(u1bAntennaIndex) 1293 switch(u1bAntennaIndex)
1311 { 1294 {
1312 case 0: 1295 case 0:
1313 switch(priv->rf_chip) 1296 /* Mac register, main antenna */
1314 { 1297 write_nic_byte(dev, ANTSEL, 0x03);
1315 case RF_ZEBRA2: 1298 /* base band */
1316 case RF_ZEBRA4: 1299 write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */
1317 // Mac register, main antenna 1300 write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */
1318 write_nic_byte(dev, ANTSEL, 0x03);
1319 //base band
1320 write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
1321 write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
1322
1323
1324 bAntennaSwitched = true;
1325 break;
1326 1301
1327 default: 1302 bAntennaSwitched = true;
1328 printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
1329 break;
1330 }
1331 break; 1303 break;
1332 1304
1333 case 1: 1305 case 1:
1334 switch(priv->rf_chip) 1306 /* Mac register, aux antenna */
1335 { 1307 write_nic_byte(dev, ANTSEL, 0x00);
1336 case RF_ZEBRA2: 1308 /* base band */
1337 case RF_ZEBRA4: 1309 write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */
1338 // Mac register, aux antenna 1310 write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */
1339 write_nic_byte(dev, ANTSEL, 0x00); 1311
1340 //base band 1312 bAntennaSwitched = true;
1341 write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
1342 write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
1343
1344 bAntennaSwitched = true;
1345 break;
1346 1313
1347 default:
1348 printk("SetAntenna8185: unknown RFChipID(%d)\n", priv->rf_chip);
1349 break;
1350 }
1351 break; 1314 break;
1352 1315
1353 default: 1316 default:
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
index afe10f0b75a8..6edf5a46fa40 100644
--- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c
+++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
@@ -854,134 +854,48 @@ bool SetZebraRFPowerState8185(struct net_device *dev,
854 btConfig3 = read_nic_byte(dev, CONFIG3); 854 btConfig3 = read_nic_byte(dev, CONFIG3);
855 write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En)); 855 write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En));
856 856
857 switch (priv->rf_chip) { 857 switch (eRFPowerState) {
858 case RF_ZEBRA2: 858 case eRfOn:
859 switch (eRFPowerState) { 859 write_nic_word(dev, 0x37C, 0x00EC);
860 case eRfOn:
861 RF_WriteReg(dev,0x4,0x9FF);
862 860
863 write_nic_dword(dev, ANAPARAM, ANAPARM_ON); 861 /* turn on AFE */
864 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON); 862 write_nic_byte(dev, 0x54, 0x00);
863 write_nic_byte(dev, 0x62, 0x00);
865 864
866 write_nic_byte(dev, CONFIG4, priv->RFProgType); 865 /* turn on RF */
866 RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
867 RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
867 868
868 /* turn on CCK and OFDM */ 869 /* turn on RF again */
869 u1bTmp = read_nic_byte(dev, 0x24E); 870 RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
870 write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6)))); 871 RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
871 break;
872 case eRfSleep:
873 break;
874 case eRfOff:
875 break;
876 default:
877 bResult = false;
878 break;
879 }
880 break;
881 case RF_ZEBRA4:
882 switch (eRFPowerState) {
883 case eRfOn:
884 write_nic_word(dev, 0x37C, 0x00EC);
885
886 /* turn on AFE */
887 write_nic_byte(dev, 0x54, 0x00);
888 write_nic_byte(dev, 0x62, 0x00);
889
890 /* turn on RF */
891 RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
892 RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
893
894 /* turn on RF again */
895 RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
896 RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
897 872
898 /* turn on BB */ 873 /* turn on BB */
899 write_phy_ofdm(dev,0x10,0x40); 874 write_phy_ofdm(dev, 0x10, 0x40);
900 write_phy_ofdm(dev,0x12,0x40); 875 write_phy_ofdm(dev, 0x12, 0x40);
901
902 /* Avoid power down at init time. */
903 write_nic_byte(dev, CONFIG4, priv->RFProgType);
904
905 u1bTmp = read_nic_byte(dev, 0x24E);
906 write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
907 break;
908 case eRfSleep:
909 for (QueueID = 0, i = 0; QueueID < 6;) {
910 if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
911 QueueID++;
912 continue;
913 } else {
914 priv->TxPollingTimes ++;
915 if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
916 bActionAllowed = false;
917 break;
918 } else
919 udelay(10);
920 }
921 }
922 876
923 if (bActionAllowed) { 877 /* Avoid power down at init time. */
924 /* turn off BB RXIQ matrix to cut off rx signal */ 878 write_nic_byte(dev, CONFIG4, priv->RFProgType);
925 write_phy_ofdm(dev, 0x10, 0x00);
926 write_phy_ofdm(dev, 0x12, 0x00);
927
928 /* turn off RF */
929 RF_WriteReg(dev, 0x4, 0x0000);
930 RF_WriteReg(dev, 0x0, 0x0000);
931
932 /* turn off AFE except PLL */
933 write_nic_byte(dev, 0x62, 0xff);
934 write_nic_byte(dev, 0x54, 0xec);
935
936 mdelay(1);
937
938 {
939 int i = 0;
940 while (true) {
941 u8 tmp24F = read_nic_byte(dev, 0x24f);
942
943 if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
944 bTurnOffBB = true;
945 break;
946 } else {
947 udelay(10);
948 i++;
949 priv->TxPollingTimes++;
950
951 if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
952 bTurnOffBB = false;
953 break;
954 } else
955 udelay(10);
956 }
957 }
958 }
959
960 if (bTurnOffBB) {
961 /* turn off BB */
962 u1bTmp = read_nic_byte(dev, 0x24E);
963 write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
964
965 /* turn off AFE PLL */
966 write_nic_byte(dev, 0x54, 0xFC);
967 write_nic_word(dev, 0x37C, 0x00FC);
968 }
969 }
970 break;
971 case eRfOff:
972 for (QueueID = 0, i = 0; QueueID < 6;) {
973 if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
974 QueueID++;
975 continue;
976 } else {
977 udelay(10);
978 i++;
979 }
980 879
981 if (i >= MAX_DOZE_WAITING_TIMES_85B) 880 u1bTmp = read_nic_byte(dev, 0x24E);
881 write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
882 break;
883 case eRfSleep:
884 for (QueueID = 0, i = 0; QueueID < 6;) {
885 if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
886 QueueID++;
887 continue;
888 } else {
889 priv->TxPollingTimes++;
890 if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
891 bActionAllowed = false;
982 break; 892 break;
893 } else
894 udelay(10);
983 } 895 }
896 }
984 897
898 if (bActionAllowed) {
985 /* turn off BB RXIQ matrix to cut off rx signal */ 899 /* turn off BB RXIQ matrix to cut off rx signal */
986 write_phy_ofdm(dev, 0x10, 0x00); 900 write_phy_ofdm(dev, 0x10, 0x00);
987 write_phy_ofdm(dev, 0x12, 0x00); 901 write_phy_ofdm(dev, 0x12, 0x00);
@@ -998,22 +912,23 @@ bool SetZebraRFPowerState8185(struct net_device *dev,
998 912
999 { 913 {
1000 int i = 0; 914 int i = 0;
1001 915 while (true) {
1002 while (true)
1003 {
1004 u8 tmp24F = read_nic_byte(dev, 0x24f); 916 u8 tmp24F = read_nic_byte(dev, 0x24f);
1005 917
1006 if ((tmp24F == 0x01) || (tmp24F == 0x09)) { 918 if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
1007 bTurnOffBB = true; 919 bTurnOffBB = true;
1008 break; 920 break;
1009 } else { 921 } else {
1010 bTurnOffBB = false;
1011 udelay(10); 922 udelay(10);
1012 i++; 923 i++;
1013 } 924 priv->TxPollingTimes++;
1014 925
1015 if (i > MAX_POLLING_24F_TIMES_87SE) 926 if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
1016 break; 927 bTurnOffBB = false;
928 break;
929 } else
930 udelay(10);
931 }
1017 } 932 }
1018 } 933 }
1019 934
@@ -1022,15 +937,68 @@ bool SetZebraRFPowerState8185(struct net_device *dev,
1022 u1bTmp = read_nic_byte(dev, 0x24E); 937 u1bTmp = read_nic_byte(dev, 0x24E);
1023 write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6)); 938 write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
1024 939
1025 /* turn off AFE PLL (80M) */ 940 /* turn off AFE PLL */
1026 write_nic_byte(dev, 0x54, 0xFC); 941 write_nic_byte(dev, 0x54, 0xFC);
1027 write_nic_word(dev, 0x37C, 0x00FC); 942 write_nic_word(dev, 0x37C, 0x00FC);
1028 } 943 }
1029 break; 944 }
1030 default: 945 break;
1031 bResult = false; 946 case eRfOff:
1032 printk("SetZebraRFPowerState8185(): unknown state to set: 0x%X!!!\n", eRFPowerState); 947 for (QueueID = 0, i = 0; QueueID < 6;) {
1033 break; 948 if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
949 QueueID++;
950 continue;
951 } else {
952 udelay(10);
953 i++;
954 }
955
956 if (i >= MAX_DOZE_WAITING_TIMES_85B)
957 break;
958 }
959
960 /* turn off BB RXIQ matrix to cut off rx signal */
961 write_phy_ofdm(dev, 0x10, 0x00);
962 write_phy_ofdm(dev, 0x12, 0x00);
963
964 /* turn off RF */
965 RF_WriteReg(dev, 0x4, 0x0000);
966 RF_WriteReg(dev, 0x0, 0x0000);
967
968 /* turn off AFE except PLL */
969 write_nic_byte(dev, 0x62, 0xff);
970 write_nic_byte(dev, 0x54, 0xec);
971
972 mdelay(1);
973
974 {
975 int i = 0;
976
977 while (true) {
978 u8 tmp24F = read_nic_byte(dev, 0x24f);
979
980 if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
981 bTurnOffBB = true;
982 break;
983 } else {
984 bTurnOffBB = false;
985 udelay(10);
986 i++;
987 }
988
989 if (i > MAX_POLLING_24F_TIMES_87SE)
990 break;
991 }
992 }
993
994 if (bTurnOffBB) {
995 /* turn off BB */
996 u1bTmp = read_nic_byte(dev, 0x24E);
997 write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
998
999 /* turn off AFE PLL (80M) */
1000 write_nic_byte(dev, 0x54, 0xFC);
1001 write_nic_word(dev, 0x37C, 0x00FC);
1034 } 1002 }
1035 break; 1003 break;
1036 } 1004 }
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
index 50309f2da9c1..a0ece1fd64a5 100644
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -238,100 +238,12 @@ PlatformIORead4Byte(
238 return data; 238 return data;
239} 239}
240 240
241void 241void SetOutputEnableOfRfPins(struct net_device *dev)
242SetOutputEnableOfRfPins(
243 struct net_device *dev
244 )
245{ 242{
246 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 243 write_nic_word(dev, RFPinsEnable, 0x1bff);
247
248 switch(priv->rf_chip)
249 {
250 case RFCHIPID_RTL8225:
251 case RF_ZEBRA2:
252 case RF_ZEBRA4:
253 write_nic_word(dev, RFPinsEnable, 0x1bff);
254 //write_nic_word(dev, RFPinsEnable, 0x1fff);
255 break;
256 }
257} 244}
258 245
259void 246static int
260ZEBRA_RFSerialWrite(
261 struct net_device *dev,
262 u32 data2Write,
263 u8 totalLength,
264 u8 low2high
265 )
266{
267 ThreeWireReg twreg;
268 int i;
269 u16 oval,oval2,oval3;
270 u32 mask;
271 u16 UshortBuffer;
272
273 u8 u1bTmp;
274 // RTL8187S HSSI Read/Write Function
275 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
276 u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
277 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
278 UshortBuffer = read_nic_word(dev, RFPinsOutput);
279 oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko.
280
281 oval2 = read_nic_word(dev, RFPinsEnable);
282 oval3 = read_nic_word(dev, RFPinsSelect);
283
284 // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
285 oval3 &= 0xfff8;
286
287 write_nic_word(dev, RFPinsEnable, (oval2|0x0007)); // Set To Output Enable
288 write_nic_word(dev, RFPinsSelect, (oval3|0x0007)); // Set To SW Switch
289 udelay(10);
290
291 // Add this to avoid hardware and software 3-wire conflict.
292 // 2005.03.01, by rcnjko.
293 twreg.longData = 0;
294 twreg.struc.enableB = 1;
295 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Set SI_EN (RFLE)
296 udelay(2);
297 twreg.struc.enableB = 0;
298 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Clear SI_EN (RFLE)
299 udelay(10);
300
301 mask = (low2high)?0x01:((u32)0x01<<(totalLength-1));
302
303 for(i=0; i<totalLength/2; i++)
304 {
305 twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
306 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
307 twreg.struc.clk = 1;
308 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
309 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
310
311 mask = (low2high)?(mask<<1):(mask>>1);
312 twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
313 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
314 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
315 twreg.struc.clk = 0;
316 write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
317 mask = (low2high)?(mask<<1):(mask>>1);
318 }
319
320 twreg.struc.enableB = 1;
321 twreg.struc.clk = 0;
322 twreg.struc.data = 0;
323 write_nic_word(dev, RFPinsOutput, twreg.longData|oval);
324 udelay(10);
325
326 write_nic_word(dev, RFPinsOutput, oval|0x0004);
327 write_nic_word(dev, RFPinsSelect, oval3|0x0000);
328
329 SetOutputEnableOfRfPins(dev);
330}
331//by amy
332
333
334int
335HwHSSIThreeWire( 247HwHSSIThreeWire(
336 struct net_device *dev, 248 struct net_device *dev,
337 u8 *pDataBuf, 249 u8 *pDataBuf,
@@ -469,420 +381,30 @@ HwHSSIThreeWire(
469 381
470 return bResult; 382 return bResult;
471} 383}
472//by amy
473
474int
475HwThreeWire(
476 struct net_device *dev,
477 u8 *pDataBuf,
478 u8 nDataBufBitCnt,
479 int bHold,
480 int bWrite
481 )
482{
483 int bResult = 1;
484 u8 TryCnt;
485 u8 u1bTmp;
486
487 do
488 {
489 // Check if WE and RE are cleared.
490 for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
491 {
492 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
493 if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
494 {
495 break;
496 }
497 udelay(10);
498 }
499 if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
500 panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
501
502 // Fill up data buffer for write operation.
503 if(nDataBufBitCnt == 16)
504 {
505 write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
506 }
507 else if(nDataBufBitCnt == 64)
508 {
509 write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
510 write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
511 }
512 else
513 {
514 int idx;
515 int ByteCnt = nDataBufBitCnt / 8;
516
517 if ((nDataBufBitCnt % 8) != 0)
518 panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
519 nDataBufBitCnt);
520
521 if (nDataBufBitCnt > 64)
522 panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
523 nDataBufBitCnt);
524
525 for(idx = 0; idx < ByteCnt; idx++)
526 {
527 write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
528 }
529 }
530
531 // Fill up length field.
532 u1bTmp = (u8)(nDataBufBitCnt - 1); // Number of bits - 1.
533 if(bHold)
534 u1bTmp |= SW_3W_CMD0_HOLD;
535 write_nic_byte(dev, SW_3W_CMD0, u1bTmp);
536
537 // Set up command: WE or RE.
538 if(bWrite)
539 {
540 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
541 }
542 else
543 {
544 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
545 }
546
547 // Check if WE and RE are cleared and DONE is set.
548 for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
549 {
550 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
551 if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 &&
552 (u1bTmp & SW_3W_CMD1_DONE) != 0 )
553 {
554 break;
555 }
556 udelay(10);
557 }
558 if(TryCnt == TC_3W_POLL_MAX_TRY_CNT)
559 {
560 //RT_ASSERT(TryCnt != TC_3W_POLL_MAX_TRY_CNT,
561 // ("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear or DONE is not set!!\n", u1bTmp));
562 // Workaround suggested by wcchu: clear WE here. 2006.07.07, by rcnjko.
563 write_nic_byte(dev, SW_3W_CMD1, 0);
564 }
565
566 // Read back data for read operation.
567 // <RJ_TODO> I am not sure if this is correct output format of a read operation.
568 if(bWrite == 0)
569 {
570 if(nDataBufBitCnt == 16)
571 {
572 *((u16 *)pDataBuf) = read_nic_word(dev, SW_3W_DB0);
573 }
574 else if(nDataBufBitCnt == 64)
575 {
576 *((u32 *)pDataBuf) = read_nic_dword(dev, SW_3W_DB0);
577 *((u32 *)(pDataBuf + 4)) = read_nic_dword(dev, SW_3W_DB1);
578 }
579 else
580 {
581 int idx;
582 int ByteCnt = nDataBufBitCnt / 8;
583
584 if ((nDataBufBitCnt % 8) != 0)
585 panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
586 nDataBufBitCnt);
587
588 if (nDataBufBitCnt > 64)
589 panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
590 nDataBufBitCnt);
591
592 for(idx = 0; idx < ByteCnt; idx++)
593 {
594 *(pDataBuf+idx) = read_nic_byte(dev, (SW_3W_DB0+idx));
595 }
596 }
597 }
598
599 }while(0);
600
601 return bResult;
602}
603
604 384
605void 385void
606RF_WriteReg( 386RF_WriteReg(struct net_device *dev, u8 offset, u32 data)
607 struct net_device *dev,
608 u8 offset,
609 u32 data
610 )
611{ 387{
612 //RFReg reg; 388 u32 data2Write;
613 u32 data2Write; 389 u8 len;
614 u8 len;
615 u8 low2high;
616 //u32 RF_Read = 0;
617 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
618
619
620 switch(priv->rf_chip)
621 {
622 case RFCHIPID_RTL8225:
623 case RF_ZEBRA2: // Annie 2006-05-12.
624 case RF_ZEBRA4: //by amy
625 switch(priv->RegThreeWireMode)
626 {
627 case SW_THREE_WIRE:
628 { // Perform SW 3-wire programming by driver.
629 data2Write = (data << 4) | (u32)(offset & 0x0f);
630 len = 16;
631 low2high = 0;
632 ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
633 }
634 break;
635 390
636 case HW_THREE_WIRE: 391 /* Pure HW 3-wire. */
637 { // Pure HW 3-wire. 392 data2Write = (data << 4) | (u32)(offset & 0x0f);
638 data2Write = (data << 4) | (u32)(offset & 0x0f); 393 len = 16;
639 len = 16;
640 HwThreeWire(
641 dev,
642 (u8 *)(&data2Write), // pDataBuf,
643 len, // nDataBufBitCnt,
644 0, // bHold,
645 1); // bWrite
646 }
647 break;
648 case HW_THREE_WIRE_PI: //Parallel Interface
649 { // Pure HW 3-wire.
650 data2Write = (data << 4) | (u32)(offset & 0x0f);
651 len = 16;
652 HwHSSIThreeWire(
653 dev,
654 (u8*)(&data2Write), // pDataBuf,
655 len, // nDataBufBitCnt,
656 0, // bSI
657 1); // bWrite
658
659 //printk("33333\n");
660 }
661 break;
662
663 case HW_THREE_WIRE_SI: //Serial Interface
664 { // Pure HW 3-wire.
665 data2Write = (data << 4) | (u32)(offset & 0x0f);
666 len = 16;
667// printk(" enter ZEBRA_RFSerialWrite\n ");
668// low2high = 0;
669// ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
670
671 HwHSSIThreeWire(
672 dev,
673 (u8*)(&data2Write), // pDataBuf,
674 len, // nDataBufBitCnt,
675 1, // bSI
676 1); // bWrite
677
678// printk(" exit ZEBRA_RFSerialWrite\n ");
679 }
680 break;
681
682
683 default:
684 DMESGE("RF_WriteReg(): invalid RegThreeWireMode(%d) !!!", priv->RegThreeWireMode);
685 break;
686 }
687 break;
688
689 default:
690 DMESGE("RF_WriteReg(): unknown RFChipID: %#X", priv->rf_chip);
691 break;
692 }
693}
694
695
696void
697ZEBRA_RFSerialRead(
698 struct net_device *dev,
699 u32 data2Write,
700 u8 wLength,
701 u32 *data2Read,
702 u8 rLength,
703 u8 low2high
704 )
705{
706 ThreeWireReg twreg;
707 int i;
708 u16 oval,oval2,oval3,tmp, wReg80;
709 u32 mask;
710 u8 u1bTmp;
711 ThreeWireReg tdata;
712 //PHAL_DATA_8187 pHalData = GetHalData8187(pAdapter);
713 { // RTL8187S HSSI Read/Write Function
714 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
715 u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
716 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
717 }
718
719 wReg80 = oval = read_nic_word(dev, RFPinsOutput);
720 oval2 = read_nic_word(dev, RFPinsEnable);
721 oval3 = read_nic_word(dev, RFPinsSelect);
722
723 write_nic_word(dev, RFPinsEnable, oval2|0xf);
724 write_nic_word(dev, RFPinsSelect, oval3|0xf);
725
726 *data2Read = 0;
727
728 // We must clear BIT0-3 here, otherwise,
729 // SW_Enalbe will be true when we first call ZEBRA_RFSerialRead() after 8187MPVC open,
730 // which will cause the value read become 0. 2005.04.11, by rcnjko.
731 oval &= ~0xf;
732
733 // Avoid collision with hardware three-wire.
734 twreg.longData = 0;
735 twreg.struc.enableB = 1;
736 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(4);
737
738 twreg.longData = 0;
739 twreg.struc.enableB = 0;
740 twreg.struc.clk = 0;
741 twreg.struc.read_write = 0;
742 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(5);
743
744 mask = (low2high) ? 0x01 : ((u32)0x01<<(32-1));
745 for(i = 0; i < wLength/2; i++)
746 {
747 twreg.struc.data = ((data2Write&mask) != 0) ? 1 : 0;
748 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
749 twreg.struc.clk = 1;
750 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
751 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
752
753 mask = (low2high) ? (mask<<1): (mask>>1);
754
755 if(i == 2)
756 {
757 // Commented out by Jackie, 2004.08.26. <RJ_NOTE> We must comment out the following two lines for we cannot pull down VCOPDN during RF Serail Read.
758 //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0xe); // turn off data enable
759 //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0xe);
760
761 twreg.struc.read_write=1;
762 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
763 twreg.struc.clk = 0;
764 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
765 break;
766 }
767 twreg.struc.data = ((data2Write&mask) != 0) ? 1: 0;
768 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
769 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
770
771 twreg.struc.clk = 0;
772 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
773
774 mask = (low2high) ? (mask<<1) : (mask>>1);
775 }
776
777 twreg.struc.clk = 0;
778 twreg.struc.data = 0;
779 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
780 mask = (low2high) ? 0x01 : ((u32)0x01 << (12-1));
781
782 //
783 // 061016, by rcnjko:
784 // We must set data pin to HW controled, otherwise RF can't driver it and
785 // value RF register won't be able to read back properly.
786 //
787 write_nic_word(dev, RFPinsEnable, ( ((oval2|0x0E) & (~0x01))) );
788 394
789 for(i = 0; i < rLength; i++) 395 HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1);
790 {
791 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
792 twreg.struc.clk = 1;
793 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
794 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
795 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
796 tmp = read_nic_word(dev, RFPinsInput);
797 tdata.longData = tmp;
798 *data2Read |= tdata.struc.clk ? mask : 0;
799
800 twreg.struc.clk = 0;
801 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
802
803 mask = (low2high) ? (mask<<1) : (mask>>1);
804 }
805 twreg.struc.enableB = 1;
806 twreg.struc.clk = 0;
807 twreg.struc.data = 0;
808 twreg.struc.read_write = 1;
809 write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
810
811 //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, oval2|0x8); // Set To Output Enable
812 write_nic_word(dev, RFPinsEnable, oval2); // Set To Output Enable, <RJ_NOTE> We cannot enable BIT3 here, otherwise, we will failed to switch channel. 2005.04.12.
813 //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0x1bff);
814 write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
815 //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0x0488);
816 write_nic_word(dev, RFPinsOutput, 0x3a0);
817 //PlatformEFIOWrite2Byte(pAdapter, RFPinsOutput, 0x0480);
818} 396}
819 397
820 398u32 RF_ReadReg(struct net_device *dev, u8 offset)
821u32
822RF_ReadReg(
823 struct net_device *dev,
824 u8 offset
825 )
826{ 399{
827 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 400 u32 data2Write;
828 u32 data2Write; 401 u8 wlen;
829 u8 wlen; 402 u32 dataRead;
830 u8 rlen;
831 u8 low2high;
832 u32 dataRead;
833 403
834 switch(priv->rf_chip) 404 data2Write = ((u32)(offset & 0x0f));
835 { 405 wlen = 16;
836 case RFCHIPID_RTL8225: 406 HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0);
837 case RF_ZEBRA2: 407 dataRead = data2Write;
838 case RF_ZEBRA4:
839 switch(priv->RegThreeWireMode)
840 {
841 case HW_THREE_WIRE_PI: // For 87S Parallel Interface.
842 {
843 data2Write = ((u32)(offset&0x0f));
844 wlen=16;
845 HwHSSIThreeWire(
846 dev,
847 (u8*)(&data2Write), // pDataBuf,
848 wlen, // nDataBufBitCnt,
849 0, // bSI
850 0); // bWrite
851 dataRead= data2Write;
852 }
853 break;
854
855 case HW_THREE_WIRE_SI: // For 87S Serial Interface.
856 {
857 data2Write = ((u32)(offset&0x0f)) ;
858 wlen=16;
859 HwHSSIThreeWire(
860 dev,
861 (u8*)(&data2Write), // pDataBuf,
862 wlen, // nDataBufBitCnt,
863 1, // bSI
864 0 // bWrite
865 );
866 dataRead= data2Write;
867 }
868 break;
869
870 // Perform SW 3-wire programming by driver.
871 default:
872 {
873 data2Write = ((u32)(offset&0x1f)) << 27; // For Zebra E-cut. 2005.04.11, by rcnjko.
874 wlen = 6;
875 rlen = 12;
876 low2high = 0;
877 ZEBRA_RFSerialRead(dev, data2Write, wlen,&dataRead,rlen, low2high);
878 }
879 break;
880 }
881 break;
882 default:
883 dataRead = 0;
884 break;
885 }
886 408
887 return dataRead; 409 return dataRead;
888} 410}
@@ -1043,15 +565,12 @@ ZEBRA_Config_85BASIC_HardCode(
1043 565
1044 // Page0 : reg0-reg15 566 // Page0 : reg0-reg15
1045 567
1046// RF_WriteReg(dev, 0x00, 0x003f); mdelay(1);//1
1047 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);// 1 568 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);// 1
1048 569
1049 RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1); 570 RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
1050 571
1051// RF_WriteReg(dev, 0x02, 0x004c); mdelay(1);//2
1052 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);// 2 572 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);// 2
1053 573
1054// RF_WriteReg(dev, 0x03, 0x0000); mdelay(1);//3
1055 RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);// 3 574 RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);// 3
1056 575
1057 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); 576 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
@@ -1080,8 +599,6 @@ ZEBRA_Config_85BASIC_HardCode(
1080 599
1081 RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1); 600 RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
1082// Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. 601// Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl.
1083// RF_WriteReg(dev, 0x08, 0x0597); mdelay(1);
1084// RF_WriteReg(dev, 0x09, 0x050a); mdelay(1);
1085 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); 602 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
1086 RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1); 603 RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
1087 604
@@ -1097,7 +614,6 @@ ZEBRA_Config_85BASIC_HardCode(
1097 614
1098 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); 615 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
1099 616
1100// RF_WriteReg(dev, 0x00, 0x017f); mdelay(1);//6
1101 RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1);// 6 617 RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1);// 6
1102 618
1103 RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1); 619 RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
@@ -1106,20 +622,14 @@ ZEBRA_Config_85BASIC_HardCode(
1106 { 622 {
1107 RF_WriteReg(dev, 0x01, i); mdelay(1); 623 RF_WriteReg(dev, 0x01, i); mdelay(1);
1108 RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1); 624 RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
1109 //DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
1110 } 625 }
1111 626
1112 RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /// 203, 343 627 RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /// 203, 343
1113 //RF_WriteReg(dev, 0x06, 0x0300); mdelay(1); // 400
1114 RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); // 400 628 RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); // 400
1115 629
1116 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30, and HSSI disable 137 630 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30, and HSSI disable 137
1117 mdelay(10); // Deay 10 ms. //0xfd 631 mdelay(10); // Deay 10 ms. //0xfd
1118 632
1119// RF_WriteReg(dev, 0x0c, 0x09be); mdelay(1); // 7
1120 //RF_WriteReg(dev, 0x0c, 0x07be); mdelay(1);
1121 //mdelay(10); // Deay 10 ms. //0xfd
1122
1123 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); // Z4 synthesizer loop filter setting, 392 633 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); // Z4 synthesizer loop filter setting, 392
1124 mdelay(10); // Deay 10 ms. //0xfd 634 mdelay(10); // Deay 10 ms. //0xfd
1125 635
@@ -1165,10 +675,8 @@ ZEBRA_Config_85BASIC_HardCode(
1165 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); 675 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
1166 } 676 }
1167//by amy 080312 677//by amy 080312
1168// RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); //-by amy 080312
1169 678
1170 RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); // switch to reg0-reg15, and HSSI enable 679 RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); // switch to reg0-reg15, and HSSI enable
1171// RF_WriteReg(dev, 0x0d, 0x009f); mdelay(1); // Rx BB start calibration, 00c//-edward
1172 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); // Rx BB start calibration, 00c//+edward 680 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); // Rx BB start calibration, 00c//+edward
1173 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); // temperature meter off 681 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); // temperature meter off
1174 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); // Rx mode 682 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); // Rx mode
@@ -1217,13 +725,10 @@ ZEBRA_Config_85BASIC_HardCode(
1217 // AGC.txt 725 // AGC.txt
1218 //============================================================================= 726 //=============================================================================
1219 727
1220// PlatformIOWrite4Byte( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
1221 write_phy_ofdm(dev, 0x00, 0x12); 728 write_phy_ofdm(dev, 0x00, 0x12);
1222 //WriteBBPortUchar(dev, 0x00001280);
1223 729
1224 for (i=0; i<128; i++) 730 for (i=0; i<128; i++)
1225 { 731 {
1226 //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
1227 732
1228 data = ZEBRA_AGC[i+1]; 733 data = ZEBRA_AGC[i+1];
1229 data = data << 8; 734 data = data << 8;
@@ -1239,7 +744,6 @@ ZEBRA_Config_85BASIC_HardCode(
1239 } 744 }
1240 745
1241 PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080); // Annie, 2006-05-05 746 PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
1242 //WriteBBPortUchar(dev, 0x00001080);
1243 747
1244 //============================================================================= 748 //=============================================================================
1245 749
@@ -1252,8 +756,6 @@ ZEBRA_Config_85BASIC_HardCode(
1252 u4bRegOffset=i; 756 u4bRegOffset=i;
1253 u4bRegValue=OFDM_CONFIG[i]; 757 u4bRegValue=OFDM_CONFIG[i];
1254 758
1255 //DbgPrint("OFDM - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
1256
1257 WriteBBPortUchar(dev, 759 WriteBBPortUchar(dev,
1258 (0x00000080 | 760 (0x00000080 |
1259 (u4bRegOffset & 0x7f) | 761 (u4bRegOffset & 0x7f) |
@@ -1277,9 +779,6 @@ UpdateInitialGain(
1277 ) 779 )
1278{ 780{
1279 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 781 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1280 //unsigned char* IGTable;
1281 //u8 DIG_CurrentInitialGain = 4;
1282 //unsigned char u1Tmp;
1283 782
1284 //lzm add 080826 783 //lzm add 080826
1285 if(priv->eRFPowerState != eRfOn) 784 if(priv->eRFPowerState != eRfOn)
@@ -1291,81 +790,59 @@ UpdateInitialGain(
1291 return; 790 return;
1292 } 791 }
1293 792
1294 switch(priv->rf_chip) 793 switch (priv->InitialGain) {
1295 { 794 case 1: /* m861dBm */
1296 case RF_ZEBRA4: 795 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
1297 // Dynamic set initial gain, follow 87B 796 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1298 switch(priv->InitialGain) 797 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1299 { 798 break;
1300 case 1: //m861dBm
1301 //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm \n");
1302 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
1303 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1304 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1305 break;
1306
1307 case 2: //m862dBm
1308 //DMESG("RTL8187 + 8225 Initial Gain State 2: -82 dBm \n");
1309 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
1310 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1311 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1312 break;
1313
1314 case 3: //m863dBm
1315 //DMESG("RTL8187 + 8225 Initial Gain State 3: -82 dBm \n");
1316 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
1317 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1318 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1319 break;
1320
1321 case 4: //m864dBm
1322 //DMESG("RTL8187 + 8225 Initial Gain State 4: -78 dBm \n");
1323 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
1324 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1325 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1326 break;
1327 799
1328 case 5: //m82dBm 800 case 2: /* m862dBm */
1329 //DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm \n"); 801 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
1330 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); 802 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1331 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); 803 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1332 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); 804 break;
1333 break;
1334 805
1335 case 6: //m78dBm 806 case 3: /* m863dBm */
1336 //DMESG ("RTL8187 + 8225 Initial Gain State 6: -70 dBm \n"); 807 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
1337 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); 808 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1338 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); 809 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1339 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); 810 break;
1340 break;
1341 811
1342 case 7: //m74dBm 812 case 4: /* m864dBm */
1343 //DMESG("RTL8187 + 8225 Initial Gain State 7: -66 dBm \n"); 813 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
1344 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); 814 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
1345 write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1); 815 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1346 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); 816 break;
1347 break;
1348 817
1349 case 8: 818 case 5: /* m82dBm */
1350 //DMESG("RTL8187 + 8225 Initial Gain State 8:\n"); 819 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
1351 write_phy_ofdm(dev, 0x17, 0x66); mdelay(1); 820 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
1352 write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1); 821 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
1353 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); 822 break;
1354 break;
1355 823
824 case 6: /* m78dBm */
825 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
826 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
827 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
828 break;
1356 829
1357 default: //MP 830 case 7: /* m74dBm */
1358 //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm (default)\n"); 831 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
1359 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); 832 write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
1360 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); 833 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
1361 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1362 break;
1363 }
1364 break; 834 break;
1365 835
836 case 8:
837 write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
838 write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
839 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
840 break;
1366 841
1367 default: 842 default: /* MP */
1368 DMESG("UpdateInitialGain(): unknown RFChipID: %#X\n", priv->rf_chip); 843 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
844 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
845 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
1369 break; 846 break;
1370 } 847 }
1371} 848}
@@ -1379,13 +856,11 @@ InitTxPwrTracking87SE(
1379 struct net_device *dev 856 struct net_device *dev
1380) 857)
1381{ 858{
1382 //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1383 u32 u4bRfReg; 859 u32 u4bRfReg;
1384 860
1385 u4bRfReg = RF_ReadReg(dev, 0x02); 861 u4bRfReg = RF_ReadReg(dev, 0x02);
1386 862
1387 // Enable Thermal meter indication. 863 // Enable Thermal meter indication.
1388 //printk("InitTxPwrTracking87SE(): Enable thermal meter indication, Write RF[0x02] = %#x", u4bRfReg|PWR_METER_EN);
1389 RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1); 864 RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
1390} 865}
1391 866
@@ -1397,21 +872,14 @@ PhyConfig8185(
1397 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 872 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1398 write_nic_dword(dev, RCR, priv->ReceiveConfig); 873 write_nic_dword(dev, RCR, priv->ReceiveConfig);
1399 priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03; 874 priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
1400 // RF config 875 /* RF config */
1401 switch(priv->rf_chip) 876 ZEBRA_Config_85BASIC_HardCode(dev);
1402 {
1403 case RF_ZEBRA2:
1404 case RF_ZEBRA4:
1405 ZEBRA_Config_85BASIC_HardCode( dev);
1406 break;
1407 }
1408//{by amy 080312 877//{by amy 080312
1409 // Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. 878 // Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06.
1410 if(priv->bDigMechanism) 879 if(priv->bDigMechanism)
1411 { 880 {
1412 if(priv->InitialGain == 0) 881 if(priv->InitialGain == 0)
1413 priv->InitialGain = 4; 882 priv->InitialGain = 4;
1414 //printk("PhyConfig8185(): DIG is enabled, set default initial gain index to %d\n", priv->InitialGain);
1415 } 883 }
1416 884
1417 // 885 //
@@ -1429,34 +897,17 @@ PhyConfig8185(
1429 return; 897 return;
1430} 898}
1431 899
1432
1433
1434
1435void 900void
1436HwConfigureRTL8185( 901HwConfigureRTL8185(
1437 struct net_device *dev 902 struct net_device *dev
1438 ) 903 )
1439{ 904{
1440 //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. 905 //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
1441// u8 bUNIVERSAL_CONTROL_RL = 1;
1442 u8 bUNIVERSAL_CONTROL_RL = 0; 906 u8 bUNIVERSAL_CONTROL_RL = 0;
1443
1444 u8 bUNIVERSAL_CONTROL_AGC = 1; 907 u8 bUNIVERSAL_CONTROL_AGC = 1;
1445 u8 bUNIVERSAL_CONTROL_ANT = 1; 908 u8 bUNIVERSAL_CONTROL_ANT = 1;
1446 u8 bAUTO_RATE_FALLBACK_CTL = 1; 909 u8 bAUTO_RATE_FALLBACK_CTL = 1;
1447 u8 val8; 910 u8 val8;
1448 //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1449 //struct ieee80211_device *ieee = priv->ieee80211;
1450 //if(IS_WIRELESS_MODE_A(dev) || IS_WIRELESS_MODE_G(dev))
1451//{by amy 080312 if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
1452// {
1453// write_nic_word(dev, BRSR, 0xffff);
1454// }
1455// else
1456// {
1457// write_nic_word(dev, BRSR, 0x000f);
1458// }
1459//by amy 080312}
1460 write_nic_word(dev, BRSR, 0x0fff); 911 write_nic_word(dev, BRSR, 0x0fff);
1461 // Retry limit 912 // Retry limit
1462 val8 = read_nic_byte(dev, CW_CONF); 913 val8 = read_nic_byte(dev, CW_CONF);
@@ -1507,20 +958,11 @@ HwConfigureRTL8185(
1507 val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1; 958 val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
1508 959
1509 // <RJ_TODO_8185B> We shall set up the ARFR according to user's setting. 960 // <RJ_TODO_8185B> We shall set up the ARFR according to user's setting.
1510 //write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
1511//by amy
1512 // Aadded by Roger, 2007.11.15.
1513 PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps. 961 PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps.
1514//by amy
1515 }
1516 else
1517 {
1518 } 962 }
1519 write_nic_byte(dev, RATE_FALLBACK, val8); 963 write_nic_byte(dev, RATE_FALLBACK, val8);
1520} 964}
1521 965
1522
1523
1524static void 966static void
1525MacConfig_85BASIC_HardCode( 967MacConfig_85BASIC_HardCode(
1526 struct net_device *dev) 968 struct net_device *dev)
@@ -1548,14 +990,11 @@ MacConfig_85BASIC_HardCode(
1548 { 990 {
1549 u4bRegOffset |= (u4bPageIndex << 8); 991 u4bRegOffset |= (u4bPageIndex << 8);
1550 } 992 }
1551 //DbgPrint("MAC - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
1552 write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue); 993 write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
1553 } 994 }
1554 //============================================================================ 995 //============================================================================
1555} 996}
1556 997
1557
1558
1559static void 998static void
1560MacConfig_85BASIC( 999MacConfig_85BASIC(
1561 struct net_device *dev) 1000 struct net_device *dev)
@@ -1578,8 +1017,6 @@ MacConfig_85BASIC(
1578 PlatformIOWrite1Byte(dev, 0x1F8, 0x00); 1017 PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
1579 1018
1580 // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. 1019 // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
1581 //PlatformIOWrite4Byte(dev, RFTiming, 0x00004001);
1582//by amy
1583 // power save parameter based on "87SE power save parameters 20071127.doc", as follow. 1020 // power save parameter based on "87SE power save parameters 20071127.doc", as follow.
1584 1021
1585 //Enable DA10 TX power saving 1022 //Enable DA10 TX power saving
@@ -1598,35 +1035,18 @@ MacConfig_85BASIC(
1598 write_nic_word(dev, 0x378, 0x0560); 1035 write_nic_word(dev, 0x378, 0x0560);
1599 write_nic_word(dev, 0x37A, 0x0560); 1036 write_nic_word(dev, 0x37A, 0x0560);
1600 write_nic_word(dev, 0x37C, 0x00EC); 1037 write_nic_word(dev, 0x37C, 0x00EC);
1601// write_nic_word(dev, 0x37E, 0x00FE);//-edward
1602 write_nic_word(dev, 0x37E, 0x00EC);//+edward 1038 write_nic_word(dev, 0x37E, 0x00EC);//+edward
1603 write_nic_byte(dev, 0x24E,0x01); 1039 write_nic_byte(dev, 0x24E,0x01);
1604//by amy
1605
1606} 1040}
1607 1041
1608
1609
1610
1611u8 1042u8
1612GetSupportedWirelessMode8185( 1043GetSupportedWirelessMode8185(
1613 struct net_device *dev 1044 struct net_device *dev
1614) 1045)
1615{ 1046{
1616 u8 btSupportedWirelessMode = 0; 1047 u8 btSupportedWirelessMode = 0;
1617 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1618
1619 switch(priv->rf_chip)
1620 {
1621 case RF_ZEBRA2:
1622 case RF_ZEBRA4:
1623 btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
1624 break;
1625 default:
1626 btSupportedWirelessMode = WIRELESS_MODE_B;
1627 break;
1628 }
1629 1048
1049 btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
1630 return btSupportedWirelessMode; 1050 return btSupportedWirelessMode;
1631} 1051}
1632 1052
@@ -1641,7 +1061,6 @@ ActUpdateChannelAccessSetting(
1641 struct ieee80211_device *ieee = priv->ieee80211; 1061 struct ieee80211_device *ieee = priv->ieee80211;
1642 AC_CODING eACI; 1062 AC_CODING eACI;
1643 AC_PARAM AcParam; 1063 AC_PARAM AcParam;
1644 //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
1645 u8 bFollowLegacySetting = 0; 1064 u8 bFollowLegacySetting = 0;
1646 u8 u1bAIFS; 1065 u8 u1bAIFS;
1647 1066
@@ -1663,40 +1082,14 @@ ActUpdateChannelAccessSetting(
1663 ChnlAccessSetting->CWmaxIndex = 7; // 2006.06.02, by rcnjko. 1082 ChnlAccessSetting->CWmaxIndex = 7; // 2006.06.02, by rcnjko.
1664 1083
1665 write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer); 1084 write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
1666 //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SLOT_TIME, &ChnlAccessSetting->SlotTimeTimer ); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
1667 write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. 1085 write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
1668 1086
1669 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer ); 1087 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
1670 1088
1671 //write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
1672 //write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
1673 //write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
1674 //write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
1675
1676 write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer); 1089 write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
1677 1090
1678 write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. 1091 write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
1679 1092
1680#ifdef TODO
1681 // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
1682 if( pStaQos->CurrentQosMode > QOS_DISABLE )
1683 { // QoS mode.
1684 if(pStaQos->QBssWirelessMode == WirelessMode)
1685 {
1686 // Follow AC Parameters of the QBSS.
1687 for(eACI = 0; eACI < AC_MAX; eACI++)
1688 {
1689 Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
1690 }
1691 }
1692 else
1693 {
1694 // Follow Default WMM AC Parameters.
1695 bFollowLegacySetting = 1;
1696 }
1697 }
1698 else
1699#endif
1700 { // Legacy 802.11. 1093 { // Legacy 802.11.
1701 bFollowLegacySetting = 1; 1094 bFollowLegacySetting = 1;
1702 1095
@@ -1719,14 +1112,12 @@ ActUpdateChannelAccessSetting(
1719 AcParam.f.TXOPLimit = 0; 1112 AcParam.f.TXOPLimit = 0;
1720 1113
1721 //lzm reserved 080826 1114 //lzm reserved 080826
1722#if 1
1723 // For turbo mode setting. port from 87B by Isaiah 2008-08-01 1115 // For turbo mode setting. port from 87B by Isaiah 2008-08-01
1724 if( ieee->current_network.Turbo_Enable == 1 ) 1116 if( ieee->current_network.Turbo_Enable == 1 )
1725 AcParam.f.TXOPLimit = 0x01FF; 1117 AcParam.f.TXOPLimit = 0x01FF;
1726 // For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB) 1118 // For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB)
1727 if (ieee->iw_mode == IW_MODE_ADHOC) 1119 if (ieee->iw_mode == IW_MODE_ADHOC)
1728 AcParam.f.TXOPLimit = 0x0020; 1120 AcParam.f.TXOPLimit = 0x0020;
1729#endif
1730 1121
1731 for(eACI = 0; eACI < AC_MAX; eACI++) 1122 for(eACI = 0; eACI < AC_MAX; eACI++)
1732 { 1123 {
@@ -1770,18 +1161,13 @@ ActUpdateChannelAccessSetting(
1770 1161
1771 // Cehck ACM bit. 1162 // Cehck ACM bit.
1772 // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. 1163 // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
1773 //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
1774 { 1164 {
1775 PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn); 1165 PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
1776 AC_CODING eACI = pAciAifsn->f.ACI; 1166 AC_CODING eACI = pAciAifsn->f.ACI;
1777 1167
1778 //modified Joseph 1168 //modified Joseph
1779 //for 8187B AsynIORead issue 1169 //for 8187B AsynIORead issue
1780#ifdef TODO
1781 u8 AcmCtrl = pHalData->AcmControl;
1782#else
1783 u8 AcmCtrl = 0; 1170 u8 AcmCtrl = 0;
1784#endif
1785 if( pAciAifsn->f.ACM ) 1171 if( pAciAifsn->f.ACM )
1786 { // ACM bit is 1. 1172 { // ACM bit is 1.
1787 switch(eACI) 1173 switch(eACI)
@@ -1823,19 +1209,10 @@ ActUpdateChannelAccessSetting(
1823 break; 1209 break;
1824 } 1210 }
1825 } 1211 }
1826
1827 //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
1828
1829#ifdef TO_DO
1830 pHalData->AcmControl = AcmCtrl;
1831#endif
1832 //write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
1833 write_nic_byte(dev, ACM_CONTROL, 0); 1212 write_nic_byte(dev, ACM_CONTROL, 0);
1834 } 1213 }
1835 } 1214 }
1836 } 1215 }
1837
1838
1839 } 1216 }
1840} 1217}
1841 1218
@@ -1847,7 +1224,6 @@ ActSetWirelessMode8185(
1847{ 1224{
1848 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1225 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1849 struct ieee80211_device *ieee = priv->ieee80211; 1226 struct ieee80211_device *ieee = priv->ieee80211;
1850 //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
1851 u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev); 1227 u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
1852 1228
1853 if( (btWirelessMode & btSupportedWirelessMode) == 0 ) 1229 if( (btWirelessMode & btSupportedWirelessMode) == 0 )
@@ -1880,24 +1256,11 @@ ActSetWirelessMode8185(
1880 } 1256 }
1881 } 1257 }
1882 1258
1883 1259 /* 2. Swtich band: RF or BB specific actions,
1884 // 2. Swtich band: RF or BB specific actions, 1260 * for example, refresh tables in omc8255, or change initial gain if necessary.
1885 // for example, refresh tables in omc8255, or change initial gain if necessary. 1261 * Nothing to do for Zebra to switch band.
1886 switch(priv->rf_chip) 1262 * Update current wireless mode if we swtich to specified band successfully. */
1887 { 1263 ieee->mode = (WIRELESS_MODE)btWirelessMode;
1888 case RF_ZEBRA2:
1889 case RF_ZEBRA4:
1890 {
1891 // Nothing to do for Zebra to switch band.
1892 // Update current wireless mode if we swtich to specified band successfully.
1893 ieee->mode = (WIRELESS_MODE)btWirelessMode;
1894 }
1895 break;
1896
1897 default:
1898 DMESGW("ActSetWirelessMode8185(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
1899 break;
1900 }
1901 1264
1902 // 3. Change related setting. 1265 // 3. Change related setting.
1903 if( ieee->mode == WIRELESS_MODE_A ){ 1266 if( ieee->mode == WIRELESS_MODE_A ){
@@ -1909,7 +1272,6 @@ ActSetWirelessMode8185(
1909 else if( ieee->mode == WIRELESS_MODE_G ){ 1272 else if( ieee->mode == WIRELESS_MODE_G ){
1910 DMESG("WIRELESS_MODE_G\n"); 1273 DMESG("WIRELESS_MODE_G\n");
1911 } 1274 }
1912
1913 ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting); 1275 ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
1914} 1276}
1915 1277
@@ -1927,11 +1289,7 @@ DrvIFIndicateDisassociation(
1927 u16 reason 1289 u16 reason
1928 ) 1290 )
1929{ 1291{
1930 //printk("==> DrvIFIndicateDisassociation()\n");
1931
1932 // nothing is needed after disassociation request. 1292 // nothing is needed after disassociation request.
1933
1934 //printk("<== DrvIFIndicateDisassociation()\n");
1935} 1293}
1936void 1294void
1937MgntDisconnectIBSS( 1295MgntDisconnectIBSS(
@@ -1941,11 +1299,7 @@ MgntDisconnectIBSS(
1941 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1299 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1942 u8 i; 1300 u8 i;
1943 1301
1944 //printk("XXXXXXXXXX MgntDisconnect IBSS\n");
1945
1946 DrvIFIndicateDisassociation(dev, unspec_reason); 1302 DrvIFIndicateDisassociation(dev, unspec_reason);
1947
1948// PlatformZeroMemory( pMgntInfo->Bssid, 6 );
1949 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x55; 1303 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x55;
1950 1304
1951 priv->ieee80211->state = IEEE80211_NOLINK; 1305 priv->ieee80211->state = IEEE80211_NOLINK;
@@ -1957,16 +1311,10 @@ MgntDisconnectIBSS(
1957 // Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send. 1311 // Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
1958 1312
1959 // Disable Beacon Queue Own bit, suggested by jong 1313 // Disable Beacon Queue Own bit, suggested by jong
1960// Adapter->HalFunc.SetTxDescOWNHandler(Adapter, BEACON_QUEUE, 0, 0);
1961 ieee80211_stop_send_beacons(priv->ieee80211); 1314 ieee80211_stop_send_beacons(priv->ieee80211);
1962 1315
1963 priv->ieee80211->link_change(dev); 1316 priv->ieee80211->link_change(dev);
1964 notify_wx_assoc_event(priv->ieee80211); 1317 notify_wx_assoc_event(priv->ieee80211);
1965
1966 // Stop SW Beacon.Use hw beacon so do not need to do so.by amy
1967
1968// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
1969
1970} 1318}
1971void 1319void
1972MlmeDisassociateRequest( 1320MlmeDisassociateRequest(
@@ -1986,14 +1334,8 @@ MlmeDisassociateRequest(
1986 DrvIFIndicateDisassociation(dev, unspec_reason); 1334 DrvIFIndicateDisassociation(dev, unspec_reason);
1987 1335
1988 1336
1989 // pMgntInfo->AsocTimestamp = 0;
1990 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22; 1337 for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22;
1991// pMgntInfo->mBrates.Length = 0;
1992// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
1993
1994 ieee80211_disassociate(priv->ieee80211); 1338 ieee80211_disassociate(priv->ieee80211);
1995
1996
1997 } 1339 }
1998 1340
1999} 1341}
@@ -2011,23 +1353,12 @@ MgntDisconnectAP(
2011// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). 1353// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
2012// 1354//
2013// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success 1355// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
2014// SecClearAllKeys(Adapter);
2015 1356
2016 // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. 1357 // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
2017#ifdef TODO
2018 if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
2019 (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key
2020 {
2021 SecClearAllKeys(Adapter);
2022 RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
2023 }
2024#endif
2025 // 2004.10.11, by rcnjko. 1358 // 2004.10.11, by rcnjko.
2026 //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
2027 MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn ); 1359 MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
2028 1360
2029 priv->ieee80211->state = IEEE80211_NOLINK; 1361 priv->ieee80211->state = IEEE80211_NOLINK;
2030// pMgntInfo->AsocTimestamp = 0;
2031} 1362}
2032bool 1363bool
2033MgntDisconnect( 1364MgntDisconnect(
@@ -2039,20 +1370,7 @@ MgntDisconnect(
2039 // 1370 //
2040 // Schedule an workitem to wake up for ps mode, 070109, by rcnjko. 1371 // Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
2041 // 1372 //
2042#ifdef TODO
2043 if(pMgntInfo->mPss != eAwake)
2044 {
2045 //
2046 // Using AwkaeTimer to prevent mismatch ps state.
2047 // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
2048 //
2049 // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
2050 PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
2051 }
2052#endif
2053 1373
2054 // Indication of disassociation event.
2055 //DrvIFIndicateDisassociation(Adapter, asRsn);
2056 if(IS_DOT11D_ENABLE(priv->ieee80211)) 1374 if(IS_DOT11D_ENABLE(priv->ieee80211))
2057 Dot11d_Reset(priv->ieee80211); 1375 Dot11d_Reset(priv->ieee80211);
2058 // In adhoc mode, update beacon frame. 1376 // In adhoc mode, update beacon frame.
@@ -2060,8 +1378,6 @@ MgntDisconnect(
2060 { 1378 {
2061 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC ) 1379 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
2062 { 1380 {
2063// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectIBSS\n"));
2064 //printk("MgntDisconnect() ===> MgntDisconnectIBSS\n");
2065 MgntDisconnectIBSS(dev); 1381 MgntDisconnectIBSS(dev);
2066 } 1382 }
2067 if( priv->ieee80211->iw_mode == IW_MODE_INFRA ) 1383 if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
@@ -2071,17 +1387,10 @@ MgntDisconnect(
2071 // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is 1387 // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
2072 // used to handle disassociation related things to AP, e.g. send Disassoc 1388 // used to handle disassociation related things to AP, e.g. send Disassoc
2073 // frame to AP. 2005.01.27, by rcnjko. 1389 // frame to AP. 2005.01.27, by rcnjko.
2074// SecClearAllKeys(Adapter);
2075
2076// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectAP\n"));
2077 //printk("MgntDisconnect() ===> MgntDisconnectAP\n");
2078 MgntDisconnectAP(dev, asRsn); 1390 MgntDisconnectAP(dev, asRsn);
2079 } 1391 }
2080
2081 // Inidicate Disconnect, 2005.02.23, by rcnjko. 1392 // Inidicate Disconnect, 2005.02.23, by rcnjko.
2082// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
2083 } 1393 }
2084
2085 return true; 1394 return true;
2086} 1395}
2087// 1396//
@@ -2101,25 +1410,12 @@ SetRFPowerState(
2101 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1410 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2102 bool bResult = false; 1411 bool bResult = false;
2103 1412
2104// printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
2105 if(eRFPowerState == priv->eRFPowerState) 1413 if(eRFPowerState == priv->eRFPowerState)
2106 { 1414 {
2107// printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
2108 return bResult; 1415 return bResult;
2109 } 1416 }
2110 1417
2111 switch(priv->rf_chip) 1418 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
2112 {
2113 case RF_ZEBRA2:
2114 case RF_ZEBRA4:
2115 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
2116 break;
2117
2118 default:
2119 printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
2120 break;;
2121}
2122// printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
2123 1419
2124 return bResult; 1420 return bResult;
2125} 1421}
@@ -2149,33 +1445,25 @@ MgntActSet_RF_State(
2149 RT_RF_POWER_STATE rtState; 1445 RT_RF_POWER_STATE rtState;
2150 u16 RFWaitCounter = 0; 1446 u16 RFWaitCounter = 0;
2151 unsigned long flag; 1447 unsigned long flag;
2152// printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
2153 // 1448 //
2154 // Prevent the race condition of RF state change. By Bruce, 2007-11-28. 1449 // Prevent the race condition of RF state change. By Bruce, 2007-11-28.
2155 // Only one thread can change the RF state at one time, and others should wait to be executed. 1450 // Only one thread can change the RF state at one time, and others should wait to be executed.
2156 // 1451 //
2157#if 1
2158 while(true) 1452 while(true)
2159 { 1453 {
2160// down(&priv->rf_state);
2161 spin_lock_irqsave(&priv->rf_ps_lock,flag); 1454 spin_lock_irqsave(&priv->rf_ps_lock,flag);
2162 if(priv->RFChangeInProgress) 1455 if(priv->RFChangeInProgress)
2163 { 1456 {
2164// printk("====================>haha111111111\n");
2165// up(&priv->rf_state);
2166// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
2167 spin_unlock_irqrestore(&priv->rf_ps_lock,flag); 1457 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
2168 // Set RF after the previous action is done. 1458 // Set RF after the previous action is done.
2169 while(priv->RFChangeInProgress) 1459 while(priv->RFChangeInProgress)
2170 { 1460 {
2171 RFWaitCounter ++; 1461 RFWaitCounter ++;
2172// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
2173 udelay(1000); // 1 ms 1462 udelay(1000); // 1 ms
2174 1463
2175 // Wait too long, return FALSE to avoid to be stuck here. 1464 // Wait too long, return FALSE to avoid to be stuck here.
2176 if(RFWaitCounter > 1000) // 1sec 1465 if(RFWaitCounter > 1000) // 1sec
2177 { 1466 {
2178// RT_ASSERT(FALSE, ("MgntActSet_RF_State(): Wait too logn to set RF\n"));
2179 printk("MgntActSet_RF_State(): Wait too long to set RF\n"); 1467 printk("MgntActSet_RF_State(): Wait too long to set RF\n");
2180 // TODO: Reset RF state? 1468 // TODO: Reset RF state?
2181 return false; 1469 return false;
@@ -2184,17 +1472,13 @@ MgntActSet_RF_State(
2184 } 1472 }
2185 else 1473 else
2186 { 1474 {
2187// printk("========================>haha2\n");
2188 priv->RFChangeInProgress = true; 1475 priv->RFChangeInProgress = true;
2189// up(&priv->rf_state);
2190 spin_unlock_irqrestore(&priv->rf_ps_lock,flag); 1476 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
2191 break; 1477 break;
2192 } 1478 }
2193 } 1479 }
2194#endif
2195 rtState = priv->eRFPowerState; 1480 rtState = priv->eRFPowerState;
2196 1481
2197
2198 switch(StateToSet) 1482 switch(StateToSet)
2199 { 1483 {
2200 case eRfOn: 1484 case eRfOn:
@@ -2215,7 +1499,6 @@ MgntActSet_RF_State(
2215 } 1499 }
2216 } 1500 }
2217 else 1501 else
2218// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", pMgntInfo->RfOffReason, ChangeSource));
2219 ; 1502 ;
2220 break; 1503 break;
2221 1504
@@ -2232,38 +1515,26 @@ MgntActSet_RF_State(
2232 // 1515 //
2233 // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), 1516 // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
2234 // because we do NOT need to set ssid to dummy ones. 1517 // because we do NOT need to set ssid to dummy ones.
2235 // Revised by Roger, 2007.12.04.
2236 // 1518 //
2237 MgntDisconnect( dev, disas_lv_ss ); 1519 MgntDisconnect( dev, disas_lv_ss );
2238 1520
2239 // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. 1521 // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
2240 // 2007.05.28, by shien chang.
2241// PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
2242// pMgntInfo->NumBssDesc = 0;
2243// PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
2244// pMgntInfo->NumBssDesc4Query = 0;
2245 } 1522 }
2246 1523
2247
2248
2249 priv->RfOffReason |= ChangeSource; 1524 priv->RfOffReason |= ChangeSource;
2250 bActionAllowed = true; 1525 bActionAllowed = true;
2251 break; 1526 break;
2252
2253 case eRfSleep: 1527 case eRfSleep:
2254 priv->RfOffReason |= ChangeSource; 1528 priv->RfOffReason |= ChangeSource;
2255 bActionAllowed = true; 1529 bActionAllowed = true;
2256 break; 1530 break;
2257
2258 default: 1531 default:
2259 break; 1532 break;
2260 } 1533 }
2261 1534
2262 if(bActionAllowed) 1535 if(bActionAllowed)
2263 { 1536 {
2264// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, pMgntInfo->RfOffReason));
2265 // Config HW to the specified mode. 1537 // Config HW to the specified mode.
2266// printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
2267 SetRFPowerState(dev, StateToSet); 1538 SetRFPowerState(dev, StateToSet);
2268 1539
2269 // Turn on RF. 1540 // Turn on RF.
@@ -2273,7 +1544,6 @@ MgntActSet_RF_State(
2273 if(bConnectBySSID) 1544 if(bConnectBySSID)
2274 { 1545 {
2275 // by amy not supported 1546 // by amy not supported
2276// MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
2277 } 1547 }
2278 } 1548 }
2279 // Turn off RF. 1549 // Turn off RF.
@@ -2282,18 +1552,11 @@ MgntActSet_RF_State(
2282 HalDisableRx8185Dummy(dev); 1552 HalDisableRx8185Dummy(dev);
2283 } 1553 }
2284 } 1554 }
2285 else
2286 {
2287 // printk("MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason);
2288 }
2289 1555
2290 // Release RF spinlock 1556 // Release RF spinlock
2291// down(&priv->rf_state);
2292 spin_lock_irqsave(&priv->rf_ps_lock,flag); 1557 spin_lock_irqsave(&priv->rf_ps_lock,flag);
2293 priv->RFChangeInProgress = false; 1558 priv->RFChangeInProgress = false;
2294// up(&priv->rf_state);
2295 spin_unlock_irqrestore(&priv->rf_ps_lock,flag); 1559 spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
2296// printk("<===MgntActSet_RF_State()\n");
2297 return bActionAllowed; 1560 return bActionAllowed;
2298} 1561}
2299void 1562void
@@ -2302,15 +1565,12 @@ InactivePowerSave(
2302 ) 1565 )
2303{ 1566{
2304 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1567 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2305 //u8 index = 0;
2306
2307 // 1568 //
2308 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem 1569 // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
2309 // is really scheduled. 1570 // is really scheduled.
2310 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the 1571 // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
2311 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing 1572 // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
2312 // blocks the IPS procedure of switching RF. 1573 // blocks the IPS procedure of switching RF.
2313 // By Bruce, 2007-12-25.
2314 // 1574 //
2315 priv->bSwRfProcessing = true; 1575 priv->bSwRfProcessing = true;
2316 1576
@@ -2326,7 +1586,6 @@ InactivePowerSave(
2326// 1586//
2327// Description: 1587// Description:
2328// Enter the inactive power save mode. RF will be off 1588// Enter the inactive power save mode. RF will be off
2329// 2007.08.17, by shien chang.
2330// 1589//
2331void 1590void
2332IPSEnter( 1591IPSEnter(
@@ -2335,13 +1594,11 @@ IPSEnter(
2335{ 1594{
2336 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1595 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2337 RT_RF_POWER_STATE rtState; 1596 RT_RF_POWER_STATE rtState;
2338 //printk("==============================>enter IPS\n");
2339 if (priv->bInactivePs) 1597 if (priv->bInactivePs)
2340 { 1598 {
2341 rtState = priv->eRFPowerState; 1599 rtState = priv->eRFPowerState;
2342 1600
2343 // 1601 //
2344 // Added by Bruce, 2007-12-25.
2345 // Do not enter IPS in the following conditions: 1602 // Do not enter IPS in the following conditions:
2346 // (1) RF is already OFF or Sleep 1603 // (1) RF is already OFF or Sleep
2347 // (2) bSwRfProcessing (indicates the IPS is still under going) 1604 // (2) bSwRfProcessing (indicates the IPS is still under going)
@@ -2352,12 +1609,10 @@ IPSEnter(
2352 if (rtState == eRfOn && !priv->bSwRfProcessing 1609 if (rtState == eRfOn && !priv->bSwRfProcessing
2353 && (priv->ieee80211->state != IEEE80211_LINKED )) 1610 && (priv->ieee80211->state != IEEE80211_LINKED ))
2354 { 1611 {
2355 // printk("IPSEnter(): Turn off RF.\n");
2356 priv->eInactivePowerState = eRfOff; 1612 priv->eInactivePowerState = eRfOff;
2357 InactivePowerSave(dev); 1613 InactivePowerSave(dev);
2358 } 1614 }
2359 } 1615 }
2360// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
2361} 1616}
2362void 1617void
2363IPSLeave( 1618IPSLeave(
@@ -2366,20 +1621,17 @@ IPSLeave(
2366{ 1621{
2367 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1622 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2368 RT_RF_POWER_STATE rtState; 1623 RT_RF_POWER_STATE rtState;
2369 //printk("===================================>leave IPS\n");
2370 if (priv->bInactivePs) 1624 if (priv->bInactivePs)
2371 { 1625 {
2372 rtState = priv->eRFPowerState; 1626 rtState = priv->eRFPowerState;
2373 if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) 1627 if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
2374 { 1628 {
2375// printk("IPSLeave(): Turn on RF.\n");
2376 priv->eInactivePowerState = eRfOn; 1629 priv->eInactivePowerState = eRfOn;
2377 InactivePowerSave(dev); 1630 InactivePowerSave(dev);
2378 } 1631 }
2379 } 1632 }
2380// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
2381} 1633}
2382//by amy for power save 1634
2383void rtl8185b_adapter_start(struct net_device *dev) 1635void rtl8185b_adapter_start(struct net_device *dev)
2384{ 1636{
2385 struct r8180_priv *priv = ieee80211_priv(dev); 1637 struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2388,75 +1640,45 @@ void rtl8185b_adapter_start(struct net_device *dev)
2388 u8 SupportedWirelessMode; 1640 u8 SupportedWirelessMode;
2389 u8 InitWirelessMode; 1641 u8 InitWirelessMode;
2390 u8 bInvalidWirelessMode = 0; 1642 u8 bInvalidWirelessMode = 0;
2391 //int i;
2392 u8 tmpu8; 1643 u8 tmpu8;
2393 //u8 u1tmp,u2tmp;
2394 u8 btCR9346; 1644 u8 btCR9346;
2395 u8 TmpU1b; 1645 u8 TmpU1b;
2396 u8 btPSR; 1646 u8 btPSR;
2397 1647
2398 //rtl8180_rtx_disable(dev);
2399//{by amy 080312
2400 write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0)); 1648 write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0));
2401//by amy 080312}
2402 rtl8180_reset(dev); 1649 rtl8180_reset(dev);
2403 1650
2404 priv->dma_poll_mask = 0; 1651 priv->dma_poll_mask = 0;
2405 priv->dma_poll_stop_mask = 0; 1652 priv->dma_poll_stop_mask = 0;
2406 1653
2407 //rtl8180_beacon_tx_disable(dev);
2408
2409 HwConfigureRTL8185(dev); 1654 HwConfigureRTL8185(dev);
2410
2411 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]); 1655 write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
2412 write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff ); 1656 write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
2413
2414 write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); // default network type to 'No Link' 1657 write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); // default network type to 'No Link'
2415
2416 //write_nic_byte(dev, BRSR, 0x0); // Set BRSR= 1M
2417
2418 write_nic_word(dev, BcnItv, 100); 1658 write_nic_word(dev, BcnItv, 100);
2419 write_nic_word(dev, AtimWnd, 2); 1659 write_nic_word(dev, AtimWnd, 2);
2420
2421 //PlatformEFIOWrite2Byte(dev, FEMR, 0xFFFF);
2422 PlatformIOWrite2Byte(dev, FEMR, 0xFFFF); 1660 PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
2423
2424 write_nic_byte(dev, WPA_CONFIG, 0); 1661 write_nic_byte(dev, WPA_CONFIG, 0);
2425
2426 MacConfig_85BASIC(dev); 1662 MacConfig_85BASIC(dev);
2427
2428 // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. 1663 // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
2429 // BT_DEMO_BOARD type 1664 // BT_DEMO_BOARD type
2430 PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a); 1665 PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
2431//by amy
2432//#ifdef CONFIG_RTL818X_S
2433 // for jong required
2434// PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
2435//#endif
2436//by amy
2437 //BT_QA_BOARD
2438 //PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
2439 1666
2440 //----------------------------------------------------------------------------- 1667 //-----------------------------------------------------------------------------
2441 // Set up PHY related. 1668 // Set up PHY related.
2442 //----------------------------------------------------------------------------- 1669 //-----------------------------------------------------------------------------
2443 // Enable Config3.PARAM_En to revise AnaaParm. 1670 // Enable Config3.PARAM_En to revise AnaaParm.
2444 write_nic_byte(dev, CR9346, 0xc0); // enable config register write 1671 write_nic_byte(dev, CR9346, 0xc0); // enable config register write
2445//by amy
2446 tmpu8 = read_nic_byte(dev, CONFIG3); 1672 tmpu8 = read_nic_byte(dev, CONFIG3);
2447 write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) ); 1673 write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) );
2448//by amy
2449 // Turn on Analog power. 1674 // Turn on Analog power.
2450 // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. 1675 // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
2451 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON); 1676 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
2452 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON); 1677 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
2453//by amy
2454 write_nic_word(dev, ANAPARAM3, 0x0010); 1678 write_nic_word(dev, ANAPARAM3, 0x0010);
2455//by amy
2456 1679
2457 write_nic_byte(dev, CONFIG3, tmpu8); 1680 write_nic_byte(dev, CONFIG3, tmpu8);
2458 write_nic_byte(dev, CR9346, 0x00); 1681 write_nic_byte(dev, CR9346, 0x00);
2459//{by amy 080312 for led
2460 // enable EEM0 and EEM1 in 9346CR 1682 // enable EEM0 and EEM1 in 9346CR
2461 btCR9346 = read_nic_byte(dev, CR9346); 1683 btCR9346 = read_nic_byte(dev, CR9346);
2462 write_nic_byte(dev, CR9346, (btCR9346|0xC0) ); 1684 write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
@@ -2474,7 +1696,6 @@ void rtl8185b_adapter_start(struct net_device *dev)
2474 // B-cut RF Radio on/off 5e[3]=0 1696 // B-cut RF Radio on/off 5e[3]=0
2475 btPSR = read_nic_byte(dev, PSR); 1697 btPSR = read_nic_byte(dev, PSR);
2476 write_nic_byte(dev, PSR, (btPSR | BIT3)); 1698 write_nic_byte(dev, PSR, (btPSR | BIT3));
2477//by amy 080312 for led}
2478 // setup initial timing for RFE. 1699 // setup initial timing for RFE.
2479 write_nic_word(dev, RFPinsOutput, 0x0480); 1700 write_nic_word(dev, RFPinsOutput, 0x0480);
2480 SetOutputEnableOfRfPins(dev); 1701 SetOutputEnableOfRfPins(dev);
@@ -2537,55 +1758,19 @@ void rtl8185b_adapter_start(struct net_device *dev)
2537 InitWirelessMode = ieee->mode; 1758 InitWirelessMode = ieee->mode;
2538 } 1759 }
2539//by amy for power save 1760//by amy for power save
2540// printk("initialize ENABLE_IPS\n");
2541 priv->eRFPowerState = eRfOff; 1761 priv->eRFPowerState = eRfOff;
2542 priv->RfOffReason = 0; 1762 priv->RfOffReason = 0;
2543 { 1763 {
2544 // u32 tmp2;
2545 // u32 tmp = jiffies;
2546 MgntActSet_RF_State(dev, eRfOn, 0); 1764 MgntActSet_RF_State(dev, eRfOn, 0);
2547 // tmp2 = jiffies;
2548 // printk("rf on cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
2549 } 1765 }
2550// DrvIFIndicateCurrentPhyStatus(priv);
2551 // 1766 //
2552 // If inactive power mode is enabled, disable rf while in disconnected state. 1767 // If inactive power mode is enabled, disable rf while in disconnected state.
2553 // 2007.07.16, by shien chang.
2554 // 1768 //
2555 if (priv->bInactivePs) 1769 if (priv->bInactivePs)
2556 { 1770 {
2557 // u32 tmp2;
2558 // u32 tmp = jiffies;
2559 MgntActSet_RF_State(dev,eRfOff, RF_CHANGE_BY_IPS); 1771 MgntActSet_RF_State(dev,eRfOff, RF_CHANGE_BY_IPS);
2560 // tmp2 = jiffies;
2561 // printk("rf off cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
2562
2563 } 1772 }
2564// IPSEnter(dev);
2565//by amy for power save 1773//by amy for power save
2566#ifdef TODO
2567 // Turn off RF if necessary. 2005.08.23, by rcnjko.
2568 // We shall turn off RF after setting CMDR, otherwise,
2569 // RF will be turnned on after we enable MAC Tx/Rx.
2570 if(Adapter->MgntInfo.RegRfOff == TRUE)
2571 {
2572 SetRFPowerState8185(Adapter, RF_OFF);
2573 }
2574 else
2575 {
2576 SetRFPowerState8185(Adapter, RF_ON);
2577 }
2578#endif
2579
2580/* //these is equal with above TODO.
2581 write_nic_byte(dev, CR9346, 0xc0); // enable config register write
2582 write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3) | CONFIG3_PARM_En);
2583 RF_WriteReg(dev, 0x4, 0x9FF);
2584 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
2585 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
2586 write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
2587 write_nic_byte(dev, CR9346, 0x00);
2588*/
2589 1774
2590 ActSetWirelessMode8185(dev, (u8)(InitWirelessMode)); 1775 ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
2591 1776
@@ -2594,14 +1779,11 @@ void rtl8185b_adapter_start(struct net_device *dev)
2594 rtl8185b_irq_enable(dev); 1779 rtl8185b_irq_enable(dev);
2595 1780
2596 netif_start_queue(dev); 1781 netif_start_queue(dev);
2597
2598 } 1782 }
2599 1783
2600
2601void rtl8185b_rx_enable(struct net_device *dev) 1784void rtl8185b_rx_enable(struct net_device *dev)
2602{ 1785{
2603 u8 cmd; 1786 u8 cmd;
2604 //u32 rxconf;
2605 /* for now we accept data, management & ctl frame*/ 1787 /* for now we accept data, management & ctl frame*/
2606 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1788 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2607 1789
@@ -2613,11 +1795,6 @@ void rtl8185b_rx_enable(struct net_device *dev)
2613 priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP; 1795 priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
2614 } 1796 }
2615 1797
2616 /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
2617 rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
2618 rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
2619 }*/
2620
2621 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){ 1798 if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
2622 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV; 1799 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
2623 } 1800 }
@@ -2629,9 +1806,6 @@ void rtl8185b_rx_enable(struct net_device *dev)
2629 1806
2630 fix_rx_fifo(dev); 1807 fix_rx_fifo(dev);
2631 1808
2632#ifdef DEBUG_RX
2633 DMESG("rxconf: %x %x",priv->ReceiveConfig ,read_nic_dword(dev,RCR));
2634#endif
2635 cmd=read_nic_byte(dev,CMD); 1809 cmd=read_nic_byte(dev,CMD);
2636 write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT)); 1810 write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
2637 1811
@@ -2640,9 +1814,7 @@ void rtl8185b_rx_enable(struct net_device *dev)
2640void rtl8185b_tx_enable(struct net_device *dev) 1814void rtl8185b_tx_enable(struct net_device *dev)
2641{ 1815{
2642 u8 cmd; 1816 u8 cmd;
2643 //u8 tx_agc_ctl;
2644 u8 byte; 1817 u8 byte;
2645 //u32 txconf;
2646 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1818 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
2647 1819
2648 write_nic_dword(dev, TCR, priv->TransmitConfig); 1820 write_nic_dword(dev, TCR, priv->TransmitConfig);
@@ -2652,21 +1824,7 @@ void rtl8185b_tx_enable(struct net_device *dev)
2652 1824
2653 fix_tx_fifo(dev); 1825 fix_tx_fifo(dev);
2654 1826
2655#ifdef DEBUG_TX
2656 DMESG("txconf: %x %x",priv->TransmitConfig,read_nic_dword(dev,TCR));
2657#endif
2658
2659 cmd=read_nic_byte(dev,CMD); 1827 cmd=read_nic_byte(dev,CMD);
2660 write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT)); 1828 write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
2661
2662 //write_nic_dword(dev,TX_CONF,txconf);
2663
2664
2665/*
2666 rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
2667 write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
2668 rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
2669 */
2670} 1829}
2671 1830
2672
diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile
index 5e4aa9546b51..e032c3e1e864 100644
--- a/drivers/staging/rtl8192e/Makefile
+++ b/drivers/staging/rtl8192e/Makefile
@@ -1,13 +1,15 @@
1NIC_SELECT = RTL8192E 1NIC_SELECT = RTL8192E
2 2
3
4EXTRA_CFLAGS += -DRTL8192E 3EXTRA_CFLAGS += -DRTL8192E
5EXTRA_CFLAGS += -std=gnu89 4EXTRA_CFLAGS += -std=gnu89
6EXTRA_CFLAGS += -O2 5EXTRA_CFLAGS += -O2
7EXTRA_CFLAGS += -DTHOMAS_TURBO 6EXTRA_CFLAGS += -DTHOMAS_TURBO
8EXTRA_CFLAGS += -DENABLE_DOT11D 7EXTRA_CFLAGS += -DENABLE_DOT11D
9 8
10r8192_pci-objs := \ 9EXTRA_CFLAGS += -DENABLE_IPS
10EXTRA_CFLAGS += -DENABLE_LPS
11
12r8192e_pci-objs := \
11 r8192E_core.o \ 13 r8192E_core.o \
12 r8180_93cx6.o \ 14 r8180_93cx6.o \
13 r8192E_wx.o \ 15 r8192E_wx.o \
@@ -31,4 +33,5 @@ r8192_pci-objs := \
31 ieee80211/ieee80211_crypt_ccmp.o \ 33 ieee80211/ieee80211_crypt_ccmp.o \
32 ieee80211/ieee80211_crypt_wep.o 34 ieee80211/ieee80211_crypt_wep.o
33 35
34obj-$(CONFIG_RTL8192E) += r8192_pci.o 36obj-$(CONFIG_RTL8192E) += r8192e_pci.o
37
diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h
index 15b7a4ba37b6..5b0e2dbc2bb8 100644
--- a/drivers/staging/rtl8192e/dot11d.h
+++ b/drivers/staging/rtl8192e/dot11d.h
@@ -1,102 +1,96 @@
1#ifndef __INC_DOT11D_H 1#ifndef INC_DOT11D_H
2#define __INC_DOT11D_H 2#define INC_DOT11D_H
3 3
4#ifdef ENABLE_DOT11D 4#ifdef ENABLE_DOT11D
5#include "ieee80211.h" 5#include "ieee80211.h"
6 6
7//#define ENABLE_DOT11D
8
9//#define DOT11D_MAX_CHNL_NUM 83
10
11typedef struct _CHNL_TXPOWER_TRIPLE { 7typedef struct _CHNL_TXPOWER_TRIPLE {
12 u8 FirstChnl; 8 u8 FirstChnl;
13 u8 NumChnls; 9 u8 NumChnls;
14 u8 MaxTxPowerInDbm; 10 u8 MaxTxPowerInDbm;
15}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; 11} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
16 12
17typedef enum _DOT11D_STATE { 13typedef enum _DOT11D_STATE {
18 DOT11D_STATE_NONE = 0, 14 DOT11D_STATE_NONE = 0,
19 DOT11D_STATE_LEARNED, 15 DOT11D_STATE_LEARNED,
20 DOT11D_STATE_DONE, 16 DOT11D_STATE_DONE,
21}DOT11D_STATE; 17} DOT11D_STATE;
18
19/**
20 * struct _RT_DOT11D_INFO
21 * @CountryIeLen: value greater than 0 if @CountryIeBuf contains
22 * valid country information element.
23 * @chanell_map: holds channel values
24 * 0 - invalid,
25 * 1 - valid (active scan),
26 * 2 - valid (passive scan)
27 * @CountryIeSrcAddr - Source AP of the country IE
28 */
22 29
23typedef struct _RT_DOT11D_INFO { 30typedef struct _RT_DOT11D_INFO {
24 //DECLARE_RT_OBJECT(RT_DOT11D_INFO); 31 bool bEnabled;
25 32
26 bool bEnabled; // dot11MultiDomainCapabilityEnabled 33 u16 CountryIeLen;
34 u8 CountryIeBuf[MAX_IE_LEN];
35 u8 CountryIeSrcAddr[6];
36 u8 CountryIeWatchdog;
27 37
28 u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. 38 u8 channel_map[MAX_CHANNEL_NUMBER+1];
29 u8 CountryIeBuf[MAX_IE_LEN]; 39 u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
30 u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
31 u8 CountryIeWatchdog;
32
33 u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
34 //u8 ChnlListLen; // #Bytes valid in ChnlList[].
35 //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
36 u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
37 40
38 DOT11D_STATE State; 41 DOT11D_STATE State;
39}RT_DOT11D_INFO, *PRT_DOT11D_INFO; 42} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
40#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 ) 43
41#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]) 44#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == \
42#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) 45 (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && \
46 (a)[5] == (b)[5]) ? 1 : 0)
47
48#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], \
49 (des)[2] = (src)[2], (des)[3] = (src)[3], \
50 (des)[4] = (src)[4], (des)[5] = (src)[5])
51
52#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO) \
53 ((__pIeeeDev)->pDot11dInfo))
43 54
44#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled 55#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
45#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) 56#define IS_COUNTRY_IE_VALID(__pIeeeDev) \
57 (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
46 58
47#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) 59#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \
48#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) 60 eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
61
62#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \
63 cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
49 64
50#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ 65#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
51 (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ 66 (((__Ie).Length == 0 || (__Ie).Length != \
52 FALSE : \ 67 GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? FALSE : \
53 (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) 68 (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \
69 (__Ie).Octet, (__Ie).Length)))
54 70
55#define CIE_WATCHDOG_TH 1 71#define CIE_WATCHDOG_TH 1
56#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog 72#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
57#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 73#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
58#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) 74#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
59 75
60#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) 76#define IS_DOT11D_STATE_DONE(__pIeeeDev) \
61 77 (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
62 78
63void 79
64Dot11d_Init( 80void Dot11d_Init(struct ieee80211_device *dev);
65 struct ieee80211_device *dev 81
66 ); 82void Dot11d_Reset(struct ieee80211_device *dev);
67 83
68void 84void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
69Dot11d_Reset( 85 u16 CoutryIeLen, u8 *pCoutryIe);
70 struct ieee80211_device *dev 86
71 ); 87u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 channel);
72 88
73void 89void DOT11D_ScanComplete(struct ieee80211_device *dev);
74Dot11d_UpdateCountryIe( 90
75 struct ieee80211_device *dev, 91int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
76 u8 * pTaddr, 92
77 u16 CoutryIeLen, 93int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
78 u8 * pCoutryIe 94
79 ); 95#endif /* ENABLE_DOT11D */
80 96#endif /* INC_DOT11D_H */
81u8
82DOT11D_GetMaxTxPwrInDbm(
83 struct ieee80211_device *dev,
84 u8 Channel
85 );
86
87void
88DOT11D_ScanComplete(
89 struct ieee80211_device * dev
90 );
91
92int IsLegalChannel(
93 struct ieee80211_device * dev,
94 u8 channel
95);
96
97int ToLegalChannel(
98 struct ieee80211_device * dev,
99 u8 channel
100);
101#endif //ENABLE_DOT11D
102#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h
index 3ba9e9e90bda..c39249eb54b5 100644
--- a/drivers/staging/rtl8192e/ieee80211.h
+++ b/drivers/staging/rtl8192e/ieee80211.h
@@ -547,9 +547,6 @@ do { if (ieee80211_debug_level & (level)) \
547 547
548/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ 548/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
549 549
550#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
551#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
552
553/* 550/*
554 * To use the debug system; 551 * To use the debug system;
555 * 552 *
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
index aa76390487bb..1f613a28152f 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
@@ -35,6 +35,7 @@
35#endif 35#endif
36#include <linux/timer.h> 36#include <linux/timer.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/semaphore.h>
38 39
39#include <linux/delay.h> 40#include <linux/delay.h>
40#include <linux/wireless.h> 41#include <linux/wireless.h>
@@ -180,6 +181,8 @@ typedef struct cb_desc {
180 u8 DrvAggrNum; 181 u8 DrvAggrNum;
181 u16 pkt_size; 182 u16 pkt_size;
182 u8 reserved12; 183 u8 reserved12;
184
185 u8 bdhcp;
183}cb_desc, *pcb_desc; 186}cb_desc, *pcb_desc;
184 187
185/*--------------------------Define -------------------------------------------*/ 188/*--------------------------Define -------------------------------------------*/
@@ -615,9 +618,6 @@ do { if (ieee80211_debug_level & (level)) \
615 618
616/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ 619/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
617 620
618#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
619#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
620
621/* 621/*
622 * To use the debug system; 622 * To use the debug system;
623 * 623 *
@@ -743,6 +743,8 @@ struct ieee80211_snap_hdr {
743#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) 743#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
744#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) 744#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
745#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) 745#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
746#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA)
747
746 748
747#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE) 749#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
748#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) 750#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
@@ -1055,7 +1057,7 @@ struct ieee80211_device;
1055#define SEC_ALG_NONE 0 1057#define SEC_ALG_NONE 0
1056#define SEC_ALG_WEP 1 1058#define SEC_ALG_WEP 1
1057#define SEC_ALG_TKIP 2 1059#define SEC_ALG_TKIP 2
1058#define SEC_ALG_CCMP 3 1060#define SEC_ALG_CCMP 4
1059 1061
1060#define WEP_KEYS 4 1062#define WEP_KEYS 4
1061#define WEP_KEY_LEN 13 1063#define WEP_KEY_LEN 13
@@ -1124,6 +1126,14 @@ enum ieee80211_mfie {
1124/* Minimal header; can be used for passing 802.11 frames with sufficient 1126/* Minimal header; can be used for passing 802.11 frames with sufficient
1125 * information to determine what type of underlying data type is actually 1127 * information to determine what type of underlying data type is actually
1126 * stored in the data. */ 1128 * stored in the data. */
1129 struct ieee80211_pspoll_hdr {
1130 __le16 frame_ctl;
1131 __le16 aid;
1132 u8 bssid[ETH_ALEN];
1133 u8 ta[ETH_ALEN];
1134 //u8 payload[0];
1135} __attribute__ ((packed));
1136
1127struct ieee80211_hdr { 1137struct ieee80211_hdr {
1128 __le16 frame_ctl; 1138 __le16 frame_ctl;
1129 __le16 duration_id; 1139 __le16 duration_id;
@@ -1660,6 +1670,7 @@ struct ieee80211_network {
1660 bool ralink_cap_exist; 1670 bool ralink_cap_exist;
1661 bool atheros_cap_exist; 1671 bool atheros_cap_exist;
1662 bool cisco_cap_exist; 1672 bool cisco_cap_exist;
1673 bool marvell_cap_exist;
1663 bool unknown_cap_exist; 1674 bool unknown_cap_exist;
1664// u8 berp_info; 1675// u8 berp_info;
1665 bool berp_info_valid; 1676 bool berp_info_valid;
@@ -1865,6 +1876,19 @@ typedef struct _RT_POWER_SAVE_CONTROL
1865 // Leisre Poswer Save : Disable RF if connected but traffic is not busy 1876 // Leisre Poswer Save : Disable RF if connected but traffic is not busy
1866 // 1877 //
1867 bool bLeisurePs; 1878 bool bLeisurePs;
1879 u32 PowerProfile;
1880 u8 LpsIdleCount;
1881 u8 RegMaxLPSAwakeIntvl;
1882 u8 LPSAwakeIntvl;
1883
1884 u32 CurPsLevel;
1885 u32 RegRfPsLevel;
1886
1887 bool bFwCtrlLPS;
1888 u8 FWCtrlPSMode;
1889
1890 bool LinkReqInIPSRFOffPgs;
1891 bool BufConnectinfoBefore;
1868 1892
1869}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL; 1893}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
1870 1894
@@ -1905,14 +1929,121 @@ typedef struct _RT_LINK_DETECT_T{
1905 1929
1906 u32 NumTxOkInPeriod; 1930 u32 NumTxOkInPeriod;
1907 u32 NumRxOkInPeriod; 1931 u32 NumRxOkInPeriod;
1932 u32 NumRxUnicastOkInPeriod;
1908 bool bBusyTraffic; 1933 bool bBusyTraffic;
1909}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; 1934}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
1910 1935
1936//added by amy 090330
1937typedef enum _HW_VARIABLES{
1938 HW_VAR_ETHER_ADDR,
1939 HW_VAR_MULTICAST_REG,
1940 HW_VAR_BASIC_RATE,
1941 HW_VAR_BSSID,
1942 HW_VAR_MEDIA_STATUS,
1943 HW_VAR_SECURITY_CONF,
1944 HW_VAR_BEACON_INTERVAL,
1945 HW_VAR_ATIM_WINDOW,
1946 HW_VAR_LISTEN_INTERVAL,
1947 HW_VAR_CS_COUNTER,
1948 HW_VAR_DEFAULTKEY0,
1949 HW_VAR_DEFAULTKEY1,
1950 HW_VAR_DEFAULTKEY2,
1951 HW_VAR_DEFAULTKEY3,
1952 HW_VAR_SIFS,
1953 HW_VAR_DIFS,
1954 HW_VAR_EIFS,
1955 HW_VAR_SLOT_TIME,
1956 HW_VAR_ACK_PREAMBLE,
1957 HW_VAR_CW_CONFIG,
1958 HW_VAR_CW_VALUES,
1959 HW_VAR_RATE_FALLBACK_CONTROL,
1960 HW_VAR_CONTENTION_WINDOW,
1961 HW_VAR_RETRY_COUNT,
1962 HW_VAR_TR_SWITCH,
1963 HW_VAR_COMMAND, // For Command Register, Annie, 2006-04-07.
1964 HW_VAR_WPA_CONFIG, //2004/08/23, kcwu, for 8187 Security config
1965 HW_VAR_AMPDU_MIN_SPACE, // The spacing between sub-frame. Roger, 2008.07.04.
1966 HW_VAR_SHORTGI_DENSITY, // The density for shortGI. Roger, 2008.07.04.
1967 HW_VAR_AMPDU_FACTOR,
1968 HW_VAR_MCS_RATE_AVAILABLE,
1969 HW_VAR_AC_PARAM, // For AC Parameters, 2005.12.01, by rcnjko.
1970 HW_VAR_ACM_CTRL, // For ACM Control, Annie, 2005-12-13.
1971 HW_VAR_DIS_Req_Qsize, // For DIS_Reg_Qsize, Joseph
1972 HW_VAR_CCX_CHNL_LOAD, // For CCX 2 channel load request, 2006.05.04.
1973 HW_VAR_CCX_NOISE_HISTOGRAM, // For CCX 2 noise histogram request, 2006.05.04.
1974 HW_VAR_CCX_CLM_NHM, // For CCX 2 parallel channel load request and noise histogram request, 2006.05.12.
1975 HW_VAR_TxOPLimit, // For turbo mode related settings, added by Roger, 2006.12.07
1976 HW_VAR_TURBO_MODE, // For turbo mode related settings, added by Roger, 2006.12.15.
1977 HW_VAR_RF_STATE, // For change or query RF power state, 061214, rcnjko.
1978 HW_VAR_RF_OFF_BY_HW, // For UI to query if external HW signal disable RF, 061229, rcnjko.
1979 HW_VAR_BUS_SPEED, // In unit of bps. 2006.07.03, by rcnjko.
1980 HW_VAR_SET_DEV_POWER, // Set to low power, added by LanHsin, 2007.
1981
1982 //1!!!!!!!!!!!!!!!!!!!!!!!!!!!
1983 //1Attention Please!!!<11n or 8190 specific code should be put below this line>
1984 //1!!!!!!!!!!!!!!!!!!!!!!!!!!!
1985 HW_VAR_RCR, //for RCR, David 2006,05,11
1986 HW_VAR_RATR_0,
1987 HW_VAR_RRSR,
1988 HW_VAR_CPU_RST,
1989 HW_VAR_CECHK_BSSID,
1990 HW_VAR_LBK_MODE, // Set lookback mode, 2008.06.11. added by Roger.
1991 // Set HW related setting for 11N AES bug.
1992 HW_VAR_AES_11N_FIX,
1993 // Set Usb Rx Aggregation
1994 HW_VAR_USB_RX_AGGR,
1995 HW_VAR_USER_CONTROL_TURBO_MODE,
1996 HW_VAR_RETRY_LIMIT,
1997#ifndef _RTL8192_EXT_PATCH_
1998 HW_VAR_INIT_TX_RATE, //Get Current Tx rate register. 2008.12.10. Added by tynli
1999#endif
2000 HW_VAR_TX_RATE_REG, //Get Current Tx rate register. 2008.12.10. Added by tynli
2001 HW_VAR_EFUSE_USAGE, //Get current EFUSE utilization. 2008.12.19. Added by Roger.
2002 HW_VAR_EFUSE_BYTES,
2003 HW_VAR_AUTOLOAD_STATUS, //Get current autoload status, 0: autoload success, 1: autoload fail. 2008.12.19. Added by Roger.
2004 HW_VAR_RF_2R_DISABLE, // 2R disable
2005 HW_VAR_SET_RPWM,
2006 HW_VAR_H2C_FW_PWRMODE, // For setting FW related H2C cmd structure. by tynli. 2009.2.18
2007 HW_VAR_H2C_FW_JOINBSSRPT, // For setting FW related H2C cmd structure. by tynli. 2009.2.18
2008 HW_VAR_1X1_RECV_COMBINE, // For 1T2R but only 1SS, Add by hpfan 2009.04.16 hpfan
2009 HW_VAR_STOP_SEND_BEACON,
2010 HW_VAR_TSF_TIMER, // Read from TSF register to get the current TSF timer, by Bruce, 2009-07-22.
2011 HW_VAR_IO_CMD,
2012 HW_VAR_HANDLE_FW_C2H, //Added by tynli. For handling FW C2H command. 2009.10.07.
2013 HW_VAR_DL_FW_RSVD_PAGE, //Added by tynli. Download the packets that FW will use to RSVD page. 2009.10.14.
2014 HW_VAR_AID, //Added by tynli.
2015 HW_VAR_HW_SEQ_ENABLE, //Added by tynli. 2009.10.20.
2016 HW_VAR_UPDATE_TSF, //Added by tynli. 2009.10.22. For Hw count TBTT time.
2017 HW_VAR_BCN_VALID, //Added by tynli.
2018 HW_VAR_FWLPS_RF_ON //Added by tynli. 2009.11.09. For checking if Fw finishs RF on sequence.
2019}HW_VARIABLES;
2020
2021#define RT_CHECK_FOR_HANG_PERIOD 2
1911 2022
1912struct ieee80211_device { 2023struct ieee80211_device {
1913 struct net_device *dev; 2024 struct net_device *dev;
1914 struct ieee80211_security sec; 2025 struct ieee80211_security sec;
1915 2026
2027 bool need_sw_enc;
2028#ifdef ENABLE_LPS
2029 bool bAwakePktSent;
2030 u8 LPSDelayCnt;
2031 bool bIsAggregateFrame;
2032 bool polling;
2033 void (*LeisurePSLeave)(struct net_device *dev);
2034#endif
2035
2036#ifdef ENABLE_IPS
2037 bool proto_stoppping;
2038 bool wx_set_enc;
2039 struct semaphore ips_sem;
2040 struct work_struct ips_leave_wq;
2041 void (*ieee80211_ips_leave_wq) (struct net_device *dev);
2042 void (*ieee80211_ips_leave)(struct net_device *dev);
2043#endif
2044 void (*SetHwRegHandler)(struct net_device *dev,u8 variable,u8* val);
2045 u8 (*rtllib_ap_sec_type)(struct ieee80211_device *ieee);
2046
1916 //hw security related 2047 //hw security related
1917// u8 hwsec_support; //support? 2048// u8 hwsec_support; //support?
1918 u8 hwsec_active; //hw security active. 2049 u8 hwsec_active; //hw security active.
@@ -2319,7 +2450,7 @@ struct ieee80211_device {
2319 * stop_send_bacons is NOT guaranteed to be called only 2450 * stop_send_bacons is NOT guaranteed to be called only
2320 * after start_send_beacons. 2451 * after start_send_beacons.
2321 */ 2452 */
2322 void (*start_send_beacons) (struct net_device *dev,u16 tx_rate); 2453 void (*start_send_beacons) (struct net_device *dev);
2323 void (*stop_send_beacons) (struct net_device *dev); 2454 void (*stop_send_beacons) (struct net_device *dev);
2324 2455
2325 /* power save mode related */ 2456 /* power save mode related */
@@ -2373,6 +2504,19 @@ struct ieee80211_device {
2373 u8 priv[0]; 2504 u8 priv[0];
2374}; 2505};
2375 2506
2507#define RT_RF_OFF_LEVL_ASPM BIT0 // PCI ASPM
2508#define RT_RF_OFF_LEVL_CLK_REQ BIT1 // PCI clock request
2509#define RT_RF_OFF_LEVL_PCI_D3 BIT2 // PCI D3 mode
2510#define RT_RF_OFF_LEVL_HALT_NIC BIT3 // NIC halt, re-initialize hw parameters
2511#define RT_RF_OFF_LEVL_FREE_FW BIT4 // FW free, re-download the FW
2512#define RT_RF_OFF_LEVL_FW_32K BIT5 // FW in 32k
2513#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT6 // Always enable ASPM and Clock Req in initialization.
2514#define RT_RF_LPS_DISALBE_2R BIT30 // When LPS is on, disable 2R if no packet is received or transmittd.
2515#define RT_RF_LPS_LEVEL_ASPM BIT31 // LPS with ASPM
2516#define RT_IN_PS_LEVEL(pPSC, _PS_FLAG) ((pPSC->CurPsLevel & _PS_FLAG) ? true : false)
2517#define RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel &= (~(_PS_FLAG)))
2518#define RT_SET_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel |= _PS_FLAG)
2519
2376#define IEEE_A (1<<0) 2520#define IEEE_A (1<<0)
2377#define IEEE_B (1<<1) 2521#define IEEE_B (1<<1)
2378#define IEEE_G (1<<2) 2522#define IEEE_G (1<<2)
@@ -2609,9 +2753,9 @@ extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
2609extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); 2753extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
2610extern void ieee80211_check_all_nets(struct ieee80211_device *ieee); 2754extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
2611extern void ieee80211_start_protocol(struct ieee80211_device *ieee); 2755extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
2612extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); 2756extern void ieee80211_stop_protocol(struct ieee80211_device *ieee,u8 shutdown);
2613extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); 2757extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
2614extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); 2758extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee,u8 shutdown);
2615extern void ieee80211_reset_queue(struct ieee80211_device *ieee); 2759extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
2616extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); 2760extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
2617extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); 2761extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
@@ -2798,5 +2942,7 @@ extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
2798 struct ieee80211_rx_stats *stats); 2942 struct ieee80211_rx_stats *stats);
2799 2943
2800void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index); 2944void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index);
2945void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
2946void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee);
2801#define RT_ASOC_RETRY_LIMIT 5 2947#define RT_ASOC_RETRY_LIMIT 5
2802#endif /* IEEE80211_H */ 2948#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
index b1c54932da3e..b3c9bf4b4ea6 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
@@ -225,7 +225,7 @@ out:
225} 225}
226 226
227 227
228void __exit ieee80211_crypto_deinit(void) 228void ieee80211_crypto_deinit(void)
229{ 229{
230 struct list_head *ptr, *n; 230 struct list_head *ptr, *n;
231 231
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
index ab871b360b5d..1776f7e69bfe 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
@@ -331,7 +331,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
331 if (!(keyidx & (1 << 5))) { 331 if (!(keyidx & (1 << 5))) {
332 if (net_ratelimit()) { 332 if (net_ratelimit()) {
333 printk(KERN_DEBUG "CCMP: received packet without ExtIV" 333 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
334 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 334 " flag from %pM\n", hdr->addr2);
335 } 335 }
336 key->dot11RSNAStatsCCMPFormatErrors++; 336 key->dot11RSNAStatsCCMPFormatErrors++;
337 return -2; 337 return -2;
@@ -344,9 +344,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
344 } 344 }
345 if (!key->key_set) { 345 if (!key->key_set) {
346 if (net_ratelimit()) { 346 if (net_ratelimit()) {
347 printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT 347 printk(KERN_DEBUG "CCMP: received packet from %pM"
348 " with keyid=%d that does not have a configured" 348 " with keyid=%d that does not have a configured"
349 " key\n", MAC_ARG(hdr->addr2), keyidx); 349 " key\n", hdr->addr2, keyidx);
350 } 350 }
351 return -3; 351 return -3;
352 } 352 }
@@ -361,11 +361,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
361 361
362 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { 362 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
363 if (net_ratelimit()) { 363 if (net_ratelimit()) {
364 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT 364 //printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
365 " previous PN %02x%02x%02x%02x%02x%02x " 365 // " previous PN %pm received PN %pm\n",
366 "received PN %02x%02x%02x%02x%02x%02x\n", 366 // hdr->addr2, key->rx_pn, pn);
367 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
368 MAC_ARG(pn));
369 } 367 }
370 key->dot11RSNAStatsCCMPReplays++; 368 key->dot11RSNAStatsCCMPReplays++;
371 return -4; 369 return -4;
@@ -402,7 +400,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
402 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { 400 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
403 if (net_ratelimit()) { 401 if (net_ratelimit()) {
404 printk(KERN_DEBUG "CCMP: decrypt failed: STA=" 402 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
405 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 403 "%pM\n", hdr->addr2);
406 } 404 }
407 key->dot11RSNAStatsCCMPDecryptErrors++; 405 key->dot11RSNAStatsCCMPDecryptErrors++;
408 return -5; 406 return -5;
@@ -477,12 +475,19 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
477static char * ieee80211_ccmp_print_stats(char *p, void *priv) 475static char * ieee80211_ccmp_print_stats(char *p, void *priv)
478{ 476{
479 struct ieee80211_ccmp_data *ccmp = priv; 477 struct ieee80211_ccmp_data *ccmp = priv;
480 p += sprintf(p, "key[%d] alg=CCMP key_set=%d " 478 int i;
481 "tx_pn=%02x%02x%02x%02x%02x%02x " 479
482 "rx_pn=%02x%02x%02x%02x%02x%02x " 480 p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=",
483 "format_errors=%d replays=%d decrypt_errors=%d\n", 481 ccmp->key_idx, ccmp->key_set);
484 ccmp->key_idx, ccmp->key_set, 482
485 MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), 483 for (i = 0; i < ARRAY_SIZE(ccmp->tx_pn); i++)
484 p += sprintf(p, "%02x", ccmp->tx_pn[i]);
485
486 sprintf(p, " rx_pn=");
487 for (i = 0; i < ARRAY_SIZE(ccmp->rx_pn); i++)
488 p += sprintf(p, "%02x", ccmp->tx_pn[i]);
489
490 p += sprintf(p, " format_errors=%d replays=%d decrypt_errors=%d\n",
486 ccmp->dot11RSNAStatsCCMPFormatErrors, 491 ccmp->dot11RSNAStatsCCMPFormatErrors,
487 ccmp->dot11RSNAStatsCCMPReplays, 492 ccmp->dot11RSNAStatsCCMPReplays,
488 ccmp->dot11RSNAStatsCCMPDecryptErrors); 493 ccmp->dot11RSNAStatsCCMPDecryptErrors);
@@ -519,7 +524,7 @@ int __init ieee80211_crypto_ccmp_init(void)
519} 524}
520 525
521 526
522void __exit ieee80211_crypto_ccmp_exit(void) 527void ieee80211_crypto_ccmp_exit(void)
523{ 528{
524 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); 529 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
525} 530}
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
index 7a1797e6cbec..03cb21eb0658 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
@@ -520,7 +520,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
520 if (!(keyidx & (1 << 5))) { 520 if (!(keyidx & (1 << 5))) {
521 if (net_ratelimit()) { 521 if (net_ratelimit()) {
522 printk(KERN_DEBUG "TKIP: received packet without ExtIV" 522 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
523 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 523 " flag from %pM\n", hdr->addr2);
524 } 524 }
525 return -2; 525 return -2;
526 } 526 }
@@ -532,9 +532,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
532 } 532 }
533 if (!tkey->key_set) { 533 if (!tkey->key_set) {
534 if (net_ratelimit()) { 534 if (net_ratelimit()) {
535 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT 535 printk(KERN_DEBUG "TKIP: received packet from %pM"
536 " with keyid=%d that does not have a configured" 536 " with keyid=%d that does not have a configured"
537 " key\n", MAC_ARG(hdr->addr2), keyidx); 537 " key\n", hdr->addr2, keyidx);
538 } 538 }
539 return -3; 539 return -3;
540 } 540 }
@@ -547,9 +547,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
547 if (iv32 < tkey->rx_iv32 || 547 if (iv32 < tkey->rx_iv32 ||
548 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { 548 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
549 if (net_ratelimit()) { 549 if (net_ratelimit()) {
550 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT 550 printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
551 " previous TSC %08x%04x received TSC " 551 " previous TSC %08x%04x received TSC "
552 "%08x%04x\n", MAC_ARG(hdr->addr2), 552 "%08x%04x\n", hdr->addr2,
553 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); 553 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
554 } 554 }
555 tkey->dot11RSNAStatsTKIPReplays++; 555 tkey->dot11RSNAStatsTKIPReplays++;
@@ -582,8 +582,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
582 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { 582 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
583 if (net_ratelimit()) { 583 if (net_ratelimit()) {
584 printk(KERN_DEBUG ": TKIP: failed to decrypt " 584 printk(KERN_DEBUG ": TKIP: failed to decrypt "
585 "received packet from " MAC_FMT "\n", 585 "received packet from %pM\n",
586 MAC_ARG(hdr->addr2)); 586 hdr->addr2);
587 } 587 }
588 return -7; 588 return -7;
589 } 589 }
@@ -606,8 +606,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
606 tkey->rx_phase1_done = 0; 606 tkey->rx_phase1_done = 0;
607 } 607 }
608 if (net_ratelimit()) { 608 if (net_ratelimit()) {
609 printk(KERN_DEBUG "TKIP: ICV error detected: STA=" 609 printk(KERN_DEBUG
610 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 610 "TKIP: ICV error detected: STA=%pM\n",
611 hdr->addr2);
611 } 612 }
612 tkey->dot11RSNAStatsTKIPICVErrors++; 613 tkey->dot11RSNAStatsTKIPICVErrors++;
613 return -5; 614 return -5;
@@ -816,8 +817,8 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
816 817
817 /* TODO: needed parameters: count, keyid, key type, TSC */ 818 /* TODO: needed parameters: count, keyid, key type, TSC */
818 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" 819 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
819 MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", 820 "%pM)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
820 MAC_ARG(hdr->addr2)); 821 hdr->addr2);
821 memset(&wrqu, 0, sizeof(wrqu)); 822 memset(&wrqu, 0, sizeof(wrqu));
822 wrqu.data.length = strlen(buf); 823 wrqu.data.length = strlen(buf);
823 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); 824 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
@@ -862,8 +863,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
862 struct ieee80211_hdr_4addr *hdr; 863 struct ieee80211_hdr_4addr *hdr;
863 hdr = (struct ieee80211_hdr_4addr *) skb->data; 864 hdr = (struct ieee80211_hdr_4addr *) skb->data;
864 printk(KERN_DEBUG "%s: Michael MIC verification failed for " 865 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
865 "MSDU from " MAC_FMT " keyidx=%d\n", 866 "MSDU from %pM keyidx=%d\n",
866 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), 867 skb->dev ? skb->dev->name : "N/A", hdr->addr2,
867 keyidx); 868 keyidx);
868 if (skb->dev) 869 if (skb->dev)
869 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); 870 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
@@ -1011,7 +1012,7 @@ int __init ieee80211_crypto_tkip_init(void)
1011} 1012}
1012 1013
1013 1014
1014void __exit ieee80211_crypto_tkip_exit(void) 1015void ieee80211_crypto_tkip_exit(void)
1015{ 1016{
1016 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); 1017 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
1017} 1018}
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
index 06d91715143c..ce265ae5fe18 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
@@ -312,6 +312,17 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
312 if (skb->len < 24) 312 if (skb->len < 24)
313 return 0; 313 return 0;
314 314
315#if 1
316 if (ieee->hwsec_active)
317 {
318 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
319 tcb_desc->bHwSec = 1;
320
321 if(ieee->need_sw_enc)
322 tcb_desc->bHwSec = 0;
323 }
324#endif
325
315 hdr = (struct ieee80211_hdr_4addr *) skb->data; 326 hdr = (struct ieee80211_hdr_4addr *) skb->data;
316 fc = le16_to_cpu(hdr->frame_ctl); 327 fc = le16_to_cpu(hdr->frame_ctl);
317 328
@@ -366,8 +377,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
366 strcmp(crypt->ops->name, "TKIP") == 0) { 377 strcmp(crypt->ops->name, "TKIP") == 0) {
367 if (net_ratelimit()) { 378 if (net_ratelimit()) {
368 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 379 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
369 "received packet from " MAC_FMT "\n", 380 "received packet from %pM\n",
370 ieee->dev->name, MAC_ARG(hdr->addr2)); 381 ieee->dev->name, hdr->addr2);
371 } 382 }
372 return -1; 383 return -1;
373 } 384 }
@@ -378,8 +389,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
378 atomic_dec(&crypt->refcnt); 389 atomic_dec(&crypt->refcnt);
379 if (res < 0) { 390 if (res < 0) {
380 IEEE80211_DEBUG_DROP( 391 IEEE80211_DEBUG_DROP(
381 "decryption failed (SA=" MAC_FMT 392 "decryption failed (SA=%pM"
382 ") res=%d\n", MAC_ARG(hdr->addr2), res); 393 ") res=%d\n", hdr->addr2, res);
383 if (res == -2) 394 if (res == -2)
384 IEEE80211_DEBUG_DROP("Decryption failed ICV " 395 IEEE80211_DEBUG_DROP("Decryption failed ICV "
385 "mismatch (key %d)\n", 396 "mismatch (key %d)\n",
@@ -406,6 +417,10 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
406 { 417 {
407 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); 418 cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
408 tcb_desc->bHwSec = 1; 419 tcb_desc->bHwSec = 1;
420
421 if(ieee->need_sw_enc)
422 tcb_desc->bHwSec = 0;
423
409 } 424 }
410 425
411 hdr = (struct ieee80211_hdr_4addr *) skb->data; 426 hdr = (struct ieee80211_hdr_4addr *) skb->data;
@@ -416,8 +431,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
416 atomic_dec(&crypt->refcnt); 431 atomic_dec(&crypt->refcnt);
417 if (res < 0) { 432 if (res < 0) {
418 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" 433 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
419 " (SA=" MAC_FMT " keyidx=%d)\n", 434 " (SA=%pM keyidx=%d)\n",
420 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); 435 ieee->dev->name, hdr->addr2, keyidx);
421 return -1; 436 return -1;
422 } 437 }
423 438
@@ -799,7 +814,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee,
799#endif 814#endif
800} 815}
801 816
802u8 parse_subframe(struct sk_buff *skb, 817u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb,
803 struct ieee80211_rx_stats *rx_stats, 818 struct ieee80211_rx_stats *rx_stats,
804 struct ieee80211_rxb *rxb,u8* src,u8* dst) 819 struct ieee80211_rxb *rxb,u8* src,u8* dst)
805{ 820{
@@ -839,6 +854,7 @@ u8 parse_subframe(struct sk_buff *skb,
839 } 854 }
840 855
841 skb_pull(skb, LLCOffset); 856 skb_pull(skb, LLCOffset);
857 ieee->bIsAggregateFrame = bIsAggregateFrame;//added by amy for Leisure PS
842 858
843 if(!bIsAggregateFrame) { 859 if(!bIsAggregateFrame) {
844 rxb->nr_subframes = 1; 860 rxb->nr_subframes = 1;
@@ -940,6 +956,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
940 u8 TID = 0; 956 u8 TID = 0;
941 u16 SeqNum = 0; 957 u16 SeqNum = 0;
942 PRX_TS_RECORD pTS = NULL; 958 PRX_TS_RECORD pTS = NULL;
959 bool unicast_packet = false;
943 //bool bIsAggregateFrame = false; 960 //bool bIsAggregateFrame = false;
944 //added by amy for reorder 961 //added by amy for reorder
945#ifdef NOT_YET 962#ifdef NOT_YET
@@ -1045,8 +1062,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1045 * frames silently instead of filling system log with 1062 * frames silently instead of filling system log with
1046 * these reports. */ 1063 * these reports. */
1047 IEEE80211_DEBUG_DROP("Decryption failed (not set)" 1064 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
1048 " (SA=" MAC_FMT ")\n", 1065 " (SA=%pM)\n",
1049 MAC_ARG(hdr->addr2)); 1066 hdr->addr2);
1050 ieee->ieee_stats.rx_discards_undecryptable++; 1067 ieee->ieee_stats.rx_discards_undecryptable++;
1051 goto rx_dropped; 1068 goto rx_dropped;
1052 } 1069 }
@@ -1114,8 +1131,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1114 (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) 1131 (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
1115 { 1132 {
1116 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth " 1133 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
1117 "from " MAC_FMT "\n", dev->name, 1134 "from %pM\n", dev->name,
1118 MAC_ARG(hdr->addr2)); 1135 hdr->addr2);
1119 /* TODO: could inform hostapd about this so that it 1136 /* TODO: could inform hostapd about this so that it
1120 * could send auth failure report */ 1137 * could send auth failure report */
1121 goto rx_dropped; 1138 goto rx_dropped;
@@ -1215,6 +1232,24 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1215 if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) 1232 if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
1216 goto rx_dropped; 1233 goto rx_dropped;
1217 1234
1235#ifdef ENABLE_LPS
1236 if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == 1)
1237 && (ieee->polling)) {
1238 if (WLAN_FC_MORE_DATA(fc)) {
1239 /* more data bit is set, let's request a new frame from the AP */
1240 ieee80211_sta_ps_send_pspoll_frame(ieee);
1241 } else {
1242 ieee->polling = false;
1243 }
1244 }
1245#endif
1246
1247 ieee->need_sw_enc = 0;
1248
1249 if((!rx_stats->Decrypted)){
1250 ieee->need_sw_enc = 1;
1251 }
1252
1218 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ 1253 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
1219 1254
1220 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && 1255 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
@@ -1296,6 +1331,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1296 ieee->LinkDetectInfo.NumRxOkInPeriod++; 1331 ieee->LinkDetectInfo.NumRxOkInPeriod++;
1297 1332
1298 hdr = (struct ieee80211_hdr_4addr *) skb->data; 1333 hdr = (struct ieee80211_hdr_4addr *) skb->data;
1334 if((!is_multicast_ether_addr(hdr->addr1)) && (!is_broadcast_ether_addr(hdr->addr1)))
1335 unicast_packet = true;
1336
1299 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { 1337 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
1300 if (/*ieee->ieee802_1x &&*/ 1338 if (/*ieee->ieee802_1x &&*/
1301 ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { 1339 ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
@@ -1311,8 +1349,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1311 } else { 1349 } else {
1312 IEEE80211_DEBUG_DROP( 1350 IEEE80211_DEBUG_DROP(
1313 "encryption configured, but RX " 1351 "encryption configured, but RX "
1314 "frame not encrypted (SA=" MAC_FMT ")\n", 1352 "frame not encrypted (SA=%pM)\n",
1315 MAC_ARG(hdr->addr2)); 1353 hdr->addr2);
1316 goto rx_dropped; 1354 goto rx_dropped;
1317 } 1355 }
1318 } 1356 }
@@ -1331,9 +1369,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1331 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { 1369 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
1332 IEEE80211_DEBUG_DROP( 1370 IEEE80211_DEBUG_DROP(
1333 "dropped unencrypted RX data " 1371 "dropped unencrypted RX data "
1334 "frame from " MAC_FMT 1372 "frame from %pM"
1335 " (drop_unencrypted=1)\n", 1373 " (drop_unencrypted=1)\n",
1336 MAC_ARG(hdr->addr2)); 1374 hdr->addr2);
1337 goto rx_dropped; 1375 goto rx_dropped;
1338 } 1376 }
1339/* 1377/*
@@ -1367,7 +1405,7 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1367 } 1405 }
1368 /* to parse amsdu packets */ 1406 /* to parse amsdu packets */
1369 /* qos data packets & reserved bit is 1 */ 1407 /* qos data packets & reserved bit is 1 */
1370 if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) { 1408 if(parse_subframe(ieee, skb,rx_stats,rxb,src,dst) == 0) {
1371 /* only to free rxb, and not submit the packets to upper layer */ 1409 /* only to free rxb, and not submit the packets to upper layer */
1372 for(i =0; i < rxb->nr_subframes; i++) { 1410 for(i =0; i < rxb->nr_subframes; i++) {
1373 dev_kfree_skb(rxb->subframes[i]); 1411 dev_kfree_skb(rxb->subframes[i]);
@@ -1377,6 +1415,32 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1377 goto rx_dropped; 1415 goto rx_dropped;
1378 } 1416 }
1379 1417
1418#ifdef ENABLE_LPS
1419 if(unicast_packet)
1420 {
1421 if (type == IEEE80211_FTYPE_DATA)
1422 {
1423
1424 if(ieee->bIsAggregateFrame)
1425 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod+=rxb->nr_subframes;
1426 else
1427 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++;
1428
1429 // 2009.03.03 Leave DC mode immediately when detect high traffic
1430 // DbgPrint("ending Seq %d\n", Frame_SeqNum(pduOS));
1431 if((ieee->state == IEEE80211_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
1432 {
1433 if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
1434 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
1435 {
1436 if(ieee->LeisurePSLeave)
1437 ieee->LeisurePSLeave(dev);
1438 }
1439 }
1440 }
1441 }
1442#endif
1443
1380 ieee->last_rx_ps_time = jiffies; 1444 ieee->last_rx_ps_time = jiffies;
1381//added by amy for reorder 1445//added by amy for reorder
1382 if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){ 1446 if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
@@ -2013,12 +2077,22 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
2013 info_element->data[1] == 0x13 && 2077 info_element->data[1] == 0x13 &&
2014 info_element->data[2] == 0x74)) 2078 info_element->data[2] == 0x74))
2015 { 2079 {
2016 printk("========>%s(): athros AP is exist\n",__FUNCTION__); 2080 //printk("========>%s(): athros AP is exist\n",__FUNCTION__);
2017 network->atheros_cap_exist = true; 2081 network->atheros_cap_exist = true;
2018 } 2082 }
2019 else 2083 else
2020 network->atheros_cap_exist = false; 2084 network->atheros_cap_exist = false;
2021 2085
2086 if ((info_element->len >= 3 &&
2087 info_element->data[0] == 0x00 &&
2088 info_element->data[1] == 0x50 &&
2089 info_element->data[2] == 0x43) )
2090 {
2091 network->marvell_cap_exist = true;
2092 //printk("========>%s(): marvel AP is exist\n",__FUNCTION__);
2093 }
2094
2095
2022 if(info_element->len >= 3 && 2096 if(info_element->len >= 3 &&
2023 info_element->data[0] == 0x00 && 2097 info_element->data[0] == 0x00 &&
2024 info_element->data[1] == 0x40 && 2098 info_element->data[1] == 0x40 &&
@@ -2219,7 +2293,8 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
2219 } 2293 }
2220 2294
2221 if(!network->atheros_cap_exist && !network->broadcom_cap_exist && 2295 if(!network->atheros_cap_exist && !network->broadcom_cap_exist &&
2222 !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation) 2296 !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation &&
2297 !network->marvell_cap_exist)
2223 { 2298 {
2224 network->unknown_cap_exist = true; 2299 network->unknown_cap_exist = true;
2225 } 2300 }
@@ -2333,6 +2408,7 @@ static inline int ieee80211_network_init(
2333 network->broadcom_cap_exist = false; 2408 network->broadcom_cap_exist = false;
2334 network->ralink_cap_exist = false; 2409 network->ralink_cap_exist = false;
2335 network->atheros_cap_exist = false; 2410 network->atheros_cap_exist = false;
2411 network->marvell_cap_exist = false;
2336 network->cisco_cap_exist = false; 2412 network->cisco_cap_exist = false;
2337 network->unknown_cap_exist = false; 2413 network->unknown_cap_exist = false;
2338#ifdef THOMAS_TURBO 2414#ifdef THOMAS_TURBO
@@ -2369,11 +2445,11 @@ static inline int ieee80211_network_init(
2369 } 2445 }
2370 2446
2371 if (network->mode == 0) { 2447 if (network->mode == 0) {
2372 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " 2448 IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
2373 "network.\n", 2449 "network.\n",
2374 escape_essid(network->ssid, 2450 escape_essid(network->ssid,
2375 network->ssid_len), 2451 network->ssid_len),
2376 MAC_ARG(network->bssid)); 2452 network->bssid);
2377 return 1; 2453 return 1;
2378 } 2454 }
2379 2455
@@ -2463,6 +2539,7 @@ static inline void update_network(struct ieee80211_network *dst,
2463 dst->broadcom_cap_exist = src->broadcom_cap_exist; 2539 dst->broadcom_cap_exist = src->broadcom_cap_exist;
2464 dst->ralink_cap_exist = src->ralink_cap_exist; 2540 dst->ralink_cap_exist = src->ralink_cap_exist;
2465 dst->atheros_cap_exist = src->atheros_cap_exist; 2541 dst->atheros_cap_exist = src->atheros_cap_exist;
2542 dst->marvell_cap_exist = src->marvell_cap_exist;
2466 dst->cisco_cap_exist = src->cisco_cap_exist; 2543 dst->cisco_cap_exist = src->cisco_cap_exist;
2467 dst->unknown_cap_exist = src->unknown_cap_exist; 2544 dst->unknown_cap_exist = src->unknown_cap_exist;
2468 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); 2545 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
@@ -2557,9 +2634,9 @@ static inline void ieee80211_process_probe_response(
2557 2634
2558 memset(&network, 0, sizeof(struct ieee80211_network)); 2635 memset(&network, 0, sizeof(struct ieee80211_network));
2559 IEEE80211_DEBUG_SCAN( 2636 IEEE80211_DEBUG_SCAN(
2560 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", 2637 "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
2561 escape_essid(info_element->data, info_element->len), 2638 escape_essid(info_element->data, info_element->len),
2562 MAC_ARG(beacon->header.addr3), 2639 beacon->header.addr3,
2563 (beacon->capability & (1<<0xf)) ? '1' : '0', 2640 (beacon->capability & (1<<0xf)) ? '1' : '0',
2564 (beacon->capability & (1<<0xe)) ? '1' : '0', 2641 (beacon->capability & (1<<0xe)) ? '1' : '0',
2565 (beacon->capability & (1<<0xd)) ? '1' : '0', 2642 (beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2578,10 +2655,10 @@ static inline void ieee80211_process_probe_response(
2578 (beacon->capability & (1<<0x0)) ? '1' : '0'); 2655 (beacon->capability & (1<<0x0)) ? '1' : '0');
2579 2656
2580 if (ieee80211_network_init(ieee, beacon, &network, stats)) { 2657 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
2581 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", 2658 IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
2582 escape_essid(info_element->data, 2659 escape_essid(info_element->data,
2583 info_element->len), 2660 info_element->len),
2584 MAC_ARG(beacon->header.addr3), 2661 beacon->header.addr3,
2585 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 2662 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2586 IEEE80211_STYPE_PROBE_RESP ? 2663 IEEE80211_STYPE_PROBE_RESP ?
2587 "PROBE RESPONSE" : "BEACON"); 2664 "PROBE RESPONSE" : "BEACON");
@@ -2692,11 +2769,11 @@ static inline void ieee80211_process_probe_response(
2692 /* If there are no more slots, expire the oldest */ 2769 /* If there are no more slots, expire the oldest */
2693 list_del(&oldest->list); 2770 list_del(&oldest->list);
2694 target = oldest; 2771 target = oldest;
2695 IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " 2772 IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
2696 "network list.\n", 2773 "network list.\n",
2697 escape_essid(target->ssid, 2774 escape_essid(target->ssid,
2698 target->ssid_len), 2775 target->ssid_len),
2699 MAC_ARG(target->bssid)); 2776 target->bssid);
2700 } else { 2777 } else {
2701 /* Otherwise just pull from the free list */ 2778 /* Otherwise just pull from the free list */
2702 target = list_entry(ieee->network_free_list.next, 2779 target = list_entry(ieee->network_free_list.next,
@@ -2706,10 +2783,10 @@ static inline void ieee80211_process_probe_response(
2706 2783
2707 2784
2708#ifdef CONFIG_IEEE80211_DEBUG 2785#ifdef CONFIG_IEEE80211_DEBUG
2709 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", 2786 IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
2710 escape_essid(network.ssid, 2787 escape_essid(network.ssid,
2711 network.ssid_len), 2788 network.ssid_len),
2712 MAC_ARG(network.bssid), 2789 network.bssid,
2713 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 2790 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2714 IEEE80211_STYPE_PROBE_RESP ? 2791 IEEE80211_STYPE_PROBE_RESP ?
2715 "PROBE RESPONSE" : "BEACON"); 2792 "PROBE RESPONSE" : "BEACON");
@@ -2719,10 +2796,10 @@ static inline void ieee80211_process_probe_response(
2719 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) 2796 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
2720 ieee80211_softmac_new_net(ieee,&network); 2797 ieee80211_softmac_new_net(ieee,&network);
2721 } else { 2798 } else {
2722 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", 2799 IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
2723 escape_essid(target->ssid, 2800 escape_essid(target->ssid,
2724 target->ssid_len), 2801 target->ssid_len),
2725 MAC_ARG(target->bssid), 2802 target->bssid,
2726 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 2803 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2727 IEEE80211_STYPE_PROBE_RESP ? 2804 IEEE80211_STYPE_PROBE_RESP ?
2728 "PROBE RESPONSE" : "BEACON"); 2805 "PROBE RESPONSE" : "BEACON");
@@ -2761,12 +2838,14 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
2761 struct ieee80211_hdr_4addr *header, 2838 struct ieee80211_hdr_4addr *header,
2762 struct ieee80211_rx_stats *stats) 2839 struct ieee80211_rx_stats *stats)
2763{ 2840{
2841#if 0
2764 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && 2842 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
2765 ieee->iw_mode == IW_MODE_INFRA && 2843 ieee->iw_mode == IW_MODE_INFRA &&
2766 ieee->state == IEEE80211_LINKED)) 2844 ieee->state == IEEE80211_LINKED))
2767 { 2845 {
2768 tasklet_schedule(&ieee->ps_task); 2846 tasklet_schedule(&ieee->ps_task);
2769 } 2847 }
2848#endif
2770 2849
2771 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && 2850 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
2772 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) 2851 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
@@ -2780,6 +2859,15 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
2780 IEEE80211_DEBUG_SCAN("Beacon\n"); 2859 IEEE80211_DEBUG_SCAN("Beacon\n");
2781 ieee80211_process_probe_response( 2860 ieee80211_process_probe_response(
2782 ieee, (struct ieee80211_probe_response *)header, stats); 2861 ieee, (struct ieee80211_probe_response *)header, stats);
2862
2863 //printk("----------->%s()\n", __func__);
2864 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
2865 ieee->iw_mode == IW_MODE_INFRA &&
2866 ieee->state == IEEE80211_LINKED))
2867 {
2868 tasklet_schedule(&ieee->ps_task);
2869 }
2870
2783 break; 2871 break;
2784 2872
2785 case IEEE80211_STYPE_PROBE_RESP: 2873 case IEEE80211_STYPE_PROBE_RESP:
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
index 6d1ddec39f0e..ea96c4956930 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
@@ -646,7 +646,7 @@ void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
646void ieee80211_start_send_beacons(struct ieee80211_device *ieee) 646void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
647{ 647{
648 if(ieee->start_send_beacons) 648 if(ieee->start_send_beacons)
649 ieee->start_send_beacons(ieee->dev,ieee->basic_rate); 649 ieee->start_send_beacons(ieee->dev);
650 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS) 650 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
651 ieee80211_beacons_start(ieee); 651 ieee80211_beacons_start(ieee);
652} 652}
@@ -686,6 +686,11 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
686/* called with ieee->lock held */ 686/* called with ieee->lock held */
687void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) 687void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
688{ 688{
689#ifdef ENABLE_IPS
690 if(ieee->ieee80211_ips_leave_wq != NULL)
691 ieee->ieee80211_ips_leave_wq(ieee->dev);
692#endif
693
689#ifdef ENABLE_DOT11D 694#ifdef ENABLE_DOT11D
690 if(IS_DOT11D_ENABLE(ieee) ) 695 if(IS_DOT11D_ENABLE(ieee) )
691 { 696 {
@@ -1093,6 +1098,40 @@ struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
1093 1098
1094} 1099}
1095 1100
1101struct sk_buff* ieee80211_pspoll_func(struct ieee80211_device *ieee)
1102{
1103 struct sk_buff *skb;
1104 struct ieee80211_pspoll_hdr* hdr;
1105
1106#ifdef USB_USE_ALIGNMENT
1107 u32 Tmpaddr=0;
1108 int alignment=0;
1109 skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE);
1110#else
1111 skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr)+ieee->tx_headroom);
1112#endif
1113 if (!skb)
1114 return NULL;
1115
1116#ifdef USB_USE_ALIGNMENT
1117 Tmpaddr = (u32)skb->data;
1118 alignment = Tmpaddr & 0x1ff;
1119 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
1120#endif
1121 skb_reserve(skb, ieee->tx_headroom);
1122
1123 hdr = (struct ieee80211_pspoll_hdr*)skb_put(skb,sizeof(struct ieee80211_pspoll_hdr));
1124
1125 memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN);
1126 memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN);
1127
1128 hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
1129 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_CTL |IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM);
1130
1131 return skb;
1132
1133}
1134
1096 1135
1097void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) 1136void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
1098{ 1137{
@@ -1582,6 +1621,11 @@ void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
1582{ 1621{
1583#endif 1622#endif
1584 ieee->sync_scan_hurryup = 1; 1623 ieee->sync_scan_hurryup = 1;
1624#ifdef ENABLE_IPS
1625 if(ieee->ieee80211_ips_leave != NULL)
1626 ieee->ieee80211_ips_leave(ieee->dev);
1627#endif
1628
1585 down(&ieee->wx_sem); 1629 down(&ieee->wx_sem);
1586 1630
1587 if (ieee->data_hard_stop) 1631 if (ieee->data_hard_stop)
@@ -1592,6 +1636,17 @@ void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
1592 //ieee->set_chan(ieee->dev, ieee->current_network.channel); 1636 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1593 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 1637 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1594 1638
1639#ifdef ENABLE_IPS
1640 if(ieee->eRFPowerState == eRfOff)
1641 {
1642 if(ieee->ieee80211_ips_leave_wq != NULL)
1643 ieee->ieee80211_ips_leave_wq(ieee->dev);
1644
1645 up(&ieee->wx_sem);
1646 return;
1647 }
1648#endif
1649
1595 ieee->associate_seq = 1; 1650 ieee->associate_seq = 1;
1596 ieee80211_associate_step1(ieee); 1651 ieee80211_associate_step1(ieee);
1597 1652
@@ -1897,7 +1952,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1897 ieee80211_resp_to_assoc_rq(ieee, dest); 1952 ieee80211_resp_to_assoc_rq(ieee, dest);
1898 } 1953 }
1899 1954
1900 printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); 1955 printk(KERN_INFO"New client associated: %pM\n", dest);
1901 //FIXME 1956 //FIXME
1902 #if 0 1957 #if 0
1903 spin_lock_irqsave(&ieee->lock,flags); 1958 spin_lock_irqsave(&ieee->lock,flags);
@@ -1918,43 +1973,92 @@ void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1918 1973
1919} 1974}
1920 1975
1976void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee)
1977{
1978
1979 struct sk_buff *buf = ieee80211_pspoll_func(ieee);
1980
1981 if (buf)
1982 softmac_ps_mgmt_xmit(buf, ieee);
1983
1984}
1921 1985
1922short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) 1986short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1923{ 1987{
1924 int timeout = ieee->ps_timeout; 1988 int timeout = ieee->ps_timeout;
1925 u8 dtim; 1989 u8 dtim;
1926 /*if(ieee->ps == IEEE80211_PS_DISABLED || 1990 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(ieee->PowerSaveControl));
1927 ieee->iw_mode != IW_MODE_INFRA ||
1928 ieee->state != IEEE80211_LINKED)
1929 1991
1992 if(ieee->LPSDelayCnt)
1993 {
1994 //printk("===============>Delay enter LPS for DHCP and ARP packets...\n");
1995 ieee->LPSDelayCnt --;
1930 return 0; 1996 return 0;
1931 */ 1997 }
1998
1932 dtim = ieee->current_network.dtim_data; 1999 dtim = ieee->current_network.dtim_data;
1933 //printk("DTIM\n"); 2000// printk("%s():DTIM:%d\n",__FUNCTION__,dtim);
1934 if(!(dtim & IEEE80211_DTIM_VALID)) 2001 if(!(dtim & IEEE80211_DTIM_VALID))
1935 return 0; 2002 return 0;
1936 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval 2003 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1937 //printk("VALID\n"); 2004 //printk("VALID\n");
1938 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; 2005 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1939 2006 /* there's no need to nofity AP that I find you buffered with broadcast packet */
1940 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps)) 2007 if(dtim & (IEEE80211_DTIM_UCAST & ieee->ps))
1941 return 2; 2008 return 2;
1942 2009
1943 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))) 2010 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){
2011// printk("%s():111Oh Oh ,it is not time out return 0\n",__FUNCTION__);
1944 return 0; 2012 return 0;
1945 2013 }
1946 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))) 2014 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){
2015// printk("%s():222Oh Oh ,it is not time out return 0\n",__FUNCTION__);
1947 return 0; 2016 return 0;
1948 2017 }
1949 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) && 2018 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1950 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) 2019 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1951 return 0; 2020 return 0;
1952 2021
1953 if(time_l){ 2022 if(time_l){
2023 if(ieee->bAwakePktSent == true) {
2024 pPSC->LPSAwakeIntvl = 1;//tx wake one beacon
2025 } else {
2026 u8 MaxPeriod = 1;
2027
2028 if(pPSC->LPSAwakeIntvl == 0)
2029 pPSC->LPSAwakeIntvl = 1;
2030 //pNdisCommon->RegLPSMaxIntvl /// 0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl
2031 if(pPSC->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl)
2032 MaxPeriod = 1; // 1 Beacon interval
2033 else if(pPSC->RegMaxLPSAwakeIntvl == 0xFF) // DTIM
2034 MaxPeriod = ieee->current_network.dtim_period;
2035 else
2036 MaxPeriod = pPSC->RegMaxLPSAwakeIntvl;
2037 pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (pPSC->LPSAwakeIntvl + 1);
2038 }
2039 {
2040 u8 LPSAwakeIntvl_tmp = 0;
2041 u8 period = ieee->current_network.dtim_period;
2042 u8 count = ieee->current_network.tim.tim_count;
2043 if(count == 0 ) {
2044 if(pPSC->LPSAwakeIntvl > period)
2045 LPSAwakeIntvl_tmp = period + (pPSC->LPSAwakeIntvl - period) -((pPSC->LPSAwakeIntvl-period)%period);
2046 else
2047 LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;
2048
2049 } else {
2050 if(pPSC->LPSAwakeIntvl > ieee->current_network.tim.tim_count)
2051 LPSAwakeIntvl_tmp = count + (pPSC->LPSAwakeIntvl - count) -((pPSC->LPSAwakeIntvl-count)%period);
2052 else
2053 LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;//ieee->current_network.tim.tim_count;//pPSC->LPSAwakeIntvl;
2054 }
2055 //printk("=========>%s()assoc_id:%d(%#x),bAwakePktSent:%d,DTIM:%d, sleep interval:%d, LPSAwakeIntvl_tmp:%d, count:%d\n",__func__,ieee->assoc_id,cpu_to_le16(ieee->assoc_id),ieee->bAwakePktSent,ieee->current_network.dtim_period,pPSC->LPSAwakeIntvl,LPSAwakeIntvl_tmp,count);
2056
1954 *time_l = ieee->current_network.last_dtim_sta_time[0] 2057 *time_l = ieee->current_network.last_dtim_sta_time[0]
1955 + (ieee->current_network.beacon_interval); 2058 + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp);
1956 // * ieee->current_network.dtim_period) * 1000; 2059 // * ieee->current_network.dtim_period) * 1000;
1957 } 2060 }
2061 }
1958 2062
1959 if(time_h){ 2063 if(time_h){
1960 *time_h = ieee->current_network.last_dtim_sta_time[1]; 2064 *time_h = ieee->current_network.last_dtim_sta_time[1];
@@ -1982,6 +2086,8 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1982 ieee->state != IEEE80211_LINKED)){ 2086 ieee->state != IEEE80211_LINKED)){
1983 2087
1984 // #warning CHECK_LOCK_HERE 2088 // #warning CHECK_LOCK_HERE
2089 printk("=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n",
2090 __FUNCTION__,ieee->ps,ieee->iw_mode,ieee->state);
1985 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 2091 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1986 2092
1987 ieee80211_sta_wakeup(ieee, 1); 2093 ieee80211_sta_wakeup(ieee, 1);
@@ -1991,27 +2097,27 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1991 2097
1992 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl); 2098 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1993 /* 2 wake, 1 sleep, 0 do nothing */ 2099 /* 2 wake, 1 sleep, 0 do nothing */
1994 if(sleep == 0) 2100 if(sleep == 0)//it is not time out or dtim is not valid
2101 {
2102 //printk("===========>sleep is 0,do nothing\n");
1995 goto out; 2103 goto out;
1996 2104 }
1997 if(sleep == 1){ 2105 if(sleep == 1){
1998 2106 //printk("===========>sleep is 1,to sleep\n");
1999 if(ieee->sta_sleep == 1) 2107 if(ieee->sta_sleep == 1){
2108 //printk("%s(1): sta_sleep = 1, sleep again ++++++++++ \n", __func__);
2000 ieee->enter_sleep_state(ieee->dev,th,tl); 2109 ieee->enter_sleep_state(ieee->dev,th,tl);
2110 }
2001 2111
2002 else if(ieee->sta_sleep == 0){ 2112 else if(ieee->sta_sleep == 0){
2003 // printk("send null 1\n"); 2113 // printk("send null 1\n");
2004 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 2114 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2005 2115
2006 if(ieee->ps_is_queue_empty(ieee->dev)){ 2116 if(ieee->ps_is_queue_empty(ieee->dev)){
2007
2008
2009 ieee->sta_sleep = 2; 2117 ieee->sta_sleep = 2;
2010
2011 ieee->ack_tx_to_ieee = 1; 2118 ieee->ack_tx_to_ieee = 1;
2012 2119 //printk("%s(2): sta_sleep = 0, notify AP we will sleeped ++++++++++ SendNullFunctionData\n", __func__);
2013 ieee80211_sta_ps_send_null_frame(ieee,1); 2120 ieee80211_sta_ps_send_null_frame(ieee,1);
2014
2015 ieee->ps_th = th; 2121 ieee->ps_th = th;
2016 ieee->ps_tl = tl; 2122 ieee->ps_tl = tl;
2017 } 2123 }
@@ -2019,11 +2125,13 @@ inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
2019 2125
2020 } 2126 }
2021 2127
2128 ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon.
2022 2129
2023 }else if(sleep == 2){ 2130 }else if(sleep == 2){
2024//#warning CHECK_LOCK_HERE 2131 //printk("==========>sleep is 2,to wakeup\n");
2025 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 2132 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2026 2133
2134 //printk("%s(3): pkt buffered in ap will awake ++++++++++ ieee80211_sta_wakeup\n", __func__);
2027 ieee80211_sta_wakeup(ieee,1); 2135 ieee80211_sta_wakeup(ieee,1);
2028 2136
2029 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); 2137 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
@@ -2038,9 +2146,19 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
2038{ 2146{
2039 if(ieee->sta_sleep == 0){ 2147 if(ieee->sta_sleep == 0){
2040 if(nl){ 2148 if(nl){
2041 printk("Warning: driver is probably failing to report TX ps error\n"); 2149 if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2042 ieee->ack_tx_to_ieee = 1; 2150 {
2043 ieee80211_sta_ps_send_null_frame(ieee, 0); 2151 //printk("%s(1): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__);
2152 //printk("Warning: driver is probably failing to report TX ps error\n");
2153 ieee->ack_tx_to_ieee = 1;
2154 ieee80211_sta_ps_send_null_frame(ieee, 0);
2155 }
2156 else
2157 {
2158 ieee->ack_tx_to_ieee = 1;
2159 //printk("%s(2): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__);
2160 ieee80211_sta_ps_send_pspoll_frame(ieee);
2161 }
2044 } 2162 }
2045 return; 2163 return;
2046 2164
@@ -2048,12 +2166,27 @@ void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
2048 2166
2049 if(ieee->sta_sleep == 1) 2167 if(ieee->sta_sleep == 1)
2050 ieee->sta_wake_up(ieee->dev); 2168 ieee->sta_wake_up(ieee->dev);
2169 if(nl){
2051 2170
2052 ieee->sta_sleep = 0; 2171 if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2172 {
2173 //printk("%s(3): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__);
2174 //printk("Warning: driver is probably failing to report TX ps error\n");
2175 ieee->ack_tx_to_ieee = 1;
2176 ieee80211_sta_ps_send_null_frame(ieee, 0);
2177 }
2178 else
2179 {
2180 ieee->ack_tx_to_ieee = 1;
2181 ieee->polling = true;
2182 //printk("%s(4): notify AP we are awaked ++++++++++ Send PS-Poll\n", __func__);
2183 //ieee80211_sta_ps_send_null_frame(ieee, 0);
2184 ieee80211_sta_ps_send_pspoll_frame(ieee);
2185 }
2053 2186
2054 if(nl){ 2187 } else {
2055 ieee->ack_tx_to_ieee = 1; 2188 ieee->sta_sleep = 0;
2056 ieee80211_sta_ps_send_null_frame(ieee, 0); 2189 ieee->polling = false;
2057 } 2190 }
2058} 2191}
2059 2192
@@ -2067,23 +2200,30 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
2067 /* Null frame with PS bit set */ 2200 /* Null frame with PS bit set */
2068 if(success){ 2201 if(success){
2069 ieee->sta_sleep = 1; 2202 ieee->sta_sleep = 1;
2203 //printk("notify AP we will sleep and send null ok, so sleep now++++++++++ enter_sleep_state\n");
2070 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl); 2204 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
2071 } 2205 }
2072 /* if the card report not success we can't be sure the AP 2206 } else {/* 21112005 - tx again null without PS bit if lost */
2073 * has not RXed so we can't assume the AP believe us awake
2074 */
2075 }
2076 /* 21112005 - tx again null without PS bit if lost */
2077 else {
2078 2207
2079 if((ieee->sta_sleep == 0) && !success){ 2208 if((ieee->sta_sleep == 0) && !success){
2080 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); 2209 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2081 ieee80211_sta_ps_send_null_frame(ieee, 0); 2210 //ieee80211_sta_ps_send_null_frame(ieee, 0);
2211 if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2212 {
2213 //printk("notify AP we will sleep but send bull failed, so resend++++++++++ SendNullFunctionData\n");
2214 ieee80211_sta_ps_send_null_frame(ieee, 0);
2215 }
2216 else
2217 {
2218 //printk("notify AP we are awaked but send pspoll failed, so resend++++++++++ Send PS-Poll\n");
2219 ieee80211_sta_ps_send_pspoll_frame(ieee);
2220 }
2082 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); 2221 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2083 } 2222 }
2084 } 2223 }
2085 spin_unlock_irqrestore(&ieee->lock, flags); 2224 spin_unlock_irqrestore(&ieee->lock, flags);
2086} 2225}
2226
2087void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb) 2227void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
2088{ 2228{
2089 struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data; 2229 struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
@@ -2227,7 +2367,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
2227 { 2367 {
2228 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) 2368 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2229 { 2369 {
2230 // WEP or TKIP encryption 2370 // WEP or TKIP encryption
2231 if(IsHTHalfNmodeAPs(ieee)) 2371 if(IsHTHalfNmodeAPs(ieee))
2232 { 2372 {
2233 bSupportNmode = true; 2373 bSupportNmode = true;
@@ -2238,7 +2378,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
2238 bSupportNmode = false; 2378 bSupportNmode = false;
2239 bHalfSupportNmode = false; 2379 bHalfSupportNmode = false;
2240 } 2380 }
2241 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode); 2381 printk("==========>to link with AP using SEC(%d, %d)\n", bSupportNmode, bHalfSupportNmode);
2242 } 2382 }
2243 } 2383 }
2244 /* Dummy wirless mode setting to avoid encryption issue */ 2384 /* Dummy wirless mode setting to avoid encryption issue */
@@ -2574,6 +2714,7 @@ void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
2574 ieee->ssid_set = 1; 2714 ieee->ssid_set = 1;
2575 } 2715 }
2576 2716
2717 ieee->state = IEEE80211_NOLINK;
2577 /* check if we have this cell in our network list */ 2718 /* check if we have this cell in our network list */
2578 ieee80211_softmac_check_all_nets(ieee); 2719 ieee80211_softmac_check_all_nets(ieee);
2579 2720
@@ -2705,6 +2846,10 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
2705 spin_lock_irqsave(&ieee->lock, flags); 2846 spin_lock_irqsave(&ieee->lock, flags);
2706 2847
2707 if (ieee->state == IEEE80211_NOLINK){ 2848 if (ieee->state == IEEE80211_NOLINK){
2849#ifdef ENABLE_IPS
2850 if(ieee->ieee80211_ips_leave_wq != NULL)
2851 ieee->ieee80211_ips_leave_wq(ieee->dev);
2852#endif
2708 ieee->actscanning = true; 2853 ieee->actscanning = true;
2709 ieee80211_rtl_start_scan(ieee); 2854 ieee80211_rtl_start_scan(ieee);
2710 } 2855 }
@@ -2823,21 +2968,23 @@ struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2823 return skb; 2968 return skb;
2824} 2969}
2825 2970
2826void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee) 2971void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
2827{ 2972{
2828 ieee->sync_scan_hurryup = 1; 2973 ieee->sync_scan_hurryup = 1;
2829 down(&ieee->wx_sem); 2974 down(&ieee->wx_sem);
2830 ieee80211_stop_protocol(ieee); 2975 ieee80211_stop_protocol(ieee, shutdown);
2831 up(&ieee->wx_sem); 2976 up(&ieee->wx_sem);
2832} 2977}
2833 2978
2834 2979
2835void ieee80211_stop_protocol(struct ieee80211_device *ieee) 2980void ieee80211_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
2836{ 2981{
2837 if (!ieee->proto_started) 2982 if (!ieee->proto_started)
2838 return; 2983 return;
2839 2984
2840 ieee->proto_started = 0; 2985 if(shutdown)
2986 ieee->proto_started = 0;
2987 ieee->proto_stoppping = 1;
2841 2988
2842 ieee80211_stop_send_beacons(ieee); 2989 ieee80211_stop_send_beacons(ieee);
2843 del_timer_sync(&ieee->associate_timer); 2990 del_timer_sync(&ieee->associate_timer);
@@ -2849,6 +2996,8 @@ void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2849 2996
2850 ieee80211_disassociate(ieee); 2997 ieee80211_disassociate(ieee);
2851 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS 2998 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2999
3000 ieee->proto_stoppping = 0;
2852} 3001}
2853 3002
2854void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) 3003void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
@@ -2894,6 +3043,8 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee)
2894 3043
2895 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers. 3044 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2896 3045
3046 ieee->state = IEEE80211_NOLINK;
3047
2897 3048
2898 /* if the user set the MAC of the ad-hoc cell and then 3049 /* if the user set the MAC of the ad-hoc cell and then
2899 * switch to managed mode, shall we make sure that association 3050 * switch to managed mode, shall we make sure that association
@@ -3013,7 +3164,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
3013#endif 3164#endif
3014 sema_init(&ieee->wx_sem, 1); 3165 sema_init(&ieee->wx_sem, 1);
3015 sema_init(&ieee->scan_sem, 1); 3166 sema_init(&ieee->scan_sem, 1);
3016 3167#ifdef ENABLE_IPS
3168 sema_init(&ieee->ips_sem,1);
3169#endif
3017 spin_lock_init(&ieee->mgmt_tx_lock); 3170 spin_lock_init(&ieee->mgmt_tx_lock);
3018 spin_lock_init(&ieee->beacon_lock); 3171 spin_lock_init(&ieee->beacon_lock);
3019 3172
@@ -3537,5 +3690,6 @@ EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
3537EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests); 3690EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests);
3538EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro); 3691EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro);
3539EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro); 3692EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro);
3693EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_null_frame);
3694EXPORT_SYMBOL_NOVERS(ieee80211_sta_ps_send_pspoll_frame);
3540#endif 3695#endif
3541//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
index 7c21aaab9063..1bbd49f1d6f6 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
@@ -160,7 +160,7 @@ int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
160 } 160 }
161 161
162 if (ifup) 162 if (ifup)
163 ieee80211_stop_protocol(ieee); 163 ieee80211_stop_protocol(ieee,true);
164 164
165 /* just to avoid to give inconsistent infos in the 165 /* just to avoid to give inconsistent infos in the
166 * get wx method. not really needed otherwise 166 * get wx method. not really needed otherwise
@@ -302,7 +302,7 @@ int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info
302 if (!ieee->proto_started){ 302 if (!ieee->proto_started){
303 ieee->iw_mode = wrqu->mode; 303 ieee->iw_mode = wrqu->mode;
304 }else{ 304 }else{
305 ieee80211_stop_protocol(ieee); 305 ieee80211_stop_protocol(ieee,true);
306 ieee->iw_mode = wrqu->mode; 306 ieee->iw_mode = wrqu->mode;
307 ieee80211_start_protocol(ieee); 307 ieee80211_start_protocol(ieee);
308 } 308 }
@@ -326,6 +326,17 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
326 int b40M = 0; 326 int b40M = 0;
327 static int count = 0; 327 static int count = 0;
328 chan = ieee->current_network.channel; 328 chan = ieee->current_network.channel;
329
330#ifdef ENABLE_LPS
331 if (ieee->LeisurePSLeave) {
332 ieee->LeisurePSLeave(ieee->dev);
333 }
334
335 /* notify AP to be in PS mode */
336 ieee80211_sta_ps_send_null_frame(ieee, 1);
337 ieee80211_sta_ps_send_null_frame(ieee, 1);
338#endif
339
329 netif_carrier_off(ieee->dev); 340 netif_carrier_off(ieee->dev);
330 341
331 if (ieee->data_hard_stop) 342 if (ieee->data_hard_stop)
@@ -360,6 +371,12 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
360 ieee->InitialGainHandler(ieee->dev,IG_Restore); 371 ieee->InitialGainHandler(ieee->dev,IG_Restore);
361 ieee->state = IEEE80211_LINKED; 372 ieee->state = IEEE80211_LINKED;
362 ieee->link_change(ieee->dev); 373 ieee->link_change(ieee->dev);
374
375#ifdef ENABLE_LPS
376 /* Notify AP that I wake up again */
377 ieee80211_sta_ps_send_null_frame(ieee, 0);
378#endif
379
363 // To prevent the immediately calling watch_dog after scan. 380 // To prevent the immediately calling watch_dog after scan.
364 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) 381 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
365 { 382 {
@@ -429,8 +446,9 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
429 goto out; 446 goto out;
430 } 447 }
431 448
432 if(proto_started) 449 if(proto_started){
433 ieee80211_stop_protocol(ieee); 450 ieee80211_stop_protocol(ieee,true);
451 }
434 452
435 453
436 /* this is just to be sure that the GET wx callback 454 /* this is just to be sure that the GET wx callback
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
index 798fb4154c25..a75f3668a40a 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
@@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment(
200 header = (struct ieee80211_hdr *) frag->data; 200 header = (struct ieee80211_hdr *) frag->data;
201 if (net_ratelimit()) { 201 if (net_ratelimit()) {
202 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 202 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
203 "TX packet to " MAC_FMT "\n", 203 "TX packet to %pM\n",
204 ieee->dev->name, MAC_ARG(header->addr1)); 204 ieee->dev->name, header->addr1);
205 } 205 }
206 return -1; 206 return -1;
207 } 207 }
@@ -334,6 +334,13 @@ void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* s
334 if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter)) 334 if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
335 return; 335 return;
336#endif 336#endif
337
338 if(tcb_desc->bdhcp)// || ieee->CntAfterLink<2)
339 {
340 return;
341 }
342
343
337#if 1 344#if 1
338 if(!ieee->GetNmodeSupportBySecCfg(ieee->dev)) 345 if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
339 { 346 {
@@ -628,6 +635,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
628 int qos_actived = ieee->current_network.qos_data.active; 635 int qos_actived = ieee->current_network.qos_data.active;
629 636
630 struct ieee80211_crypt_data* crypt; 637 struct ieee80211_crypt_data* crypt;
638 bool bdhcp =false;
631 639
632 cb_desc *tcb_desc; 640 cb_desc *tcb_desc;
633 641
@@ -672,6 +680,55 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
672 } 680 }
673 #endif 681 #endif
674 682
683 // The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time
684 // to prevent DHCP protocol fail
685 if (skb->len > 282){//MINIMUM_DHCP_PACKET_SIZE) {
686 if (ETH_P_IP == ether_type) {// IP header
687 const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
688 if (IPPROTO_UDP == ip->protocol) {//FIXME windows is 11 but here UDP in linux kernel is 17.
689 struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
690 //if(((ntohs(udp->source) == 68) && (ntohs(udp->dest) == 67)) ||
691 /// ((ntohs(udp->source) == 67) && (ntohs(udp->dest) == 68))) {
692 if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) ||
693 ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) {
694 // 68 : UDP BOOTP client
695 // 67 : UDP BOOTP server
696 printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]);
697 // Use low rate to send DHCP packet.
698 //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
699 //{
700 // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
701 // tcb_desc->bTxDisableRateFallBack = false;
702 //}
703 //else
704 //pTcb->DataRate = Adapter->MgntInfo.LowestBasicRate;
705 //RTPRINT(FDM, WA_IOT, ("DHCP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
706
707 bdhcp = true;
708#ifdef _RTL8192_EXT_PATCH_
709 ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701
710#else
711 ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2;
712#endif
713 }
714 }
715 }else if(ETH_P_ARP == ether_type){// IP ARP packet
716 printk("=================>DHCP Protocol start tx ARP pkt!!\n");
717 bdhcp = true;
718 ieee->LPSDelayCnt = ieee->current_network.tim.tim_count;
719
720 //if(pMgntInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom)
721 //{
722 // tcb_desc->DataRate = MgntQuery_TxRateExcludeCCKRates(Adapter->MgntInfo.mBrates);//0xc;//ofdm 6m
723 // tcb_desc->bTxDisableRateFallBack = FALSE;
724 //}
725 //else
726 // tcb_desc->DataRate = Adapter->MgntInfo.LowestBasicRate;
727 //RTPRINT(FDM, WA_IOT, ("ARP TranslateHeader(), pTcb->DataRate = 0x%x\n", pTcb->DataRate));
728
729 }
730 }
731
675 /* Save source and destination addresses */ 732 /* Save source and destination addresses */
676 memcpy(&dest, skb->data, ETH_ALEN); 733 memcpy(&dest, skb->data, ETH_ALEN);
677 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); 734 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
@@ -895,6 +952,25 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
895 else 952 else
896 //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate); 953 //tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
897 tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate); 954 tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
955
956 if(bdhcp == true){
957 // Use low rate to send DHCP packet.
958 //if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_WA_IOT_Broadcom) {
959 // tcb_desc->data_rate = MGN_1M;//MgntQuery_TxRateExcludeCCKRates(ieee);//0xc;//ofdm 6m
960 // tcb_desc->bTxDisableRateFallBack = false;
961 //}
962 //else
963 {
964 tcb_desc->data_rate = MGN_1M;
965 tcb_desc->bTxDisableRateFallBack = 1;
966 }
967
968 tcb_desc->RATRIndex = 7;
969 tcb_desc->bTxUseDriverAssingedRate = 1;
970 tcb_desc->bdhcp = 1;
971 }
972
973
898 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc); 974 ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
899 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc); 975 ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
900 ieee80211_query_HTCapShortGI(ieee, tcb_desc); 976 ieee80211_query_HTCapShortGI(ieee, tcb_desc);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
index 3441b72dd8fa..a3302d5e01ab 100644
--- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
@@ -386,10 +386,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
386 else 386 else
387 IEEE80211_DEBUG_SCAN( 387 IEEE80211_DEBUG_SCAN(
388 "Not showing network '%s (" 388 "Not showing network '%s ("
389 MAC_FMT ")' due to age (%lums).\n", 389 "%pM)' due to age (%lums).\n",
390 escape_essid(network->ssid, 390 escape_essid(network->ssid,
391 network->ssid_len), 391 network->ssid_len),
392 MAC_ARG(network->bssid), 392 network->bssid,
393 (jiffies - network->last_scanned) / (HZ / 100)); 393 (jiffies - network->last_scanned) / (HZ / 100));
394 } 394 }
395 395
@@ -933,7 +933,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
933#if 1 933#if 1
934 case IW_AUTH_WPA_ENABLED: 934 case IW_AUTH_WPA_ENABLED:
935 ieee->wpa_enabled = (data->value)?1:0; 935 ieee->wpa_enabled = (data->value)?1:0;
936 //printk("enalbe wpa:%d\n", ieee->wpa_enabled); 936 //printk("enable wpa:%d\n", ieee->wpa_enabled);
937 break; 937 break;
938 938
939#endif 939#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
index e41e8a0c739c..ae0e5b9e2183 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
113 u16 tmp = 0; 113 u16 tmp = 0;
114 u16 len = ieee->tx_headroom + 9; 114 u16 len = ieee->tx_headroom + 9;
115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) 115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
116 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev); 116 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
117 if (pBA == NULL||ieee == NULL) 117 if (pBA == NULL||ieee == NULL)
118 { 118 {
119 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); 119 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -243,7 +243,7 @@ static struct sk_buff* ieee80211_DELBA(
243 u16 len = 6 + ieee->tx_headroom; 243 u16 len = 6 + ieee->tx_headroom;
244 244
245 if (net_ratelimit()) 245 if (net_ratelimit())
246 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst)); 246 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
247 247
248 memset(&DelbaParamSet, 0, 2); 248 memset(&DelbaParamSet, 0, 2);
249 249
@@ -397,7 +397,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
397 pBaTimeoutVal = (u16*)(tag + 5); 397 pBaTimeoutVal = (u16*)(tag + 5);
398 pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); 398 pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
399 399
400 printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); 400 printk("====================>rx ADDBAREQ from :%pM\n", dst);
401//some other capability is not ready now. 401//some other capability is not ready now.
402 if( (ieee->current_network.qos_data.active == 0) || 402 if( (ieee->current_network.qos_data.active == 0) ||
403 (ieee->pHTInfo->bCurrentHTSupport == false)) //|| 403 (ieee->pHTInfo->bCurrentHTSupport == false)) //||
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
index 992b71825a8b..f968817d073c 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
@@ -458,7 +458,8 @@ typedef enum _HT_IOT_PEER
458 HT_IOT_PEER_RALINK = 3, 458 HT_IOT_PEER_RALINK = 3,
459 HT_IOT_PEER_ATHEROS = 4, 459 HT_IOT_PEER_ATHEROS = 4,
460 HT_IOT_PEER_CISCO= 5, 460 HT_IOT_PEER_CISCO= 5,
461 HT_IOT_PEER_MAX = 6 461 HT_IOT_PEER_MARVELL=6,
462 HT_IOT_PEER_MAX = 7
462}HT_IOT_PEER_E, *PHTIOT_PEER_E; 463}HT_IOT_PEER_E, *PHTIOT_PEER_E;
463 464
464// 465//
@@ -475,6 +476,7 @@ typedef enum _HT_IOT_ACTION{
475 HT_IOT_ACT_CDD_FSYNC = 0x00000080, 476 HT_IOT_ACT_CDD_FSYNC = 0x00000080,
476 HT_IOT_ACT_PURE_N_MODE = 0x00000100, 477 HT_IOT_ACT_PURE_N_MODE = 0x00000100,
477 HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, 478 HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
479 HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000,
478}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E; 480}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
479 481
480#endif //_RTL819XU_HTTYPE_H_ 482#endif //_RTL819XU_HTTYPE_H_
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
index 1e392141779a..4c4b1df350ac 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
@@ -32,7 +32,7 @@ u16 MCS_DATA_RATE[2][2][77] =
32static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; 32static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
33static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; 33static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
34static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; 34static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
35static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; 35//static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
36static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008 36static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008
37static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; 37static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
38static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; 38static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
@@ -40,8 +40,9 @@ static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
40static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; 40static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
41static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; 41static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
42static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; 42static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
43static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
43 44
44// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the 45// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
45// code in other place?? 46// code in other place??
46//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; 47//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
47/******************************************************************************************************************** 48/********************************************************************************************************************
@@ -349,12 +350,12 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
349 bool retValue = false; 350 bool retValue = false;
350 struct ieee80211_network* net = &ieee->current_network; 351 struct ieee80211_network* net = &ieee->current_network;
351#if 0 352#if 0
352 if(pMgntInfo->bHalfNMode == false) 353 if(ieee->bHalfNMode == false)
353 retValue = false; 354 retValue = false;
354 else 355 else
355#endif 356#endif
356 if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || 357 if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
357 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || 358 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
358 (memcmp(net->bssid, PCI_RALINK, 3)==0) || 359 (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
359 (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) || 360 (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
360 (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) || 361 (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
@@ -363,7 +364,7 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
363 else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || 364 else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
364 (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| 365 (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
365 (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| 366 (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
366 (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) || 367 //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
367 (net->broadcom_cap_exist)) 368 (net->broadcom_cap_exist))
368 retValue = true; 369 retValue = true;
369 else if(net->bssht.bdRT2RTAggregation) 370 else if(net->bssht.bdRT2RTAggregation)
@@ -387,13 +388,15 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee)
387 struct ieee80211_network* net = &ieee->current_network; 388 struct ieee80211_network* net = &ieee->current_network;
388 if(net->bssht.bdRT2RTAggregation) 389 if(net->bssht.bdRT2RTAggregation)
389 pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; 390 pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
390 else if(net->broadcom_cap_exist) 391 else if(net->broadcom_cap_exist){
391 pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; 392 pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
393 }
392 else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || 394 else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
393 (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| 395 (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
394 (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| 396 (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)){//||
395 (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ) 397 //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ){
396 pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; 398 pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
399 }
397 else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || 400 else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
398 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || 401 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
399 (memcmp(net->bssid, PCI_RALINK, 3)==0) || 402 (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
@@ -405,6 +408,10 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee)
405 pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; 408 pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
406 else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0) 409 else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
407 pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; 410 pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
411 else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
412 net->marvell_cap_exist){
413 pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
414 }
408 else 415 else
409 pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; 416 pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
410 417
@@ -442,6 +449,18 @@ u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
442 return ret; 449 return ret;
443 } 450 }
444 451
452u8 HTIOTActIsForcedCTS2Self(struct ieee80211_device *ieee, struct ieee80211_network *network)
453{
454 u8 retValue = 0;
455 //if(network->marvell_cap_exist)
456 if(ieee->pHTInfo->IOTPeer == HT_IOT_PEER_MARVELL)
457 {
458 retValue = 1;
459 }
460
461 return retValue;
462}
463
445 464
446/** 465/**
447* Function: HTIOTActIsDisableMCS15 466* Function: HTIOTActIsDisableMCS15
@@ -578,6 +597,23 @@ u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
578 return retValue; 597 return retValue;
579} 598}
580 599
600//
601// Send null data for to tell AP that we are awake.
602//
603bool
604HTIOTActIsNullDataPowerSaving(struct ieee80211_device* ieee,struct ieee80211_network *network)
605{
606 bool retValue = false;
607
608 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
609 {
610 if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) // ||(pBssDesc->Vender == HT_IOT_PEER_ATHEROS && pBssDesc->SubTypeOfVender == HT_IOT_PEER_ATHEROS_DIR635))
611 return true;
612
613 }
614 return retValue;
615}
616
581void HTResetIOTSetting( 617void HTResetIOTSetting(
582 PRT_HIGH_THROUGHPUT pHTInfo 618 PRT_HIGH_THROUGHPUT pHTInfo
583) 619)
@@ -1071,6 +1107,13 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
1071 // Config and configure A-MSDU setting 1107 // Config and configure A-MSDU setting
1072 // 1108 //
1073 pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; 1109 pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
1110 if (ieee->rtllib_ap_sec_type &&
1111 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))){
1112 if( (pHTInfo->IOTPeer== HT_IOT_PEER_ATHEROS) ||
1113 (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) )
1114 pHTInfo->bCurrentAMPDUEnable = false;
1115 }
1116
1074 1117
1075 nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935; 1118 nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
1076 1119
@@ -1515,6 +1558,9 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80
1515 bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); 1558 bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
1516 if(bIOTAction) 1559 if(bIOTAction)
1517 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; 1560 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
1561 bIOTAction = HTIOTActIsForcedCTS2Self(ieee, pNetwork);
1562 if(bIOTAction)
1563 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1518 1564
1519 bIOTAction = HTIOTActIsDisableMCS15(ieee); 1565 bIOTAction = HTIOTActIsDisableMCS15(ieee);
1520 if(bIOTAction) 1566 if(bIOTAction)
@@ -1537,6 +1583,9 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80
1537 if(bIOTAction) 1583 if(bIOTAction)
1538 pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; 1584 pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
1539 1585
1586 bIOTAction = HTIOTActIsNullDataPowerSaving(ieee, pNetwork);
1587 if(bIOTAction)
1588 pHTInfo->IOTAction |= HT_IOT_ACT_NULL_DATA_POWER_SAVING;
1540 1589
1541 } 1590 }
1542 else 1591 else
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
index 2816b60a08a9..e2cbfd3aa00f 100644
--- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
@@ -304,7 +304,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8
304 if(search_dir[dir] ==false ) 304 if(search_dir[dir] ==false )
305 continue; 305 continue;
306 list_for_each_entry(pRet, psearch_list, List){ 306 list_for_each_entry(pRet, psearch_list, List){
307 // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); 307 // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
308 if (memcmp(pRet->Addr, Addr, 6) == 0) 308 if (memcmp(pRet->Addr, Addr, 6) == 0)
309 if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) 309 if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
310 if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) 310 if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -466,7 +466,7 @@ bool GetTs(
466 ResetRxTsEntry(tmp); 466 ResetRxTsEntry(tmp);
467 } 467 }
468 468
469 IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr)); 469 IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
470 // Prepare TS Info releated field 470 // Prepare TS Info releated field
471 pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field 471 pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
472 pTSInfo->field.ucTSID = UP; // TSID 472 pTSInfo->field.ucTSID = UP; // TSID
@@ -552,7 +552,7 @@ void RemoveTsEntry(
552void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) 552void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
553{ 553{
554 PTS_COMMON_INFO pTS, pTmpTS; 554 PTS_COMMON_INFO pTS, pTmpTS;
555 printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr)); 555 printk("===========>RemovePeerTS,%pM\n", Addr);
556#if 1 556#if 1
557 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) 557 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
558 { 558 {
diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c
index 79f7a0f39623..262ed5fd086a 100644
--- a/drivers/staging/rtl8192e/r8180_93cx6.c
+++ b/drivers/staging/rtl8192e/r8180_93cx6.c
@@ -22,7 +22,7 @@
22 22
23static void eprom_cs(struct net_device *dev, short bit) 23static void eprom_cs(struct net_device *dev, short bit)
24{ 24{
25 if(bit) 25 if (bit)
26 write_nic_byte(dev, EPROM_CMD, 26 write_nic_byte(dev, EPROM_CMD,
27 (1<<EPROM_CS_SHIFT) | \ 27 (1<<EPROM_CS_SHIFT) | \
28 read_nic_byte(dev, EPROM_CMD)); //enable EPROM 28 read_nic_byte(dev, EPROM_CMD)); //enable EPROM
@@ -38,23 +38,23 @@ static void eprom_cs(struct net_device *dev, short bit)
38static void eprom_ck_cycle(struct net_device *dev) 38static void eprom_ck_cycle(struct net_device *dev)
39{ 39{
40 write_nic_byte(dev, EPROM_CMD, 40 write_nic_byte(dev, EPROM_CMD,
41 (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD)); 41 (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD));
42 force_pci_posting(dev); 42 force_pci_posting(dev);
43 udelay(EPROM_DELAY); 43 udelay(EPROM_DELAY);
44 write_nic_byte(dev, EPROM_CMD, 44 write_nic_byte(dev, EPROM_CMD,
45 read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT)); 45 read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT));
46 force_pci_posting(dev); 46 force_pci_posting(dev);
47 udelay(EPROM_DELAY); 47 udelay(EPROM_DELAY);
48} 48}
49 49
50 50
51static void eprom_w(struct net_device *dev,short bit) 51static void eprom_w(struct net_device *dev, short bit)
52{ 52{
53 if(bit) 53 if (bit)
54 write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \ 54 write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
55 read_nic_byte(dev,EPROM_CMD)); 55 read_nic_byte(dev, EPROM_CMD));
56 else 56 else
57 write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\ 57 write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
58 &~(1<<EPROM_W_SHIFT)); 58 &~(1<<EPROM_W_SHIFT));
59 59
60 force_pci_posting(dev); 60 force_pci_posting(dev);
@@ -66,10 +66,11 @@ static short eprom_r(struct net_device *dev)
66{ 66{
67 short bit; 67 short bit;
68 68
69 bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) ); 69 bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT));
70 udelay(EPROM_DELAY); 70 udelay(EPROM_DELAY);
71 71
72 if(bit) return 1; 72 if (bit)
73 return 1;
73 return 0; 74 return 0;
74} 75}
75 76
@@ -78,7 +79,7 @@ static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
78{ 79{
79 int i; 80 int i;
80 81
81 for(i=0; i<len; i++){ 82 for (i = 0; i < len; i++) {
82 eprom_w(dev, b[i]); 83 eprom_w(dev, b[i]);
83 eprom_ck_cycle(dev); 84 eprom_ck_cycle(dev);
84 } 85 }
@@ -88,37 +89,37 @@ static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
88u32 eprom_read(struct net_device *dev, u32 addr) 89u32 eprom_read(struct net_device *dev, u32 addr)
89{ 90{
90 struct r8192_priv *priv = ieee80211_priv(dev); 91 struct r8192_priv *priv = ieee80211_priv(dev);
91 short read_cmd[]={1,1,0}; 92 short read_cmd[] = {1, 1, 0};
92 short addr_str[8]; 93 short addr_str[8];
93 int i; 94 int i;
94 int addr_len; 95 int addr_len;
95 u32 ret; 96 u32 ret;
96 97
97 ret=0; 98 ret = 0;
98 //enable EPROM programming 99 //enable EPROM programming
99 write_nic_byte(dev, EPROM_CMD, 100 write_nic_byte(dev, EPROM_CMD,
100 (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT)); 101 (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
101 force_pci_posting(dev); 102 force_pci_posting(dev);
102 udelay(EPROM_DELAY); 103 udelay(EPROM_DELAY);
103 104
104 if (priv->epromtype==EPROM_93c56){ 105 if (priv->epromtype == EPROM_93c56) {
105 addr_str[7]=addr & 1; 106 addr_str[7] = addr & 1;
106 addr_str[6]=addr & (1<<1); 107 addr_str[6] = addr & (1<<1);
107 addr_str[5]=addr & (1<<2); 108 addr_str[5] = addr & (1<<2);
108 addr_str[4]=addr & (1<<3); 109 addr_str[4] = addr & (1<<3);
109 addr_str[3]=addr & (1<<4); 110 addr_str[3] = addr & (1<<4);
110 addr_str[2]=addr & (1<<5); 111 addr_str[2] = addr & (1<<5);
111 addr_str[1]=addr & (1<<6); 112 addr_str[1] = addr & (1<<6);
112 addr_str[0]=addr & (1<<7); 113 addr_str[0] = addr & (1<<7);
113 addr_len=8; 114 addr_len = 8;
114 }else{ 115 } else {
115 addr_str[5]=addr & 1; 116 addr_str[5] = addr & 1;
116 addr_str[4]=addr & (1<<1); 117 addr_str[4] = addr & (1<<1);
117 addr_str[3]=addr & (1<<2); 118 addr_str[3] = addr & (1<<2);
118 addr_str[2]=addr & (1<<3); 119 addr_str[2] = addr & (1<<3);
119 addr_str[1]=addr & (1<<4); 120 addr_str[1] = addr & (1<<4);
120 addr_str[0]=addr & (1<<5); 121 addr_str[0] = addr & (1<<5);
121 addr_len=6; 122 addr_len = 6;
122 } 123 }
123 eprom_cs(dev, 1); 124 eprom_cs(dev, 1);
124 eprom_ck_cycle(dev); 125 eprom_ck_cycle(dev);
@@ -129,7 +130,7 @@ u32 eprom_read(struct net_device *dev, u32 addr)
129 //I'm unsure if it is necessary, but anyway shouldn't hurt 130 //I'm unsure if it is necessary, but anyway shouldn't hurt
130 eprom_w(dev, 0); 131 eprom_w(dev, 0);
131 132
132 for(i=0;i<16;i++){ 133 for (i = 0; i < 16; i++) {
133 //eeprom needs a clk cycle between writing opcode&adr 134 //eeprom needs a clk cycle between writing opcode&adr
134 //and reading data. (eeprom outs a dummy 0) 135 //and reading data. (eeprom outs a dummy 0)
135 eprom_ck_cycle(dev); 136 eprom_ck_cycle(dev);
diff --git a/drivers/staging/rtl8192e/r8180_93cx6.h b/drivers/staging/rtl8192e/r8180_93cx6.h
index 62e14c78e960..4c3f675c6a66 100644
--- a/drivers/staging/rtl8192e/r8180_93cx6.h
+++ b/drivers/staging/rtl8192e/r8180_93cx6.h
@@ -1,17 +1,18 @@
1/* 1/* r8180_93cx6.h - 93c46 or 93c56 eeprom card programming routines
2 This is part of rtl8187 OpenSource driver 2 *
3 Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> 3 * This is part of rtl8187 OpenSource driver
4 Released under the terms of GPL (General Public Licence) 4 * Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
5 5 * Released under the terms of GPL (General Public Licence)
6 Parts of this driver are based on the GPL part of the official realtek driver 6 * Parts of this driver are based on the GPL part of the official realtek driver
7 Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon 7 *
8 Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver 8 * Parts of this driver are based on the rtl8180 driver skeleton from
9 9 * Patric Schenke & Andres Salomon.
10 We want to tanks the Authors of such projects and the Ndiswrapper project Authors. 10 *
11*/ 11 * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
12 12 *
13/*This files contains card eeprom (93c46 or 93c56) programming routines*/ 13 * We want to thank the authors of the above mentioned projects and to
14/*memory is addressed by WORDS*/ 14 * the authors of the Ndiswrapper project.
15 */
15 16
16#include "r8192E.h" 17#include "r8192E.h"
17#include "r8192E_hw.h" 18#include "r8192E_hw.h"
@@ -36,5 +37,5 @@
36#define EPROM_TXPW2 0x1b 37#define EPROM_TXPW2 0x1b
37#define EPROM_TXPW1 0x3d 38#define EPROM_TXPW1 0x3d
38 39
39 40/* Reads a 16 bits word. */
40u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word 41u32 eprom_read(struct net_device *dev, u32 addr);
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c
index 3d67fbb65b96..1bd054d42f24 100644
--- a/drivers/staging/rtl8192e/r8190_rtl8256.c
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.c
@@ -429,11 +429,12 @@ SetRFPowerState8190(
429 bool bResult = true; 429 bool bResult = true;
430 //u8 eRFPath; 430 //u8 eRFPath;
431 u8 i = 0, QueueID = 0; 431 u8 i = 0, QueueID = 0;
432 ptx_ring head=NULL,tail=NULL; 432 //ptx_ring head=NULL,tail=NULL;
433 struct rtl8192_tx_ring *ring = NULL;
433 434
434 if(priv->SetRFPowerStateInProgress == true) 435 if(priv->SetRFPowerStateInProgress == true)
435 return false; 436 return false;
436 RT_TRACE(COMP_POWER, "===========> SetRFPowerState8190()!\n"); 437 //RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n");
437 priv->SetRFPowerStateInProgress = true; 438 priv->SetRFPowerStateInProgress = true;
438 439
439 switch(priv->rf_chip) 440 switch(priv->rf_chip)
@@ -442,11 +443,11 @@ SetRFPowerState8190(
442 switch( eRFPowerState ) 443 switch( eRFPowerState )
443 { 444 {
444 case eRfOn: 445 case eRfOn:
445 RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOn !\n"); 446 //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOn !\n");
446 //RXTX enable control: On 447 //RXTX enable control: On
447 //for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++) 448 //for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
448 // PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2); 449 // PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
449 #ifdef RTL8190P 450#ifdef RTL8190P
450 if(priv->rf_type == RF_2T4R) 451 if(priv->rf_type == RF_2T4R)
451 { 452 {
452 //enable RF-Chip A/B 453 //enable RF-Chip A/B
@@ -479,36 +480,92 @@ SetRFPowerState8190(
479 //analog to digital part2 on 480 //analog to digital part2 on
480 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11] 481 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11]
481 } 482 }
482 #else 483 else if(priv->rf_type == RF_1T1R) //RF-C
483 write_nic_byte(dev, ANAPAR, 0x37);//160MHz 484 {
484 write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403 485 //enable RF-Chip C/D
485 mdelay(1); 486 rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4]
486 //enable clock 80/88 MHz 487 //analog to digital on
487 488 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x400, 0x1);// 0x88c[10]
488 priv->bHwRfOffAction = 0; 489 //digital to analog on
489 //} 490 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x80, 0x1); // 0x880[7]
490 491 //rx antenna on
491 // Baseband reset 2008.09.30 add 492 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x4, 0x1);// 0xc04[2]
492 write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); 493 //rx antenna on
493 494 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x4, 0x1);// 0xd04[2]
494 //2 AFE 495 //analog to digital part2 on
495 // 2008.09.30 add 496 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x800, 0x1); // 0x880[11]
496 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884 497 }
497 //analog to digital part2 on 498
498 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] 499#elif defined RTL8192E
499 //digital to analog on 500 // turn on RF
500 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3] 501 if((priv->ieee80211->eRFPowerState == eRfOff) && RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
501 //analog to digital on 502 { // The current RF state is OFF and the RF OFF level is halting the NIC, re-initialize the NIC.
502 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8] 503 bool rtstatus = true;
503 //rx antenna on 504 u32 InitilizeCount = 3;
504 //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] 505 do
505 //rx antenna on 2008.09.30 mark 506 {
506 //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] 507 InitilizeCount--;
507 508 priv->RegRfOff = false;
508 //2 RF 509 rtstatus = NicIFEnableNIC(dev);
509 //enable RF-Chip A/B 510 }while( (rtstatus != true) &&(InitilizeCount >0) );
511
512 if(rtstatus != true)
513 {
514 RT_TRACE(COMP_ERR,"%s():Initialize Adapter fail,return\n",__FUNCTION__);
515 priv->SetRFPowerStateInProgress = false;
516 return false;
517 }
518
519 RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
520 } else {
521 write_nic_byte(dev, ANAPAR, 0x37);//160MHz
522 //write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403
523 mdelay(1);
524 //enable clock 80/88 MHz
525 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2]
526 priv->bHwRfOffAction = 0;
527 //}
528
529 //RF-A, RF-B
530 //enable RF-Chip A/B
510 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] 531 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
511 rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4] 532 //analog to digital on
533 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
534 //digital to analog on
535 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
536 //rx antenna on
537 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
538 //rx antenna on
539 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
540 //analog to digital part2 on
541 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
542
543 // Baseband reset 2008.09.30 add
544 //write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0));
545
546 //2 AFE
547 // 2008.09.30 add
548 //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884
549 //analog to digital part2 on
550 //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
551
552
553 //digital to analog on
554 //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3]
555 //analog to digital on
556 //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8]
557 //rx antenna on
558 //PHY_SetBBReg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
559 //rx antenna on 2008.09.30 mark
560 //PHY_SetBBReg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
561
562 //2 RF
563 //enable RF-Chip A/B
564 //rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
565 //rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1); // 0x864[4]
566
567 }
568
512 #endif 569 #endif
513 break; 570 break;
514 571
@@ -517,119 +574,137 @@ SetRFPowerState8190(
517 // By Bruce, 2008-01-16. 574 // By Bruce, 2008-01-16.
518 // 575 //
519 case eRfSleep: 576 case eRfSleep:
520 case eRfOff: 577 {
521 RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOff/Sleep !\n"); 578 // HW setting had been configured with deeper mode.
522 if (pPSC->bLeisurePs) 579 if(priv->ieee80211->eRFPowerState == eRfOff)
580 break;
581
582 // Update current RF state variable.
583 //priv->ieee80211->eRFPowerState = eRFPowerState;
584
585 //if (pPSC->bLeisurePs)
523 { 586 {
524 for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) 587 for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
525 { 588 {
526 switch(QueueID) { 589 ring = &priv->tx_ring[QueueID];
527 case MGNT_QUEUE: 590
528 tail=priv->txmapringtail; 591 if(skb_queue_len(&ring->queue) == 0)
529 head=priv->txmapringhead; 592 {
593 QueueID++;
594 continue;
595 }
596 else
597 {
598 RT_TRACE((COMP_POWER|COMP_RF), "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
599 udelay(10);
600 i++;
601 }
602
603 if(i >= MAX_DOZE_WAITING_TIMES_9x)
604 {
605 RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
530 break; 606 break;
607 }
608 }
609 }
531 610
532 case BK_QUEUE: 611 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
533 tail=priv->txbkpringtail; 612#ifdef RTL8190P
534 head=priv->txbkpringhead; 613 {
614 PHY_SetRtl8190pRfOff(dev);
615 }
616 //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E)
617#elif defined RTL8192E
618 {
619 PHY_SetRtl8192eRfOff(dev);
620 }
621#endif
622 }
535 break; 623 break;
536 624
537 case BE_QUEUE: 625 case eRfOff:
538 tail=priv->txbepringtail; 626 //RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOff/Sleep !\n");
539 head=priv->txbepringhead;
540 break;
541 627
542 case VI_QUEUE: 628 // Update current RF state variable.
543 tail=priv->txvipringtail; 629 //priv->ieee80211->eRFPowerState = eRFPowerState;
544 head=priv->txvipringhead;
545 break;
546 630
547 case VO_QUEUE: 631 //
548 tail=priv->txvopringtail; 632 // Disconnect with Any AP or STA.
549 head=priv->txvopringhead; 633 //
550 break; 634 for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
635 {
636 ring = &priv->tx_ring[QueueID];
551 637
552 default: 638 if(skb_queue_len(&ring->queue) == 0)
553 tail=head=NULL;
554 break;
555 }
556 if(tail == head)
557 { 639 {
558 //DbgPrint("QueueID = %d", QueueID);
559 QueueID++; 640 QueueID++;
560 continue; 641 continue;
561 } 642 }
562 else 643 else
563 { 644 {
564 RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times BusyQueue[%d] !=0 before doze!\n", (i+1), QueueID); 645 RT_TRACE(COMP_POWER,
646 "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
565 udelay(10); 647 udelay(10);
566 i++; 648 i++;
567 } 649 }
568 650
569 if(i >= MAX_DOZE_WAITING_TIMES_9x) 651 if(i >= MAX_DOZE_WAITING_TIMES_9x)
570 { 652 {
571 RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID); 653 RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
572 break; 654 break;
573 } 655 }
574 } 656 }
657
658 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
659#if defined RTL8190P
660 {
661 PHY_SetRtl8190pRfOff(dev);
575 } 662 }
576 #ifdef RTL8190P 663 //else if(Adapter->HardwareType == HARDWARE_TYPE_RTL8192E)
577 if(priv->rf_type == RF_2T4R) 664#elif defined RTL8192E
578 { 665 {
579 //disable RF-Chip A/B 666 //if(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC) && priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
580 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4] 667 if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC))
668 { // Disable all components.
669 //
670 // Note:
671 // NicIFSetLinkStatus is a big problem when we indicate the status to OS,
672 // the OS(XP) will reset. But now, we cnnot find why the NIC is hard to receive
673 // packets after RF ON. Just keep this function here and still work to find out the root couse.
674 // By Bruce, 2009-05-01.
675 //
676 //NicIFSetLinkStatus( Adapter, RT_MEDIA_DISCONNECT );
677 //if HW radio of , need to indicate scan complete first for not be reset.
678 //if(MgntScanInProgress(pMgntInfo))
679 // MgntResetScanProcess( Adapter );
680
681 // <1> Disable Interrupt
682 //rtl8192_irq_disable(dev);
683 // <2> Stop all timer
684 //MgntCancelAllTimer(Adapter);
685 // <3> Disable Adapter
686 //NicIFHaltAdapter(Adapter, false);
687 NicIFDisableNIC(dev);
688 RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
689 }
690 else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC))
691 { // Normal case.
692 // IPS should go to this.
693 PHY_SetRtl8192eRfOff(dev);
694 }
695 }
696#else
697 else
698 {
699 RT_TRACE(COMP_DBG,DBG_TRACE,("It is not 8190Pci and 8192PciE \n"));
581 } 700 }
582 //disable RF-Chip C/D
583 rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x0); // 0x868[4]
584 //analog to digital off, for power save
585 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
586 //digital to analog off, for power save
587 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0x0); // 0x880[8:5]
588 //rx antenna off
589 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
590 //rx antenna off
591 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
592 //analog to digital part2 off, for power save
593 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0x0); // 0x880[12:9]
594#else //8192E
595 //2 RF
596 //disable RF-Chip A/B
597 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); // 0x860[4]
598 rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x0); // 0x864[4]
599 //2 AFE
600 //analog to digital off, for power save
601 //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
602 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0x0); // 2008.09.30 Modify
603 //digital to analog off, for power save
604 //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
605 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x0); // 0x880 2008.09.30 Modify
606 //rx antenna off 2008.09.30 mark
607 //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
608 //rx antenna off 2008.09.30 mark
609 //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
610 //analog to digital part2 off, for power save
611 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5]
612 // 2008.09.30 add
613 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x0); // 0x884
614
615
616 //disable clock 80/88 MHz 2008.09.30 mark
617 //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x4, 0x0); // 0x880[2]
618 //2 BB
619 // Baseband reset 2008.09.30 add
620 write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); // 0x101
621 //MAC: off
622 write_nic_byte(dev, MacBlkCtrl, 0x0); // 0x403
623 //slow down cpu/lbus clock from 160MHz to Lower
624 write_nic_byte(dev, ANAPAR, 0x07); // 0x 17 40MHz
625 priv->bHwRfOffAction = 0;
626 //}
627 #endif 701 #endif
702
628 break; 703 break;
629 704
630 default: 705 default:
631 bResult = false; 706 bResult = false;
632 RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknown state to set: 0x%X!!!\n", eRFPowerState); 707 RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
633 break; 708 break;
634 } 709 }
635 710
@@ -644,64 +719,11 @@ SetRFPowerState8190(
644 { 719 {
645 // Update current RF state variable. 720 // Update current RF state variable.
646 priv->ieee80211->eRFPowerState = eRFPowerState; 721 priv->ieee80211->eRFPowerState = eRFPowerState;
647
648 switch(priv->rf_chip )
649 {
650 case RF_8256:
651 switch(priv->ieee80211->eRFPowerState)
652 {
653 case eRfOff:
654 //
655 //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
656 //
657 if(priv->ieee80211->RfOffReason==RF_CHANGE_BY_IPS )
658 {
659 #ifdef TO_DO
660 Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
661 #endif
662 }
663 else
664 {
665 // Turn off LED if RF is not ON.
666 #ifdef TO_DO
667 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
668 #endif
669 }
670 break;
671
672 case eRfOn:
673 // Turn on RF we are still linked, which might happen when
674 // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
675 if( priv->ieee80211->state == IEEE80211_LINKED)
676 {
677 #ifdef TO_DO
678 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
679 #endif
680 }
681 else
682 {
683 // Turn off LED if RF is not ON.
684 #ifdef TO_DO
685 Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
686 #endif
687 }
688 break;
689
690 default:
691 // do nothing.
692 break;
693 }// Switch RF state
694
695 break;
696
697 default:
698 RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n");
699 break;
700 }// Switch RFChipID
701 } 722 }
702 723
724 //printk("%s()priv->ieee80211->eRFPowerState:%s\n" ,__func__,priv->ieee80211->eRFPowerState == eRfOn ? "On" : "Off");
703 priv->SetRFPowerStateInProgress = false; 725 priv->SetRFPowerStateInProgress = false;
704 RT_TRACE(COMP_POWER, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult); 726 //RT_TRACE(COMP_PS, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult);
705 return bResult; 727 return bResult;
706} 728}
707 729
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h
index 7d9095a70aec..ce49c606521a 100644
--- a/drivers/staging/rtl8192e/r8190_rtl8256.h
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.h
@@ -1,28 +1,33 @@
1/* 1/* r8190_rtl8256.h - rtl8256 radio frontend
2 This is part of the rtl8180-sa2400 driver 2 *
3 released under the GPL (See file COPYING for details). 3 * This is part of the rtl8180-sa2400 driver
4 Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> 4 * released under the GPL (See file COPYING for details).
5 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
6 *
7 * Many thanks to Realtek Corp. for their great support!
8 */
5 9
6 This files contains programming code for the rtl8256 10#ifndef RTL8225_H
7 radio frontend. 11#define RTL8225_H
8
9 *Many* thanks to Realtek Corp. for their great support!
10
11*/
12
13#ifndef RTL8225H
14#define RTL8225H
15 12
16#ifdef RTL8190P 13#ifdef RTL8190P
17#define RTL819X_TOTAL_RF_PATH 4 14#define RTL819X_TOTAL_RF_PATH 4
18#else 15#else
19#define RTL819X_TOTAL_RF_PATH 2 //for 8192E 16#define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */
20#endif 17#endif
21extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
22extern RT_STATUS PHY_RF8256_Config(struct net_device* dev);
23extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev);
24extern void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel);
25extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
26extern bool MgntActSet_RF_State(struct net_device* dev, RT_RF_POWER_STATE StateToSet, RT_RF_CHANGE_SOURCE ChangeSource);
27 18
28#endif 19extern void PHY_SetRF8256Bandwidth(struct net_device *dev,
20 HT_CHANNEL_WIDTH Bandwidth);
21
22extern RT_STATUS PHY_RF8256_Config(struct net_device *dev);
23
24extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device *dev);
25
26extern void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel);
27extern void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel);
28
29extern bool MgntActSet_RF_State(struct net_device *dev,
30 RT_RF_POWER_STATE StateToSet,
31 RT_RF_CHANGE_SOURCE ChangeSource);
32
33#endif /* RTL8225_H */
diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h
index 61b6f250b917..f4be9cc11005 100644
--- a/drivers/staging/rtl8192e/r8192E.h
+++ b/drivers/staging/rtl8192e/r8192E.h
@@ -39,7 +39,7 @@
39#include <linux/random.h> 39#include <linux/random.h>
40#include <linux/version.h> 40#include <linux/version.h>
41#include <asm/io.h> 41#include <asm/io.h>
42#include "ieee80211.h" 42#include "ieee80211/ieee80211.h"
43 43
44 44
45 45
@@ -1003,6 +1003,11 @@ typedef struct r8192_priv
1003 int irq; 1003 int irq;
1004 short irq_enabled; 1004 short irq_enabled;
1005 struct ieee80211_device *ieee80211; 1005 struct ieee80211_device *ieee80211;
1006#ifdef ENABLE_LPS
1007 bool ps_force;
1008 bool force_lps;
1009 bool bdisable_nic;
1010#endif
1006 bool being_init_adapter; 1011 bool being_init_adapter;
1007 u8 Rf_Mode; 1012 u8 Rf_Mode;
1008 short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */ 1013 short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
@@ -1477,7 +1482,7 @@ void write_nic_word(struct net_device *dev, int x,u16 y);
1477void write_nic_dword(struct net_device *dev, int x,u32 y); 1482void write_nic_dword(struct net_device *dev, int x,u32 y);
1478void force_pci_posting(struct net_device *dev); 1483void force_pci_posting(struct net_device *dev);
1479 1484
1480void rtl8192_rtx_disable(struct net_device *); 1485void rtl8192_halt_adapter(struct net_device *dev, bool reset);
1481void rtl8192_rx_enable(struct net_device *); 1486void rtl8192_rx_enable(struct net_device *);
1482void rtl8192_tx_enable(struct net_device *); 1487void rtl8192_tx_enable(struct net_device *);
1483 1488
@@ -1512,5 +1517,19 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev);
1512#ifdef ENABLE_IPS 1517#ifdef ENABLE_IPS
1513void IPSEnter(struct net_device *dev); 1518void IPSEnter(struct net_device *dev);
1514void IPSLeave(struct net_device *dev); 1519void IPSLeave(struct net_device *dev);
1520void InactivePsWorkItemCallback(struct net_device *dev);
1521void IPSLeave_wq(void *data);
1522void ieee80211_ips_leave_wq(struct net_device *dev);
1523void ieee80211_ips_leave(struct net_device *dev);
1524#endif
1525#ifdef ENABLE_LPS
1526void LeisurePSEnter(struct net_device *dev);
1527void LeisurePSLeave(struct net_device *dev);
1515#endif 1528#endif
1529
1530bool NicIFEnableNIC(struct net_device* dev);
1531bool NicIFDisableNIC(struct net_device* dev);
1532
1533void rtl8192_irq_disable(struct net_device *dev);
1534void PHY_SetRtl8192eRfOff(struct net_device* dev);
1516#endif 1535#endif
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
index 0ca5d8b4f746..886105db8b7c 100644
--- a/drivers/staging/rtl8192e/r8192E_core.c
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -66,7 +66,7 @@
66#endif 66#endif
67 67
68#ifdef ENABLE_DOT11D 68#ifdef ENABLE_DOT11D
69#include "dot11d.h" 69#include "ieee80211/dot11d.h"
70#endif 70#endif
71 71
72//set here to open your trace code. //WB 72//set here to open your trace code. //WB
@@ -75,7 +75,7 @@ u32 rt_global_debug_component = \
75 // COMP_EPROM | 75 // COMP_EPROM |
76 // COMP_PHY | 76 // COMP_PHY |
77 // COMP_RF | 77 // COMP_RF |
78 COMP_FIRMWARE | 78// COMP_FIRMWARE |
79 // COMP_TRACE | 79 // COMP_TRACE |
80 // COMP_DOWN | 80 // COMP_DOWN |
81 // COMP_SWBW | 81 // COMP_SWBW |
@@ -343,6 +343,141 @@ void write_nic_word(struct net_device *dev, int x,u16 y)
343 343
344#endif /* RTL_IO_MAP */ 344#endif /* RTL_IO_MAP */
345 345
346u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee)
347{
348 //struct r8192_priv* priv = ieee80211_priv(dev);
349 //struct ieee80211_device *ieee = priv->ieee80211;
350
351 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
352 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
353 int wpa_ie_len= ieee->wpa_ie_len;
354 struct ieee80211_crypt_data* crypt;
355 int encrypt;
356
357 crypt = ieee->crypt[ieee->tx_keyidx];
358
359 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||\
360 (ieee->host_encrypt && crypt && crypt->ops && \
361 (0 == strcmp(crypt->ops->name,"WEP")));
362
363 /* simply judge */
364 if(encrypt && (wpa_ie_len == 0)) {
365 // wep encryption, no N mode setting */
366 return SEC_ALG_WEP;
367 } else if((wpa_ie_len != 0)) {
368 // parse pairwise key type */
369 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
370 ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
371 return SEC_ALG_CCMP;
372 else
373 return SEC_ALG_TKIP;
374 } else {
375 return SEC_ALG_NONE;
376 }
377}
378
379void
380rtl8192e_SetHwReg(struct net_device *dev,u8 variable,u8* val)
381{
382 struct r8192_priv* priv = ieee80211_priv(dev);
383
384 switch(variable)
385 {
386
387 case HW_VAR_BSSID:
388 write_nic_dword(dev, BSSIDR, ((u32*)(val))[0]);
389 write_nic_word(dev, BSSIDR+2, ((u16*)(val+2))[0]);
390 break;
391
392 case HW_VAR_MEDIA_STATUS:
393 {
394 RT_OP_MODE OpMode = *((RT_OP_MODE *)(val));
395 //LED_CTL_MODE LedAction = LED_CTL_NO_LINK;
396 u8 btMsr = read_nic_byte(dev, MSR);
397
398 btMsr &= 0xfc;
399
400 switch(OpMode)
401 {
402 case RT_OP_MODE_INFRASTRUCTURE:
403 btMsr |= MSR_INFRA;
404 //LedAction = LED_CTL_LINK;
405 break;
406
407 case RT_OP_MODE_IBSS:
408 btMsr |= MSR_ADHOC;
409 // led link set seperate
410 break;
411
412 case RT_OP_MODE_AP:
413 btMsr |= MSR_AP;
414 //LedAction = LED_CTL_LINK;
415 break;
416
417 default:
418 btMsr |= MSR_NOLINK;
419 break;
420 }
421
422 write_nic_byte(dev, MSR, btMsr);
423
424 //priv->ieee80211->LedControlHandler(dev, LedAction);
425 }
426 break;
427
428 case HW_VAR_CECHK_BSSID:
429 {
430 u32 RegRCR, Type;
431
432 Type = ((u8*)(val))[0];
433 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_RCR, (u8*)(&RegRCR));
434 RegRCR = read_nic_dword(dev,RCR);
435 priv->ReceiveConfig = RegRCR;
436
437 if (Type == true)
438 RegRCR |= (RCR_CBSSID);
439 else if (Type == false)
440 RegRCR &= (~RCR_CBSSID);
441
442 //priv->ieee80211->SetHwRegHandler( dev, HW_VAR_RCR, (u8*)(&RegRCR) );
443 write_nic_dword(dev, RCR,RegRCR);
444 priv->ReceiveConfig = RegRCR;
445
446 }
447 break;
448
449 case HW_VAR_SLOT_TIME:
450 {
451 //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
452 //AC_CODING eACI;
453
454 priv->slot_time = val[0];
455 write_nic_byte(dev, SLOT_TIME, val[0]);
456
457 }
458 break;
459
460 case HW_VAR_ACK_PREAMBLE:
461 {
462 u32 regTmp = 0;
463 priv->short_preamble = (bool)(*(u8*)val );
464 regTmp = priv->basic_rate;
465 if (priv->short_preamble)
466 regTmp |= BRSR_AckShortPmb;
467 write_nic_dword(dev, RRSR, regTmp);
468 }
469 break;
470
471 case HW_VAR_CPU_RST:
472 write_nic_dword(dev, CPU_GEN, ((u32*)(val))[0]);
473 break;
474
475 default:
476 break;
477 }
478
479}
480
346 481
347/////////////////////////////////////////////////////////// 482///////////////////////////////////////////////////////////
348 483
@@ -365,11 +500,6 @@ void rtl8192_restart(struct work_struct *work);
365//void rtl8192_rq_tx_ack(struct work_struct *work); 500//void rtl8192_rq_tx_ack(struct work_struct *work);
366 501
367void watch_dog_timer_callback(unsigned long data); 502void watch_dog_timer_callback(unsigned long data);
368#ifdef ENABLE_IPS
369void IPSEnter(struct net_device *dev);
370void IPSLeave(struct net_device *dev);
371void InactivePsWorkItemCallback(struct net_device *dev);
372#endif
373/**************************************************************************** 503/****************************************************************************
374 -----------------------------PROCFS STUFF------------------------- 504 -----------------------------PROCFS STUFF-------------------------
375*****************************************************************************/ 505*****************************************************************************/
@@ -707,7 +837,7 @@ static void rtl8192_irq_enable(struct net_device *dev)
707} 837}
708 838
709 839
710static void rtl8192_irq_disable(struct net_device *dev) 840void rtl8192_irq_disable(struct net_device *dev)
711{ 841{
712 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); 842 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
713 843
@@ -717,6 +847,7 @@ static void rtl8192_irq_disable(struct net_device *dev)
717} 847}
718 848
719 849
850#if 0
720static void rtl8192_set_mode(struct net_device *dev,int mode) 851static void rtl8192_set_mode(struct net_device *dev,int mode)
721{ 852{
722 u8 ecmd; 853 u8 ecmd;
@@ -727,7 +858,7 @@ static void rtl8192_set_mode(struct net_device *dev,int mode)
727 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT); 858 ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
728 write_nic_byte(dev, EPROM_CMD, ecmd); 859 write_nic_byte(dev, EPROM_CMD, ecmd);
729} 860}
730 861#endif
731 862
732void rtl8192_update_msr(struct net_device *dev) 863void rtl8192_update_msr(struct net_device *dev)
733{ 864{
@@ -861,7 +992,7 @@ static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
861 ring->desc = NULL; 992 ring->desc = NULL;
862} 993}
863 994
864 995#if 0
865static void rtl8192_beacon_disable(struct net_device *dev) 996static void rtl8192_beacon_disable(struct net_device *dev)
866{ 997{
867 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); 998 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -873,38 +1004,116 @@ static void rtl8192_beacon_disable(struct net_device *dev)
873 reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); 1004 reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
874 write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg); 1005 write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
875} 1006}
1007#endif
1008
1009void PHY_SetRtl8192eRfOff(struct net_device* dev )
1010{
1011 //struct r8192_priv *priv = ieee80211_priv(dev);
1012
1013 //disable RF-Chip A/B
1014 rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);
1015 //analog to digital off, for power save
1016 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);
1017 //digital to analog off, for power save
1018 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0);
1019 //rx antenna off
1020 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);
1021 //rx antenna off
1022 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);
1023 //analog to digital part2 off, for power save
1024 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);
1025 rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0);
1026 // Analog parameter!!Change bias and Lbus control.
1027 write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07);
1028
1029}
876 1030
877void rtl8192_rtx_disable(struct net_device *dev) 1031void rtl8192_halt_adapter(struct net_device *dev, bool reset)
878{ 1032{
879 u8 cmd; 1033 //u8 cmd;
880 struct r8192_priv *priv = ieee80211_priv(dev); 1034 struct r8192_priv *priv = ieee80211_priv(dev);
881 int i; 1035 int i;
1036 u8 OpMode;
1037 u8 u1bTmp;
1038 u32 ulRegRead;
1039
1040 OpMode = RT_OP_MODE_NO_LINK;
1041 priv->ieee80211->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode);
882 1042
1043#if 1
1044 if(!priv->ieee80211->bSupportRemoteWakeUp)
1045 {
1046 u1bTmp = 0x0; // disable tx/rx. In 8185 we write 0x10 (Reset bit), but here we make reference to WMAC and wirte 0x0. 2006.11.21 Emily
1047 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_COMMAND, &u1bTmp ); // Using HW_VAR_COMMAND instead of writing CMDR directly. Rewrited by Annie, 2006-04-07.
1048 write_nic_byte(dev, CMDR, u1bTmp);
1049 }
1050#else
883 cmd=read_nic_byte(dev,CMDR); 1051 cmd=read_nic_byte(dev,CMDR);
884// if(!priv->ieee80211->bSupportRemoteWakeUp) { 1052 write_nic_byte(dev, CMDR, cmd &~ (CR_TE|CR_RE));
885 write_nic_byte(dev, CMDR, cmd &~ \ 1053#endif
886 (CR_TE|CR_RE));
887// }
888 force_pci_posting(dev);
889 mdelay(30);
890 1054
891 for(i = 0; i < MAX_QUEUE_SIZE; i++) { 1055 mdelay(20);
892 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
893 }
894 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
895 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
896 }
897 1056
1057 if(!reset)
1058 {
1059 //PlatformStallExecution(150000);
1060 mdelay(150);
1061
1062#ifdef RTL8192E
1063 priv->bHwRfOffAction = 2;
1064#endif
1065
1066 //
1067 // Call MgntActSet_RF_State instead to prevent RF config race condition.
1068 // By Bruce, 2008-01-17.
1069 //
1070 if(!priv->ieee80211->bSupportRemoteWakeUp)
1071 {
1072 //MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_INIT);
1073 //MgntActSet_RF_State(Adapter, eRfOff, Adapter->MgntInfo.RfOffReason);
1074 //if(Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
1075
1076 PHY_SetRtl8192eRfOff(dev);
1077
1078 // 2006.11.30. System reset bit
1079 //priv->ieee80211->GetHwRegHandler(dev, HW_VAR_CPU_RST, (u32*)(&ulRegRead) );
1080 ulRegRead = read_nic_dword(dev,CPU_GEN);
1081 ulRegRead|=CPU_GEN_SYSTEM_RESET;
1082 //priv->ieee80211->SetHwRegHandler(dev, HW_VAR_CPU_RST, &ulRegRead);
1083 write_nic_dword(dev,CPU_GEN, ulRegRead);
1084 }
1085 else
1086 {
1087 //2008.06.03 for WOL
1088 write_nic_dword(dev, WFCRC0, 0xffffffff);
1089 write_nic_dword(dev, WFCRC1, 0xffffffff);
1090 write_nic_dword(dev, WFCRC2, 0xffffffff);
1091
1092 //Write PMR register
1093 write_nic_byte(dev, PMR, 0x5);
1094 //Disable tx, enanble rx
1095 write_nic_byte(dev, MacBlkCtrl, 0xa);
1096 }
1097 }
1098
1099 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1100 skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
1101 }
1102 for(i = 0; i < MAX_QUEUE_SIZE; i++) {
1103 skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
1104 }
898 1105
899 skb_queue_purge(&priv->skb_queue); 1106 skb_queue_purge(&priv->skb_queue);
900 return; 1107 return;
901} 1108}
902 1109
1110#if 0
903static void rtl8192_reset(struct net_device *dev) 1111static void rtl8192_reset(struct net_device *dev)
904{ 1112{
905 rtl8192_irq_disable(dev); 1113 rtl8192_irq_disable(dev);
906 printk("This is RTL819xP Reset procedure\n"); 1114 printk("This is RTL819xP Reset procedure\n");
907} 1115}
1116#endif
908 1117
909static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540}; 1118static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
910inline u16 rtl8192_rate2rate(short rate) 1119inline u16 rtl8192_rate2rate(short rate)
@@ -954,6 +1163,12 @@ static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
954 /* shall not be referred by command packet */ 1163 /* shall not be referred by command packet */
955 assert(queue_index != TXCMD_QUEUE); 1164 assert(queue_index != TXCMD_QUEUE);
956 1165
1166 if((priv->bHwRadioOff == true)||(!priv->up))
1167 {
1168 kfree_skb(skb);
1169 return;
1170 }
1171
957 //spin_lock_irqsave(&priv->tx_lock,flags); 1172 //spin_lock_irqsave(&priv->tx_lock,flags);
958 1173
959 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev)); 1174 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
@@ -996,6 +1211,13 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
996 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); 1211 cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
997 u8 queue_index = tcb_desc->queue_index; 1212 u8 queue_index = tcb_desc->queue_index;
998 1213
1214 if(queue_index != TXCMD_QUEUE){
1215 if((priv->bHwRadioOff == true)||(!priv->up))
1216 {
1217 kfree_skb(skb);
1218 return 0;
1219 }
1220 }
999 1221
1000 //spin_lock_irqsave(&priv->tx_lock,flags); 1222 //spin_lock_irqsave(&priv->tx_lock,flags);
1001 1223
@@ -1379,6 +1601,15 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1379 u8* pda_addr = NULL; 1601 u8* pda_addr = NULL;
1380 int idx; 1602 int idx;
1381 1603
1604 if(priv->bdisable_nic){
1605 RT_TRACE(COMP_ERR,"%s: ERR!! Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", __FUNCTION__, skb->len, tcb_desc->queue_index);
1606 return skb->len;
1607 }
1608
1609#ifdef ENABLE_LPS
1610 priv->ieee80211->bAwakePktSent = true;
1611#endif
1612
1382 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); 1613 mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1383 /* collect the tx packets statitcs */ 1614 /* collect the tx packets statitcs */
1384 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI); 1615 pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
@@ -1481,6 +1712,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1481 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { 1712 if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1482 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \ 1713 RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1483 tcb_desc->queue_index,ring->idx, idx,skb->len); 1714 tcb_desc->queue_index,ring->idx, idx,skb->len);
1715 spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1484 return skb->len; 1716 return skb->len;
1485 } 1717 }
1486 1718
@@ -1575,7 +1807,7 @@ static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1575 return 0; 1807 return 0;
1576 priv->rx_buf[i] = skb; 1808 priv->rx_buf[i] = skb;
1577 mapping = (dma_addr_t *)skb->cb; 1809 mapping = (dma_addr_t *)skb->cb;
1578 *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb), 1810 *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
1579 priv->rxbuffersize, PCI_DMA_FROMDEVICE); 1811 priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1580 1812
1581 entry->BufferAddress = cpu_to_le32(*mapping); 1813 entry->BufferAddress = cpu_to_le32(*mapping);
@@ -1779,7 +2011,7 @@ static void rtl8192_qos_activate(struct work_struct * work)
1779 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| 2011 (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
1780 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| 2012 (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
1781 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); 2013 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1782 printk("===>u4bAcParam:%x, ", u4bAcParam); 2014 //printk("===>u4bAcParam:%x, ", u4bAcParam);
1783 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); 2015 write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1784 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332); 2016 //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1785 } 2017 }
@@ -1964,11 +2196,24 @@ void rtl8192_update_ratr_table(struct net_device* dev)
1964 write_nic_byte(dev, UFWP, 1); 2196 write_nic_byte(dev, UFWP, 1);
1965} 2197}
1966 2198
2199#if 0
1967static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04}; 2200static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
1968static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; 2201static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2202#endif
2203
1969static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev) 2204static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
1970{ 2205{
1971#if 1 2206#if 1
2207
2208 struct r8192_priv *priv = ieee80211_priv(dev);
2209 struct ieee80211_device *ieee = priv->ieee80211;
2210 if (ieee->rtllib_ap_sec_type &&
2211 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) {
2212 return false;
2213 } else {
2214 return true;
2215 }
2216#else
1972 struct r8192_priv* priv = ieee80211_priv(dev); 2217 struct r8192_priv* priv = ieee80211_priv(dev);
1973 struct ieee80211_device* ieee = priv->ieee80211; 2218 struct ieee80211_device* ieee = priv->ieee80211;
1974 int wpa_ie_len= ieee->wpa_ie_len; 2219 int wpa_ie_len= ieee->wpa_ie_len;
@@ -1995,18 +2240,6 @@ static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
1995 return true; 2240 return true;
1996 } 2241 }
1997 2242
1998#if 0
1999 //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2000 //We can't force in G mode if Pairwie key is AES and group key is TKIP
2001 if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption) ||
2002 (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
2003 (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
2004 {
2005 return false;
2006 }
2007 else
2008 return true;
2009#endif
2010 return true; 2243 return true;
2011#endif 2244#endif
2012} 2245}
@@ -2080,7 +2313,7 @@ static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2080 wireless_mode = WIRELESS_MODE_B; 2313 wireless_mode = WIRELESS_MODE_B;
2081 } 2314 }
2082 } 2315 }
2083#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA 2316#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2084 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); 2317 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2085#endif 2318#endif
2086 priv->ieee80211->mode = wireless_mode; 2319 priv->ieee80211->mode = wireless_mode;
@@ -2127,7 +2360,19 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev)
2127} 2360}
2128static void rtl8192_hw_sleep_down(struct net_device *dev) 2361static void rtl8192_hw_sleep_down(struct net_device *dev)
2129{ 2362{
2130 RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__); 2363 struct r8192_priv *priv = ieee80211_priv(dev);
2364 unsigned long flags = 0;
2365
2366 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2367 if (priv->RFChangeInProgress) {
2368 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2369 RT_TRACE(COMP_RF, "rtl8192_hw_sleep_down(): RF Change in progress! \n");
2370 printk("rtl8192_hw_sleep_down(): RF Change in progress!\n");
2371 return;
2372 }
2373 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2374 //RT_TRACE(COMP_PS, "%s()============>come to sleep down\n", __FUNCTION__);
2375
2131 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS); 2376 MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2132} 2377}
2133static void rtl8192_hw_sleep_wq (struct work_struct *work) 2378static void rtl8192_hw_sleep_wq (struct work_struct *work)
@@ -2138,21 +2383,29 @@ static void rtl8192_hw_sleep_wq (struct work_struct *work)
2138 struct delayed_work *dwork = container_of(work,struct delayed_work,work); 2383 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2139 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq); 2384 struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2140 struct net_device *dev = ieee->dev; 2385 struct net_device *dev = ieee->dev;
2141 //printk("=========>%s()\n", __FUNCTION__); 2386
2142 rtl8192_hw_sleep_down(dev); 2387 rtl8192_hw_sleep_down(dev);
2143} 2388}
2144// printk("dev is %d\n",dev); 2389
2145// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2146static void rtl8192_hw_wakeup(struct net_device* dev) 2390static void rtl8192_hw_wakeup(struct net_device* dev)
2147{ 2391{
2148// u32 flags = 0; 2392 struct r8192_priv *priv = ieee80211_priv(dev);
2393 unsigned long flags = 0;
2394
2395 spin_lock_irqsave(&priv->rf_ps_lock,flags);
2396 if (priv->RFChangeInProgress) {
2397 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2398 RT_TRACE(COMP_RF, "rtl8192_hw_wakeup(): RF Change in progress! \n");
2399 printk("rtl8192_hw_wakeup(): RF Change in progress! schedule wake up task again\n");
2400 queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->hw_wakeup_wq,MSECS(10));//PowerSave is not supported if kernel version is below 2.6.20
2401 return;
2402 }
2403 spin_unlock_irqrestore(&priv->rf_ps_lock,flags);
2149 2404
2150// spin_lock_irqsave(&priv->ps_lock,flags); 2405 //RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __FUNCTION__);
2151 RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
2152 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS); 2406 MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2153 //FIXME: will we send package stored while nic is sleep?
2154// spin_unlock_irqrestore(&priv->ps_lock,flags);
2155} 2407}
2408
2156void rtl8192_hw_wakeup_wq (struct work_struct *work) 2409void rtl8192_hw_wakeup_wq (struct work_struct *work)
2157{ 2410{
2158// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq); 2411// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
@@ -2169,7 +2422,6 @@ void rtl8192_hw_wakeup_wq (struct work_struct *work)
2169#define MAX_SLEEP_TIME 10000 2422#define MAX_SLEEP_TIME 10000
2170static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl) 2423static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2171{ 2424{
2172
2173 struct r8192_priv *priv = ieee80211_priv(dev); 2425 struct r8192_priv *priv = ieee80211_priv(dev);
2174 2426
2175 u32 rb = jiffies; 2427 u32 rb = jiffies;
@@ -2177,58 +2429,55 @@ static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2177 2429
2178 spin_lock_irqsave(&priv->ps_lock,flags); 2430 spin_lock_irqsave(&priv->ps_lock,flags);
2179 2431
2180 /* Writing HW register with 0 equals to disable 2432 // Writing HW register with 0 equals to disable
2181 * the timer, that is not really what we want 2433 // the timer, that is not really what we want
2182 */ 2434 //
2183 tl -= MSECS(4+16+7); 2435 tl -= MSECS(8+16+7);
2184
2185 //if(tl == 0) tl = 1;
2186
2187 /* FIXME HACK FIXME HACK */
2188// force_pci_posting(dev);
2189 //mdelay(1);
2190
2191// rb = read_nic_dword(dev, TSFTR);
2192 2436
2193 /* If the interval in witch we are requested to sleep is too 2437 // If the interval in witch we are requested to sleep is too
2194 * short then give up and remain awake 2438 // short then give up and remain awake
2195 */ 2439 // when we sleep after send null frame, the timer will be too short to sleep.
2440 //
2196 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) 2441 if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2197 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { 2442 ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2198 spin_unlock_irqrestore(&priv->ps_lock,flags); 2443 spin_unlock_irqrestore(&priv->ps_lock,flags);
2199 printk("too short to sleep\n"); 2444 printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME));
2200 return; 2445 return;
2201 } 2446 }
2202 2447
2203// write_nic_dword(dev, TimerInt, tl);
2204// rb = read_nic_dword(dev, TSFTR);
2205 {
2206 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2207 // if (tl<rb)
2208 queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
2209 }
2210 /* if we suspect the TimerInt is gone beyond tl
2211 * while setting it, then give up
2212 */
2213#if 1
2214 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| 2448 if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2215 ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) { 2449 ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))||
2450 ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) {
2216 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME)); 2451 printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME));
2217 spin_unlock_irqrestore(&priv->ps_lock,flags); 2452 spin_unlock_irqrestore(&priv->ps_lock,flags);
2218 return; 2453 return;
2219 } 2454 }
2220#endif 2455 {
2221// if(priv->rf_sleep) 2456 u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2222// priv->rf_sleep(dev); 2457 queue_delayed_work(priv->ieee80211->wq,
2223 2458 &priv->ieee80211->hw_wakeup_wq,tmp);
2224 //printk("<=========%s()\n", __FUNCTION__); 2459 //PowerSave not supported when kernel version less 2.6.20
2225 queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0); 2460 }
2461 queue_delayed_work(priv->ieee80211->wq,
2462 (void *)&priv->ieee80211->hw_sleep_wq,0);
2226 spin_unlock_irqrestore(&priv->ps_lock,flags); 2463 spin_unlock_irqrestore(&priv->ps_lock,flags);
2464
2227} 2465}
2228static void rtl8192_init_priv_variable(struct net_device* dev) 2466static void rtl8192_init_priv_variable(struct net_device* dev)
2229{ 2467{
2230 struct r8192_priv *priv = ieee80211_priv(dev); 2468 struct r8192_priv *priv = ieee80211_priv(dev);
2231 u8 i; 2469 u8 i;
2470 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
2471
2472 // Default Halt the NIC if RF is OFF.
2473 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC;
2474 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ;
2475 pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM;
2476 pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM;
2477 pPSC->bLeisurePs = true;
2478 pPSC->RegMaxLPSAwakeIntvl = 5;
2479 priv->bHwRadioOff = false;
2480
2232 priv->being_init_adapter = false; 2481 priv->being_init_adapter = false;
2233 priv->txbuffsize = 1600;//1024; 2482 priv->txbuffsize = 1600;//1024;
2234 priv->txfwbuffersize = 4096; 2483 priv->txfwbuffersize = 4096;
@@ -2328,6 +2577,17 @@ static void rtl8192_init_priv_variable(struct net_device* dev)
2328 //added by amy 2577 //added by amy
2329 priv->ieee80211->InitialGainHandler = InitialGain819xPci; 2578 priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2330 2579
2580#ifdef ENABLE_IPS
2581 priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq;
2582 priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave;
2583#endif
2584#ifdef ENABLE_LPS
2585 priv->ieee80211->LeisurePSLeave = LeisurePSLeave;
2586#endif//ENABL
2587
2588 priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg;
2589 priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type;
2590
2331 priv->card_type = USB; 2591 priv->card_type = USB;
2332 { 2592 {
2333 priv->ShortRetryLimit = 0x30; 2593 priv->ShortRetryLimit = 0x30;
@@ -2400,6 +2660,10 @@ static void rtl8192_init_priv_task(struct net_device* dev)
2400 priv->priv_wq = create_workqueue(DRV_NAME); 2660 priv->priv_wq = create_workqueue(DRV_NAME);
2401#endif 2661#endif
2402 2662
2663#ifdef ENABLE_IPS
2664 INIT_WORK(&priv->ieee80211->ips_leave_wq, (void*)IPSLeave_wq);
2665#endif
2666
2403// INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart); 2667// INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2404 INIT_WORK(&priv->reset_wq, rtl8192_restart); 2668 INIT_WORK(&priv->reset_wq, rtl8192_restart);
2405// INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog); 2669// INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
@@ -2550,10 +2814,7 @@ static void rtl8192_read_eeprom_info(struct net_device* dev)
2550 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); 2814 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2551 } 2815 }
2552 2816
2553 RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n", 2817 RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr);
2554 dev->dev_addr[0], dev->dev_addr[1],
2555 dev->dev_addr[2], dev->dev_addr[3],
2556 dev->dev_addr[4], dev->dev_addr[5]);
2557 2818
2558 //2 TX Power Check EEPROM Fail or not 2819 //2 TX Power Check EEPROM Fail or not
2559 if(priv->card_8192_version > VERSION_8190_BD) { 2820 if(priv->card_8192_version > VERSION_8190_BD) {
@@ -2926,13 +3187,14 @@ static void rtl8192_read_eeprom_info(struct net_device* dev)
2926 #endif 3187 #endif
2927 break; 3188 break;
2928 } 3189 }
2929/* 3190
2930 //2008.06.03, for WOL 3191
2931 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) 3192 if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304)
2932 priv->ieee80211->bSupportRemoteWakeUp = TRUE; 3193 priv->ieee80211->bSupportRemoteWakeUp = true;
2933 else 3194 else
2934 priv->ieee80211->bSupportRemoteWakeUp = FALSE; 3195 priv->ieee80211->bSupportRemoteWakeUp = false;
2935*/ 3196
3197
2936 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan); 3198 RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
2937 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan); 3199 RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
2938 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy); 3200 RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
@@ -4006,12 +4268,19 @@ static void rtl819x_ifsilentreset(struct net_device *dev)
4006 struct ieee80211_device *ieee = priv->ieee80211; 4268 struct ieee80211_device *ieee = priv->ieee80211;
4007 4269
4008 4270
4271 return;
4272
4009 // 2007.07.20. If we need to check CCK stop, please uncomment this line. 4273 // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4010 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter); 4274 //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4011 4275
4012 if(priv->ResetProgress==RESET_TYPE_NORESET) 4276 if(priv->ResetProgress==RESET_TYPE_NORESET)
4013 { 4277 {
4014RESET_START: 4278RESET_START:
4279#ifdef ENABLE_LPS
4280 //LZM for PS-Poll AID issue. 090429
4281 if(priv->ieee80211->state == IEEE80211_LINKED)
4282 LeisurePSLeave(dev);
4283#endif
4015 4284
4016 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n"); 4285 RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4017 4286
@@ -4051,9 +4320,9 @@ RESET_START:
4051 } 4320 }
4052 else{ 4321 else{
4053 printk("ieee->state is NOT LINKED\n"); 4322 printk("ieee->state is NOT LINKED\n");
4054 ieee80211_softmac_stop_protocol(priv->ieee80211); 4323 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4055 } 4324 }
4056 rtl8192_rtx_disable(dev); 4325 rtl8192_halt_adapter(dev, true);
4057 up(&priv->wx_sem); 4326 up(&priv->wx_sem);
4058 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__); 4327 RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4059 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__); 4328 RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
@@ -4150,6 +4419,128 @@ void InactivePsWorkItemCallback(struct net_device *dev)
4150 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n"); 4419 RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4151} 4420}
4152 4421
4422#ifdef ENABLE_LPS
4423//
4424// Change current and default preamble mode.
4425// 2005.01.06, by rcnjko.
4426//
4427bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, u8 rtPsMode)
4428{
4429 struct r8192_priv *priv = ieee80211_priv(dev);
4430 //PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4431 //u8 RpwmVal, FwPwrMode;
4432
4433 // Currently, we do not change power save mode on IBSS mode.
4434 if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
4435 {
4436 return false;
4437 }
4438
4439 //
4440 // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
4441 // some AP will not response to our mgnt frames with PwrMgt bit set,
4442 // e.g. cannot associate the AP.
4443 // So I commented out it. 2005.02.16, by rcnjko.
4444 //
4445// // Change device's power save mode.
4446// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
4447
4448 // Update power save mode configured.
4449 //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode);
4450 if(!priv->ps_force) {
4451 priv->ieee80211->ps = rtPsMode;
4452 }
4453
4454 // Awake immediately
4455 if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED)
4456 {
4457 unsigned long flags;
4458
4459 //PlatformSetTimer(Adapter, &(pMgntInfo->AwakeTimer), 0);
4460 // Notify the AP we awke.
4461 rtl8192_hw_wakeup(dev);
4462 priv->ieee80211->sta_sleep = 0;
4463
4464 spin_lock_irqsave(&(priv->ieee80211->mgmt_tx_lock), flags);
4465 printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n");
4466 ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0);
4467 spin_unlock_irqrestore(&(priv->ieee80211->mgmt_tx_lock), flags);
4468 }
4469
4470 return true;
4471}
4472
4473//================================================================================
4474// Leisure Power Save in linked state.
4475//================================================================================
4476
4477//
4478// Description:
4479// Enter the leisure power save mode.
4480//
4481void LeisurePSEnter(struct net_device *dev)
4482{
4483 struct r8192_priv *priv = ieee80211_priv(dev);
4484 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4485
4486 //RT_TRACE(COMP_PS, "LeisurePSEnter()...\n");
4487 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdleCount is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n",
4488 // pPSC->bLeisurePs, priv->ieee80211->ps,pPSC->LpsIdleCount,RT_CHECK_FOR_HANG_PERIOD);
4489
4490 if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) &&
4491 (priv->ieee80211->state == IEEE80211_LINKED)) ||
4492 (priv->ieee80211->iw_mode == IW_MODE_ADHOC) ||
4493 (priv->ieee80211->iw_mode == IW_MODE_MASTER))
4494 return;
4495
4496 if (pPSC->bLeisurePs)
4497 {
4498 // Idle for a while if we connect to AP a while ago.
4499 if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec
4500 {
4501
4502 if(priv->ieee80211->ps == IEEE80211_PS_DISABLED)
4503 {
4504
4505 //RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter 802.11 power save mode...\n");
4506 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);
4507
4508 }
4509 }
4510 else
4511 pPSC->LpsIdleCount++;
4512 }
4513}
4514
4515
4516//
4517// Description:
4518// Leave the leisure power save mode.
4519//
4520void LeisurePSLeave(struct net_device *dev)
4521{
4522 struct r8192_priv *priv = ieee80211_priv(dev);
4523 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4524
4525
4526 //RT_TRACE(COMP_PS, "LeisurePSLeave()...\n");
4527 //RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n",
4528 // pPSC->bLeisurePs, priv->ieee80211->ps);
4529
4530 if (pPSC->bLeisurePs)
4531 {
4532 if(priv->ieee80211->ps != IEEE80211_PS_DISABLED)
4533 {
4534 // move to lps_wakecomplete()
4535 //RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , Leave 802.11 power save..\n");
4536 MgntActSet_802_11_PowerSaveMode(dev, IEEE80211_PS_DISABLED);
4537
4538 }
4539 }
4540}
4541#endif
4542
4543
4153// 4544//
4154// Description: 4545// Description:
4155// Enter the inactive power save mode. RF will be off 4546// Enter the inactive power save mode. RF will be off
@@ -4178,6 +4569,7 @@ IPSEnter(struct net_device *dev)
4178 && (priv->ieee80211->state != IEEE80211_LINKED) ) 4569 && (priv->ieee80211->state != IEEE80211_LINKED) )
4179 { 4570 {
4180 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n"); 4571 RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4572 //printk("IPSEnter(): Turn off RF.\n");
4181 pPSC->eInactivePowerState = eRfOff; 4573 pPSC->eInactivePowerState = eRfOff;
4182// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); 4574// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4183 InactivePsWorkItemCallback(dev); 4575 InactivePsWorkItemCallback(dev);
@@ -4203,12 +4595,53 @@ IPSLeave(struct net_device *dev)
4203 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS) 4595 if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4204 { 4596 {
4205 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); 4597 RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4598 //printk("IPSLeave(): Turn on RF.\n");
4206 pPSC->eInactivePowerState = eRfOn; 4599 pPSC->eInactivePowerState = eRfOn;
4207// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); 4600// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4208 InactivePsWorkItemCallback(dev); 4601 InactivePsWorkItemCallback(dev);
4209 } 4602 }
4210 } 4603 }
4211} 4604}
4605
4606void IPSLeave_wq(void *data)
4607{
4608 struct ieee80211_device *ieee = container_of(data,struct ieee80211_device,ips_leave_wq);
4609 struct net_device *dev = ieee->dev;
4610
4611 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4612 down(&priv->ieee80211->ips_sem);
4613 IPSLeave(dev);
4614 up(&priv->ieee80211->ips_sem);
4615}
4616
4617void ieee80211_ips_leave_wq(struct net_device *dev)
4618{
4619 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4620 RT_RF_POWER_STATE rtState;
4621 rtState = priv->ieee80211->eRFPowerState;
4622
4623 if(priv->ieee80211->PowerSaveControl.bInactivePs){
4624 if(rtState == eRfOff){
4625 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
4626 {
4627 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
4628 return;
4629 }
4630 else{
4631 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
4632 queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq);
4633 }
4634 }
4635 }
4636}
4637//added by amy 090331 end
4638void ieee80211_ips_leave(struct net_device *dev)
4639{
4640 struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4641 down(&priv->ieee80211->ips_sem);
4642 IPSLeave(dev);
4643 up(&priv->ieee80211->ips_sem);
4644}
4212#endif 4645#endif
4213 4646
4214static void rtl819x_update_rxcounts( 4647static void rtl819x_update_rxcounts(
@@ -4244,15 +4677,23 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work)
4244 unsigned long flags; 4677 unsigned long flags;
4245 bool bBusyTraffic = false; 4678 bool bBusyTraffic = false;
4246 static u8 last_time = 0; 4679 static u8 last_time = 0;
4680 bool bEnterPS = false;
4681
4682 if((!priv->up) || (priv->bHwRadioOff == true))
4683 return;
4684
4247 if(!priv->up) 4685 if(!priv->up)
4248 return; 4686 return;
4249 hal_dm_watchdog(dev); 4687 hal_dm_watchdog(dev);
4250#ifdef ENABLE_IPS 4688#ifdef ENABLE_IPS
4251// printk("watch_dog ENABLE_IPS\n"); 4689// printk("watch_dog ENABLE_IPS\n");
4252 if(ieee->actscanning == false){ 4690 if(ieee->actscanning == false){
4253 if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){ 4691 //printk("%d,%d,%d,%d\n", ieee->eRFPowerState, ieee->is_set_key, ieee->proto_stoppping, ieee->wx_set_enc);
4692 if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) &&\
4693 (ieee->eRFPowerState == eRfOn)&&!ieee->is_set_key &&\
4694 (!ieee->proto_stoppping) && !ieee->wx_set_enc){
4254 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ 4695 if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4255 printk("====================>haha:IPSEnter()\n"); 4696 //printk("====================>haha:IPSEnter()\n");
4256 IPSEnter(dev); 4697 IPSEnter(dev);
4257 //ieee80211_stop_scan(priv->ieee80211); 4698 //ieee80211_stop_scan(priv->ieee80211);
4258 } 4699 }
@@ -4262,14 +4703,49 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work)
4262 {//to get busy traffic condition 4703 {//to get busy traffic condition
4263 if(ieee->state == IEEE80211_LINKED) 4704 if(ieee->state == IEEE80211_LINKED)
4264 { 4705 {
4265 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 666 || 4706 if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 ||
4266 ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) { 4707 ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) {
4267 bBusyTraffic = true; 4708 bBusyTraffic = true;
4268 } 4709 }
4269 4710
4711#ifdef ENABLE_LPS
4712 //added by amy for Leisure PS
4713 if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
4714 (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
4715 {
4716 //printk("ieee->LinkDetectInfo.NumRxUnicastOkInPeriod is %d,ieee->LinkDetectInfo.NumTxOkInPeriod is %d\n",
4717 // ieee->LinkDetectInfo.NumRxUnicastOkInPeriod,ieee->LinkDetectInfo.NumTxOkInPeriod);
4718 bEnterPS= false;
4719 }
4720 else
4721 {
4722 bEnterPS= true;
4723 }
4724
4725 //printk("***bEnterPS = %d\n", bEnterPS);
4726 // LeisurePS only work in infra mode.
4727 if(bEnterPS)
4728 {
4729 LeisurePSEnter(dev);
4730 }
4731 else
4732 {
4733 LeisurePSLeave(dev);
4734 }
4735#endif
4736
4737 }
4738 else
4739 {
4740#ifdef ENABLE_LPS
4741 //RT_TRACE(COMP_LPS,"====>no link LPS leave\n");
4742 LeisurePSLeave(dev);
4743#endif
4270 } 4744 }
4745
4271 ieee->LinkDetectInfo.NumRxOkInPeriod = 0; 4746 ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4272 ieee->LinkDetectInfo.NumTxOkInPeriod = 0; 4747 ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4748 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
4273 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; 4749 ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4274 } 4750 }
4275 4751
@@ -4288,14 +4764,14 @@ void rtl819x_watchdog_wqcallback(struct work_struct *work)
4288 if( ieee->eRFPowerState == eRfOff) 4764 if( ieee->eRFPowerState == eRfOff)
4289 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__); 4765 RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4290 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__); 4766 printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4291 // Dot11d_Reset(dev); 4767 // Dot11d_Reset(dev);
4292 ieee->state = IEEE80211_ASSOCIATING; 4768 ieee->state = IEEE80211_ASSOCIATING;
4293 notify_wx_assoc_event(priv->ieee80211); 4769 notify_wx_assoc_event(priv->ieee80211);
4294 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid); 4770 RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4295 ieee->is_roaming = true; 4771 ieee->is_roaming = true;
4296 ieee->is_set_key = false; 4772 ieee->is_set_key = false;
4297 ieee->link_change(dev); 4773 ieee->link_change(dev);
4298 queue_work(ieee->wq, &ieee->associate_procedure_wq); 4774 queue_work(ieee->wq, &ieee->associate_procedure_wq);
4299 } 4775 }
4300 } 4776 }
4301 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; 4777 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
@@ -4348,6 +4824,7 @@ int _rtl8192_up(struct net_device *dev)
4348 RT_STATUS init_status = RT_STATUS_SUCCESS; 4824 RT_STATUS init_status = RT_STATUS_SUCCESS;
4349 priv->up=1; 4825 priv->up=1;
4350 priv->ieee80211->ieee_up=1; 4826 priv->ieee80211->ieee_up=1;
4827 priv->bdisable_nic = false; //YJ,add,091111
4351 RT_TRACE(COMP_INIT, "Bringing up iface"); 4828 RT_TRACE(COMP_INIT, "Bringing up iface");
4352 4829
4353 init_status = rtl8192_adapter_start(dev); 4830 init_status = rtl8192_adapter_start(dev);
@@ -4422,6 +4899,12 @@ int rtl8192_down(struct net_device *dev)
4422#endif 4899#endif
4423 if (priv->up == 0) return -1; 4900 if (priv->up == 0) return -1;
4424 4901
4902#ifdef ENABLE_LPS
4903 //LZM for PS-Poll AID issue. 090429
4904 if(priv->ieee80211->state == IEEE80211_LINKED)
4905 LeisurePSLeave(dev);
4906#endif
4907
4425 priv->up=0; 4908 priv->up=0;
4426 priv->ieee80211->ieee_up = 0; 4909 priv->ieee80211->ieee_up = 0;
4427 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__); 4910 RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
@@ -4459,11 +4942,9 @@ int rtl8192_down(struct net_device *dev)
4459 deinit_hal_dm(dev); 4942 deinit_hal_dm(dev);
4460 del_timer_sync(&priv->watch_dog_timer); 4943 del_timer_sync(&priv->watch_dog_timer);
4461 4944
4462 ieee80211_softmac_stop_protocol(priv->ieee80211); 4945 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4463#ifdef ENABLE_IPS 4946
4464 MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT); 4947 rtl8192_halt_adapter(dev,false);
4465#endif
4466 rtl8192_rtx_disable(dev);
4467 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list)); 4948 memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4468 4949
4469 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__); 4950 RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
@@ -4479,10 +4960,10 @@ void rtl8192_commit(struct net_device *dev)
4479 if (priv->up == 0) return ; 4960 if (priv->up == 0) return ;
4480 4961
4481 4962
4482 ieee80211_softmac_stop_protocol(priv->ieee80211); 4963 ieee80211_softmac_stop_protocol(priv->ieee80211,true);
4483 4964
4484 rtl8192_irq_disable(dev); 4965 rtl8192_irq_disable(dev);
4485 rtl8192_rtx_disable(dev); 4966 rtl8192_halt_adapter(dev,true);
4486 _rtl8192_up(dev); 4967 _rtl8192_up(dev);
4487} 4968}
4488 4969
@@ -5806,8 +6287,7 @@ static void rtl8192_rx(struct net_device *dev)
5806 6287
5807 skb = new_skb; 6288 skb = new_skb;
5808 priv->rx_buf[priv->rx_idx] = skb; 6289 priv->rx_buf[priv->rx_idx] = skb;
5809 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE); 6290 *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5810// *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5811 } 6291 }
5812 6292
5813 } 6293 }
@@ -6036,7 +6516,7 @@ void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6036 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code 6516 /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6037 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct. 6517 * is or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6038 * Otherwise call cancel_delayed_work is enough. 6518 * Otherwise call cancel_delayed_work is enough.
6039 * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel) 6519 * FIXME (2.6.20 should 2.6.22, work_struct should not cancel)
6040 * */ 6520 * */
6041 cancel_delayed_work(&priv->watch_dog_wq); 6521 cancel_delayed_work(&priv->watch_dog_wq);
6042 cancel_delayed_work(&priv->update_beacon_wq); 6522 cancel_delayed_work(&priv->update_beacon_wq);
@@ -6381,11 +6861,13 @@ void setKey( struct net_device *dev,
6381 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) 6861 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6382 { 6862 {
6383 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); 6863 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6384 up(&priv->wx_sem); 6864 //up(&priv->wx_sem);
6385 return ; 6865 return ;
6386 } 6866 }
6387 else{ 6867 else{
6868 down(&priv->ieee80211->ips_sem);
6388 IPSLeave(dev); 6869 IPSLeave(dev);
6870 up(&priv->ieee80211->ips_sem);
6389 } 6871 }
6390 } 6872 }
6391 } 6873 }
@@ -6394,7 +6876,7 @@ void setKey( struct net_device *dev,
6394 if (EntryNo >= TOTAL_CAM_ENTRY) 6876 if (EntryNo >= TOTAL_CAM_ENTRY)
6395 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); 6877 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6396 6878
6397 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr)); 6879 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6398 6880
6399 if (DefaultKey) 6881 if (DefaultKey)
6400 usConfig |= BIT15 | (KeyType<<2); 6882 usConfig |= BIT15 | (KeyType<<2);
@@ -6455,6 +6937,65 @@ void CamPrintDbgReg(struct net_device* dev)
6455 RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue); 6937 RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
6456} 6938}
6457 6939
6940bool NicIFEnableNIC(struct net_device* dev)
6941{
6942 RT_STATUS init_status = RT_STATUS_SUCCESS;
6943 struct r8192_priv* priv = ieee80211_priv(dev);
6944 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
6945
6946 //YJ,add,091109
6947 if (priv->up == 0){
6948 RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__);
6949 priv->bdisable_nic = false; //YJ,add,091111
6950 return false;
6951 }
6952 // <1> Reset memory: descriptor, buffer,..
6953 //NicIFResetMemory(Adapter);
6954
6955 // <2> Enable Adapter
6956 //printk("===========>%s()\n",__FUNCTION__);
6957 //priv->bfirst_init = true;
6958 init_status = rtl8192_adapter_start(dev);
6959 if (init_status != RT_STATUS_SUCCESS) {
6960 RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
6961 priv->bdisable_nic = false; //YJ,add,091111
6962 return -1;
6963 }
6964 //printk("start adapter finished\n");
6965 RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC);
6966 //priv->bfirst_init = false;
6967
6968 // <3> Enable Interrupt
6969 rtl8192_irq_enable(dev);
6970 priv->bdisable_nic = false;
6971 //RT_TRACE(COMP_PS,"<===========%s()\n",__FUNCTION__);
6972 return (init_status == RT_STATUS_SUCCESS) ? true:false;
6973}
6974bool NicIFDisableNIC(struct net_device* dev)
6975{
6976 bool status = true;
6977 struct r8192_priv* priv = ieee80211_priv(dev);
6978 u8 tmp_state = 0;
6979 // <1> Disable Interrupt
6980 //RT_TRACE(COMP_PS, "=========>%s()\n",__FUNCTION__);
6981 priv->bdisable_nic = true; //YJ,move,091109
6982 tmp_state = priv->ieee80211->state;
6983
6984 ieee80211_softmac_stop_protocol(priv->ieee80211, false);
6985
6986 priv->ieee80211->state = tmp_state;
6987 rtl8192_cancel_deferred_work(priv);
6988 rtl8192_irq_disable(dev);
6989 // <2> Stop all timer
6990
6991 // <3> Disable Adapter
6992 rtl8192_halt_adapter(dev, false);
6993// priv->bdisable_nic = true;
6994 //RT_TRACE(COMP_PS, "<=========%s()\n",__FUNCTION__);
6995
6996 return status;
6997}
6998
6458 6999
6459/*************************************************************************** 7000/***************************************************************************
6460 ------------------- module init / exit stubs ---------------- 7001 ------------------- module init / exit stubs ----------------
diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c
index 5ffb4f74055b..a249f00da60d 100644
--- a/drivers/staging/rtl8192e/r8192E_dm.c
+++ b/drivers/staging/rtl8192e/r8192E_dm.c
@@ -19,26 +19,28 @@ Major Change History:
19#include "r819xE_phy.h" 19#include "r819xE_phy.h"
20#include "r819xE_phyreg.h" 20#include "r819xE_phyreg.h"
21#include "r8190_rtl8256.h" 21#include "r8190_rtl8256.h"
22
23#define DRV_NAME "rtl819xE"
22/*---------------------------Define Local Constant---------------------------*/ 24/*---------------------------Define Local Constant---------------------------*/
23// 25//
24// Indicate different AP vendor for IOT issue. 26// Indicate different AP vendor for IOT issue.
25// 27//
26#ifdef RTL8190P 28#ifdef RTL8190P
27static u32 edca_setting_DL[HT_IOT_PEER_MAX] = 29static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
28{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322}; 30{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322};
29static u32 edca_setting_UL[HT_IOT_PEER_MAX] = 31static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
30{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322}; 32{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322};
31#else 33#else
32#ifdef RTL8192E 34#ifdef RTL8192E
33static u32 edca_setting_DL[HT_IOT_PEER_MAX] = 35static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
34{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322}; 36{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322};
35static u32 edca_setting_UL[HT_IOT_PEER_MAX] = 37static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
36{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322}; 38{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322};
37#else 39#else
38static u32 edca_setting_DL[HT_IOT_PEER_MAX] = 40static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
39{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f}; 41{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5ea44f, 0x5e4322};
40static u32 edca_setting_UL[HT_IOT_PEER_MAX] = 42static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
41{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f}; 43{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f, 0x5e4322};
42#endif 44#endif
43#endif 45#endif
44 46
@@ -275,6 +277,30 @@ void dm_CheckRxAggregation(struct net_device *dev) {
275#endif 277#endif
276 278
277 279
280// call the script file to enable
281void dm_check_ac_dc_power(struct net_device *dev)
282{
283 struct r8192_priv *priv = ieee80211_priv(dev);
284 static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
285 char *argv[] = {ac_dc_check_script_path,DRV_NAME,NULL};
286 static char *envp[] = {"HOME=/",
287 "TERM=linux",
288 "PATH=/usr/bin:/bin",
289 NULL};
290
291 if(priv->ResetProgress == RESET_TYPE_SILENT)
292 {
293 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n");
294 return;
295 }
296
297 if(priv->ieee80211->state != IEEE80211_LINKED) {
298 return;
299 }
300 call_usermodehelper(ac_dc_check_script_path,argv,envp,1);
301
302 return;
303};
278 304
279void hal_dm_watchdog(struct net_device *dev) 305void hal_dm_watchdog(struct net_device *dev)
280{ 306{
@@ -282,6 +308,8 @@ void hal_dm_watchdog(struct net_device *dev)
282 308
283 //static u8 previous_bssid[6] ={0}; 309 //static u8 previous_bssid[6] ={0};
284 310
311 dm_check_ac_dc_power(dev);
312
285 /*Add by amy 2008/05/15 ,porting from windows code.*/ 313 /*Add by amy 2008/05/15 ,porting from windows code.*/
286 dm_check_rate_adaptive(dev); 314 dm_check_rate_adaptive(dev);
287 dm_dynamic_txpower(dev); 315 dm_dynamic_txpower(dev);
diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h
index 388908fc8d20..346bfb18e2b0 100644
--- a/drivers/staging/rtl8192e/r8192E_hw.h
+++ b/drivers/staging/rtl8192e/r8192E_hw.h
@@ -808,4 +808,12 @@ enum _RTL8192Pci_HW {
808#define GPI 0x108 808#define GPI 0x108
809#define GPO 0x109 809#define GPO 0x109
810#define GPE 0x10a 810#define GPE 0x10a
811
812#define ANAPAR_FOR_8192PciE 0x17 // Analog parameter register
813
814#define MSR_NOLINK 0x00
815#define MSR_ADHOC 0x01
816#define MSR_INFRA 0x02
817#define MSR_AP 0x03
818
811#endif 819#endif
diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c
index d1eb89229cdf..0b0f39ce3ced 100644
--- a/drivers/staging/rtl8192e/r8192E_wx.c
+++ b/drivers/staging/rtl8192e/r8192E_wx.c
@@ -22,7 +22,7 @@
22#include "r8192E_hw.h" 22#include "r8192E_hw.h"
23#include "r8192E_wx.h" 23#include "r8192E_wx.h"
24#ifdef ENABLE_DOT11D 24#ifdef ENABLE_DOT11D
25#include "dot11d.h" 25#include "ieee80211/dot11d.h"
26#endif 26#endif
27 27
28#define RATE_COUNT 12 28#define RATE_COUNT 12
@@ -70,6 +70,9 @@ static int r8192_wx_set_rate(struct net_device *dev,
70 int ret; 70 int ret;
71 struct r8192_priv *priv = ieee80211_priv(dev); 71 struct r8192_priv *priv = ieee80211_priv(dev);
72 72
73 if(priv->bHwRadioOff == true)
74 return 0;
75
73 down(&priv->wx_sem); 76 down(&priv->wx_sem);
74 77
75 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra); 78 ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
@@ -87,6 +90,9 @@ static int r8192_wx_set_rts(struct net_device *dev,
87 int ret; 90 int ret;
88 struct r8192_priv *priv = ieee80211_priv(dev); 91 struct r8192_priv *priv = ieee80211_priv(dev);
89 92
93 if(priv->bHwRadioOff == true)
94 return 0;
95
90 down(&priv->wx_sem); 96 down(&priv->wx_sem);
91 97
92 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra); 98 ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
@@ -111,6 +117,9 @@ static int r8192_wx_set_power(struct net_device *dev,
111 int ret; 117 int ret;
112 struct r8192_priv *priv = ieee80211_priv(dev); 118 struct r8192_priv *priv = ieee80211_priv(dev);
113 119
120 if(priv->bHwRadioOff == true)
121 return 0;
122
114 down(&priv->wx_sem); 123 down(&priv->wx_sem);
115 124
116 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra); 125 ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
@@ -290,6 +299,9 @@ static int r8192_wx_set_rawtx(struct net_device *dev,
290 struct r8192_priv *priv = ieee80211_priv(dev); 299 struct r8192_priv *priv = ieee80211_priv(dev);
291 int ret; 300 int ret;
292 301
302 if(priv->bHwRadioOff == true)
303 return 0;
304
293 down(&priv->wx_sem); 305 down(&priv->wx_sem);
294 306
295 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); 307 ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
@@ -325,6 +337,9 @@ static int r8192_wx_set_crcmon(struct net_device *dev,
325 int enable = (parms[0] > 0); 337 int enable = (parms[0] > 0);
326 short prev = priv->crcmon; 338 short prev = priv->crcmon;
327 339
340 if(priv->bHwRadioOff == true)
341 return 0;
342
328 down(&priv->wx_sem); 343 down(&priv->wx_sem);
329 344
330 if(enable) 345 if(enable)
@@ -352,6 +367,9 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
352 RT_RF_POWER_STATE rtState; 367 RT_RF_POWER_STATE rtState;
353 int ret; 368 int ret;
354 369
370 if(priv->bHwRadioOff == true)
371 return 0;
372
355 rtState = priv->ieee80211->eRFPowerState; 373 rtState = priv->ieee80211->eRFPowerState;
356 down(&priv->wx_sem); 374 down(&priv->wx_sem);
357#ifdef ENABLE_IPS 375#ifdef ENABLE_IPS
@@ -366,8 +384,10 @@ static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
366 return -1; 384 return -1;
367 } 385 }
368 else{ 386 else{
369 printk("=========>%s(): IPSLeave\n",__FUNCTION__); 387 RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__);
388 down(&priv->ieee80211->ips_sem);
370 IPSLeave(dev); 389 IPSLeave(dev);
390 up(&priv->ieee80211->ips_sem);
371 } 391 }
372 } 392 }
373 } 393 }
@@ -425,7 +445,7 @@ static int rtl8180_wx_get_range(struct net_device *dev,
425 */ 445 */
426 446
427 /* ~5 Mb/s real (802.11b) */ 447 /* ~5 Mb/s real (802.11b) */
428 range->throughput = 5 * 1000 * 1000; 448 range->throughput = 130 * 1000 * 1000;
429 449
430 // TODO: Not used in 802.11b? 450 // TODO: Not used in 802.11b?
431// range->min_nwid; /* Minimal NWID we are able to set */ 451// range->min_nwid; /* Minimal NWID we are able to set */
@@ -468,7 +488,7 @@ static int rtl8180_wx_get_range(struct net_device *dev,
468 range->pmt_flags = IW_POWER_TIMEOUT; 488 range->pmt_flags = IW_POWER_TIMEOUT;
469 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; 489 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
470 range->we_version_compiled = WIRELESS_EXT; 490 range->we_version_compiled = WIRELESS_EXT;
471 range->we_version_source = 16; 491 range->we_version_source = 18;
472 492
473// range->retry_capa; /* What retry options are supported */ 493// range->retry_capa; /* What retry options are supported */
474// range->retry_flags; /* How to decode max/min retry limit */ 494// range->retry_flags; /* How to decode max/min retry limit */
@@ -517,7 +537,12 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
517 struct ieee80211_device* ieee = priv->ieee80211; 537 struct ieee80211_device* ieee = priv->ieee80211;
518 RT_RF_POWER_STATE rtState; 538 RT_RF_POWER_STATE rtState;
519 int ret; 539 int ret;
540
541 if(priv->bHwRadioOff == true)
542 return 0;
543
520 rtState = priv->ieee80211->eRFPowerState; 544 rtState = priv->ieee80211->eRFPowerState;
545
521 if(!priv->up) return -ENETDOWN; 546 if(!priv->up) return -ENETDOWN;
522 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true) 547 if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
523 return -EAGAIN; 548 return -EAGAIN;
@@ -547,8 +572,10 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
547 return -1; 572 return -1;
548 } 573 }
549 else{ 574 else{
550 printk("=========>%s(): IPSLeave\n",__FUNCTION__); 575 //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__);
576 down(&priv->ieee80211->ips_sem);
551 IPSLeave(dev); 577 IPSLeave(dev);
578 up(&priv->ieee80211->ips_sem);
552 } 579 }
553 } 580 }
554 } 581 }
@@ -580,6 +607,9 @@ static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
580 int ret; 607 int ret;
581 struct r8192_priv *priv = ieee80211_priv(dev); 608 struct r8192_priv *priv = ieee80211_priv(dev);
582 609
610 if(priv->bHwRadioOff == true)
611 return 0;
612
583 if(!priv->up) return -ENETDOWN; 613 if(!priv->up) return -ENETDOWN;
584 614
585 down(&priv->wx_sem); 615 down(&priv->wx_sem);
@@ -599,23 +629,16 @@ static int r8192_wx_set_essid(struct net_device *dev,
599 RT_RF_POWER_STATE rtState; 629 RT_RF_POWER_STATE rtState;
600 int ret; 630 int ret;
601 631
632 if(priv->bHwRadioOff == true)
633 return 0;
634
602 rtState = priv->ieee80211->eRFPowerState; 635 rtState = priv->ieee80211->eRFPowerState;
603 down(&priv->wx_sem); 636 down(&priv->wx_sem);
637
604#ifdef ENABLE_IPS 638#ifdef ENABLE_IPS
605 if(priv->ieee80211->PowerSaveControl.bInactivePs){ 639 down(&priv->ieee80211->ips_sem);
606 if(rtState == eRfOff){ 640 IPSLeave(dev);
607 if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS) 641 up(&priv->ieee80211->ips_sem);
608 {
609 RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
610 up(&priv->wx_sem);
611 return -1;
612 }
613 else{
614 printk("=========>%s(): IPSLeave\n",__FUNCTION__);
615 IPSLeave(dev);
616 }
617 }
618 }
619#endif 642#endif
620 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b); 643 ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
621 644
@@ -650,6 +673,9 @@ static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
650 int ret; 673 int ret;
651 struct r8192_priv *priv = ieee80211_priv(dev); 674 struct r8192_priv *priv = ieee80211_priv(dev);
652 675
676 if(priv->bHwRadioOff == true)
677 return 0;
678
653 down(&priv->wx_sem); 679 down(&priv->wx_sem);
654 680
655 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); 681 ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
@@ -673,6 +699,9 @@ static int r8192_wx_set_frag(struct net_device *dev,
673{ 699{
674 struct r8192_priv *priv = ieee80211_priv(dev); 700 struct r8192_priv *priv = ieee80211_priv(dev);
675 701
702 if(priv->bHwRadioOff == true)
703 return 0;
704
676 if (wrqu->frag.disabled) 705 if (wrqu->frag.disabled)
677 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; 706 priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
678 else { 707 else {
@@ -711,8 +740,16 @@ static int r8192_wx_set_wap(struct net_device *dev,
711 struct r8192_priv *priv = ieee80211_priv(dev); 740 struct r8192_priv *priv = ieee80211_priv(dev);
712// struct sockaddr *temp = (struct sockaddr *)awrq; 741// struct sockaddr *temp = (struct sockaddr *)awrq;
713 742
743 if(priv->bHwRadioOff == true)
744 return 0;
745
714 down(&priv->wx_sem); 746 down(&priv->wx_sem);
715 747
748#ifdef ENABLE_IPS
749 down(&priv->ieee80211->ips_sem);
750 IPSLeave(dev);
751 up(&priv->ieee80211->ips_sem);
752#endif
716 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra); 753 ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
717 754
718 up(&priv->wx_sem); 755 up(&priv->wx_sem);
@@ -753,14 +790,24 @@ static int r8192_wx_set_enc(struct net_device *dev,
753 u32 hwkey[4]={0,0,0,0}; 790 u32 hwkey[4]={0,0,0,0};
754 u8 mask=0xff; 791 u8 mask=0xff;
755 u32 key_idx=0; 792 u32 key_idx=0;
756 u8 zero_addr[4][6] ={ {0x00,0x00,0x00,0x00,0x00,0x00}, 793 u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00},
757 {0x00,0x00,0x00,0x00,0x00,0x01}, 794 {0x00,0x00,0x00,0x00,0x00,0x01},
758 {0x00,0x00,0x00,0x00,0x00,0x02}, 795 {0x00,0x00,0x00,0x00,0x00,0x02},
759 {0x00,0x00,0x00,0x00,0x00,0x03} }; 796 {0x00,0x00,0x00,0x00,0x00,0x03} };
760 int i; 797 int i;
761 798
799 if(priv->bHwRadioOff == true)
800 return 0;
801
762 if(!priv->up) return -ENETDOWN; 802 if(!priv->up) return -ENETDOWN;
763 803
804 priv->ieee80211->wx_set_enc = 1;
805#ifdef ENABLE_IPS
806 down(&priv->ieee80211->ips_sem);
807 IPSLeave(dev);
808 up(&priv->ieee80211->ips_sem);
809#endif
810
764 down(&priv->wx_sem); 811 down(&priv->wx_sem);
765 812
766 RT_TRACE(COMP_SEC, "Setting SW wep key"); 813 RT_TRACE(COMP_SEC, "Setting SW wep key");
@@ -768,7 +815,6 @@ static int r8192_wx_set_enc(struct net_device *dev,
768 815
769 up(&priv->wx_sem); 816 up(&priv->wx_sem);
770 817
771
772 //sometimes, the length is zero while we do not type key value 818 //sometimes, the length is zero while we do not type key value
773 if(wrqu->encoding.length!=0){ 819 if(wrqu->encoding.length!=0){
774 820
@@ -868,6 +914,8 @@ static int r8192_wx_set_enc(struct net_device *dev,
868 } 914 }
869#endif 915#endif
870 916
917 priv->ieee80211->wx_set_enc = 0;
918
871 return ret; 919 return ret;
872} 920}
873 921
@@ -893,6 +941,9 @@ static int r8192_wx_set_retry(struct net_device *dev,
893 struct r8192_priv *priv = ieee80211_priv(dev); 941 struct r8192_priv *priv = ieee80211_priv(dev);
894 int err = 0; 942 int err = 0;
895 943
944 if(priv->bHwRadioOff == true)
945 return 0;
946
896 down(&priv->wx_sem); 947 down(&priv->wx_sem);
897 948
898 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 949 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
@@ -985,6 +1036,10 @@ static int r8192_wx_set_sens(struct net_device *dev,
985 struct r8192_priv *priv = ieee80211_priv(dev); 1036 struct r8192_priv *priv = ieee80211_priv(dev);
986 1037
987 short err = 0; 1038 short err = 0;
1039
1040 if(priv->bHwRadioOff == true)
1041 return 0;
1042
988 down(&priv->wx_sem); 1043 down(&priv->wx_sem);
989 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value); 1044 //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
990 if(priv->rf_set_sens == NULL) { 1045 if(priv->rf_set_sens == NULL) {
@@ -1011,7 +1066,19 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
1011 struct r8192_priv *priv = ieee80211_priv(dev); 1066 struct r8192_priv *priv = ieee80211_priv(dev);
1012 struct ieee80211_device* ieee = priv->ieee80211; 1067 struct ieee80211_device* ieee = priv->ieee80211;
1013 1068
1069 if(priv->bHwRadioOff == true)
1070 return 0;
1071
1014 down(&priv->wx_sem); 1072 down(&priv->wx_sem);
1073
1074 priv->ieee80211->wx_set_enc = 1;
1075
1076#ifdef ENABLE_IPS
1077 down(&priv->ieee80211->ips_sem);
1078 IPSLeave(dev);
1079 up(&priv->ieee80211->ips_sem);
1080#endif
1081
1015 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra); 1082 ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
1016 1083
1017 { 1084 {
@@ -1091,6 +1158,7 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
1091 } 1158 }
1092 1159
1093end_hw_sec: 1160end_hw_sec:
1161 priv->ieee80211->wx_set_enc = 0;
1094 up(&priv->wx_sem); 1162 up(&priv->wx_sem);
1095 return ret; 1163 return ret;
1096 1164
@@ -1102,6 +1170,10 @@ static int r8192_wx_set_auth(struct net_device *dev,
1102 int ret=0; 1170 int ret=0;
1103 //printk("====>%s()\n", __FUNCTION__); 1171 //printk("====>%s()\n", __FUNCTION__);
1104 struct r8192_priv *priv = ieee80211_priv(dev); 1172 struct r8192_priv *priv = ieee80211_priv(dev);
1173
1174 if(priv->bHwRadioOff == true)
1175 return 0;
1176
1105 down(&priv->wx_sem); 1177 down(&priv->wx_sem);
1106 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra); 1178 ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
1107 up(&priv->wx_sem); 1179 up(&priv->wx_sem);
@@ -1116,6 +1188,10 @@ static int r8192_wx_set_mlme(struct net_device *dev,
1116 1188
1117 int ret=0; 1189 int ret=0;
1118 struct r8192_priv *priv = ieee80211_priv(dev); 1190 struct r8192_priv *priv = ieee80211_priv(dev);
1191
1192 if(priv->bHwRadioOff == true)
1193 return 0;
1194
1119 down(&priv->wx_sem); 1195 down(&priv->wx_sem);
1120 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); 1196 ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
1121 up(&priv->wx_sem); 1197 up(&priv->wx_sem);
@@ -1129,6 +1205,10 @@ static int r8192_wx_set_gen_ie(struct net_device *dev,
1129 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length); 1205 //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
1130 int ret=0; 1206 int ret=0;
1131 struct r8192_priv *priv = ieee80211_priv(dev); 1207 struct r8192_priv *priv = ieee80211_priv(dev);
1208
1209 if(priv->bHwRadioOff == true)
1210 return 0;
1211
1132 down(&priv->wx_sem); 1212 down(&priv->wx_sem);
1133 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); 1213 ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
1134 up(&priv->wx_sem); 1214 up(&priv->wx_sem);
@@ -1142,6 +1222,42 @@ static int dummy(struct net_device *dev, struct iw_request_info *a,
1142 return -1; 1222 return -1;
1143} 1223}
1144 1224
1225// check ac/dc status with the help of user space application */
1226static int r8192_wx_adapter_power_status(struct net_device *dev,
1227 struct iw_request_info *info,
1228 union iwreq_data *wrqu, char *extra)
1229{
1230 struct r8192_priv *priv = ieee80211_priv(dev);
1231#ifdef ENABLE_LPS
1232 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
1233 struct ieee80211_device* ieee = priv->ieee80211;
1234#endif
1235 down(&priv->wx_sem);
1236
1237#ifdef ENABLE_LPS
1238 RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power");
1239 // ieee->ps shall not be set under DC mode, otherwise it conflict
1240 // with Leisure power save mode setting.
1241 //
1242 if(*extra || priv->force_lps) {
1243 priv->ps_force = false;
1244 pPSC->bLeisurePs = true;
1245 } else {
1246 //LZM for PS-Poll AID issue. 090429
1247 if(priv->ieee80211->state == IEEE80211_LINKED)
1248 LeisurePSLeave(dev);
1249
1250 priv->ps_force = true;
1251 pPSC->bLeisurePs = false;
1252 ieee->ps = *extra;
1253 }
1254
1255#endif
1256 up(&priv->wx_sem);
1257 return 0;
1258
1259}
1260
1145 1261
1146static iw_handler r8192_wx_handlers[] = 1262static iw_handler r8192_wx_handlers[] =
1147{ 1263{
@@ -1231,72 +1347,28 @@ static const struct iw_priv_args r8192_private_args[] = {
1231 SIOCIWFIRSTPRIV + 0x2, 1347 SIOCIWFIRSTPRIV + 0x2,
1232 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" 1348 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
1233 } 1349 }
1234#ifdef JOHN_IOCTL
1235 , 1350 ,
1236 { 1351 {
1237 SIOCIWFIRSTPRIV + 0x3, 1352 SIOCIWFIRSTPRIV + 0x3,
1238 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF" 1353 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1354
1239 } 1355 }
1240 , 1356 ,
1241 { 1357 {
1242 SIOCIWFIRSTPRIV + 0x4, 1358 SIOCIWFIRSTPRIV + 0x4,
1243 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF" 1359 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE,
1244 } 1360 "set_power"
1245 ,
1246 {
1247 SIOCIWFIRSTPRIV + 0x5,
1248 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
1249 }
1250 ,
1251 {
1252 SIOCIWFIRSTPRIV + 0x6,
1253 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
1254 }
1255 ,
1256 {
1257 SIOCIWFIRSTPRIV + 0x7,
1258 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
1259 }
1260 ,
1261 {
1262 SIOCIWFIRSTPRIV + 0x8,
1263 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
1264 }
1265 ,
1266 {
1267 SIOCIWFIRSTPRIV + 0x9,
1268 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
1269 }
1270
1271#endif
1272 ,
1273 {
1274 SIOCIWFIRSTPRIV + 0x3,
1275 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
1276
1277 } 1361 }
1278 1362
1279}; 1363};
1280 1364
1281 1365
1282static iw_handler r8192_private_handler[] = { 1366static iw_handler r8192_private_handler[] = {
1283// r8192_wx_set_monitor, /* SIOCIWFIRSTPRIV */
1284 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ 1367 r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
1285// r8192_wx_set_forceassociate,
1286// r8192_wx_set_beaconinterval,
1287// r8192_wx_set_monitor_type,
1288 r8192_wx_set_scan_type, 1368 r8192_wx_set_scan_type,
1289 r8192_wx_set_rawtx, 1369 r8192_wx_set_rawtx,
1290#ifdef JOHN_IOCTL
1291 r8192_wx_read_regs,
1292 r8192_wx_write_regs,
1293 r8192_wx_read_bb,
1294 r8192_wx_write_bb,
1295 r8192_wx_read_nicb,
1296 r8192_wx_write_nicb,
1297 r8192_wx_get_ap_status
1298#endif
1299 r8192_wx_force_reset, 1370 r8192_wx_force_reset,
1371 r8192_wx_adapter_power_status,
1300}; 1372};
1301 1373
1302//#if WIRELESS_EXT >= 17 1374//#if WIRELESS_EXT >= 17
diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h
index 79ebdb698a41..047030bc051a 100644
--- a/drivers/staging/rtl8192e/r8192E_wx.h
+++ b/drivers/staging/rtl8192e/r8192E_wx.h
@@ -15,7 +15,6 @@
15#ifndef R8180_WX_H 15#ifndef R8180_WX_H
16#define R8180_WX_H 16#define R8180_WX_H
17//#include <linux/wireless.h> 17//#include <linux/wireless.h>
18//#include "ieee80211.h"
19extern struct iw_handler_def r8192_wx_handlers_def; 18extern struct iw_handler_def r8192_wx_handlers_def;
20/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */ 19/* Enable the rtl819x_core.c to share this function, david 2008.9.22 */
21extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev); 20extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
index 2aaa4e1bb375..87c334fb7333 100644
--- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c
+++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
@@ -135,7 +135,7 @@ RT_STATUS cmpk_message_handle_tx(
135 * Transform from little endian to big endian 135 * Transform from little endian to big endian
136 * and pending zero 136 * and pending zero
137 */ 137 */
138 seg_ptr = skb->tail; 138 seg_ptr = skb_tail_pointer(skb);
139 for(i=0 ; i < frag_length; i+=4) { 139 for(i=0 ; i < frag_length; i+=4) {
140 *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0; 140 *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
141 *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0; 141 *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c
index 1f9e413bcd49..793a17545554 100644
--- a/drivers/staging/rtl8192e/r819xE_firmware.c
+++ b/drivers/staging/rtl8192e/r819xE_firmware.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Procedure: Init boot code/firmware code/data session 2 * Procedure: Init boot code/firmware code/data session
3 * 3 *
4 * Description: This routine will intialize firmware. If any error occurs 4 * Description: This routine will intialize firmware. If any error occurs
5 * during the initialization process, the routine shall terminate 5 * during the initialization process, the routine shall terminate
@@ -7,19 +7,21 @@
7 * NdisOpenFile only from MiniportInitialize. 7 * NdisOpenFile only from MiniportInitialize.
8 * 8 *
9 * Arguments: The pointer of the adapter 9 * Arguments: The pointer of the adapter
10 10 *
11 * Returns: 11 * Returns:
12 * NDIS_STATUS_FAILURE - the following initialization process 12 * NDIS_STATUS_FAILURE - the following initialization process
13 * should be terminated 13 * should be terminated
14 * NDIS_STATUS_SUCCESS - if firmware initialization process 14 * NDIS_STATUS_SUCCESS - if firmware initialization process
15 * success 15 * success
16 */ 16 */
17
17#include "r8192E.h" 18#include "r8192E.h"
18#include "r8192E_hw.h" 19#include "r8192E_hw.h"
20
19#include <linux/firmware.h> 21#include <linux/firmware.h>
20 22
21/* It should be double word alignment */ 23/* It should be double word alignment */
22#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8) 24#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8)
23 25
24enum firmware_init_step { 26enum firmware_init_step {
25 FW_INIT_STEP0_BOOT = 0, 27 FW_INIT_STEP0_BOOT = 0,
@@ -47,17 +49,17 @@ void firmware_init_param(struct net_device *dev)
47static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, 49static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
48 u32 buffer_len) 50 u32 buffer_len)
49{ 51{
50 struct r8192_priv *priv = ieee80211_priv(dev); 52 struct r8192_priv *priv = ieee80211_priv(dev);
51 bool rt_status = true; 53 bool rt_status = true;
52 u16 frag_threshold; 54 u16 frag_threshold;
53 u16 frag_length, frag_offset = 0; 55 u16 frag_length, frag_offset = 0;
54 int i; 56 int i;
55 57
56 rt_firmware *pfirmware = priv->pFirmware; 58 rt_firmware *pfirmware = priv->pFirmware;
57 struct sk_buff *skb; 59 struct sk_buff *skb;
58 unsigned char *seg_ptr; 60 unsigned char *seg_ptr;
59 cb_desc *tcb_desc; 61 cb_desc *tcb_desc;
60 u8 bLastIniPkt; 62 u8 bLastIniPkt;
61 63
62 firmware_init_param(dev); 64 firmware_init_param(dev);
63 65
@@ -89,10 +91,17 @@ static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
89 * Transform from little endian to big endian and pending zero 91 * Transform from little endian to big endian and pending zero
90 */ 92 */
91 for (i = 0; i < frag_length; i += 4) { 93 for (i = 0; i < frag_length; i += 4) {
92 *seg_ptr++ = ((i+0) < frag_length) ? code_virtual_address[i+3] : 0; 94 *seg_ptr++ = ((i+0) < frag_length) ? \
93 *seg_ptr++ = ((i+1) < frag_length) ? code_virtual_address[i+2] : 0; 95 code_virtual_address[i+3] : 0;
94 *seg_ptr++ = ((i+2) < frag_length) ? code_virtual_address[i+1] : 0; 96
95 *seg_ptr++ = ((i+3) < frag_length) ? code_virtual_address[i+0] : 0; 97 *seg_ptr++ = ((i+1) < frag_length) ? \
98 code_virtual_address[i+2] : 0;
99
100 *seg_ptr++ = ((i+2) < frag_length) ? \
101 code_virtual_address[i+1] : 0;
102
103 *seg_ptr++ = ((i+3) < frag_length) ? \
104 code_virtual_address[i+0] : 0;
96 } 105 }
97 tcb_desc->txbuf_size = (u16)i; 106 tcb_desc->txbuf_size = (u16)i;
98 skb_put(skb, i); 107 skb_put(skb, i);
@@ -204,16 +213,16 @@ CPUCheckFirmwareReady_Fail:
204 213
205bool init_firmware(struct net_device *dev) 214bool init_firmware(struct net_device *dev)
206{ 215{
207 struct r8192_priv *priv = ieee80211_priv(dev); 216 struct r8192_priv *priv = ieee80211_priv(dev);
208 bool rt_status = TRUE; 217 bool rt_status = true;
209 u32 file_length = 0; 218 u32 file_length = 0;
210 u8 *mapped_file = NULL; 219 u8 *mapped_file = NULL;
211 u32 init_step = 0; 220 u32 init_step = 0;
212 enum opt_rst_type rst_opt = OPT_SYSTEM_RESET; 221 enum opt_rst_type rst_opt = OPT_SYSTEM_RESET;
213 enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT; 222 enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT;
214 223
215 rt_firmware *pfirmware = priv->pFirmware; 224 rt_firmware *pfirmware = priv->pFirmware;
216 const struct firmware *fw_entry; 225 const struct firmware *fw_entry;
217 const char *fw_name[3] = { "RTL8192E/boot.img", 226 const char *fw_name[3] = { "RTL8192E/boot.img",
218 "RTL8192E/main.img", 227 "RTL8192E/main.img",
219 "RTL8192E/data.img"}; 228 "RTL8192E/data.img"};
@@ -240,31 +249,37 @@ bool init_firmware(struct net_device *dev)
240 * Download boot, main, and data image for System reset. 249 * Download boot, main, and data image for System reset.
241 * Download data image for firmware reseta 250 * Download data image for firmware reseta
242 */ 251 */
243 for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { 252 for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; \
253 init_step++) {
244 /* 254 /*
245 * Open Image file, and map file to contineous memory if open file success. 255 * Open Image file, and map file to contineous memory if open file success.
246 * or read image file from array. Default load from IMG file 256 * or read image file from array. Default load from IMG file
247 */ 257 */
248 if (rst_opt == OPT_SYSTEM_RESET) { 258 if (rst_opt == OPT_SYSTEM_RESET) {
249 if (pfirmware->firmware_buf_size[init_step] == 0) { 259 if (pfirmware->firmware_buf_size[init_step] == 0) {
250 rc = request_firmware(&fw_entry, fw_name[init_step], &priv->pdev->dev); 260 rc = request_firmware(&fw_entry,
261 fw_name[init_step], &priv->pdev->dev);
262
251 if (rc < 0) { 263 if (rc < 0) {
252 RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n"); 264 RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n");
253 goto download_firmware_fail; 265 goto download_firmware_fail;
254 } 266 }
255 267
256 if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) { 268 if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) {
257 RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!\n"); 269 RT_TRACE(COMP_FIRMWARE, \
270 "img file size exceed the container buffer fail!\n");
258 goto download_firmware_fail; 271 goto download_firmware_fail;
259 } 272 }
260 273
261 if (init_step != FW_INIT_STEP1_MAIN) { 274 if (init_step != FW_INIT_STEP1_MAIN) {
262 memcpy(pfirmware->firmware_buf[init_step], fw_entry->data, fw_entry->size); 275 memcpy(pfirmware->firmware_buf[init_step],
276 fw_entry->data, fw_entry->size);
263 pfirmware->firmware_buf_size[init_step] = fw_entry->size; 277 pfirmware->firmware_buf_size[init_step] = fw_entry->size;
264 278
265 } else { 279 } else {
266 memset(pfirmware->firmware_buf[init_step], 0, 128); 280 memset(pfirmware->firmware_buf[init_step], 0, 128);
267 memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data, fw_entry->size); 281 memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data,
282 fw_entry->size);
268 pfirmware->firmware_buf_size[init_step] = fw_entry->size+128; 283 pfirmware->firmware_buf_size[init_step] = fw_entry->size+128;
269 } 284 }
270 285
@@ -273,6 +288,7 @@ bool init_firmware(struct net_device *dev)
273 } 288 }
274 mapped_file = pfirmware->firmware_buf[init_step]; 289 mapped_file = pfirmware->firmware_buf[init_step];
275 file_length = pfirmware->firmware_buf_size[init_step]; 290 file_length = pfirmware->firmware_buf_size[init_step];
291
276 } else if (rst_opt == OPT_FIRMWARE_RESET) { 292 } else if (rst_opt == OPT_FIRMWARE_RESET) {
277 /* we only need to download data.img here */ 293 /* we only need to download data.img here */
278 mapped_file = pfirmware->firmware_buf[init_step]; 294 mapped_file = pfirmware->firmware_buf[init_step];
@@ -346,7 +362,10 @@ bool init_firmware(struct net_device *dev)
346 362
347download_firmware_fail: 363download_firmware_fail:
348 RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); 364 RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
349 rt_status = FALSE; 365 rt_status = false;
350 return rt_status; 366 return rt_status;
351
352} 367}
368
369MODULE_FIRMWARE("RTL8192E/boot.img");
370MODULE_FIRMWARE("RTL8192E/main.img");
371MODULE_FIRMWARE("RTL8192E/data.img");
diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c
index c44059aeacb6..7bd4fae0667e 100644
--- a/drivers/staging/rtl8192e/r819xE_phy.c
+++ b/drivers/staging/rtl8192e/r819xE_phy.c
@@ -5,7 +5,7 @@
5#include "r819xE_phy.h" 5#include "r819xE_phy.h"
6#include "r8192E_dm.h" 6#include "r8192E_dm.h"
7#ifdef ENABLE_DOT11D 7#ifdef ENABLE_DOT11D
8#include "dot11d.h" 8#include "ieee80211/dot11d.h"
9#endif 9#endif
10static u32 RF_CHANNEL_TABLE_ZEBRA[] = { 10static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
11 0, 11 0,
diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h
index fa77abe88827..41e0d777eabd 100644
--- a/drivers/staging/rtl8192e/r819xE_phy.h
+++ b/drivers/staging/rtl8192e/r819xE_phy.h
@@ -1,43 +1,46 @@
1#ifndef _R819XU_PHY_H 1#ifndef _R819XU_PHY_H
2#define _R819XU_PHY_H 2#define _R819XU_PHY_H
3/* Channel switch:The size of command tables for switch channel*/ 3
4/* Channel switch: the size of command tables for switch channel */
4#define MAX_PRECMD_CNT 16 5#define MAX_PRECMD_CNT 16
5#define MAX_RFDEPENDCMD_CNT 16 6#define MAX_RFDEPENDCMD_CNT 16
6#define MAX_POSTCMD_CNT 16 7#define MAX_POSTCMD_CNT 16
7 8
8#ifdef RTL8190P 9#ifdef RTL8190P
9#define MACPHY_Array_PGLength 21 10#define MACPHY_Array_PGLength 21
10#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG 11#define Rtl819XMACPHY_Array_PG Rtl8190PciMACPHY_Array_PG
11#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array 12#define Rtl819XMACPHY_Array Rtl8190PciMACPHY_Array
12#define RadioC_ArrayLength 246 13#define RadioC_ArrayLength 246
13#define RadioD_ArrayLength 78 14#define RadioD_ArrayLength 78
14#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array 15#define Rtl819XRadioA_Array Rtl8190PciRadioA_Array
15#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array 16#define Rtl819XRadioB_Array Rtl8190PciRadioB_Array
16#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array 17#define Rtl819XRadioC_Array Rtl8190PciRadioC_Array
17#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array 18#define Rtl819XRadioD_Array Rtl8190PciRadioD_Array
18#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array 19#define Rtl819XAGCTAB_Array Rtl8190PciAGCTAB_Array
19#define PHY_REGArrayLength 280 20#define PHY_REGArrayLength 280
20#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray 21#define Rtl819XPHY_REGArray Rtl8190PciPHY_REGArray
21#define PHY_REG_1T2RArrayLength 280 22#define PHY_REG_1T2RArrayLength 280
22#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray 23#define Rtl819XPHY_REG_1T2RArray Rtl8190PciPHY_REG_1T2RArray
24#endif
25
26
27#ifdef RTL8192E
28#define MACPHY_Array_PGLength 30
29#define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG
30#define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array
31#define RadioC_ArrayLength 1
32#define RadioD_ArrayLength 1
33#define Rtl819XRadioA_Array Rtl8192PciERadioA_Array
34#define Rtl819XRadioB_Array Rtl8192PciERadioB_Array
35#define Rtl819XRadioC_Array Rtl8192PciERadioC_Array
36#define Rtl819XRadioD_Array Rtl8192PciERadioD_Array
37#define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array
38#define PHY_REGArrayLength 1
39#define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray
40#define PHY_REG_1T2RArrayLength 296
41#define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray
23#endif 42#endif
24 43
25 #ifdef RTL8192E
26 #define MACPHY_Array_PGLength 30
27 #define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG
28 #define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array
29 #define RadioC_ArrayLength 1
30 #define RadioD_ArrayLength 1
31 #define Rtl819XRadioA_Array Rtl8192PciERadioA_Array
32 #define Rtl819XRadioB_Array Rtl8192PciERadioB_Array
33 #define Rtl819XRadioC_Array Rtl8192PciERadioC_Array
34 #define Rtl819XRadioD_Array Rtl8192PciERadioD_Array
35 #define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array
36 #define PHY_REGArrayLength 1
37 #define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray
38 #define PHY_REG_1T2RArrayLength 296
39 #define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray
40 #endif
41#define AGCTAB_ArrayLength 384 44#define AGCTAB_ArrayLength 384
42#define MACPHY_ArrayLength 18 45#define MACPHY_ArrayLength 18
43 46
@@ -45,7 +48,7 @@
45#define RadioB_ArrayLength 78 48#define RadioB_ArrayLength 78
46 49
47 50
48typedef enum _SwChnlCmdID{ 51typedef enum _SwChnlCmdID {
49 CmdID_End, 52 CmdID_End,
50 CmdID_SetTxPowerLevel, 53 CmdID_SetTxPowerLevel,
51 CmdID_BBRegWrite10, 54 CmdID_BBRegWrite10,
@@ -53,16 +56,15 @@ typedef enum _SwChnlCmdID{
53 CmdID_WritePortUshort, 56 CmdID_WritePortUshort,
54 CmdID_WritePortUchar, 57 CmdID_WritePortUchar,
55 CmdID_RF_WriteReg, 58 CmdID_RF_WriteReg,
56}SwChnlCmdID; 59} SwChnlCmdID;
57 60
58/*--------------------------------Define structure--------------------------------*/ 61/* switch channel data structure */
59/* 1. Switch channel related */ 62typedef struct _SwChnlCmd {
60typedef struct _SwChnlCmd{ 63 SwChnlCmdID CmdID;
61 SwChnlCmdID CmdID; 64 u32 Para1;
62 u32 Para1; 65 u32 Para2;
63 u32 Para2; 66 u32 msDelay;
64 u32 msDelay; 67} __attribute__ ((packed)) SwChnlCmd;
65}__attribute__ ((packed)) SwChnlCmd;
66 68
67extern u32 rtl819XMACPHY_Array_PG[]; 69extern u32 rtl819XMACPHY_Array_PG[];
68extern u32 rtl819XPHY_REG_1T2RArray[]; 70extern u32 rtl819XPHY_REG_1T2RArray[];
@@ -72,54 +74,90 @@ extern u32 rtl819XRadioB_Array[];
72extern u32 rtl819XRadioC_Array[]; 74extern u32 rtl819XRadioC_Array[];
73extern u32 rtl819XRadioD_Array[]; 75extern u32 rtl819XRadioD_Array[];
74 76
75typedef enum _HW90_BLOCK{ 77typedef enum _HW90_BLOCK {
76 HW90_BLOCK_MAC = 0, 78 HW90_BLOCK_MAC = 0,
77 HW90_BLOCK_PHY0 = 1, 79 HW90_BLOCK_PHY0 = 1,
78 HW90_BLOCK_PHY1 = 2, 80 HW90_BLOCK_PHY1 = 2,
79 HW90_BLOCK_RF = 3, 81 HW90_BLOCK_RF = 3,
80 HW90_BLOCK_MAXIMUM = 4, // Never use this 82 /* Don't ever use this. */
81}HW90_BLOCK_E, *PHW90_BLOCK_E; 83 HW90_BLOCK_MAXIMUM = 4,
82 84} HW90_BLOCK_E, *PHW90_BLOCK_E;
83typedef enum _RF90_RADIO_PATH{ 85
84 RF90_PATH_A = 0, //Radio Path A 86typedef enum _RF90_RADIO_PATH {
85 RF90_PATH_B = 1, //Radio Path B 87 /* Radio paths */
86 RF90_PATH_C = 2, //Radio Path C 88 RF90_PATH_A = 0,
87 RF90_PATH_D = 3, //Radio Path D 89 RF90_PATH_B = 1,
88 RF90_PATH_MAX //Max RF number 92 support 90 RF90_PATH_C = 2,
89}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E; 91 RF90_PATH_D = 3,
90 92
91#define bMaskByte0 0xff 93 /* Max RF number 92 support */
92#define bMaskByte1 0xff00 94 RF90_PATH_MAX
93#define bMaskByte2 0xff0000 95} RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
94#define bMaskByte3 0xff000000 96
95#define bMaskHWord 0xffff0000 97#define bMaskByte0 0xff
96#define bMaskLWord 0x0000ffff 98#define bMaskByte1 0xff00
97#define bMaskDWord 0xffffffff 99#define bMaskByte2 0xff0000
98 100#define bMaskByte3 0xff000000
99//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask); 101#define bMaskHWord 0xffff0000
100extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath); 102#define bMaskLWord 0x0000ffff
101extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData); 103#define bMaskDWord 0xffffffff
102extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask); 104
103//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset); 105/*extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
104//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data); 106
105extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data); 107extern u32 rtl8192_phy_RFSerialRead(struct net_device *dev,
106extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask); 108 RF90_RADIO_PATH_E eRFPath, u32 Offset);
107extern void rtl8192_phy_configmac(struct net_device* dev); 109
108extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType); 110extern void rtl8192_phy_RFSerialWrite(struct net_device *dev,
109//extern void rtl8192_InitBBRFRegDef(struct net_device* dev); 111 RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
110extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath); 112
111//extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev); 113extern void rtl8192_InitBBRFRegDef(struct net_device *dev);
112extern RT_STATUS rtl8192_BBConfig(struct net_device* dev); 114
113extern void rtl8192_phy_getTxPower(struct net_device* dev); 115extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device *dev); */
114extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel); 116
117extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath);
118
119extern void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr,
120 u32 dwBitMask, u32 dwData);
121
122extern u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr,
123 u32 dwBitMask);
124
125extern void rtl8192_phy_SetRFReg(struct net_device *dev,
126 RF90_RADIO_PATH_E eRFPath, u32 RegAddr,
127 u32 BitMask, u32 Data);
128
129extern u32 rtl8192_phy_QueryRFReg(struct net_device *dev,
130 RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
131
132extern void rtl8192_phy_configmac(struct net_device *dev);
133
134extern void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType);
135
136extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device *dev,
137 HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
138
139extern RT_STATUS rtl8192_BBConfig(struct net_device *dev);
140
141extern void rtl8192_phy_getTxPower(struct net_device *dev);
142
143extern void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel);
144
115extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev); 145extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev);
146
116extern void rtl8192_phy_updateInitGain(struct net_device* dev); 147extern void rtl8192_phy_updateInitGain(struct net_device* dev);
117extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E eRFPath);
118 148
119extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel); 149extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev,
120extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); 150 RF90_RADIO_PATH_E eRFPath);
151
152extern u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel);
153
154extern void rtl8192_SetBWMode(struct net_device *dev,
155 HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
156
121extern void rtl8192_SwChnl_WorkItem(struct net_device *dev); 157extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
158
122extern void rtl8192_SetBWModeWorkItem(struct net_device *dev); 159extern void rtl8192_SetBWModeWorkItem(struct net_device *dev);
160
123extern void InitialGain819xPci(struct net_device *dev, u8 Operation); 161extern void InitialGain819xPci(struct net_device *dev, u8 Operation);
124 162
125#endif 163#endif /* _R819XU_PHY_H */
diff --git a/drivers/staging/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/r819xE_phyreg.h
index 37f0feefaf2c..d5de279f6644 100644
--- a/drivers/staging/rtl8192e/r819xE_phyreg.h
+++ b/drivers/staging/rtl8192e/r819xE_phyreg.h
@@ -38,6 +38,8 @@
38#define MCS_TXAGC 0x340 // MCS AGC 38#define MCS_TXAGC 0x340 // MCS AGC
39#define CCK_TXAGC 0x348 // CCK AGC 39#define CCK_TXAGC 0x348 // CCK AGC
40 40
41#define MacBlkCtrl 0x403 // Mac block on/off control register
42
41//page8 43//page8
42#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC 44#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC
43#define rFPGA0_TxInfo 0x804 45#define rFPGA0_TxInfo 0x804
@@ -79,55 +81,70 @@
79#define rFPGA0_XB_LSSIReadBack 0x8a4 81#define rFPGA0_XB_LSSIReadBack 0x8a4
80#define rFPGA0_XC_LSSIReadBack 0x8a8 82#define rFPGA0_XC_LSSIReadBack 0x8a8
81#define rFPGA0_XD_LSSIReadBack 0x8ac 83#define rFPGA0_XD_LSSIReadBack 0x8ac
82#define rFPGA0_PSDReport 0x8b4 84#define rFPGA0_PSDReport 0x8b4
83#define rFPGA0_XAB_RFInterfaceRB 0x8e0 85#define rFPGA0_XAB_RFInterfaceRB 0x8e0
84#define rFPGA0_XCD_RFInterfaceRB 0x8e4 86#define rFPGA0_XCD_RFInterfaceRB 0x8e4
85 87
86//page 9 88/* Page 9 - RF mode & OFDM TxSC */
87#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC 89#define rFPGA1_RFMOD 0x900
88#define rFPGA1_TxBlock 0x904 90#define rFPGA1_TxBlock 0x904
89#define rFPGA1_DebugSelect 0x908 91#define rFPGA1_DebugSelect 0x908
90#define rFPGA1_TxInfo 0x90c 92#define rFPGA1_TxInfo 0x90c
91 93
92//page a 94/* Page a */
93#define rCCK0_System 0xa00 95#define rCCK0_System 0xa00
94#define rCCK0_AFESetting 0xa04 96#define rCCK0_AFESetting 0xa04
95#define rCCK0_CCA 0xa08 97#define rCCK0_CCA 0xa08
96#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level 98/* AGC default value, saturation level */
97#define rCCK0_RxAGC2 0xa10 //AGC & DAGC 99#define rCCK0_RxAGC1 0xa0c
98#define rCCK0_RxHP 0xa14 100/* AGC & DAGC */
99#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold 101#define rCCK0_RxAGC2 0xa10
100#define rCCK0_DSPParameter2 0xa1c //SQ threshold 102#define rCCK0_RxHP 0xa14
101#define rCCK0_TxFilter1 0xa20 103/* Timing recovery & channel estimation threshold */
102#define rCCK0_TxFilter2 0xa24 104#define rCCK0_DSPParameter1 0xa18
103#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 105/* SQ threshold */
104#define rCCK0_FalseAlarmReport 0xa2c //0xa2d 106#define rCCK0_DSPParameter2 0xa1c
105#define rCCK0_TRSSIReport 0xa50 107#define rCCK0_TxFilter1 0xa20
106#define rCCK0_RxReport 0xa54 //0xa57 108#define rCCK0_TxFilter2 0xa24
107#define rCCK0_FACounterLower 0xa5c //0xa5b 109/* Debug port and TX filter 3 */
108#define rCCK0_FACounterUpper 0xa58 //0xa5c 110#define rCCK0_DebugPort 0xa28
109 111#define rCCK0_FalseAlarmReport 0xa2c
110//page c 112#define rCCK0_TRSSIReport 0xa50
111#define rOFDM0_LSTF 0xc00 113#define rCCK0_RxReport 0xa54
114#define rCCK0_FACounterLower 0xa5c
115#define rCCK0_FACounterUpper 0xa58
116
117/* Page c */
118#define rOFDM0_LSTF 0xc00
112#define rOFDM0_TRxPathEnable 0xc04 119#define rOFDM0_TRxPathEnable 0xc04
113#define rOFDM0_TRMuxPar 0xc08 120#define rOFDM0_TRMuxPar 0xc08
114#define rOFDM0_TRSWIsolation 0xc0c 121#define rOFDM0_TRSWIsolation 0xc0c
115#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter 122/* RxIQ DC offset, Rx digital filter, DC notch filter */
116#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix 123#define rOFDM0_XARxAFE 0xc10
117#define rOFDM0_XBRxAFE 0xc18 124/* RxIQ imblance matrix */
125#define rOFDM0_XARxIQImbalance 0xc14
126#define rOFDM0_XBRxAFE 0xc18
118#define rOFDM0_XBRxIQImbalance 0xc1c 127#define rOFDM0_XBRxIQImbalance 0xc1c
119#define rOFDM0_XCRxAFE 0xc20 128#define rOFDM0_XCRxAFE 0xc20
120#define rOFDM0_XCRxIQImbalance 0xc24 129#define rOFDM0_XCRxIQImbalance 0xc24
121#define rOFDM0_XDRxAFE 0xc28 130#define rOFDM0_XDRxAFE 0xc28
122#define rOFDM0_XDRxIQImbalance 0xc2c 131#define rOFDM0_XDRxIQImbalance 0xc2c
123#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD 132/* PD, BW & SBD */
124#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. 133#define rOFDM0_RxDetector1 0xc30
125#define rOFDM0_RxDetector3 0xc38 //Frame Sync. 134/* SBD */
126#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI 135#define rOFDM0_RxDetector2 0xc34
127#define rOFDM0_RxDSP 0xc40 //Rx Sync Path 136/* Frame Sync */
128#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC 137#define rOFDM0_RxDetector3 0xc38
129#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold 138/* PD, SBD, Frame Sync & Short-GI */
130#define rOFDM0_ECCAThreshold 0xc4c // energy CCA 139#define rOFDM0_RxDetector4 0xc3c
140/* Rx Sync Path */
141#define rOFDM0_RxDSP 0xc40
142/* CFO & DAGC */
143#define rOFDM0_CFOandDAGC 0xc44
144/* CCA Drop threshold */
145#define rOFDM0_CCADropThreshold 0xc48
146/* Energy CCA */
147#define rOFDM0_ECCAThreshold 0xc4c
131#define rOFDM0_XAAGCCore1 0xc50 148#define rOFDM0_XAAGCCore1 0xc50
132#define rOFDM0_XAAGCCore2 0xc54 149#define rOFDM0_XAAGCCore2 0xc54
133#define rOFDM0_XBAGCCore1 0xc58 150#define rOFDM0_XBAGCCore1 0xc58
@@ -139,501 +156,517 @@
139#define rOFDM0_AGCParameter1 0xc70 156#define rOFDM0_AGCParameter1 0xc70
140#define rOFDM0_AGCParameter2 0xc74 157#define rOFDM0_AGCParameter2 0xc74
141#define rOFDM0_AGCRSSITable 0xc78 158#define rOFDM0_AGCRSSITable 0xc78
142#define rOFDM0_HTSTFAGC 0xc7c 159#define rOFDM0_HTSTFAGC 0xc7c
143#define rOFDM0_XATxIQImbalance 0xc80 160#define rOFDM0_XATxIQImbalance 0xc80
144#define rOFDM0_XATxAFE 0xc84 161#define rOFDM0_XATxAFE 0xc84
145#define rOFDM0_XBTxIQImbalance 0xc88 162#define rOFDM0_XBTxIQImbalance 0xc88
146#define rOFDM0_XBTxAFE 0xc8c 163#define rOFDM0_XBTxAFE 0xc8c
147#define rOFDM0_XCTxIQImbalance 0xc90 164#define rOFDM0_XCTxIQImbalance 0xc90
148#define rOFDM0_XCTxAFE 0xc94 165#define rOFDM0_XCTxAFE 0xc94
149#define rOFDM0_XDTxIQImbalance 0xc98 166#define rOFDM0_XDTxIQImbalance 0xc98
150#define rOFDM0_XDTxAFE 0xc9c 167#define rOFDM0_XDTxAFE 0xc9c
151#define rOFDM0_RxHPParameter 0xce0 168#define rOFDM0_RxHPParameter 0xce0
152#define rOFDM0_TxPseudoNoiseWgt 0xce4 169#define rOFDM0_TxPseudoNoiseWgt 0xce4
153#define rOFDM0_FrameSync 0xcf0 170#define rOFDM0_FrameSync 0xcf0
154#define rOFDM0_DFSReport 0xcf4 171#define rOFDM0_DFSReport 0xcf4
155#define rOFDM0_TxCoeff1 0xca4 172#define rOFDM0_TxCoeff1 0xca4
156#define rOFDM0_TxCoeff2 0xca8 173#define rOFDM0_TxCoeff2 0xca8
157#define rOFDM0_TxCoeff3 0xcac 174#define rOFDM0_TxCoeff3 0xcac
158#define rOFDM0_TxCoeff4 0xcb0 175#define rOFDM0_TxCoeff4 0xcb0
159#define rOFDM0_TxCoeff5 0xcb4 176#define rOFDM0_TxCoeff5 0xcb4
160#define rOFDM0_TxCoeff6 0xcb8 177#define rOFDM0_TxCoeff6 0xcb8
161 178
162 179
163//page d 180/* Page d */
164#define rOFDM1_LSTF 0xd00 181#define rOFDM1_LSTF 0xd00
165#define rOFDM1_TRxPathEnable 0xd04 182#define rOFDM1_TRxPathEnable 0xd04
166#define rOFDM1_CFO 0xd08 183#define rOFDM1_CFO 0xd08
167#define rOFDM1_CSI1 0xd10 184#define rOFDM1_CSI1 0xd10
168#define rOFDM1_SBD 0xd14 185#define rOFDM1_SBD 0xd14
169#define rOFDM1_CSI2 0xd18 186#define rOFDM1_CSI2 0xd18
170#define rOFDM1_CFOTracking 0xd2c 187#define rOFDM1_CFOTracking 0xd2c
171#define rOFDM1_TRxMesaure1 0xd34 188#define rOFDM1_TRxMesaure1 0xd34
172#define rOFDM1_IntfDet 0xd3c 189#define rOFDM1_IntfDet 0xd3c
173#define rOFDM1_PseudoNoiseStateAB 0xd50 190#define rOFDM1_PseudoNoiseStateAB 0xd50
174#define rOFDM1_PseudoNoiseStateCD 0xd54 191#define rOFDM1_PseudoNoiseStateCD 0xd54
175#define rOFDM1_RxPseudoNoiseWgt 0xd58 192#define rOFDM1_RxPseudoNoiseWgt 0xd58
176#define rOFDM_PHYCounter1 0xda0 //cca, parity fail 193/* cca, parity fail */
177#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail 194#define rOFDM_PHYCounter1 0xda0
178#define rOFDM_PHYCounter3 0xda8 //MCS not support 195/* rate illegal, crc8 fail */
179#define rOFDM_ShortCFOAB 0xdac 196#define rOFDM_PHYCounter2 0xda4
180#define rOFDM_ShortCFOCD 0xdb0 197/* MCS not supported */
181#define rOFDM_LongCFOAB 0xdb4 198#define rOFDM_PHYCounter3 0xda8
182#define rOFDM_LongCFOCD 0xdb8 199#define rOFDM_ShortCFOAB 0xdac
183#define rOFDM_TailCFOAB 0xdbc 200#define rOFDM_ShortCFOCD 0xdb0
184#define rOFDM_TailCFOCD 0xdc0 201#define rOFDM_LongCFOAB 0xdb4
202#define rOFDM_LongCFOCD 0xdb8
203#define rOFDM_TailCFOAB 0xdbc
204#define rOFDM_TailCFOCD 0xdc0
185#define rOFDM_PWMeasure1 0xdc4 205#define rOFDM_PWMeasure1 0xdc4
186#define rOFDM_PWMeasure2 0xdc8 206#define rOFDM_PWMeasure2 0xdc8
187#define rOFDM_BWReport 0xdcc 207#define rOFDM_BWReport 0xdcc
188#define rOFDM_AGCReport 0xdd0 208#define rOFDM_AGCReport 0xdd0
189#define rOFDM_RxSNR 0xdd4 209#define rOFDM_RxSNR 0xdd4
190#define rOFDM_RxEVMCSI 0xdd8 210#define rOFDM_RxEVMCSI 0xdd8
191#define rOFDM_SIGReport 0xddc 211#define rOFDM_SIGReport 0xddc
192 212
193//page e 213/* Page e */
194#define rTxAGC_Rate18_06 0xe00 214#define rTxAGC_Rate18_06 0xe00
195#define rTxAGC_Rate54_24 0xe04 215#define rTxAGC_Rate54_24 0xe04
196#define rTxAGC_CCK_Mcs32 0xe08 216#define rTxAGC_CCK_Mcs32 0xe08
197#define rTxAGC_Mcs03_Mcs00 0xe10 217#define rTxAGC_Mcs03_Mcs00 0xe10
198#define rTxAGC_Mcs07_Mcs04 0xe14 218#define rTxAGC_Mcs07_Mcs04 0xe14
199#define rTxAGC_Mcs11_Mcs08 0xe18 219#define rTxAGC_Mcs11_Mcs08 0xe18
200#define rTxAGC_Mcs15_Mcs12 0xe1c 220#define rTxAGC_Mcs15_Mcs12 0xe1c
201 221
202 222
203//RF 223/* RF Zebra 1 */
204//Zebra1
205#define rZebra1_HSSIEnable 0x0 224#define rZebra1_HSSIEnable 0x0
206#define rZebra1_TRxEnable1 0x1 225#define rZebra1_TRxEnable1 0x1
207#define rZebra1_TRxEnable2 0x2 226#define rZebra1_TRxEnable2 0x2
208#define rZebra1_AGC 0x4 227#define rZebra1_AGC 0x4
209#define rZebra1_ChargePump 0x5 228#define rZebra1_ChargePump 0x5
210#define rZebra1_Channel 0x7 229#define rZebra1_Channel 0x7
211#define rZebra1_TxGain 0x8 230#define rZebra1_TxGain 0x8
212#define rZebra1_TxLPF 0x9 231#define rZebra1_TxLPF 0x9
213#define rZebra1_RxLPF 0xb 232#define rZebra1_RxLPF 0xb
214#define rZebra1_RxHPFCorner 0xc 233#define rZebra1_RxHPFCorner 0xc
215 234
216//Zebra4 235/* Zebra 4 */
217#define rGlobalCtrl 0 236#define rGlobalCtrl 0
218#define rRTL8256_TxLPF 19 237#define rRTL8256_TxLPF 19
219#define rRTL8256_RxLPF 11 238#define rRTL8256_RxLPF 11
220 239
221//RTL8258 240/* RTL8258 */
222#define rRTL8258_TxLPF 0x11 241#define rRTL8258_TxLPF 0x11
223#define rRTL8258_RxLPF 0x13 242#define rRTL8258_RxLPF 0x13
224#define rRTL8258_RSSILPF 0xa 243#define rRTL8258_RSSILPF 0xa
225 244
226//Bit Mask 245/* Bit Mask */
227//page-1 246/* Page 1 */
228#define bBBResetB 0x100 247#define bBBResetB 0x100
229#define bGlobalResetB 0x200 248#define bGlobalResetB 0x200
230#define bOFDMTxStart 0x4 249#define bOFDMTxStart 0x4
231#define bCCKTxStart 0x8 250#define bCCKTxStart 0x8
232#define bCRC32Debug 0x100 251#define bCRC32Debug 0x100
233#define bPMACLoopback 0x10 252#define bPMACLoopback 0x10
234#define bTxLSIG 0xffffff 253#define bTxLSIG 0xffffff
235#define bOFDMTxRate 0xf 254#define bOFDMTxRate 0xf
236#define bOFDMTxReserved 0x10 255#define bOFDMTxReserved 0x10
237#define bOFDMTxLength 0x1ffe0 256#define bOFDMTxLength 0x1ffe0
238#define bOFDMTxParity 0x20000 257#define bOFDMTxParity 0x20000
239#define bTxHTSIG1 0xffffff 258#define bTxHTSIG1 0xffffff
240#define bTxHTMCSRate 0x7f 259#define bTxHTMCSRate 0x7f
241#define bTxHTBW 0x80 260#define bTxHTBW 0x80
242#define bTxHTLength 0xffff00 261#define bTxHTLength 0xffff00
243#define bTxHTSIG2 0xffffff 262#define bTxHTSIG2 0xffffff
244#define bTxHTSmoothing 0x1 263#define bTxHTSmoothing 0x1
245#define bTxHTSounding 0x2 264#define bTxHTSounding 0x2
246#define bTxHTReserved 0x4 265#define bTxHTReserved 0x4
247#define bTxHTAggreation 0x8 266#define bTxHTAggreation 0x8
248#define bTxHTSTBC 0x30 267#define bTxHTSTBC 0x30
249#define bTxHTAdvanceCoding 0x40 268#define bTxHTAdvanceCoding 0x40
250#define bTxHTShortGI 0x80 269#define bTxHTShortGI 0x80
251#define bTxHTNumberHT_LTF 0x300 270#define bTxHTNumberHT_LTF 0x300
252#define bTxHTCRC8 0x3fc00 271#define bTxHTCRC8 0x3fc00
253#define bCounterReset 0x10000 272#define bCounterReset 0x10000
254#define bNumOfOFDMTx 0xffff 273#define bNumOfOFDMTx 0xffff
255#define bNumOfCCKTx 0xffff0000 274#define bNumOfCCKTx 0xffff0000
256#define bTxIdleInterval 0xffff 275#define bTxIdleInterval 0xffff
257#define bOFDMService 0xffff0000 276#define bOFDMService 0xffff0000
258#define bTxMACHeader 0xffffffff 277#define bTxMACHeader 0xffffffff
259#define bTxDataInit 0xff 278#define bTxDataInit 0xff
260#define bTxHTMode 0x100 279#define bTxHTMode 0x100
261#define bTxDataType 0x30000 280#define bTxDataType 0x30000
262#define bTxRandomSeed 0xffffffff 281#define bTxRandomSeed 0xffffffff
263#define bCCKTxPreamble 0x1 282#define bCCKTxPreamble 0x1
264#define bCCKTxSFD 0xffff0000 283#define bCCKTxSFD 0xffff0000
265#define bCCKTxSIG 0xff 284#define bCCKTxSIG 0xff
266#define bCCKTxService 0xff00 285#define bCCKTxService 0xff00
267#define bCCKLengthExt 0x8000 286#define bCCKLengthExt 0x8000
268#define bCCKTxLength 0xffff0000 287#define bCCKTxLength 0xffff0000
269#define bCCKTxCRC16 0xffff 288#define bCCKTxCRC16 0xffff
270#define bCCKTxStatus 0x1 289#define bCCKTxStatus 0x1
271#define bOFDMTxStatus 0x2 290#define bOFDMTxStatus 0x2
272 291
273//page-8 292/* Page 8 */
274#define bRFMOD 0x1 293#define bRFMOD 0x1
275#define bJapanMode 0x2 294#define bJapanMode 0x2
276#define bCCKTxSC 0x30 295#define bCCKTxSC 0x30
277#define bCCKEn 0x1000000 296#define bCCKEn 0x1000000
278#define bOFDMEn 0x2000000 297#define bOFDMEn 0x2000000
279#define bOFDMRxADCPhase 0x10000 298#define bOFDMRxADCPhase 0x10000
280#define bOFDMTxDACPhase 0x40000 299#define bOFDMTxDACPhase 0x40000
281#define bXATxAGC 0x3f 300#define bXATxAGC 0x3f
282#define bXBTxAGC 0xf00 301#define bXBTxAGC 0xf00
283#define bXCTxAGC 0xf000 302#define bXCTxAGC 0xf000
284#define bXDTxAGC 0xf0000 303#define bXDTxAGC 0xf0000
285#define bPAStart 0xf0000000 304#define bPAStart 0xf0000000
286#define bTRStart 0x00f00000 305#define bTRStart 0x00f00000
287#define bRFStart 0x0000f000 306#define bRFStart 0x0000f000
288#define bBBStart 0x000000f0 307#define bBBStart 0x000000f0
289#define bBBCCKStart 0x0000000f 308#define bBBCCKStart 0x0000000f
290#define bPAEnd 0xf //Reg0x814 309/* Reg)x814 */
291#define bTREnd 0x0f000000 310#define bPAEnd 0xf
292#define bRFEnd 0x000f0000 311#define bTREnd 0x0f000000
293#define bCCAMask 0x000000f0 //T2R 312#define bRFEnd 0x000f0000
294#define bR2RCCAMask 0x00000f00 313/* T2R */
295#define bHSSI_R2TDelay 0xf8000000 314#define bCCAMask 0x000000f0
296#define bHSSI_T2RDelay 0xf80000 315#define bR2RCCAMask 0x00000f00
297#define bContTxHSSI 0x400 //channel gain at continue Tx 316#define bHSSI_R2TDelay 0xf8000000
298#define bIGFromCCK 0x200 317#define bHSSI_T2RDelay 0xf80000
299#define bAGCAddress 0x3f 318/* Channel gain at continue TX. */
300#define bRxHPTx 0x7000 319#define bContTxHSSI 0x400
301#define bRxHPT2R 0x38000 320#define bIGFromCCK 0x200
302#define bRxHPCCKIni 0xc0000 321#define bAGCAddress 0x3f
303#define bAGCTxCode 0xc00000 322#define bRxHPTx 0x7000
304#define bAGCRxCode 0x300000 323#define bRxHPT2R 0x38000
305#define b3WireDataLength 0x800 324#define bRxHPCCKIni 0xc0000
306#define b3WireAddressLength 0x400 325#define bAGCTxCode 0xc00000
307#define b3WireRFPowerDown 0x1 326#define bAGCRxCode 0x300000
308//#define bHWSISelect 0x8 327#define b3WireDataLength 0x800
309#define b5GPAPEPolarity 0x40000000 328#define b3WireAddressLength 0x400
310#define b2GPAPEPolarity 0x80000000 329#define b3WireRFPowerDown 0x1
311#define bRFSW_TxDefaultAnt 0x3 330/*#define bHWSISelect 0x8 */
312#define bRFSW_TxOptionAnt 0x30 331#define b5GPAPEPolarity 0x40000000
313#define bRFSW_RxDefaultAnt 0x300 332#define b2GPAPEPolarity 0x80000000
314#define bRFSW_RxOptionAnt 0x3000 333#define bRFSW_TxDefaultAnt 0x3
315#define bRFSI_3WireData 0x1 334#define bRFSW_TxOptionAnt 0x30
316#define bRFSI_3WireClock 0x2 335#define bRFSW_RxDefaultAnt 0x300
317#define bRFSI_3WireLoad 0x4 336#define bRFSW_RxOptionAnt 0x3000
318#define bRFSI_3WireRW 0x8 337#define bRFSI_3WireData 0x1
319#define bRFSI_3Wire 0xf //3-wire total control 338#define bRFSI_3WireClock 0x2
320#define bRFSI_RFENV 0x10 339#define bRFSI_3WireLoad 0x4
321#define bRFSI_TRSW 0x20 340#define bRFSI_3WireRW 0x8
322#define bRFSI_TRSWB 0x40 341/* 3-wire total control */
323#define bRFSI_ANTSW 0x100 342#define bRFSI_3Wire 0xf
324#define bRFSI_ANTSWB 0x200 343#define bRFSI_RFENV 0x10
325#define bRFSI_PAPE 0x400 344#define bRFSI_TRSW 0x20
326#define bRFSI_PAPE5G 0x800 345#define bRFSI_TRSWB 0x40
327#define bBandSelect 0x1 346#define bRFSI_ANTSW 0x100
328#define bHTSIG2_GI 0x80 347#define bRFSI_ANTSWB 0x200
329#define bHTSIG2_Smoothing 0x01 348#define bRFSI_PAPE 0x400
330#define bHTSIG2_Sounding 0x02 349#define bRFSI_PAPE5G 0x800
331#define bHTSIG2_Aggreaton 0x08 350#define bBandSelect 0x1
332#define bHTSIG2_STBC 0x30 351#define bHTSIG2_GI 0x80
333#define bHTSIG2_AdvCoding 0x40 352#define bHTSIG2_Smoothing 0x01
353#define bHTSIG2_Sounding 0x02
354#define bHTSIG2_Aggreaton 0x08
355#define bHTSIG2_STBC 0x30
356#define bHTSIG2_AdvCoding 0x40
334#define bHTSIG2_NumOfHTLTF 0x300 357#define bHTSIG2_NumOfHTLTF 0x300
335#define bHTSIG2_CRC8 0x3fc 358#define bHTSIG2_CRC8 0x3fc
336#define bHTSIG1_MCS 0x7f 359#define bHTSIG1_MCS 0x7f
337#define bHTSIG1_BandWidth 0x80 360#define bHTSIG1_BandWidth 0x80
338#define bHTSIG1_HTLength 0xffff 361#define bHTSIG1_HTLength 0xffff
339#define bLSIG_Rate 0xf 362#define bLSIG_Rate 0xf
340#define bLSIG_Reserved 0x10 363#define bLSIG_Reserved 0x10
341#define bLSIG_Length 0x1fffe 364#define bLSIG_Length 0x1fffe
342#define bLSIG_Parity 0x20 365#define bLSIG_Parity 0x20
343#define bCCKRxPhase 0x4 366#define bCCKRxPhase 0x4
344#define bLSSIReadAddress 0x3f000000 //LSSI "Read" Address 367/* LSSI "read" address */
345#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal 368#define bLSSIReadAddress 0x3f000000
346#define bLSSIReadBackData 0xfff 369/* LSSI "read" edge signal */
347#define bLSSIReadOKFlag 0x1000 370#define bLSSIReadEdge 0x80000000
348#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz 371#define bLSSIReadBackData 0xfff
349 372#define bLSSIReadOKFlag 0x1000
350#define bRegulator0Standby 0x1 373/* 0: 44 MHz, 1: 88MHz */
351#define bRegulatorPLLStandby 0x2 374#define bCCKSampleRate 0x8
352#define bRegulator1Standby 0x4 375
353#define bPLLPowerUp 0x8 376#define bRegulator0Standby 0x1
354#define bDPLLPowerUp 0x10 377#define bRegulatorPLLStandby 0x2
355#define bDA10PowerUp 0x20 378#define bRegulator1Standby 0x4
356#define bAD7PowerUp 0x200 379#define bPLLPowerUp 0x8
357#define bDA6PowerUp 0x2000 380#define bDPLLPowerUp 0x10
358#define bXtalPowerUp 0x4000 381#define bDA10PowerUp 0x20
359#define b40MDClkPowerUP 0x8000 382#define bAD7PowerUp 0x200
360#define bDA6DebugMode 0x20000 383#define bDA6PowerUp 0x2000
361#define bDA6Swing 0x380000 384#define bXtalPowerUp 0x4000
362#define bADClkPhase 0x4000000 385#define b40MDClkPowerUP 0x8000
363#define b80MClkDelay 0x18000000 386#define bDA6DebugMode 0x20000
364#define bAFEWatchDogEnable 0x20000000 387#define bDA6Swing 0x380000
365#define bXtalCap 0x0f000000 388#define bADClkPhase 0x4000000
366#define bXtalCap01 0xc0000000 389#define b80MClkDelay 0x18000000
367#define bXtalCap23 0x3 390#define bAFEWatchDogEnable 0x20000000
368#define bXtalCap92x 0x0f000000 391#define bXtalCap 0x0f000000
369#define bIntDifClkEnable 0x400 392#define bXtalCap01 0xc0000000
370#define bExtSigClkEnable 0x800 393#define bXtalCap23 0x3
394#define bXtalCap92x 0x0f000000
395#define bIntDifClkEnable 0x400
396#define bExtSigClkEnable 0x800
371#define bBandgapMbiasPowerUp 0x10000 397#define bBandgapMbiasPowerUp 0x10000
372#define bAD11SHGain 0xc0000 398#define bAD11SHGain 0xc0000
373#define bAD11InputRange 0x700000 399#define bAD11InputRange 0x700000
374#define bAD11OPCurrent 0x3800000 400#define bAD11OPCurrent 0x3800000
375#define bIPathLoopback 0x4000000 401#define bIPathLoopback 0x4000000
376#define bQPathLoopback 0x8000000 402#define bQPathLoopback 0x8000000
377#define bAFELoopback 0x10000000 403#define bAFELoopback 0x10000000
378#define bDA10Swing 0x7e0 404#define bDA10Swing 0x7e0
379#define bDA10Reverse 0x800 405#define bDA10Reverse 0x800
380#define bDAClkSource 0x1000 406#define bDAClkSource 0x1000
381#define bAD7InputRange 0x6000 407#define bAD7InputRange 0x6000
382#define bAD7Gain 0x38000 408#define bAD7Gain 0x38000
383#define bAD7OutputCMMode 0x40000 409#define bAD7OutputCMMode 0x40000
384#define bAD7InputCMMode 0x380000 410#define bAD7InputCMMode 0x380000
385#define bAD7Current 0xc00000 411#define bAD7Current 0xc00000
386#define bRegulatorAdjust 0x7000000 412#define bRegulatorAdjust 0x7000000
387#define bAD11PowerUpAtTx 0x1 413#define bAD11PowerUpAtTx 0x1
388#define bDA10PSAtTx 0x10 414#define bDA10PSAtTx 0x10
389#define bAD11PowerUpAtRx 0x100 415#define bAD11PowerUpAtRx 0x100
390#define bDA10PSAtRx 0x1000 416#define bDA10PSAtRx 0x1000
391 417
392#define bCCKRxAGCFormat 0x200 418#define bCCKRxAGCFormat 0x200
393 419
394#define bPSDFFTSamplepPoint 0xc000 420#define bPSDFFTSamplepPoint 0xc000
395#define bPSDAverageNum 0x3000 421#define bPSDAverageNum 0x3000
396#define bIQPathControl 0xc00 422#define bIQPathControl 0xc00
397#define bPSDFreq 0x3ff 423#define bPSDFreq 0x3ff
398#define bPSDAntennaPath 0x30 424#define bPSDAntennaPath 0x30
399#define bPSDIQSwitch 0x40 425#define bPSDIQSwitch 0x40
400#define bPSDRxTrigger 0x400000 426#define bPSDRxTrigger 0x400000
401#define bPSDTxTrigger 0x80000000 427#define bPSDTxTrigger 0x80000000
402#define bPSDSineToneScale 0x7f000000 428#define bPSDSineToneScale 0x7f000000
403#define bPSDReport 0xffff 429#define bPSDReport 0xffff
404 430
405//page-9 431/* Page 8 */
406#define bOFDMTxSC 0x30000000 432#define bOFDMTxSC 0x30000000
407#define bCCKTxOn 0x1 433#define bCCKTxOn 0x1
408#define bOFDMTxOn 0x2 434#define bOFDMTxOn 0x2
409#define bDebugPage 0xfff //reset debug page and also HWord, LWord 435/* Reset debug page and also HWord, LWord */
410#define bDebugItem 0xff //reset debug page and LWord 436#define bDebugPage 0xfff
411#define bAntL 0x10 437/* Reset debug page and LWord */
412#define bAntNonHT 0x100 438#define bDebugItem 0xff
413#define bAntHT1 0x1000 439#define bAntL 0x10
414#define bAntHT2 0x10000 440#define bAntNonHT 0x100
415#define bAntHT1S1 0x100000 441#define bAntHT1 0x1000
416#define bAntNonHTS1 0x1000000 442#define bAntHT2 0x10000
417 443#define bAntHT1S1 0x100000
418//page-a 444#define bAntNonHTS1 0x1000000
419#define bCCKBBMode 0x3 445
420#define bCCKTxPowerSaving 0x80 446/* Page a */
421#define bCCKRxPowerSaving 0x40 447#define bCCKBBMode 0x3
422#define bCCKSideBand 0x10 448#define bCCKTxPowerSaving 0x80
423#define bCCKScramble 0x8 449#define bCCKRxPowerSaving 0x40
424#define bCCKAntDiversity 0x8000 450#define bCCKSideBand 0x10
451#define bCCKScramble 0x8
452#define bCCKAntDiversity 0x8000
425#define bCCKCarrierRecovery 0x4000 453#define bCCKCarrierRecovery 0x4000
426#define bCCKTxRate 0x3000 454#define bCCKTxRate 0x3000
427#define bCCKDCCancel 0x0800 455#define bCCKDCCancel 0x0800
428#define bCCKISICancel 0x0400 456#define bCCKISICancel 0x0400
429#define bCCKMatchFilter 0x0200 457#define bCCKMatchFilter 0x0200
430#define bCCKEqualizer 0x0100 458#define bCCKEqualizer 0x0100
431#define bCCKPreambleDetect 0x800000 459#define bCCKPreambleDetect 0x800000
432#define bCCKFastFalseCCA 0x400000 460#define bCCKFastFalseCCA 0x400000
433#define bCCKChEstStart 0x300000 461#define bCCKChEstStart 0x300000
434#define bCCKCCACount 0x080000 462#define bCCKCCACount 0x080000
435#define bCCKcs_lim 0x070000 463#define bCCKcs_lim 0x070000
436#define bCCKBistMode 0x80000000 464#define bCCKBistMode 0x80000000
437#define bCCKCCAMask 0x40000000 465#define bCCKCCAMask 0x40000000
438#define bCCKTxDACPhase 0x4 466#define bCCKTxDACPhase 0x4
439#define bCCKRxADCPhase 0x20000000 //r_rx_clk 467/* r_rx_clk */
468#define bCCKRxADCPhase 0x20000000
440#define bCCKr_cp_mode0 0x0100 469#define bCCKr_cp_mode0 0x0100
441#define bCCKTxDCOffset 0xf0 470#define bCCKTxDCOffset 0xf0
442#define bCCKRxDCOffset 0xf 471#define bCCKRxDCOffset 0xf
443#define bCCKCCAMode 0xc000 472#define bCCKCCAMode 0xc000
444#define bCCKFalseCS_lim 0x3f00 473#define bCCKFalseCS_lim 0x3f00
445#define bCCKCS_ratio 0xc00000 474#define bCCKCS_ratio 0xc00000
446#define bCCKCorgBit_sel 0x300000 475#define bCCKCorgBit_sel 0x300000
447#define bCCKPD_lim 0x0f0000 476#define bCCKPD_lim 0x0f0000
448#define bCCKNewCCA 0x80000000 477#define bCCKNewCCA 0x80000000
449#define bCCKRxHPofIG 0x8000 478#define bCCKRxHPofIG 0x8000
450#define bCCKRxIG 0x7f00 479#define bCCKRxIG 0x7f00
451#define bCCKLNAPolarity 0x800000 480#define bCCKLNAPolarity 0x800000
452#define bCCKRx1stGain 0x7f0000 481#define bCCKRx1stGain 0x7f0000
453#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity 482/* CCK Rx Initial gain polarity */
454#define bCCKRxAGCSatLevel 0x1f000000 483#define bCCKRFExtend 0x20000000
455#define bCCKRxAGCSatCount 0xe0 484#define bCCKRxAGCSatLevel 0x1f000000
456#define bCCKRxRFSettle 0x1f //AGCsamp_dly 485#define bCCKRxAGCSatCount 0xe0
457#define bCCKFixedRxAGC 0x8000 486/* AGCSAmp_dly */
458//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 487#define bCCKRxRFSettle 0x1f
459#define bCCKAntennaPolarity 0x2000 488#define bCCKFixedRxAGC 0x8000
460#define bCCKTxFilterType 0x0c00 489/*#define bCCKRxAGCFormat 0x4000 remove to HSSI register 0x824 */
490#define bCCKAntennaPolarity 0x2000
491#define bCCKTxFilterType 0x0c00
461#define bCCKRxAGCReportType 0x0300 492#define bCCKRxAGCReportType 0x0300
462#define bCCKRxDAGCEn 0x80000000 493#define bCCKRxDAGCEn 0x80000000
463#define bCCKRxDAGCPeriod 0x20000000 494#define bCCKRxDAGCPeriod 0x20000000
464#define bCCKRxDAGCSatLevel 0x1f000000 495#define bCCKRxDAGCSatLevel 0x1f000000
465#define bCCKTimingRecovery 0x800000 496#define bCCKTimingRecovery 0x800000
466#define bCCKTxC0 0x3f0000 497#define bCCKTxC0 0x3f0000
467#define bCCKTxC1 0x3f000000 498#define bCCKTxC1 0x3f000000
468#define bCCKTxC2 0x3f 499#define bCCKTxC2 0x3f
469#define bCCKTxC3 0x3f00 500#define bCCKTxC3 0x3f00
470#define bCCKTxC4 0x3f0000 501#define bCCKTxC4 0x3f0000
471#define bCCKTxC5 0x3f000000 502#define bCCKTxC5 0x3f000000
472#define bCCKTxC6 0x3f 503#define bCCKTxC6 0x3f
473#define bCCKTxC7 0x3f00 504#define bCCKTxC7 0x3f00
474#define bCCKDebugPort 0xff0000 505#define bCCKDebugPort 0xff0000
475#define bCCKDACDebug 0x0f000000 506#define bCCKDACDebug 0x0f000000
476#define bCCKFalseAlarmEnable 0x8000 507#define bCCKFalseAlarmEnable 0x8000
477#define bCCKFalseAlarmRead 0x4000 508#define bCCKFalseAlarmRead 0x4000
478#define bCCKTRSSI 0x7f 509#define bCCKTRSSI 0x7f
479#define bCCKRxAGCReport 0xfe 510#define bCCKRxAGCReport 0xfe
480#define bCCKRxReport_AntSel 0x80000000 511#define bCCKRxReport_AntSel 0x80000000
481#define bCCKRxReport_MFOff 0x40000000 512#define bCCKRxReport_MFOff 0x40000000
482#define bCCKRxRxReport_SQLoss 0x20000000 513#define bCCKRxRxReport_SQLoss 0x20000000
483#define bCCKRxReport_Pktloss 0x10000000 514#define bCCKRxReport_Pktloss 0x10000000
484#define bCCKRxReport_Lockedbit 0x08000000 515#define bCCKRxReport_Lockedbit 0x08000000
485#define bCCKRxReport_RateError 0x04000000 516#define bCCKRxReport_RateError 0x04000000
486#define bCCKRxReport_RxRate 0x03000000 517#define bCCKRxReport_RxRate 0x03000000
487#define bCCKRxFACounterLower 0xff 518#define bCCKRxFACounterLower 0xff
488#define bCCKRxFACounterUpper 0xff000000 519#define bCCKRxFACounterUpper 0xff000000
489#define bCCKRxHPAGCStart 0xe000 520#define bCCKRxHPAGCStart 0xe000
490#define bCCKRxHPAGCFinal 0x1c00 521#define bCCKRxHPAGCFinal 0x1c00
491 522
492#define bCCKRxFalseAlarmEnable 0x8000 523#define bCCKRxFalseAlarmEnable 0x8000
493#define bCCKFACounterFreeze 0x4000 524#define bCCKFACounterFreeze 0x4000
494 525
495#define bCCKTxPathSel 0x10000000 526#define bCCKTxPathSel 0x10000000
496#define bCCKDefaultRxPath 0xc000000 527#define bCCKDefaultRxPath 0xc000000
497#define bCCKOptionRxPath 0x3000000 528#define bCCKOptionRxPath 0x3000000
498 529
499//page c 530/* Page c */
500#define bNumOfSTF 0x3 531#define bNumOfSTF 0x3
501#define bShift_L 0xc0 532#define bShift_L 0xc0
502#define bGI_TH 0xc 533#define bGI_TH 0xc
503#define bRxPathA 0x1 534#define bRxPathA 0x1
504#define bRxPathB 0x2 535#define bRxPathB 0x2
505#define bRxPathC 0x4 536#define bRxPathC 0x4
506#define bRxPathD 0x8 537#define bRxPathD 0x8
507#define bTxPathA 0x1 538#define bTxPathA 0x1
508#define bTxPathB 0x2 539#define bTxPathB 0x2
509#define bTxPathC 0x4 540#define bTxPathC 0x4
510#define bTxPathD 0x8 541#define bTxPathD 0x8
511#define bTRSSIFreq 0x200 542#define bTRSSIFreq 0x200
512#define bADCBackoff 0x3000 543#define bADCBackoff 0x3000
513#define bDFIRBackoff 0xc000 544#define bDFIRBackoff 0xc000
514#define bTRSSILatchPhase 0x10000 545#define bTRSSILatchPhase 0x10000
515#define bRxIDCOffset 0xff 546#define bRxIDCOffset 0xff
516#define bRxQDCOffset 0xff00 547#define bRxQDCOffset 0xff00
517#define bRxDFIRMode 0x1800000 548#define bRxDFIRMode 0x1800000
518#define bRxDCNFType 0xe000000 549#define bRxDCNFType 0xe000000
519#define bRXIQImb_A 0x3ff 550#define bRXIQImb_A 0x3ff
520#define bRXIQImb_B 0xfc00 551#define bRXIQImb_B 0xfc00
521#define bRXIQImb_C 0x3f0000 552#define bRXIQImb_C 0x3f0000
522#define bRXIQImb_D 0xffc00000 553#define bRXIQImb_D 0xffc00000
523#define bDC_dc_Notch 0x60000 554#define bDC_dc_Notch 0x60000
524#define bRxNBINotch 0x1f000000 555#define bRxNBINotch 0x1f000000
525#define bPD_TH 0xf 556#define bPD_TH 0xf
526#define bPD_TH_Opt2 0xc000 557#define bPD_TH_Opt2 0xc000
527#define bPWED_TH 0x700 558#define bPWED_TH 0x700
528#define bIfMF_Win_L 0x800 559#define bIfMF_Win_L 0x800
529#define bPD_Option 0x1000 560#define bPD_Option 0x1000
530#define bMF_Win_L 0xe000 561#define bMF_Win_L 0xe000
531#define bBW_Search_L 0x30000 562#define bBW_Search_L 0x30000
532#define bwin_enh_L 0xc0000 563#define bwin_enh_L 0xc0000
533#define bBW_TH 0x700000 564#define bBW_TH 0x700000
534#define bED_TH2 0x3800000 565#define bED_TH2 0x3800000
535#define bBW_option 0x4000000 566#define bBW_option 0x4000000
536#define bRatio_TH 0x18000000 567#define bRatio_TH 0x18000000
537#define bWindow_L 0xe0000000 568#define bWindow_L 0xe0000000
538#define bSBD_Option 0x1 569#define bSBD_Option 0x1
539#define bFrame_TH 0x1c 570#define bFrame_TH 0x1c
540#define bFS_Option 0x60 571#define bFS_Option 0x60
541#define bDC_Slope_check 0x80 572#define bDC_Slope_check 0x80
542#define bFGuard_Counter_DC_L 0xe00 573#define bFGuard_Counter_DC_L 0xe00
543#define bFrame_Weight_Short 0x7000 574#define bFrame_Weight_Short 0x7000
544#define bSub_Tune 0xe00000 575#define bSub_Tune 0xe00000
545#define bFrame_DC_Length 0xe000000 576#define bFrame_DC_Length 0xe000000
546#define bSBD_start_offset 0x30000000 577#define bSBD_start_offset 0x30000000
547#define bFrame_TH_2 0x7 578#define bFrame_TH_2 0x7
548#define bFrame_GI2_TH 0x38 579#define bFrame_GI2_TH 0x38
549#define bGI2_Sync_en 0x40 580#define bGI2_Sync_en 0x40
550#define bSarch_Short_Early 0x300 581#define bSarch_Short_Early 0x300
551#define bSarch_Short_Late 0xc00 582#define bSarch_Short_Late 0xc00
552#define bSarch_GI2_Late 0x70000 583#define bSarch_GI2_Late 0x70000
553#define bCFOAntSum 0x1 584#define bCFOAntSum 0x1
554#define bCFOAcc 0x2 585#define bCFOAcc 0x2
555#define bCFOStartOffset 0xc 586#define bCFOStartOffset 0xc
556#define bCFOLookBack 0x70 587#define bCFOLookBack 0x70
557#define bCFOSumWeight 0x80 588#define bCFOSumWeight 0x80
558#define bDAGCEnable 0x10000 589#define bDAGCEnable 0x10000
559#define bTXIQImb_A 0x3ff 590#define bTXIQImb_A 0x3ff
560#define bTXIQImb_B 0xfc00 591#define bTXIQImb_B 0xfc00
561#define bTXIQImb_C 0x3f0000 592#define bTXIQImb_C 0x3f0000
562#define bTXIQImb_D 0xffc00000 593#define bTXIQImb_D 0xffc00000
563#define bTxIDCOffset 0xff 594#define bTxIDCOffset 0xff
564#define bTxQDCOffset 0xff00 595#define bTxQDCOffset 0xff00
565#define bTxDFIRMode 0x10000 596#define bTxDFIRMode 0x10000
566#define bTxPesudoNoiseOn 0x4000000 597#define bTxPesudoNoiseOn 0x4000000
567#define bTxPesudoNoise_A 0xff 598#define bTxPesudoNoise_A 0xff
568#define bTxPesudoNoise_B 0xff00 599#define bTxPesudoNoise_B 0xff00
569#define bTxPesudoNoise_C 0xff0000 600#define bTxPesudoNoise_C 0xff0000
570#define bTxPesudoNoise_D 0xff000000 601#define bTxPesudoNoise_D 0xff000000
571#define bCCADropOption 0x20000 602#define bCCADropOption 0x20000
572#define bCCADropThres 0xfff00000 603#define bCCADropThres 0xfff00000
573#define bEDCCA_H 0xf 604#define bEDCCA_H 0xf
574#define bEDCCA_L 0xf0 605#define bEDCCA_L 0xf0
575#define bLambda_ED 0x300 606#define bLambda_ED 0x300
576#define bRxInitialGain 0x7f 607#define bRxInitialGain 0x7f
577#define bRxAntDivEn 0x80 608#define bRxAntDivEn 0x80
578#define bRxAGCAddressForLNA 0x7f00 609#define bRxAGCAddressForLNA 0x7f00
579#define bRxHighPowerFlow 0x8000 610#define bRxHighPowerFlow 0x8000
580#define bRxAGCFreezeThres 0xc0000 611#define bRxAGCFreezeThres 0xc0000
581#define bRxFreezeStep_AGC1 0x300000 612#define bRxFreezeStep_AGC1 0x300000
582#define bRxFreezeStep_AGC2 0xc00000 613#define bRxFreezeStep_AGC2 0xc00000
583#define bRxFreezeStep_AGC3 0x3000000 614#define bRxFreezeStep_AGC3 0x3000000
584#define bRxFreezeStep_AGC0 0xc000000 615#define bRxFreezeStep_AGC0 0xc000000
585#define bRxRssi_Cmp_En 0x10000000 616#define bRxRssi_Cmp_En 0x10000000
586#define bRxQuickAGCEn 0x20000000 617#define bRxQuickAGCEn 0x20000000
587#define bRxAGCFreezeThresMode 0x40000000 618#define bRxAGCFreezeThresMode 0x40000000
588#define bRxOverFlowCheckType 0x80000000 619#define bRxOverFlowCheckType 0x80000000
589#define bRxAGCShift 0x7f 620#define bRxAGCShift 0x7f
590#define bTRSW_Tri_Only 0x80 621#define bTRSW_Tri_Only 0x80
591#define bPowerThres 0x300 622#define bPowerThres 0x300
592#define bRxAGCEn 0x1 623#define bRxAGCEn 0x1
593#define bRxAGCTogetherEn 0x2 624#define bRxAGCTogetherEn 0x2
594#define bRxAGCMin 0x4 625#define bRxAGCMin 0x4
595#define bRxHP_Ini 0x7 626#define bRxHP_Ini 0x7
596#define bRxHP_TRLNA 0x70 627#define bRxHP_TRLNA 0x70
597#define bRxHP_RSSI 0x700 628#define bRxHP_RSSI 0x700
598#define bRxHP_BBP1 0x7000 629#define bRxHP_BBP1 0x7000
599#define bRxHP_BBP2 0x70000 630#define bRxHP_BBP2 0x70000
600#define bRxHP_BBP3 0x700000 631#define bRxHP_BBP3 0x700000
601#define bRSSI_H 0x7f0000 //the threshold for high power 632/* The threshold for high power */
602#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity 633#define bRSSI_H 0x7f0000
603#define bRxSettle_TRSW 0x7 634/* The threshold for ant diversity */
604#define bRxSettle_LNA 0x38 635#define bRSSI_Gen 0x7f000000
605#define bRxSettle_RSSI 0x1c0 636#define bRxSettle_TRSW 0x7
606#define bRxSettle_BBP 0xe00 637#define bRxSettle_LNA 0x38
607#define bRxSettle_RxHP 0x7000 638#define bRxSettle_RSSI 0x1c0
608#define bRxSettle_AntSW_RSSI 0x38000 639#define bRxSettle_BBP 0xe00
609#define bRxSettle_AntSW 0xc0000 640#define bRxSettle_RxHP 0x7000
610#define bRxProcessTime_DAGC 0x300000 641#define bRxSettle_AntSW_RSSI 0x38000
611#define bRxSettle_HSSI 0x400000 642#define bRxSettle_AntSW 0xc0000
612#define bRxProcessTime_BBPPW 0x800000 643#define bRxProcessTime_DAGC 0x300000
613#define bRxAntennaPowerShift 0x3000000 644#define bRxSettle_HSSI 0x400000
614#define bRSSITableSelect 0xc000000 645#define bRxProcessTime_BBPPW 0x800000
615#define bRxHP_Final 0x7000000 646#define bRxAntennaPowerShift 0x3000000
616#define bRxHTSettle_BBP 0x7 647#define bRSSITableSelect 0xc000000
617#define bRxHTSettle_HSSI 0x8 648#define bRxHP_Final 0x7000000
618#define bRxHTSettle_RxHP 0x70 649#define bRxHTSettle_BBP 0x7
619#define bRxHTSettle_BBPPW 0x80 650#define bRxHTSettle_HSSI 0x8
620#define bRxHTSettle_Idle 0x300 651#define bRxHTSettle_RxHP 0x70
621#define bRxHTSettle_Reserved 0x1c00 652#define bRxHTSettle_BBPPW 0x80
622#define bRxHTRxHPEn 0x8000 653#define bRxHTSettle_Idle 0x300
623#define bRxHTAGCFreezeThres 0x30000 654#define bRxHTSettle_Reserved 0x1c00
624#define bRxHTAGCTogetherEn 0x40000 655#define bRxHTRxHPEn 0x8000
625#define bRxHTAGCMin 0x80000 656#define bRxHTAGCFreezeThres 0x30000
626#define bRxHTAGCEn 0x100000 657#define bRxHTAGCTogetherEn 0x40000
627#define bRxHTDAGCEn 0x200000 658#define bRxHTAGCMin 0x80000
628#define bRxHTRxHP_BBP 0x1c00000 659#define bRxHTAGCEn 0x100000
629#define bRxHTRxHP_Final 0xe0000000 660#define bRxHTDAGCEn 0x200000
630#define bRxPWRatioTH 0x3 661#define bRxHTRxHP_BBP 0x1c00000
631#define bRxPWRatioEn 0x4 662#define bRxHTRxHP_Final 0xe0000000
632#define bRxMFHold 0x3800 663#define bRxPWRatioTH 0x3
633#define bRxPD_Delay_TH1 0x38 664#define bRxPWRatioEn 0x4
634#define bRxPD_Delay_TH2 0x1c0 665#define bRxMFHold 0x3800
635#define bRxPD_DC_COUNT_MAX 0x600 666#define bRxPD_Delay_TH1 0x38
636//#define bRxMF_Hold 0x3800 667#define bRxPD_Delay_TH2 0x1c0
668#define bRxPD_DC_COUNT_MAX 0x600
669/*#define bRxMF_Hold 0x3800*/
637#define bRxPD_Delay_TH 0x8000 670#define bRxPD_Delay_TH 0x8000
638#define bRxProcess_Delay 0xf0000 671#define bRxProcess_Delay 0xf0000
639#define bRxSearchrange_GI2_Early 0x700000 672#define bRxSearchrange_GI2_Early 0x700000
@@ -659,7 +692,7 @@
659 692
660#define bExtLNAGain 0x7c00 693#define bExtLNAGain 0x7c00
661 694
662//page d 695/* Page d */
663#define bSTBCEn 0x4 696#define bSTBCEn 0x4
664#define bAntennaMapping 0x10 697#define bAntennaMapping 0x10
665#define bNss 0x20 698#define bNss 0x20
@@ -669,12 +702,12 @@
669#define bOFDMContinueTx 0x10000000 702#define bOFDMContinueTx 0x10000000
670#define bOFDMSingleCarrier 0x20000000 703#define bOFDMSingleCarrier 0x20000000
671#define bOFDMSingleTone 0x40000000 704#define bOFDMSingleTone 0x40000000
672//#define bRxPath1 0x01 705/*#define bRxPath1 0x01
673//#define bRxPath2 0x02 706#define bRxPath2 0x02
674//#define bRxPath3 0x04 707#define bRxPath3 0x04
675//#define bRxPath4 0x08 708#define bRxPath4 0x08
676//#define bTxPath1 0x10 709#define bTxPath1 0x10
677//#define bTxPath2 0x20 710#define bTxPath2 0x20*/
678#define bHTDetect 0x100 711#define bHTDetect 0x100
679#define bCFOEn 0x10000 712#define bCFOEn 0x10000
680#define bCFOValue 0xfff00000 713#define bCFOValue 0xfff00000
@@ -687,8 +720,10 @@
687#define bCounter_MCSNoSupport 0xffff 720#define bCounter_MCSNoSupport 0xffff
688#define bCounter_FastSync 0xffff 721#define bCounter_FastSync 0xffff
689#define bShortCFO 0xfff 722#define bShortCFO 0xfff
690#define bShortCFOTLength 12 //total 723/* total */
691#define bShortCFOFLength 11 //fraction 724#define bShortCFOTLength 12
725/* fraction */
726#define bShortCFOFLength 11
692#define bLongCFO 0x7ff 727#define bLongCFO 0x7ff
693#define bLongCFOTLength 11 728#define bLongCFOTLength 11
694#define bLongCFOFLength 11 729#define bLongCFOFLength 11
@@ -765,18 +800,18 @@
765#define bUChCfg 0x7000000 800#define bUChCfg 0x7000000
766#define bUpdEqz 0x8000000 801#define bUpdEqz 0x8000000
767 802
768//page e 803/* Page e */
769#define bTxAGCRate18_06 0x7f7f7f7f 804#define bTxAGCRate18_06 0x7f7f7f7f
770#define bTxAGCRate54_24 0x7f7f7f7f 805#define bTxAGCRate54_24 0x7f7f7f7f
771#define bTxAGCRateMCS32 0x7f 806#define bTxAGCRateMCS32 0x7f
772#define bTxAGCRateCCK 0x7f00 807#define bTxAGCRateCCK 0x7f00
773#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f 808#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f
774#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f 809#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f
775#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f 810#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f
776#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f 811#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f
777 812
778 813
779//Rx Pseduo noise 814/* Rx Pseduo noise */
780#define bRxPesudoNoiseOn 0x20000000 815#define bRxPesudoNoiseOn 0x20000000
781#define bRxPesudoNoise_A 0xff 816#define bRxPesudoNoise_A 0xff
782#define bRxPesudoNoise_B 0xff00 817#define bRxPesudoNoise_B 0xff00
@@ -787,8 +822,7 @@
787#define bPesudoNoiseState_C 0xffff 822#define bPesudoNoiseState_C 0xffff
788#define bPesudoNoiseState_D 0xffff0000 823#define bPesudoNoiseState_D 0xffff0000
789 824
790//RF 825/* RF Zebra 1 */
791//Zebra1
792#define bZebra1_HSSIEnable 0x8 826#define bZebra1_HSSIEnable 0x8
793#define bZebra1_TRxControl 0xc00 827#define bZebra1_TRxControl 0xc00
794#define bZebra1_TRxGainSetting 0x07f 828#define bZebra1_TRxGainSetting 0x07f
@@ -799,7 +833,7 @@
799#define bZebra1_TxLPFBW 0x400 833#define bZebra1_TxLPFBW 0x400
800#define bZebra1_RxLPFBW 0x600 834#define bZebra1_RxLPFBW 0x600
801 835
802//Zebra4 836/* Zebra4 */
803#define bRTL8256RegModeCtrl1 0x100 837#define bRTL8256RegModeCtrl1 0x100
804#define bRTL8256RegModeCtrl0 0x40 838#define bRTL8256RegModeCtrl0 0x40
805#define bRTL8256_TxLPFBW 0x18 839#define bRTL8256_TxLPFBW 0x18
@@ -810,7 +844,7 @@
810#define bRTL8258_RxLPFBW 0xc00 844#define bRTL8258_RxLPFBW 0xc00
811#define bRTL8258_RSSILPFBW 0xc0 845#define bRTL8258_RSSILPFBW 0xc0
812 846
813//byte endable for sb_write 847/* byte endable for sb_write */
814#define bByte0 0x1 848#define bByte0 0x1
815#define bByte1 0x2 849#define bByte1 0x2
816#define bByte2 0x4 850#define bByte2 0x4
@@ -819,7 +853,7 @@
819#define bWord1 0xc 853#define bWord1 0xc
820#define bDWord 0xf 854#define bDWord 0xf
821 855
822//for PutRegsetting & GetRegSetting BitMask 856/* for PutRegsetting & GetRegSetting BitMask */
823#define bMaskByte0 0xff 857#define bMaskByte0 0xff
824#define bMaskByte1 0xff00 858#define bMaskByte1 0xff00
825#define bMaskByte2 0xff0000 859#define bMaskByte2 0xff0000
@@ -828,7 +862,7 @@
828#define bMaskLWord 0x0000ffff 862#define bMaskLWord 0x0000ffff
829#define bMaskDWord 0xffffffff 863#define bMaskDWord 0xffffffff
830 864
831//for PutRFRegsetting & GetRFRegSetting BitMask 865/* for PutRFRegsetting & GetRFRegSetting BitMask */
832#define bMask12Bits 0xfff 866#define bMask12Bits 0xfff
833 867
834#define bEnable 0x1 868#define bEnable 0x1
@@ -837,14 +871,16 @@
837#define LeftAntenna 0x0 871#define LeftAntenna 0x0
838#define RightAntenna 0x1 872#define RightAntenna 0x1
839 873
840#define tCheckTxStatus 500 //500ms 874/* 500 ms */
841#define tUpdateRxCounter 100 //100ms 875#define tCheckTxStatus 500
876/* 100 ms */
877#define tUpdateRxCounter 100
842 878
843#define rateCCK 0 879#define rateCCK 0
844#define rateOFDM 1 880#define rateOFDM 1
845#define rateHT 2 881#define rateHT 2
846 882
847//define Register-End 883/* define Register-End */
848#define bPMAC_End 0x1ff 884#define bPMAC_End 0x1ff
849#define bFPGAPHY0_End 0x8ff 885#define bFPGAPHY0_End 0x8ff
850#define bFPGAPHY1_End 0x9ff 886#define bFPGAPHY1_End 0x9ff
@@ -852,12 +888,12 @@
852#define bOFDMPHY0_End 0xcff 888#define bOFDMPHY0_End 0xcff
853#define bOFDMPHY1_End 0xdff 889#define bOFDMPHY1_End 0xdff
854 890
855//define max debug item in each debug page 891/*#define max debug item in each debug page
856//#define bMaxItem_FPGA_PHY0 0x9 892#define bMaxItem_FPGA_PHY0 0x9
857//#define bMaxItem_FPGA_PHY1 0x3 893#define bMaxItem_FPGA_PHY1 0x3
858//#define bMaxItem_PHY_11B 0x16 894#define bMaxItem_PHY_11B 0x16
859//#define bMaxItem_OFDM_PHY0 0x29 895#define bMaxItem_OFDM_PHY0 0x29
860//#define bMaxItem_OFDM_PHY1 0x0 896#define bMaxItem_OFDM_PHY1 0x0 */
861 897
862#define bPMACControl 0x0 898#define bPMACControl 0x0
863#define bWMACControl 0x1 899#define bWMACControl 0x1
@@ -868,11 +904,12 @@
868#define PathC 0x2 904#define PathC 0x2
869#define PathD 0x3 905#define PathD 0x3
870 906
871#define rRTL8256RxMixerPole 0xb 907#define rRTL8256RxMixerPole 0xb
872#define bZebraRxMixerPole 0x6 908#define bZebraRxMixerPole 0x6
873#define rRTL8256TxBBOPBias 0x9 909#define rRTL8256TxBBOPBias 0x9
874#define bRTL8256TxBBOPBias 0x400 910#define bRTL8256TxBBOPBias 0x400
875#define rRTL8256TxBBBW 19 911#define rRTL8256TxBBBW 19
876#define bRTL8256TxBBBW 0x18 912#define bRTL8256TxBBBW 0x18
913
877 914
878#endif //__INC_HAL8190PCIPHYREG_H 915#endif /* __INC_HAL8190PCIPHYREG_H */
diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig
index 123fa6d6a93b..b72a96206f58 100644
--- a/drivers/staging/rtl8192su/Kconfig
+++ b/drivers/staging/rtl8192su/Kconfig
@@ -1,6 +1,7 @@
1config RTL8192SU 1config RTL8192SU
2 tristate "RealTek RTL8192SU Wireless LAN NIC driver" 2 tristate "RealTek RTL8192SU Wireless LAN NIC driver"
3 depends on PCI && WLAN && USB 3 depends on PCI && WLAN && USB
4 depends on WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV
5 default N 6 default N
6 ---help--- 7 ---help---
diff --git a/drivers/staging/rtl8192su/TODO b/drivers/staging/rtl8192su/TODO
index f11eec700030..3c8da157a93c 100644
--- a/drivers/staging/rtl8192su/TODO
+++ b/drivers/staging/rtl8192su/TODO
@@ -4,7 +4,6 @@ TODO:
4 - cleanup ieee80211.h 4 - cleanup ieee80211.h
5 - move rtl8192su's specific code out from ieee80211.h 5 - move rtl8192su's specific code out from ieee80211.h
6 - abstract rtl819su's specific code 6 - abstract rtl819su's specific code
7 - use list_for_each_safe() in ieee80211_crypto_deinit
8- switch to use shared "librtl" instead of private ieee80211 stack 7- switch to use shared "librtl" instead of private ieee80211 stack
9- switch to use LIB80211 8- switch to use LIB80211
10- switch to use MAC80211 9- switch to use MAC80211
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
index 2b8c85556dcb..32b261d15594 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
@@ -30,6 +30,7 @@
30#include <linux/jiffies.h> 30#include <linux/jiffies.h>
31#include <linux/timer.h> 31#include <linux/timer.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/semaphore.h>
33 34
34#include <linux/delay.h> 35#include <linux/delay.h>
35#include <linux/wireless.h> 36#include <linux/wireless.h>
@@ -195,10 +196,6 @@ extern u32 ieee80211_debug_level;
195#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0) 196#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
196#endif /* CONFIG_IEEE80211_DEBUG */ 197#endif /* CONFIG_IEEE80211_DEBUG */
197 198
198#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
199#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
200 ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
201
202/* 199/*
203 * To use the debug system; 200 * To use the debug system;
204 * 201 *
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
index 521e7b989934..c4640e63196b 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
@@ -226,19 +226,20 @@ out:
226void __exit ieee80211_crypto_deinit(void) 226void __exit ieee80211_crypto_deinit(void)
227{ 227{
228 struct list_head *ptr, *n; 228 struct list_head *ptr, *n;
229 struct ieee80211_crypto_alg *alg = NULL;
229 230
230 if (hcrypt == NULL) 231 if (hcrypt == NULL)
231 return; 232 return;
232 233
233 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; 234 list_for_each_safe(ptr, n, &hcrypt->algs) {
234 ptr = n, n = ptr->next) { 235 alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
235 struct ieee80211_crypto_alg *alg = 236 if (alg) {
236 (struct ieee80211_crypto_alg *) ptr; 237 list_del(ptr);
237 list_del(ptr); 238 printk(KERN_DEBUG
238 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " 239 "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
239 "'%s' (deinit)\n", alg->ops->name); 240 alg->ops->name);
240 kfree(alg); 241 kfree(alg);
242 }
241 } 243 }
242
243 kfree(hcrypt); 244 kfree(hcrypt);
244} 245}
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
index 7bc956e1f458..8a93f7d3eb38 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
@@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
288 if (!(keyidx & (1 << 5))) { 288 if (!(keyidx & (1 << 5))) {
289 if (net_ratelimit()) { 289 if (net_ratelimit()) {
290 printk(KERN_DEBUG "CCMP: received packet without ExtIV" 290 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
291 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 291 " flag from %pM\n", hdr->addr2);
292 } 292 }
293 key->dot11RSNAStatsCCMPFormatErrors++; 293 key->dot11RSNAStatsCCMPFormatErrors++;
294 return -2; 294 return -2;
@@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
301 } 301 }
302 if (!key->key_set) { 302 if (!key->key_set) {
303 if (net_ratelimit()) { 303 if (net_ratelimit()) {
304 printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT 304 printk(KERN_DEBUG "CCMP: received packet from %pM"
305 " with keyid=%d that does not have a configured" 305 " with keyid=%d that does not have a configured"
306 " key\n", MAC_ARG(hdr->addr2), keyidx); 306 " key\n", hdr->addr2, keyidx);
307 } 307 }
308 return -3; 308 return -3;
309 } 309 }
@@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
318 318
319 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { 319 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
320 if (net_ratelimit()) { 320 if (net_ratelimit()) {
321 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT 321 printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
322 " previous PN %02x%02x%02x%02x%02x%02x " 322 " previous PN %pm received PN %pm\n",
323 "received PN %02x%02x%02x%02x%02x%02x\n", 323 hdr->addr2, key->rx_pn, pn);
324 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
325 MAC_ARG(pn));
326 } 324 }
327 key->dot11RSNAStatsCCMPReplays++; 325 key->dot11RSNAStatsCCMPReplays++;
328 return -4; 326 return -4;
@@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
359 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { 357 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
360 if (net_ratelimit()) { 358 if (net_ratelimit()) {
361 printk(KERN_DEBUG "CCMP: decrypt failed: STA=" 359 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
362 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 360 "%pM\n", hdr->addr2);
363 } 361 }
364 key->dot11RSNAStatsCCMPDecryptErrors++; 362 key->dot11RSNAStatsCCMPDecryptErrors++;
365 return -5; 363 return -5;
@@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
435{ 433{
436 struct ieee80211_ccmp_data *ccmp = priv; 434 struct ieee80211_ccmp_data *ccmp = priv;
437 p += sprintf(p, "key[%d] alg=CCMP key_set=%d " 435 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
438 "tx_pn=%02x%02x%02x%02x%02x%02x " 436 "tx_pn=%pm rx_pn=%pm "
439 "rx_pn=%02x%02x%02x%02x%02x%02x "
440 "format_errors=%d replays=%d decrypt_errors=%d\n", 437 "format_errors=%d replays=%d decrypt_errors=%d\n",
441 ccmp->key_idx, ccmp->key_set, 438 ccmp->key_idx, ccmp->key_set,
442 MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), 439 ccmp->tx_pn, ccmp->rx_pn,
443 ccmp->dot11RSNAStatsCCMPFormatErrors, 440 ccmp->dot11RSNAStatsCCMPFormatErrors,
444 ccmp->dot11RSNAStatsCCMPReplays, 441 ccmp->dot11RSNAStatsCCMPReplays,
445 ccmp->dot11RSNAStatsCCMPDecryptErrors); 442 ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
index 9b9438fb5f60..7e48748da102 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
@@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
410 if (!(keyidx & (1 << 5))) { 410 if (!(keyidx & (1 << 5))) {
411 if (net_ratelimit()) { 411 if (net_ratelimit()) {
412 printk(KERN_DEBUG "TKIP: received packet without ExtIV" 412 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
413 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 413 " flag from %pM\n", hdr->addr2);
414 } 414 }
415 return -2; 415 return -2;
416 } 416 }
@@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
422 } 422 }
423 if (!tkey->key_set) { 423 if (!tkey->key_set) {
424 if (net_ratelimit()) { 424 if (net_ratelimit()) {
425 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT 425 printk(KERN_DEBUG "TKIP: received packet from %pM"
426 " with keyid=%d that does not have a configured" 426 " with keyid=%d that does not have a configured"
427 " key\n", MAC_ARG(hdr->addr2), keyidx); 427 " key\n", hdr->addr2, keyidx);
428 } 428 }
429 return -3; 429 return -3;
430 } 430 }
@@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
437 if (iv32 < tkey->rx_iv32 || 437 if (iv32 < tkey->rx_iv32 ||
438 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { 438 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
439 if (net_ratelimit()) { 439 if (net_ratelimit()) {
440 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT 440 printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
441 " previous TSC %08x%04x received TSC " 441 " previous TSC %08x%04x received TSC "
442 "%08x%04x\n", MAC_ARG(hdr->addr2), 442 "%08x%04x\n", hdr->addr2,
443 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); 443 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
444 } 444 }
445 tkey->dot11RSNAStatsTKIPReplays++; 445 tkey->dot11RSNAStatsTKIPReplays++;
@@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
460 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { 460 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
461 if (net_ratelimit()) { 461 if (net_ratelimit()) {
462 printk(KERN_DEBUG ": TKIP: failed to decrypt " 462 printk(KERN_DEBUG ": TKIP: failed to decrypt "
463 "received packet from " MAC_FMT "\n", 463 "received packet from %pM\n",
464 MAC_ARG(hdr->addr2)); 464 hdr->addr2);
465 } 465 }
466 return -7; 466 return -7;
467 } 467 }
@@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
480 } 480 }
481 if (net_ratelimit()) { 481 if (net_ratelimit()) {
482 printk(KERN_DEBUG "TKIP: ICV error detected: STA=" 482 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
483 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 483 "%pM\n", hdr->addr2);
484 } 484 }
485 tkey->dot11RSNAStatsTKIPICVErrors++; 485 tkey->dot11RSNAStatsTKIPICVErrors++;
486 return -5; 486 return -5;
@@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
635 struct ieee80211_hdr_4addr *hdr; 635 struct ieee80211_hdr_4addr *hdr;
636 hdr = (struct ieee80211_hdr_4addr *) skb->data; 636 hdr = (struct ieee80211_hdr_4addr *) skb->data;
637 printk(KERN_DEBUG "%s: Michael MIC verification failed for " 637 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
638 "MSDU from " MAC_FMT " keyidx=%d\n", 638 "MSDU from %pM keyidx=%d\n",
639 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), 639 skb->dev ? skb->dev->name : "N/A", hdr->addr2,
640 keyidx); 640 keyidx);
641 if (skb->dev) 641 if (skb->dev)
642 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); 642 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
index e8c67d5dfb76..c024fa600729 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
@@ -262,7 +262,7 @@ static int store_debug_level(struct file *file, const char *buffer,
262 unsigned long count, void *data) 262 unsigned long count, void *data)
263{ 263{
264 char buf[] = "0x00000000"; 264 char buf[] = "0x00000000";
265 unsigned long len = min(sizeof(buf) - 1, count); 265 unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
266 char *p = (char *)buf; 266 char *p = (char *)buf;
267 unsigned long val; 267 unsigned long val;
268 268
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
index 095b8c643146..cc80faf6598b 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
@@ -314,8 +314,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
314 strcmp(crypt->ops->name, "TKIP") == 0) { 314 strcmp(crypt->ops->name, "TKIP") == 0) {
315 if (net_ratelimit()) { 315 if (net_ratelimit()) {
316 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 316 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
317 "received packet from " MAC_FMT "\n", 317 "received packet from %pM\n",
318 ieee->dev->name, MAC_ARG(hdr->addr2)); 318 ieee->dev->name, hdr->addr2);
319 } 319 }
320 return -1; 320 return -1;
321 } 321 }
@@ -326,8 +326,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
326 atomic_dec(&crypt->refcnt); 326 atomic_dec(&crypt->refcnt);
327 if (res < 0) { 327 if (res < 0) {
328 IEEE80211_DEBUG_DROP( 328 IEEE80211_DEBUG_DROP(
329 "decryption failed (SA=" MAC_FMT 329 "decryption failed (SA=%pM"
330 ") res=%d\n", MAC_ARG(hdr->addr2), res); 330 ") res=%d\n", hdr->addr2, res);
331 if (res == -2) 331 if (res == -2)
332 IEEE80211_DEBUG_DROP("Decryption failed ICV " 332 IEEE80211_DEBUG_DROP("Decryption failed ICV "
333 "mismatch (key %d)\n", 333 "mismatch (key %d)\n",
@@ -364,8 +364,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
364 atomic_dec(&crypt->refcnt); 364 atomic_dec(&crypt->refcnt);
365 if (res < 0) { 365 if (res < 0) {
366 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" 366 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
367 " (SA=" MAC_FMT " keyidx=%d)\n", 367 " (SA=%pM keyidx=%d)\n",
368 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); 368 ieee->dev->name, hdr->addr2, keyidx);
369 return -1; 369 return -1;
370 } 370 }
371 371
@@ -939,8 +939,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
939 * frames silently instead of filling system log with 939 * frames silently instead of filling system log with
940 * these reports. */ 940 * these reports. */
941 IEEE80211_DEBUG_DROP("Decryption failed (not set)" 941 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
942 " (SA=" MAC_FMT ")\n", 942 " (SA=%pM)\n",
943 MAC_ARG(hdr->addr2)); 943 hdr->addr2);
944 ieee->ieee_stats.rx_discards_undecryptable++; 944 ieee->ieee_stats.rx_discards_undecryptable++;
945 goto rx_dropped; 945 goto rx_dropped;
946 } 946 }
@@ -1143,8 +1143,8 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1143 } else { 1143 } else {
1144 IEEE80211_DEBUG_DROP( 1144 IEEE80211_DEBUG_DROP(
1145 "encryption configured, but RX " 1145 "encryption configured, but RX "
1146 "frame not encrypted (SA=" MAC_FMT ")\n", 1146 "frame not encrypted (SA=%pM)\n",
1147 MAC_ARG(hdr->addr2)); 1147 hdr->addr2);
1148 goto rx_dropped; 1148 goto rx_dropped;
1149 } 1149 }
1150 } 1150 }
@@ -1163,9 +1163,9 @@ int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1163 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { 1163 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
1164 IEEE80211_DEBUG_DROP( 1164 IEEE80211_DEBUG_DROP(
1165 "dropped unencrypted RX data " 1165 "dropped unencrypted RX data "
1166 "frame from " MAC_FMT 1166 "frame from %pM"
1167 " (drop_unencrypted=1)\n", 1167 " (drop_unencrypted=1)\n",
1168 MAC_ARG(hdr->addr2)); 1168 hdr->addr2);
1169 goto rx_dropped; 1169 goto rx_dropped;
1170 } 1170 }
1171/* 1171/*
@@ -2159,11 +2159,11 @@ static inline int ieee80211_network_init(
2159 } 2159 }
2160 2160
2161 if (network->mode == 0) { 2161 if (network->mode == 0) {
2162 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " 2162 IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
2163 "network.\n", 2163 "network.\n",
2164 escape_essid(network->ssid, 2164 escape_essid(network->ssid,
2165 network->ssid_len), 2165 network->ssid_len),
2166 MAC_ARG(network->bssid)); 2166 network->bssid);
2167 return 1; 2167 return 1;
2168 } 2168 }
2169 2169
@@ -2345,9 +2345,9 @@ static inline void ieee80211_process_probe_response(
2345 2345
2346 memset(&network, 0, sizeof(struct ieee80211_network)); 2346 memset(&network, 0, sizeof(struct ieee80211_network));
2347 IEEE80211_DEBUG_SCAN( 2347 IEEE80211_DEBUG_SCAN(
2348 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", 2348 "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
2349 escape_essid(info_element->data, info_element->len), 2349 escape_essid(info_element->data, info_element->len),
2350 MAC_ARG(beacon->header.addr3), 2350 beacon->header.addr3,
2351 (beacon->capability & (1<<0xf)) ? '1' : '0', 2351 (beacon->capability & (1<<0xf)) ? '1' : '0',
2352 (beacon->capability & (1<<0xe)) ? '1' : '0', 2352 (beacon->capability & (1<<0xe)) ? '1' : '0',
2353 (beacon->capability & (1<<0xd)) ? '1' : '0', 2353 (beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2366,10 +2366,10 @@ static inline void ieee80211_process_probe_response(
2366 (beacon->capability & (1<<0x0)) ? '1' : '0'); 2366 (beacon->capability & (1<<0x0)) ? '1' : '0');
2367 2367
2368 if (ieee80211_network_init(ieee, beacon, &network, stats)) { 2368 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
2369 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", 2369 IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
2370 escape_essid(info_element->data, 2370 escape_essid(info_element->data,
2371 info_element->len), 2371 info_element->len),
2372 MAC_ARG(beacon->header.addr3), 2372 beacon->header.addr3,
2373 WLAN_FC_GET_STYPE(beacon->header.frame_control) == 2373 WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
2374 IEEE80211_STYPE_PROBE_RESP ? 2374 IEEE80211_STYPE_PROBE_RESP ?
2375 "PROBE RESPONSE" : "BEACON"); 2375 "PROBE RESPONSE" : "BEACON");
@@ -2478,11 +2478,11 @@ static inline void ieee80211_process_probe_response(
2478 /* If there are no more slots, expire the oldest */ 2478 /* If there are no more slots, expire the oldest */
2479 list_del(&oldest->list); 2479 list_del(&oldest->list);
2480 target = oldest; 2480 target = oldest;
2481 IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " 2481 IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
2482 "network list.\n", 2482 "network list.\n",
2483 escape_essid(target->ssid, 2483 escape_essid(target->ssid,
2484 target->ssid_len), 2484 target->ssid_len),
2485 MAC_ARG(target->bssid)); 2485 target->bssid);
2486 } else { 2486 } else {
2487 /* Otherwise just pull from the free list */ 2487 /* Otherwise just pull from the free list */
2488 target = list_entry(ieee->network_free_list.next, 2488 target = list_entry(ieee->network_free_list.next,
@@ -2492,10 +2492,10 @@ static inline void ieee80211_process_probe_response(
2492 2492
2493 2493
2494#ifdef CONFIG_IEEE80211_DEBUG 2494#ifdef CONFIG_IEEE80211_DEBUG
2495 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", 2495 IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
2496 escape_essid(network.ssid, 2496 escape_essid(network.ssid,
2497 network.ssid_len), 2497 network.ssid_len),
2498 MAC_ARG(network.bssid), 2498 network.bssid,
2499 WLAN_FC_GET_STYPE(beacon->header.frame_control) == 2499 WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
2500 IEEE80211_STYPE_PROBE_RESP ? 2500 IEEE80211_STYPE_PROBE_RESP ?
2501 "PROBE RESPONSE" : "BEACON"); 2501 "PROBE RESPONSE" : "BEACON");
@@ -2505,10 +2505,10 @@ static inline void ieee80211_process_probe_response(
2505 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) 2505 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
2506 ieee80211_softmac_new_net(ieee,&network); 2506 ieee80211_softmac_new_net(ieee,&network);
2507 } else { 2507 } else {
2508 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", 2508 IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
2509 escape_essid(target->ssid, 2509 escape_essid(target->ssid,
2510 target->ssid_len), 2510 target->ssid_len),
2511 MAC_ARG(target->bssid), 2511 target->bssid,
2512 WLAN_FC_GET_STYPE(beacon->header.frame_control) == 2512 WLAN_FC_GET_STYPE(beacon->header.frame_control) ==
2513 IEEE80211_STYPE_PROBE_RESP ? 2513 IEEE80211_STYPE_PROBE_RESP ?
2514 "PROBE RESPONSE" : "BEACON"); 2514 "PROBE RESPONSE" : "BEACON");
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
index 0ba2a01a06a1..9d8cb0e575d3 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
@@ -1709,7 +1709,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1709 ieee80211_resp_to_assoc_rq(ieee, dest); 1709 ieee80211_resp_to_assoc_rq(ieee, dest);
1710 } 1710 }
1711 1711
1712 printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); 1712 printk(KERN_INFO"New client associated: %pM\n", dest);
1713 //FIXME 1713 //FIXME
1714} 1714}
1715 1715
@@ -2145,8 +2145,8 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
2145 ieee80211_sta_wakeup(ieee,0); 2145 ieee80211_sta_wakeup(ieee,0);
2146 2146
2147 /* update the tx status */ 2147 /* update the tx status */
2148// ieee->stats.tx_bytes += txb->payload_size; 2148 ieee->stats.tx_bytes += txb->payload_size;
2149// ieee->stats.tx_packets++; 2149 ieee->stats.tx_packets++;
2150 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); 2150 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2151 if(tcb_desc->bMulticast) { 2151 if(tcb_desc->bMulticast) {
2152 ieee->stats.multicast++; 2152 ieee->stats.multicast++;
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
index 4d54e1e62d22..484c3aba5cb3 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
@@ -199,8 +199,8 @@ int ieee80211_encrypt_fragment(
199 header = (struct rtl_ieee80211_hdr *)frag->data; 199 header = (struct rtl_ieee80211_hdr *)frag->data;
200 if (net_ratelimit()) { 200 if (net_ratelimit()) {
201 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 201 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
202 "TX packet to " MAC_FMT "\n", 202 "TX packet to %pM\n",
203 ieee->dev->name, MAC_ARG(header->addr1)); 203 ieee->dev->name, header->addr1);
204 } 204 }
205 return -1; 205 return -1;
206 } 206 }
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
index 85c7e96b622d..122f8004904b 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
@@ -261,10 +261,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
261 else 261 else
262 IEEE80211_DEBUG_SCAN( 262 IEEE80211_DEBUG_SCAN(
263 "Not showing network '%s (" 263 "Not showing network '%s ("
264 MAC_FMT ")' due to age (%lums).\n", 264 "%pM)' due to age (%lums).\n",
265 escape_essid(network->ssid, 265 escape_essid(network->ssid,
266 network->ssid_len), 266 network->ssid_len),
267 MAC_ARG(network->bssid), 267 network->bssid,
268 (jiffies - network->last_scanned) / (HZ / 100)); 268 (jiffies - network->last_scanned) / (HZ / 100));
269 } 269 }
270 270
@@ -731,7 +731,7 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
731#if 1 731#if 1
732 case IW_AUTH_WPA_ENABLED: 732 case IW_AUTH_WPA_ENABLED:
733 ieee->wpa_enabled = (data->value)?1:0; 733 ieee->wpa_enabled = (data->value)?1:0;
734 //printk("enalbe wpa:%d\n", ieee->wpa_enabled); 734 //printk("enable wpa:%d\n", ieee->wpa_enabled);
735 break; 735 break;
736 736
737#endif 737#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
index c6962450e06f..8c37dd124fc9 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
113 u16 tmp = 0; 113 u16 tmp = 0;
114 u16 len = ieee->tx_headroom + 9; 114 u16 len = ieee->tx_headroom + 9;
115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) 115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
116 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev); 116 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
117 if (pBA == NULL||ieee == NULL) 117 if (pBA == NULL||ieee == NULL)
118 { 118 {
119 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); 119 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -200,7 +200,7 @@ static struct sk_buff* ieee80211_DELBA(
200 u16 len = 6 + ieee->tx_headroom; 200 u16 len = 6 + ieee->tx_headroom;
201 201
202 if (net_ratelimit()) 202 if (net_ratelimit())
203 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst)); 203 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
204 204
205 memset(&DelbaParamSet, 0, 2); 205 memset(&DelbaParamSet, 0, 2);
206 206
@@ -339,7 +339,10 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
339 339
340 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) 340 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
341 { 341 {
342 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); 342 IEEE80211_DEBUG(IEEE80211_DL_ERR,
343 " Invalid skb len in BAREQ(%d / %zd)\n",
344 skb->len,
345 sizeof(struct ieee80211_hdr_3addr) + 9);
343 return -1; 346 return -1;
344 } 347 }
345 348
@@ -354,7 +357,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
354 pBaTimeoutVal = (u16*)(tag + 5); 357 pBaTimeoutVal = (u16*)(tag + 5);
355 pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); 358 pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
356 359
357 printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); 360 printk("====================>rx ADDBAREQ from :%pM\n", dst);
358//some other capability is not ready now. 361//some other capability is not ready now.
359 if( (ieee->current_network.qos_data.active == 0) || 362 if( (ieee->current_network.qos_data.active == 0) ||
360 (ieee->pHTInfo->bCurrentHTSupport == false) || 363 (ieee->pHTInfo->bCurrentHTSupport == false) ||
@@ -440,7 +443,10 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
440 443
441 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) 444 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
442 { 445 {
443 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); 446 IEEE80211_DEBUG(IEEE80211_DL_ERR,
447 " Invalid skb len in BARSP(%d / %zd)\n",
448 skb->len,
449 sizeof(struct ieee80211_hdr_3addr) + 9);
444 return -1; 450 return -1;
445 } 451 }
446 rsp = ( struct ieee80211_hdr_3addr*)skb->data; 452 rsp = ( struct ieee80211_hdr_3addr*)skb->data;
@@ -570,7 +576,10 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
570 576
571 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) 577 if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
572 { 578 {
573 IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %ld)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); 579 IEEE80211_DEBUG(IEEE80211_DL_ERR,
580 " Invalid skb len in DELBA(%d / %zd)\n",
581 skb->len,
582 sizeof(struct ieee80211_hdr_3addr) + 6);
574 return -1; 583 return -1;
575 } 584 }
576 585
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
index 33c7fa7edc8b..01114c5181bb 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
@@ -42,7 +42,7 @@ static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
42static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91}; 42static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
43static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; 43static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
44static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; 44static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
45// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the 45// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
46// code in other place?? 46// code in other place??
47//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; 47//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
48/******************************************************************************************************************** 48/********************************************************************************************************************
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
index ad3bf35d80e6..60cf1f8781ce 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
@@ -291,7 +291,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8
291 if(search_dir[dir] ==false ) 291 if(search_dir[dir] ==false )
292 continue; 292 continue;
293 list_for_each_entry(pRet, psearch_list, List){ 293 list_for_each_entry(pRet, psearch_list, List){
294 // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); 294 // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
295 if (memcmp(pRet->Addr, Addr, 6) == 0) 295 if (memcmp(pRet->Addr, Addr, 6) == 0)
296 if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) 296 if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
297 if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) 297 if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -447,7 +447,7 @@ bool GetTs(
447 ResetRxTsEntry(tmp); 447 ResetRxTsEntry(tmp);
448 } 448 }
449 449
450 IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr)); 450 IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
451 // Prepare TS Info releated field 451 // Prepare TS Info releated field
452 pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field 452 pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
453 pTSInfo->field.ucTSID = UP; // TSID 453 pTSInfo->field.ucTSID = UP; // TSID
@@ -533,7 +533,7 @@ void RemoveTsEntry(
533void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) 533void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
534{ 534{
535 PTS_COMMON_INFO pTS, pTmpTS; 535 PTS_COMMON_INFO pTS, pTmpTS;
536 printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr)); 536 printk("===========>RemovePeerTS,%pM\n", Addr);
537#if 1 537#if 1
538 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) 538 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
539 { 539 {
diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.c b/drivers/staging/rtl8192su/r8192SU_HWImg.c
index cbb65795a302..ba8e12c209ca 100644
--- a/drivers/staging/rtl8192su/r8192SU_HWImg.c
+++ b/drivers/staging/rtl8192su/r8192SU_HWImg.c
@@ -2,4282 +2,6 @@
2 2
3#include "r8192SU_HWImg.h" 3#include "r8192SU_HWImg.h"
4 4
5u8 Rtl8192SUFwImgArray[ImgArrayLength] = {
60x92,0x81,0x2b,0x90,0x30,0x00,0x00,0x00,0x08,0x74,0x00,0x00,0x88,0x96,0x00,0x00,
70x30,0x00,0x00,0x00,0x00,0x95,0x00,0x00,0x00,0x00,0x2b,0x00,0x03,0x03,0x23,0x00,
80x92,0x81,0x02,0x01,0x00,0x00,0x12,0x04,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
90x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x00,
100x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110x7f,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
140x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
160x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
180x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
190x1f,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
200x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
210x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
220x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
230x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
240x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
250x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
260x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
270x25,0xb0,0x1a,0x3c,0x80,0x03,0x5a,0x37,0x00,0x80,0x1b,0x3c,0x80,0x00,0x7b,0x37,
280x00,0x00,0x5b,0xaf,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x37,0x00,0x80,0x1b,0x3c,
290x80,0x00,0x7b,0x37,0x00,0x00,0x5b,0xaf,0x00,0x80,0x1a,0x3c,0x10,0x6d,0x5a,0x27,
300x08,0x00,0x40,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
310x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
320x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
330x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
340x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
350x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
360x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
370x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
380x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
390x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
400x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
410x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
420x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
430x04,0x00,0xa1,0xaf,0x08,0x00,0xa2,0xaf,0x0c,0x00,0xa3,0xaf,0x10,0x00,0xa4,0xaf,
440x14,0x00,0xa5,0xaf,0x18,0x00,0xa6,0xaf,0x1c,0x00,0xa7,0xaf,0x20,0x00,0xa8,0xaf,
450x24,0x00,0xa9,0xaf,0x28,0x00,0xaa,0xaf,0x2c,0x00,0xab,0xaf,0x30,0x00,0xac,0xaf,
460x34,0x00,0xad,0xaf,0x38,0x00,0xae,0xaf,0x3c,0x00,0xaf,0xaf,0x12,0x40,0x00,0x00,
470x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0xb0,0xaf,0x44,0x00,0xb1,0xaf,
480x48,0x00,0xb2,0xaf,0x4c,0x00,0xb3,0xaf,0x50,0x00,0xb4,0xaf,0x54,0x00,0xb5,0xaf,
490x58,0x00,0xb6,0xaf,0x5c,0x00,0xb7,0xaf,0x60,0x00,0xb8,0xaf,0x64,0x00,0xb9,0xaf,
500x68,0x00,0xbc,0xaf,0x6c,0x00,0xbd,0xaf,0x70,0x00,0xbe,0xaf,0x74,0x00,0xbf,0xaf,
510x78,0x00,0xa8,0xaf,0x7c,0x00,0xa9,0xaf,0x80,0x00,0xaa,0xaf,0xdf,0x1a,0x00,0x08,
520x21,0x20,0xa0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
530x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
540x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
550x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
560x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
570x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
580x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
590x25,0xb0,0x06,0x3c,0x00,0x80,0x02,0x3c,0xe8,0xff,0xbd,0x27,0x18,0x03,0xc3,0x34,
600x00,0x03,0x42,0x24,0x14,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x62,0xac,
610x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x42,0xb0,0x03,0x3c,
620x03,0x00,0x63,0x34,0x00,0x00,0x62,0x90,0x02,0x80,0x0a,0x3c,0x02,0x80,0x10,0x3c,
630xff,0x00,0x42,0x30,0x00,0x46,0x02,0x00,0x10,0x00,0x42,0x30,0x13,0x00,0x40,0x10,
640x03,0x46,0x08,0x00,0xc4,0x7d,0x42,0x8d,0x68,0x15,0x05,0x26,0xd4,0x63,0xa4,0x94,
650x01,0x00,0x47,0x24,0x10,0x00,0x02,0x24,0xb0,0x03,0xc9,0x34,0x00,0x00,0x62,0xa0,
660x07,0x00,0x80,0x10,0x1c,0x03,0xc6,0x34,0xd8,0x63,0xa2,0x8c,0xd4,0x63,0xa0,0xa4,
670xd8,0x63,0xa0,0xac,0x00,0x00,0x04,0x24,0x00,0x00,0xc2,0xac,0x00,0x00,0x20,0xad,
680x01,0x00,0x82,0x24,0xc4,0x7d,0x47,0xad,0xd4,0x63,0xa2,0xa4,0x12,0x00,0x00,0x05,
690x42,0xb0,0x02,0x3c,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
700x00,0x60,0x81,0x40,0x68,0x15,0x04,0x26,0x0c,0x4b,0x83,0x94,0x08,0x4b,0x85,0x94,
710x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x80,0x00,0x63,0x30,0x41,0xb0,0x02,0x3c,
720x25,0x18,0x65,0x00,0x08,0x00,0x42,0x34,0x18,0x00,0xbd,0x27,0x00,0x00,0x43,0xa4,
730x08,0x00,0xe0,0x03,0x08,0x4b,0x83,0xa4,0x80,0xff,0x03,0x24,0x03,0x00,0x42,0x34,
740x00,0x00,0x43,0xa0,0xc8,0x0e,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,
750x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0x04,0x26,
760x0c,0x4b,0x83,0x94,0x08,0x4b,0x85,0x94,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,
770x80,0x00,0x63,0x30,0x41,0xb0,0x02,0x3c,0x25,0x18,0x65,0x00,0x08,0x00,0x42,0x34,
780x18,0x00,0xbd,0x27,0x00,0x00,0x43,0xa4,0x08,0x00,0xe0,0x03,0x08,0x4b,0x83,0xa4,
790xff,0x00,0x84,0x30,0x0b,0x00,0x82,0x2c,0xff,0xff,0xe7,0x30,0x10,0x00,0xa8,0x93,
800x19,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0x02,0x80,0x03,0x3c,0x80,0x10,0x04,0x00,
810xc0,0x91,0x63,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0x00,0x00,0x00,0x00,
820x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x43,0xb0,0x02,0x3c,0x78,0x00,0x44,0x34,
830x07,0x00,0xe2,0x30,0x00,0x00,0x85,0xac,0x04,0x00,0x86,0xac,0x04,0x00,0x40,0x18,
840x00,0x00,0x00,0x00,0xf8,0xff,0xe2,0x30,0x08,0x00,0x42,0x24,0xff,0xff,0x47,0x30,
850x21,0x10,0xe8,0x00,0x00,0x80,0x03,0x3c,0x08,0x00,0x82,0xac,0x25,0x10,0x43,0x00,
860x08,0x00,0x82,0xac,0x01,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
870x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x6c,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,
880x20,0x01,0x00,0x08,0x60,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,
890x54,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x48,0x00,0x44,0x34,
900x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x3c,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,
910x20,0x01,0x00,0x08,0x30,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,
920x24,0x00,0x44,0x34,0x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x18,0x00,0x44,0x34,
930x43,0xb0,0x02,0x3c,0x20,0x01,0x00,0x08,0x0c,0x00,0x44,0x34,0x20,0x01,0x00,0x08,
940x43,0xb0,0x04,0x3c,0x01,0x00,0x02,0x24,0x25,0xb0,0x03,0x3c,0x04,0x20,0x82,0x00,
950x18,0x03,0x67,0x34,0x00,0x80,0x02,0x3c,0x43,0xb0,0x03,0x3c,0x34,0x05,0x46,0x24,
960x88,0x00,0x65,0x34,0x21,0x10,0x00,0x00,0x01,0x00,0x42,0x24,0xff,0xff,0x42,0x30,
970x05,0x00,0x43,0x2c,0xfd,0xff,0x60,0x14,0x01,0x00,0x42,0x24,0x00,0x00,0xe6,0xac,
980x00,0x00,0xa2,0x94,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x30,0x24,0x10,0x44,0x00,
990xf4,0xff,0x40,0x1c,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
1000x25,0xb0,0x08,0x3c,0x00,0x80,0x02,0x3c,0xc8,0xff,0xbd,0x27,0x18,0x03,0x03,0x35,
1010x90,0x05,0x42,0x24,0x00,0x00,0x62,0xac,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
1020x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf,
1030x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,0x0c,0x00,0xf2,0x84,0x08,0x00,0xf5,0x8c,
1040xff,0x00,0xc6,0x30,0x00,0x01,0x02,0x24,0x23,0x10,0x46,0x00,0xff,0xff,0x51,0x30,
1050xd0,0x03,0x08,0x35,0xff,0x00,0x96,0x30,0x00,0x00,0x12,0xad,0x21,0xa0,0xa0,0x00,
1060x21,0x30,0xc5,0x00,0x00,0x00,0x15,0xad,0x21,0x20,0xc0,0x02,0x21,0x28,0xa0,0x02,
1070x21,0x38,0x20,0x02,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x23,0x18,0x51,0x02,
1080xff,0xff,0x82,0x32,0x00,0x94,0x03,0x00,0x03,0x94,0x12,0x00,0xa6,0x01,0x00,0x08,
1090x02,0x9a,0x02,0x00,0x28,0xb0,0x03,0x3c,0xc0,0x10,0x13,0x00,0x21,0x10,0x43,0x00,
1100x00,0x00,0x44,0x90,0x25,0xb0,0x10,0x3c,0x20,0x10,0x02,0x3c,0xff,0x00,0x93,0x30,
1110x00,0x22,0x13,0x00,0xff,0xff,0x43,0x32,0x01,0x01,0x45,0x2a,0x21,0xa0,0x82,0x00,
1120x21,0xa8,0xb1,0x02,0xd0,0x03,0x02,0x36,0x00,0x01,0x11,0x24,0x0b,0x88,0x65,0x00,
1130x21,0x20,0xc0,0x02,0x00,0x00,0x53,0xac,0x4d,0x01,0x00,0x0c,0xb0,0x03,0x10,0x36,
1140x21,0x30,0x80,0x02,0x21,0x20,0xc0,0x02,0x21,0x28,0xa0,0x02,0x21,0x38,0x20,0x02,
1150x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x23,0x18,0x51,0x02,0x00,0x94,0x03,0x00,
1160x03,0x94,0x12,0x00,0x00,0x00,0x12,0xae,0xe2,0xff,0x40,0x1e,0x00,0x00,0x00,0x00,
1170x34,0x00,0xbf,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,
1180x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
1190x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0xc8,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,
1200x25,0xb0,0x04,0x3c,0x20,0x00,0xb2,0xaf,0x68,0x15,0x52,0x24,0x00,0x80,0x02,0x3c,
1210x18,0x03,0x83,0x34,0xc8,0x06,0x42,0x24,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
1220x30,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
1230x00,0x00,0x62,0xac,0xb0,0x03,0x93,0x34,0x21,0xa0,0x40,0x02,0x54,0x64,0x42,0x8e,
1240xc0,0x64,0x50,0x8e,0x21,0x20,0x00,0x00,0x00,0x00,0x62,0xae,0x58,0x64,0x42,0xae,
1250x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x64,0x44,0x8e,
1260xc4,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,
1270x0a,0x18,0x82,0x00,0xc0,0x64,0x43,0xae,0xc0,0x64,0x85,0x8e,0x00,0x00,0x00,0x00,
1280x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,
1290x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0xff,0x00,0x15,0x24,0x21,0x20,0x00,0x00,
1300x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24,
1310x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,0x05,0x00,0x35,0x12,0x21,0x30,0x60,0x00,
1320x08,0x64,0x91,0xa2,0x54,0x64,0x83,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
1330x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34,
1340x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c,
1350x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c,
1360x25,0x18,0x64,0x00,0xc0,0xff,0x02,0x24,0x24,0x18,0x62,0x00,0x08,0x00,0x03,0xae,
1370xc9,0x64,0x84,0x92,0x2a,0xb0,0x02,0x3c,0x01,0x00,0x03,0x24,0x01,0x00,0x84,0x24,
1380x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc4,0xff,0x35,0x16,0xc9,0x64,0x84,0xa2,
1390xfc,0x4a,0x82,0x8e,0x41,0xb0,0x03,0x3c,0x30,0x00,0xbf,0x8f,0x00,0x38,0x42,0x34,
1400x00,0x00,0x62,0xac,0x2c,0x00,0xb5,0x8f,0xfc,0x4a,0x82,0xae,0x24,0x00,0xb3,0x8f,
1410x28,0x00,0xb4,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
1420x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c,
1430xc8,0xff,0xbd,0x27,0x18,0x03,0x83,0x34,0x38,0x08,0x42,0x24,0x34,0x00,0xbf,0xaf,
1440x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
1450x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x00,0x00,0x62,0xac,
1460x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,
1470x68,0x15,0xd2,0x26,0xb0,0x03,0x93,0x34,0x2d,0x02,0x00,0x08,0x21,0xa8,0x40,0x02,
1480x2a,0xb0,0x02,0x3c,0x08,0x00,0x04,0xae,0x09,0x00,0x42,0x34,0x01,0x00,0x03,0x24,
1490x02,0x00,0x04,0x24,0x00,0x00,0x43,0xa0,0x00,0x00,0x44,0xa0,0x42,0x00,0x34,0x12,
1500x00,0x00,0x00,0x00,0x6c,0x64,0x42,0x8e,0xd8,0x64,0x50,0x8e,0x01,0x00,0x04,0x24,
1510x00,0x00,0x62,0xae,0x70,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,
1520x00,0x00,0x00,0x00,0xd8,0x64,0x44,0x8e,0xdc,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,
1530x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xd8,0x64,0x43,0xae,
1540xd8,0x64,0xa5,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,
1550xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,
1560xff,0x00,0x14,0x24,0x01,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,
1570x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24,0x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,
1580x05,0x00,0x34,0x12,0x21,0x30,0x60,0x00,0x6c,0x64,0xa3,0xae,0x10,0x64,0xb1,0xa2,
1590x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,
1600xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34,0x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,
1610x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c,0x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,
1620x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c,0x25,0x18,0x64,0x00,0xc0,0xff,0x05,0x24,
1630x82,0x11,0x03,0x00,0x24,0x20,0x65,0x00,0x01,0x00,0x42,0x30,0xc0,0xff,0x40,0x10,
1640x04,0x00,0x84,0x34,0x2a,0xb0,0x02,0x3c,0x08,0x00,0x03,0xae,0x09,0x00,0x42,0x34,
1650x01,0x00,0x03,0x24,0x02,0x00,0x04,0x24,0x00,0x00,0x43,0xa0,0x00,0x00,0x44,0xa0,
1660xc0,0xff,0x34,0x16,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
1670x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc2,0x26,0xfc,0x4a,0x43,0x8c,
1680x34,0x00,0xbf,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,
1690x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
1700x00,0x38,0x63,0x34,0x41,0xb0,0x04,0x3c,0x38,0x00,0xbd,0x27,0x00,0x00,0x83,0xac,
1710x08,0x00,0xe0,0x03,0xfc,0x4a,0x43,0xac,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c,
1720xc0,0xff,0xbd,0x27,0x18,0x03,0x83,0x34,0x08,0x0a,0x42,0x24,0x38,0x00,0xbf,0xaf,
1730x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf,
1740x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
1750x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
1760x02,0x80,0x17,0x3c,0x68,0x15,0xf2,0x26,0xb0,0x03,0x93,0x34,0x02,0x80,0x14,0x3c,
1770xab,0x02,0x00,0x08,0x21,0xb0,0x40,0x02,0x2a,0xb0,0x03,0x3c,0x08,0x00,0x04,0xae,
1780x05,0x00,0x63,0x34,0x01,0x00,0x02,0x24,0x02,0x00,0x04,0x24,0x00,0x00,0x62,0xa0,
1790x00,0x00,0x64,0xa0,0xca,0x7d,0x82,0x96,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,
1800xca,0x7d,0x82,0xa6,0xca,0x7d,0x83,0x96,0x25,0xb0,0x02,0x3c,0x66,0x03,0x42,0x34,
1810x00,0x00,0x43,0xa4,0x4a,0x00,0x35,0x12,0x00,0x00,0x00,0x00,0x60,0x64,0x42,0x8e,
1820xcc,0x64,0x50,0x8e,0x01,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x64,0x64,0x42,0xae,
1830x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0xcc,0x64,0x44,0x8e,
1840xd0,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,
1850x0a,0x18,0x82,0x00,0xcc,0x64,0x43,0xae,0xcc,0x64,0xc5,0x8e,0x00,0x00,0x00,0x00,
1860x00,0x00,0x65,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,
1870x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0xff,0x00,0x15,0x24,0x01,0x00,0x04,0x24,
1880x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0x20,0x10,0x02,0x3c,0x20,0x00,0x07,0x24,
1890x00,0x1a,0x11,0x00,0x21,0x18,0x62,0x00,0x05,0x00,0x35,0x12,0x21,0x30,0x60,0x00,
1900x60,0x64,0xc3,0xae,0x0c,0x64,0xd1,0xa2,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
1910x04,0x00,0x04,0x8e,0x08,0x00,0x03,0x8e,0xff,0xe0,0x02,0x3c,0xff,0xff,0x42,0x34,
1920x1f,0x00,0x84,0x30,0x24,0x18,0x62,0x00,0x00,0x26,0x04,0x00,0xff,0xdf,0x02,0x3c,
1930x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x00,0x40,0x04,0x3c,
1940x25,0x18,0x64,0x00,0xc0,0xff,0x05,0x24,0x82,0x11,0x03,0x00,0x24,0x20,0x65,0x00,
1950x01,0x00,0x42,0x30,0xb8,0xff,0x40,0x10,0x04,0x00,0x84,0x34,0x08,0x00,0x03,0xae,
1960x2a,0xb0,0x03,0x3c,0x05,0x00,0x63,0x34,0x01,0x00,0x02,0x24,0x02,0x00,0x04,0x24,
1970x00,0x00,0x62,0xa0,0x00,0x00,0x64,0xa0,0xca,0x7d,0x82,0x96,0x00,0x00,0x00,0x00,
1980x01,0x00,0x42,0x24,0xca,0x7d,0x82,0xa6,0xca,0x7d,0x83,0x96,0x25,0xb0,0x02,0x3c,
1990x66,0x03,0x42,0x34,0x00,0x00,0x43,0xa4,0xb8,0xff,0x35,0x16,0x00,0x00,0x00,0x00,
2000x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
2010x68,0x15,0xe2,0x26,0xfc,0x4a,0x43,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
2020x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
2030x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x38,0x63,0x34,
2040x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x83,0xac,0x08,0x00,0xe0,0x03,
2050xfc,0x4a,0x43,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,0x38,0x00,0xbf,0xaf,
2060x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
2070x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x02,0x80,0x06,0x3c,
2080x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x18,0x03,0x42,0x34,
2090x24,0x0c,0x63,0x24,0x40,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,0x21,0xa8,0x00,0x00,
2100x03,0x00,0x80,0x10,0x7f,0x00,0xa2,0x30,0xbf,0x00,0xa2,0x30,0x01,0x00,0x15,0x24,
2110x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc2,0x90,0x25,0xb0,0x04,0x3c,0x88,0x02,0x83,0x34,
2120x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
2130x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0xb0,0x03,0x93,0x34,0x02,0x80,0x14,0x3c,
2140x43,0x03,0x00,0x08,0x21,0xb8,0x40,0x02,0x24,0x10,0xa2,0x00,0x04,0x00,0x42,0x34,
2150x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x0d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,
2160x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,
2170x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,
2180x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,
2190x00,0x00,0xa2,0xa4,0x5a,0x00,0x23,0x12,0x00,0x00,0x00,0x00,0x24,0x64,0x42,0x8e,
2200x90,0x64,0x50,0x8e,0x03,0x00,0x04,0x24,0x00,0x00,0x62,0xae,0x28,0x64,0x42,0xae,
2210x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x90,0x64,0x44,0x8e,
2220x94,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,
2230x0a,0x18,0x82,0x00,0x90,0x64,0x43,0xae,0x90,0x64,0xe2,0x8e,0x00,0x00,0x00,0x00,
2240x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,
2250x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,
2260x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12,0x00,0x12,0x11,0x00,
2270x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x5a,0x00,0xa0,0x12,0x24,0x64,0xe2,0xae,
2280xec,0x63,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x24,0x64,0x46,0x8c,0x90,0x64,0x45,0x8c,
2290x03,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
2300x04,0x00,0x04,0x8e,0x14,0x00,0x03,0x8e,0x08,0x00,0x05,0x8e,0xff,0xe0,0x02,0x3c,
2310x1f,0x00,0x84,0x30,0x42,0x1a,0x03,0x00,0xff,0xff,0x42,0x34,0x00,0x26,0x04,0x00,
2320x24,0x28,0xa2,0x00,0x3f,0x00,0x63,0x30,0x25,0x28,0xa4,0x00,0x0c,0x00,0x63,0x28,
2330x06,0x00,0x60,0x14,0x21,0x20,0xa0,0x00,0x00,0x00,0x02,0x96,0x00,0x00,0x00,0x00,
2340xfd,0x0f,0x42,0x28,0x08,0x00,0x40,0x14,0x82,0x11,0x05,0x00,0xff,0xdf,0x02,0x3c,
2350xff,0xff,0x42,0x34,0x24,0x28,0x82,0x00,0x00,0x40,0x03,0x3c,0x25,0x20,0xa3,0x00,
2360x21,0x28,0x80,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30,0xa6,0xff,0x40,0x10,
2370xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,0x0d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,
2380x08,0x00,0x04,0xae,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,
2390x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,
2400x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,
2410xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0xa8,0xff,0x23,0x16,0x00,0x00,0x00,0x00,
2420x22,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,0xec,0x63,0x43,0x90,0x41,0x00,0xe4,0x34,
2430xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,
2440x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
2450x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc5,0x26,0xfc,0x4a,0xa4,0x8c,
2460x01,0x00,0x02,0x3c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f,
2470x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,
2480x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x80,0x42,0x34,0x25,0x20,0x82,0x00,
2490x41,0xb0,0x03,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x64,0xac,0x08,0x00,0xe0,0x03,
2500xfc,0x4a,0xa4,0xac,0x65,0x03,0x00,0x08,0xe8,0x63,0xf1,0xa2,0xe8,0x63,0x43,0x90,
2510x40,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0xa3,0xac,
2520x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,
2530x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x68,0x15,0xc5,0x26,
2540xfc,0x4a,0xa4,0x8c,0x01,0x00,0x02,0x3c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
2550x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
2560x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x00,0x80,0x42,0x34,
2570x25,0x20,0x82,0x00,0x41,0xb0,0x03,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x64,0xac,
2580x08,0x00,0xe0,0x03,0xfc,0x4a,0xa4,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,
2590x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
2600x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
2610x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
2620x18,0x03,0x42,0x34,0x78,0x0f,0x63,0x24,0x10,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,
2630x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xdf,0x00,0xa2,0x30,0xef,0x00,0xa2,0x30,
2640x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c,
2650xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,
2660x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,
2670x21,0x98,0x40,0x00,0x02,0x80,0x14,0x3c,0x19,0x04,0x00,0x08,0x21,0xb8,0x40,0x02,
2680x24,0x10,0xa2,0x00,0x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,
2690x15,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,
2700x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,
2710x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,
2720xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x5a,0x00,0x23,0x12,
2730x00,0x00,0x00,0x00,0x30,0x64,0x42,0x8e,0x9c,0x64,0x50,0x8e,0x04,0x00,0x04,0x24,
2740x00,0x00,0x62,0xae,0x34,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,
2750x00,0x00,0x00,0x00,0x9c,0x64,0x44,0x8e,0xa0,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,
2760x3f,0x00,0x62,0x24,0x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0x9c,0x64,0x43,0xae,
2770x9c,0x64,0xe2,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,
2780xff,0xff,0x10,0x32,0x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,
2790x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,
2800x0d,0x00,0x22,0x12,0x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,
2810x59,0x00,0xa0,0x12,0x30,0x64,0xe2,0xae,0xf4,0x63,0xf1,0xa2,0x68,0x15,0xc2,0x26,
2820x30,0x64,0x46,0x8c,0x9c,0x64,0x45,0x8c,0x04,0x00,0x04,0x24,0x20,0x00,0x07,0x24,
2830x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x04,0x00,0x04,0x8e,0x14,0x00,0x03,0x8e,
2840x08,0x00,0x05,0x8e,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x42,0x1a,0x03,0x00,
2850xff,0xff,0x42,0x34,0x00,0x26,0x04,0x00,0x24,0x28,0xa2,0x00,0x3f,0x00,0x63,0x30,
2860x25,0x28,0xa4,0x00,0x0c,0x00,0x63,0x28,0x06,0x00,0x60,0x14,0x21,0x20,0xa0,0x00,
2870x00,0x00,0x02,0x96,0x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x08,0x00,0x40,0x14,
2880x82,0x11,0x05,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34,0x24,0x28,0x82,0x00,
2890x00,0x40,0x03,0x3c,0x25,0x20,0xa3,0x00,0x21,0x28,0x80,0x00,0x82,0x11,0x05,0x00,
2900x01,0x00,0x42,0x30,0xa6,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,
2910x15,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x08,0x00,0x04,0xae,0x0b,0x10,0x75,0x00,
2920x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,
2930xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,
2940xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,
2950xa8,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,
2960xf4,0x63,0x43,0x90,0x43,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
2970x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
2980x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
2990x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
3000x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
3010x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x06,0x00,0x03,0x3c,
3020x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
3030x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x3b,0x04,0x00,0x08,0xf0,0x63,0xf1,0xa2,
3040xf0,0x63,0x43,0x90,0x42,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
3050x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
3060x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
3070x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
3080x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
3090x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x06,0x00,0x03,0x3c,
3100x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
3110x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,
3120x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
3130x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
3140x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
3150x18,0x03,0x42,0x34,0xc8,0x12,0x63,0x24,0x01,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,
3160x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xf7,0x00,0xa2,0x30,0xfe,0x00,0xa2,0x30,
3170x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c,
3180xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
3190x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0x21,0x98,0x40,0x00,
3200x02,0x80,0x14,0x3c,0xf8,0x04,0x00,0x08,0x21,0xb8,0x40,0x02,0x00,0x00,0x02,0x96,
3210x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x54,0x00,0x40,0x10,0xff,0xdf,0x02,0x3c,
3220x00,0x20,0x02,0x3c,0x25,0x28,0xa2,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30,
3230x57,0x00,0x40,0x14,0x2a,0xb0,0x07,0x3c,0xc0,0xff,0x02,0x24,0x24,0x10,0xa2,0x00,
3240x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x1d,0x00,0xe2,0x34,
3250x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,
3260x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,
3270x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,
3280xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x53,0x00,0x23,0x12,0x00,0x00,0x00,0x00,
3290x3c,0x64,0x42,0x8e,0xa8,0x64,0x50,0x8e,0x05,0x00,0x04,0x24,0x00,0x00,0x62,0xae,
3300x40,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,
3310xa8,0x64,0x44,0x8e,0xac,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,
3320x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xa8,0x64,0x43,0xae,0xa8,0x64,0xe2,0x8e,
3330x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,
3340x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00,
3350x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12,
3360x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x52,0x00,0xa0,0x12,
3370x3c,0x64,0xe2,0xae,0x04,0x64,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x3c,0x64,0x46,0x8c,
3380xa8,0x64,0x45,0x8c,0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,
3390x10,0x00,0xa0,0xaf,0x14,0x00,0x03,0x8e,0x04,0x00,0x04,0x8e,0x08,0x00,0x05,0x8e,
3400x42,0x1a,0x03,0x00,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x3f,0x00,0x63,0x30,
3410xff,0xff,0x42,0x34,0x24,0x28,0xa2,0x00,0x00,0x26,0x04,0x00,0x0c,0x00,0x63,0x28,
3420xaa,0xff,0x60,0x10,0x25,0x28,0xa4,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34,
3430x24,0x10,0xa2,0x00,0x00,0x40,0x03,0x3c,0x25,0x28,0x43,0x00,0x82,0x11,0x05,0x00,
3440x01,0x00,0x42,0x30,0xad,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,
3450x1d,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,
3460x02,0x00,0x03,0x24,0x08,0x00,0x05,0xae,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,
3470xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,
3480xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,
3490xaf,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,
3500x04,0x64,0x43,0x90,0x45,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
3510x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
3520x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
3530x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
3540x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
3550x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x18,0x00,0x03,0x3c,
3560x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
3570x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x1a,0x05,0x00,0x08,0xf8,0x63,0xf1,0xa2,
3580xf8,0x63,0x43,0x90,0x44,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
3590x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
3600x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
3610x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
3620x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
3630x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x18,0x00,0x03,0x3c,
3640x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
3650x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xc0,0xff,0xbd,0x27,0x2c,0x00,0xb5,0xaf,
3660x38,0x00,0xbf,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x28,0x00,0xb4,0xaf,
3670x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
3680x02,0x80,0x06,0x3c,0x7c,0x7e,0xc5,0x90,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
3690x18,0x03,0x42,0x34,0x28,0x16,0x63,0x24,0x02,0x00,0xa4,0x30,0x00,0x00,0x43,0xac,
3700x21,0xa8,0x00,0x00,0x03,0x00,0x80,0x10,0xfb,0x00,0xa2,0x30,0xfd,0x00,0xa2,0x30,
3710x01,0x00,0x15,0x24,0x7c,0x7e,0xc2,0xa0,0x7c,0x7e,0xc3,0x90,0x25,0xb0,0x02,0x3c,
3720xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
3730x00,0x60,0x81,0x40,0x02,0x80,0x16,0x3c,0x68,0x15,0xd2,0x26,0x21,0x98,0x40,0x00,
3740x02,0x80,0x14,0x3c,0xd0,0x05,0x00,0x08,0x21,0xb8,0x40,0x02,0x00,0x00,0x02,0x96,
3750x00,0x00,0x00,0x00,0xfd,0x0f,0x42,0x28,0x54,0x00,0x40,0x10,0xff,0xdf,0x02,0x3c,
3760x00,0x20,0x02,0x3c,0x25,0x28,0xa2,0x00,0x82,0x11,0x05,0x00,0x01,0x00,0x42,0x30,
3770x57,0x00,0x40,0x14,0x2a,0xb0,0x07,0x3c,0xc0,0xff,0x02,0x24,0x24,0x10,0xa2,0x00,
3780x04,0x00,0x42,0x34,0x2a,0xb0,0x07,0x3c,0x08,0x00,0x02,0xae,0x25,0x00,0xe2,0x34,
3790x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,0x02,0x00,0x03,0x24,
3800x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,0xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,
3810x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,0xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,
3820xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,0x53,0x00,0x23,0x12,0x00,0x00,0x00,0x00,
3830x48,0x64,0x42,0x8e,0xb4,0x64,0x50,0x8e,0x06,0x00,0x04,0x24,0x00,0x00,0x62,0xae,
3840x4c,0x64,0x42,0xae,0x00,0x00,0x70,0xae,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,
3850xb4,0x64,0x44,0x8e,0xb8,0x64,0x43,0x8e,0x20,0x00,0x84,0x24,0x3f,0x00,0x62,0x24,
3860x2b,0x10,0x44,0x00,0x0a,0x18,0x82,0x00,0xb4,0x64,0x43,0xae,0xb4,0x64,0xe2,0x8e,
3870x00,0x00,0x00,0x00,0x00,0x00,0x62,0xae,0x02,0x80,0x02,0x3c,0xff,0xff,0x10,0x32,
3880x25,0x80,0x02,0x02,0x00,0x00,0x70,0xae,0x0c,0x00,0x02,0x92,0x00,0x00,0x00,0x00,
3890x00,0x00,0x62,0xae,0x0c,0x00,0x11,0x92,0xff,0x00,0x02,0x24,0x0d,0x00,0x22,0x12,
3900x00,0x12,0x11,0x00,0x20,0x10,0x03,0x3c,0x21,0x10,0x43,0x00,0x52,0x00,0xa0,0x12,
3910x48,0x64,0xe2,0xae,0x00,0x64,0xf1,0xa2,0x68,0x15,0xc2,0x26,0x48,0x64,0x46,0x8c,
3920xb4,0x64,0x45,0x8c,0x06,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,
3930x10,0x00,0xa0,0xaf,0x14,0x00,0x03,0x8e,0x04,0x00,0x04,0x8e,0x08,0x00,0x05,0x8e,
3940x42,0x1a,0x03,0x00,0xff,0xe0,0x02,0x3c,0x1f,0x00,0x84,0x30,0x3f,0x00,0x63,0x30,
3950xff,0xff,0x42,0x34,0x24,0x28,0xa2,0x00,0x00,0x26,0x04,0x00,0x0c,0x00,0x63,0x28,
3960xaa,0xff,0x60,0x10,0x25,0x28,0xa4,0x00,0xff,0xdf,0x02,0x3c,0xff,0xff,0x42,0x34,
3970x24,0x10,0xa2,0x00,0x00,0x40,0x03,0x3c,0x25,0x28,0x43,0x00,0x82,0x11,0x05,0x00,
3980x01,0x00,0x42,0x30,0xad,0xff,0x40,0x10,0xc0,0xff,0x02,0x24,0x2a,0xb0,0x07,0x3c,
3990x25,0x00,0xe2,0x34,0x04,0x00,0x43,0x24,0x0b,0x10,0x75,0x00,0x01,0x00,0x04,0x24,
4000x02,0x00,0x03,0x24,0x08,0x00,0x05,0xae,0x00,0x00,0x44,0xa0,0x00,0x00,0x43,0xa0,
4010xca,0x7d,0x84,0x96,0x25,0xb0,0x06,0x3c,0x66,0x03,0xc5,0x34,0x01,0x00,0x84,0x24,
4020xca,0x7d,0x84,0xa6,0xca,0x7d,0x82,0x96,0xff,0x00,0x03,0x24,0x00,0x00,0xa2,0xa4,
4030xaf,0xff,0x23,0x16,0x00,0x00,0x00,0x00,0x21,0x00,0xa0,0x12,0x68,0x15,0xc2,0x26,
4040x00,0x64,0x43,0x90,0x47,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
4050x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
4060x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
4070x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
4080x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
4090x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x60,0x00,0x03,0x3c,
4100x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
4110x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0xf2,0x05,0x00,0x08,0xfc,0x63,0xf1,0xa2,
4120xfc,0x63,0x43,0x90,0x46,0x00,0xe4,0x34,0xb0,0x03,0xc5,0x34,0x00,0x00,0x83,0xa0,
4130x00,0x00,0xa3,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
4140x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
4150x68,0x15,0xc5,0x26,0xfc,0x4a,0xa2,0x8c,0x38,0x00,0xbf,0x8f,0x34,0x00,0xb7,0x8f,
4160x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
4170x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x60,0x00,0x03,0x3c,
4180x25,0x10,0x43,0x00,0x41,0xb0,0x04,0x3c,0x40,0x00,0xbd,0x27,0x00,0x00,0x82,0xac,
4190x08,0x00,0xe0,0x03,0xfc,0x4a,0xa2,0xac,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
4200x88,0x19,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,
4210x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
4220x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x05,0x3c,0x68,0x15,0xa5,0x24,
4230x04,0x4b,0xa2,0x8c,0xfc,0x4a,0xa4,0x8c,0x00,0x08,0x03,0x3c,0x24,0x10,0x43,0x00,
4240x25,0x20,0x82,0x00,0x41,0xb0,0x03,0x3c,0x00,0x00,0x64,0xac,0x08,0x00,0xe0,0x03,
4250xfc,0x4a,0xa4,0xac,0x25,0xb0,0x04,0x3c,0x00,0x80,0x02,0x3c,0xc0,0xff,0xbd,0x27,
4260x18,0x03,0x83,0x34,0xe4,0x19,0x42,0x24,0x3c,0x00,0xbf,0xaf,0x38,0x00,0xbe,0xaf,
4270x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x28,0x00,0xb4,0xaf,
4280x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
4290x00,0x00,0x62,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
4300x02,0x80,0x02,0x3c,0x2a,0xb0,0x03,0x3c,0x68,0x15,0x51,0x24,0xb0,0x03,0x93,0x34,
4310x2c,0x00,0x77,0x34,0x02,0x80,0x15,0x3c,0x02,0x80,0x16,0x3c,0x9c,0x06,0x00,0x08,
4320x02,0x80,0x1e,0x3c,0x14,0x64,0x26,0x92,0xe4,0x64,0x25,0x8e,0x00,0x32,0x06,0x00,
4330x21,0x30,0xc2,0x00,0x78,0x64,0x26,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
4340xe4,0x64,0x30,0x8e,0x0a,0x00,0x04,0x24,0x21,0x90,0x00,0x00,0x00,0x00,0x70,0xae,
4350x4d,0x01,0x00,0x0c,0xff,0xff,0x10,0x32,0x02,0x80,0x02,0x3c,0x25,0x80,0x02,0x02,
4360x0c,0x00,0x05,0x92,0x02,0x00,0x04,0x92,0xff,0x00,0x02,0x24,0xff,0x00,0xa3,0x30,
4370x04,0x00,0x62,0x10,0x21,0x80,0x04,0x02,0x00,0x00,0x63,0xae,0x01,0x00,0x12,0x24,
4380x14,0x64,0x25,0xa2,0x88,0x96,0xb0,0xae,0x21,0x28,0x00,0x02,0x02,0x00,0xa2,0x90,
4390x08,0x00,0x10,0x26,0x21,0x20,0x00,0x02,0xff,0x00,0x42,0x30,0x00,0x00,0x62,0xae,
4400x03,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x63,0xae,
4410x00,0x00,0x72,0xae,0x03,0x00,0xa2,0x90,0x84,0x96,0xc3,0x92,0x02,0x00,0xa2,0x90,
4420x00,0x00,0x00,0x00,0xff,0x00,0x42,0x30,0x2c,0x00,0x42,0x28,0x11,0x00,0x40,0x10,
4430x08,0x00,0x02,0x24,0x03,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,0x7f,0x00,0x42,0x30,
4440x84,0x96,0xc2,0xa2,0x02,0x00,0xa3,0x90,0x02,0x80,0x02,0x3c,0x74,0x84,0x42,0x24,
4450xff,0x00,0x63,0x30,0xc0,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x04,0x00,0x62,0x8c,
4460x00,0x00,0x00,0x00,0x09,0xf8,0x40,0x00,0x80,0x96,0xc2,0xaf,0x21,0xa0,0x40,0x00,
4470x08,0x00,0x02,0x24,0x0a,0x00,0x04,0x24,0x05,0x00,0x82,0x12,0x00,0x01,0x07,0x24,
4480x01,0x00,0x02,0x24,0x02,0x00,0x03,0x24,0x01,0x00,0xe2,0xa2,0x01,0x00,0xe3,0xa2,
4490xbc,0xff,0x40,0x16,0x20,0x10,0x02,0x3c,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
4500x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0xfc,0x4a,0x22,0x8e,0x00,0x04,0x03,0x3c,
4510x41,0xb0,0x04,0x3c,0x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x3c,0x00,0xbf,0x8f,
4520xfc,0x4a,0x22,0xae,0x38,0x00,0xbe,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f,
4530x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,
4540x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x40,0x00,0xbd,0x27,
4550xc8,0xff,0xbd,0x27,0xff,0xff,0xa8,0x30,0x02,0x80,0x02,0x3c,0x25,0x40,0x02,0x01,
4560x30,0x00,0xb6,0xaf,0x20,0x00,0xb2,0xaf,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb5,0xaf,
4570x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
4580x00,0x00,0x03,0x8d,0xff,0xff,0xd2,0x30,0x21,0xb0,0xa0,0x00,0x00,0xc0,0x02,0x24,
4590x08,0x00,0x45,0x26,0x04,0x00,0x06,0x8d,0x24,0x18,0x62,0x00,0xff,0x3f,0xa5,0x30,
4600xf0,0xff,0x02,0x3c,0x25,0x18,0x65,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,
4610x00,0x80,0x05,0x3c,0x25,0x18,0x65,0x00,0xff,0x01,0xc6,0x34,0x00,0x00,0x03,0xad,
4620x04,0x00,0x06,0xad,0x21,0x48,0x80,0x00,0xff,0xff,0xe7,0x30,0x18,0x00,0x12,0xa5,
4630x1a,0x00,0x07,0xa1,0x18,0x00,0x03,0x8d,0xff,0x7f,0x02,0x3c,0xff,0xff,0x42,0x34,
4640x24,0x18,0x62,0x00,0x02,0x80,0x15,0x3c,0x18,0x00,0x03,0xad,0x68,0x15,0xa5,0x26,
4650xd6,0x63,0xa3,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x62,0x24,0xd6,0x63,0xa2,0xa0,
4660x18,0x00,0x04,0x8d,0xff,0x80,0x02,0x3c,0x20,0x00,0x45,0x26,0xff,0xff,0x42,0x34,
4670x7f,0x00,0x63,0x30,0xff,0xff,0xb2,0x30,0x24,0x20,0x82,0x00,0x00,0x1e,0x03,0x00,
4680x25,0xb0,0x02,0x3c,0xc0,0x00,0x42,0x34,0x25,0x20,0x83,0x00,0x07,0x00,0x45,0x32,
4690x18,0x00,0x04,0xad,0x00,0x00,0x52,0xa4,0x03,0x00,0xa0,0x10,0xff,0xff,0x42,0x32,
4700x08,0x00,0x42,0x26,0xff,0xff,0x42,0x30,0x68,0x15,0xb4,0x26,0x54,0x65,0x86,0x8e,
4710x58,0x65,0x90,0x8e,0xf8,0xff,0x52,0x30,0x21,0x10,0xd2,0x00,0x2b,0x10,0x02,0x02,
4720x31,0x00,0x40,0x10,0xff,0x00,0x33,0x31,0x23,0x80,0x06,0x02,0x21,0x28,0xc0,0x02,
4730xff,0xff,0x07,0x32,0x01,0x00,0x11,0x24,0x21,0x20,0x60,0x02,0x10,0x01,0x00,0x0c,
4740x10,0x00,0xb1,0xaf,0x23,0x18,0x50,0x02,0xff,0xff,0x72,0x30,0x22,0x10,0x02,0x3c,
4750x21,0x10,0x42,0x02,0x21,0x20,0x60,0x02,0x4d,0x01,0x00,0x0c,0x54,0x65,0x82,0xae,
4760x21,0x28,0xd0,0x02,0x21,0x38,0x40,0x02,0x21,0x20,0x60,0x02,0x10,0x00,0xb1,0xaf,
4770x22,0x10,0x06,0x3c,0x10,0x01,0x00,0x0c,0x68,0x15,0xb1,0x26,0x54,0x65,0x23,0x8e,
4780x25,0xb0,0x10,0x3c,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02,0x00,0x00,0x43,0xac,
4790x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x54,0x65,0x25,0x8e,0xec,0x00,0x02,0x36,
4800xbd,0x00,0x04,0x36,0x00,0x00,0x45,0xac,0x00,0x00,0x83,0x90,0xc2,0x00,0x10,0x36,
4810x34,0x00,0xbf,0x8f,0x10,0x00,0x63,0x34,0x00,0x00,0x83,0xa0,0x30,0x00,0xb6,0x8f,
4820x00,0x00,0x05,0xa6,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,
4830x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,
4840x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x21,0x28,0xc0,0x02,0x21,0x20,0x60,0x02,
4850x21,0x38,0x40,0x02,0x01,0x00,0x02,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa2,0xaf,
4860x54,0x65,0x83,0x8e,0x68,0x15,0xb1,0x26,0x25,0xb0,0x10,0x3c,0x21,0x18,0x72,0x00,
4870x54,0x65,0x83,0xae,0x54,0x65,0x23,0x8e,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02,
4880x00,0x00,0x43,0xac,0x4d,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,0x54,0x65,0x25,0x8e,
4890xec,0x00,0x02,0x36,0xbd,0x00,0x04,0x36,0x00,0x00,0x45,0xac,0x00,0x00,0x83,0x90,
4900xc2,0x00,0x10,0x36,0x34,0x00,0xbf,0x8f,0x10,0x00,0x63,0x34,0x00,0x00,0x83,0xa0,
4910x30,0x00,0xb6,0x8f,0x00,0x00,0x05,0xa6,0x2c,0x00,0xb5,0x8f,0x28,0x00,0xb4,0x8f,
4920x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
4930x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
4940x25,0xb0,0x02,0x3c,0x14,0x00,0xb1,0xaf,0x18,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,
4950xbf,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0x21,0x28,0x00,0x00,0x08,0x00,0x06,0x24,
4960x04,0x00,0x63,0x2c,0x12,0x00,0x60,0x14,0x21,0x88,0x80,0x00,0x00,0x60,0x02,0x40,
4970x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x03,0x3c,
4980x00,0x7b,0x63,0x24,0x04,0x00,0x64,0x8c,0x00,0x00,0x23,0xae,0x04,0x00,0x71,0xac,
4990x00,0x00,0x91,0xac,0x04,0x00,0x24,0xae,0x00,0x60,0x82,0x40,0x18,0x00,0xbf,0x8f,
5000x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
5010x08,0x00,0x82,0x94,0x02,0x80,0x04,0x3c,0x97,0x45,0x00,0x0c,0x25,0x20,0x44,0x00,
5020x00,0x60,0x10,0x40,0x01,0x00,0x01,0x36,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
5030x08,0x00,0x25,0x8e,0x0c,0x00,0x26,0x96,0x14,0x00,0x27,0x96,0xf0,0x06,0x00,0x0c,
5040x09,0x00,0x04,0x24,0x04,0x00,0x23,0x8e,0x00,0x00,0x22,0x8e,0x21,0x20,0x20,0x02,
5050x00,0x00,0x62,0xac,0x04,0x00,0x43,0xac,0x00,0x00,0x31,0xae,0xbd,0x4e,0x00,0x0c,
5060x04,0x00,0x31,0xae,0x00,0x60,0x90,0x40,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
5070x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x02,0x80,0x02,0x3c,
5080x68,0x15,0x47,0x24,0x8c,0x64,0xe3,0x90,0xff,0xff,0xa5,0x30,0x09,0x00,0xa3,0x10,
5090x21,0x20,0xc0,0x00,0xfc,0x64,0xe2,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0xc2,0xac,
5100x06,0x65,0xe3,0x94,0x0e,0x00,0x02,0x24,0x14,0x00,0xc2,0xac,0x8b,0x07,0x00,0x08,
5110x0c,0x00,0xc3,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x3c,
5120x25,0xb0,0x02,0x3c,0xd0,0xff,0xbd,0x27,0x4c,0x1f,0x63,0x24,0x18,0x03,0x42,0x34,
5130x28,0x00,0xbf,0xaf,0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,
5140x18,0x00,0xb0,0xaf,0x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
5150x00,0x60,0x81,0x40,0x2a,0xb0,0x02,0x3c,0x36,0x00,0x42,0x34,0x00,0x00,0x43,0x90,
5160x02,0x80,0x13,0x3c,0x68,0x15,0x66,0x26,0xc0,0x18,0x03,0x00,0x5c,0x65,0xc5,0x8c,
5170x23,0xb0,0x04,0x3c,0xf0,0x07,0x63,0x30,0xff,0x1f,0x02,0x3c,0x21,0x18,0x64,0x00,
5180xff,0xff,0x42,0x34,0x24,0x20,0x62,0x00,0x23,0x88,0x85,0x00,0x2b,0x38,0x85,0x00,
5190x00,0x04,0x22,0x26,0x00,0x65,0xc3,0x8c,0x0b,0x88,0x47,0x00,0x01,0x04,0x25,0x2e,
5200xfc,0x64,0xc3,0xac,0x60,0x65,0xc4,0xac,0x06,0x65,0xc0,0xa4,0x11,0x00,0xa0,0x14,
5210x05,0x65,0xc0,0xa0,0x00,0xfc,0x83,0x24,0x23,0x10,0x02,0x3c,0x0b,0x18,0x87,0x00,
5220xff,0x03,0x42,0x34,0x2b,0x10,0x43,0x00,0x33,0x00,0x40,0x14,0x00,0x00,0x00,0x00,
5230x23,0x88,0x83,0x00,0x2b,0x10,0x83,0x00,0x5c,0x65,0xc3,0xac,0x03,0x00,0x40,0x10,
5240x01,0x04,0x25,0x2e,0x00,0x04,0x31,0x26,0x01,0x04,0x25,0x2e,0x0e,0x00,0xa0,0x10,
5250x68,0x15,0x70,0x26,0x68,0x15,0x70,0x26,0x60,0x65,0x03,0x8e,0x5c,0x65,0x04,0x8e,
5260x00,0x00,0x00,0x00,0x2b,0x10,0x83,0x00,0x25,0x00,0x40,0x14,0x2b,0x10,0x64,0x00,
5270x51,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0x80,0x00,0x03,0x24,0xd0,0x03,0x42,0x34,
5280x00,0x00,0x43,0xac,0x68,0x15,0x70,0x26,0x5c,0x65,0x03,0x96,0x2a,0xb0,0x02,0x3c,
5290x35,0x00,0x42,0x34,0xc2,0x88,0x03,0x00,0x00,0x00,0x51,0xa0,0x8f,0x10,0x00,0x0c,
5300x00,0x00,0x00,0x00,0x06,0x65,0x03,0x96,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
5310x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
5320x00,0x60,0x81,0x40,0xfc,0x4a,0x02,0x8e,0x80,0x00,0x03,0x3c,0x41,0xb0,0x04,0x3c,
5330x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x28,0x00,0xbf,0x8f,0xfc,0x4a,0x02,0xae,
5340x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
5350x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x00,0x08,0x00,0x08,0x00,0xfc,0x63,0x24,
5360xfc,0x64,0x05,0x8e,0x21,0x30,0x80,0x00,0xff,0xff,0x27,0x32,0x09,0x00,0x04,0x24,
5370x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x05,0x96,
5380x5c,0x65,0x02,0x8e,0x21,0x18,0x71,0x00,0x21,0x28,0x25,0x02,0x21,0x10,0x51,0x00,
5390x09,0x00,0x04,0x24,0x5c,0x65,0x02,0xae,0xfc,0x64,0x03,0xae,0x4d,0x01,0x00,0x0c,
5400x06,0x65,0x05,0xa6,0x68,0x15,0x70,0x26,0x5c,0x65,0x03,0x96,0x2a,0xb0,0x02,0x3c,
5410x35,0x00,0x42,0x34,0xc2,0x88,0x03,0x00,0x00,0x00,0x51,0xa0,0x8f,0x10,0x00,0x0c,
5420x00,0x00,0x00,0x00,0x06,0x65,0x03,0x96,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
5430x00,0x00,0x43,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
5440x00,0x60,0x81,0x40,0xfc,0x4a,0x02,0x8e,0x80,0x00,0x03,0x3c,0x41,0xb0,0x04,0x3c,
5450x25,0x10,0x43,0x00,0x00,0x00,0x82,0xac,0x28,0x00,0xbf,0x8f,0xfc,0x4a,0x02,0xae,
5460x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
5470x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x64,0x65,0x02,0x8e,0xfc,0x64,0x05,0x8e,
5480x21,0x30,0x80,0x00,0x23,0x88,0x44,0x00,0xff,0xff,0x27,0x32,0x09,0x00,0x04,0x24,
5490x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x02,0x96,
5500x60,0x65,0x12,0x96,0x21,0x18,0x71,0x00,0x21,0x10,0x22,0x02,0x23,0x10,0x11,0x3c,
5510xfc,0x64,0x03,0xae,0x06,0x65,0x02,0xa6,0x06,0x00,0x40,0x16,0x5c,0x65,0x11,0xae,
5520x09,0x00,0x04,0x24,0x4d,0x01,0x00,0x0c,0x68,0x15,0x70,0x26,0x46,0x08,0x00,0x08,
5530x00,0x00,0x00,0x00,0x4d,0x01,0x00,0x0c,0x09,0x00,0x04,0x24,0xfc,0x64,0x05,0x8e,
5540x09,0x00,0x04,0x24,0x23,0x10,0x06,0x3c,0x21,0x38,0x40,0x02,0x10,0x01,0x00,0x0c,
5550x10,0x00,0xa0,0xaf,0xfc,0x64,0x03,0x8e,0x06,0x65,0x02,0x96,0x21,0x20,0x51,0x02,
5560x21,0x18,0x72,0x00,0x21,0x10,0x42,0x02,0x5c,0x65,0x04,0xae,0x09,0x00,0x04,0x24,
5570xfc,0x64,0x03,0xae,0x75,0x08,0x00,0x08,0x06,0x65,0x02,0xa6,0x02,0x80,0x09,0x3c,
5580x68,0x15,0x28,0x25,0xdc,0x63,0x06,0x8d,0xff,0xff,0x02,0x34,0x3f,0x00,0xc2,0x10,
5590x21,0x38,0x80,0x00,0x2b,0x10,0xc7,0x00,0x30,0x00,0x40,0x10,0x02,0x19,0x06,0x00,
5600x21,0x10,0xc7,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x46,0x24,0xdc,0x63,0x06,0xad,
5610x68,0x15,0x26,0x25,0x04,0x40,0xc4,0x8c,0xe0,0x63,0x02,0xad,0xff,0xff,0x02,0x34,
5620x2f,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0x2b,0x10,0x87,0x00,0x1f,0x00,0x40,0x10,
5630x02,0x19,0x04,0x00,0x21,0x10,0x87,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x44,0x24,
5640x04,0x40,0xc4,0xac,0xe0,0x63,0xc2,0xac,0xc0,0x10,0x05,0x00,0x21,0x10,0x45,0x00,
5650x80,0x10,0x02,0x00,0x21,0x10,0x45,0x00,0x68,0x15,0x23,0x25,0x80,0x10,0x02,0x00,
5660x21,0x28,0x43,0x00,0x68,0x51,0xa6,0x8c,0x00,0x21,0x07,0x00,0xff,0xff,0xc2,0x38,
5670x0a,0x30,0x82,0x00,0x2b,0x18,0xc7,0x00,0x07,0x00,0x60,0x10,0x21,0x10,0xc7,0x00,
5680x02,0x19,0x06,0x00,0x23,0x10,0x43,0x00,0x10,0x00,0x46,0x24,0x68,0x51,0xa6,0xac,
5690x08,0x00,0xe0,0x03,0x6c,0x51,0xa2,0xac,0x02,0x19,0x06,0x00,0x23,0x10,0x43,0x00,
5700x68,0x51,0xa2,0xac,0x08,0x00,0xe0,0x03,0x6c,0x51,0xa2,0xac,0x21,0x10,0x87,0x00,
5710x23,0x10,0x43,0x00,0xa5,0x08,0x00,0x08,0x04,0x40,0xc2,0xac,0x21,0x10,0xc7,0x00,
5720x68,0x15,0x26,0x25,0x04,0x40,0xc4,0x8c,0x23,0x10,0x43,0x00,0xdc,0x63,0x02,0xad,
5730xe0,0x63,0x02,0xad,0xff,0xff,0x02,0x34,0xd4,0xff,0x82,0x14,0x2b,0x10,0x87,0x00,
5740x00,0x21,0x07,0x00,0x9e,0x08,0x00,0x08,0x04,0x40,0xc4,0xac,0x00,0x31,0x04,0x00,
5750x91,0x08,0x00,0x08,0xdc,0x63,0x06,0xad,0x63,0x00,0x82,0x24,0x77,0x00,0x42,0x2c,
5760x00,0x00,0x85,0x28,0x04,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0x64,0x00,0x82,0x24,
5770x64,0x00,0x03,0x24,0x0b,0x18,0x45,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
5780x0c,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x3f,0x00,0x42,0x30,0x04,0x00,0x42,0x28,
5790x17,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x24,0x08,0x42,0x34,0x00,0x00,0x43,0x8c,
5800x00,0x00,0x00,0x00,0x00,0x02,0x63,0x30,0x16,0x00,0x60,0x14,0x01,0x00,0x02,0x24,
5810x05,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x82,0x21,0x03,0x00,0x28,0x00,0x82,0x10,
5820xf5,0xff,0x02,0x24,0x02,0x00,0x82,0x28,0x39,0x00,0x40,0x14,0x02,0x00,0x02,0x24,
5830x2e,0x00,0x82,0x10,0xe9,0xff,0x02,0x24,0x03,0x00,0x02,0x24,0x24,0x00,0x82,0x10,
5840x3e,0x00,0x63,0x30,0x05,0x00,0xc4,0x24,0xd2,0x08,0x00,0x08,0x00,0x00,0x00,0x00,
5850x04,0x00,0xa4,0x90,0x00,0x00,0x00,0x00,0x42,0x20,0x04,0x00,0xd2,0x08,0x00,0x08,
5860x96,0xff,0x84,0x24,0x05,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x60,0x00,0x64,0x30,
5870x42,0x21,0x04,0x00,0x0e,0x00,0x82,0x10,0x1f,0x00,0x62,0x30,0x02,0x00,0x82,0x28,
5880x1d,0x00,0x40,0x14,0x02,0x00,0x02,0x24,0x14,0x00,0x82,0x10,0x1f,0x00,0x62,0x30,
5890x03,0x00,0x02,0x24,0xeb,0xff,0x82,0x14,0x1f,0x00,0x62,0x30,0x40,0x10,0x02,0x00,
5900xdd,0xff,0x03,0x24,0x23,0x30,0x62,0x00,0xf6,0x08,0x00,0x08,0x05,0x00,0xc4,0x24,
5910x40,0x10,0x02,0x00,0xf5,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00,
5920x3e,0x00,0x63,0x30,0x23,0x30,0x43,0x00,0xf6,0x08,0x00,0x08,0x05,0x00,0xc4,0x24,
5930xdd,0xff,0x02,0x24,0x16,0x09,0x00,0x08,0x23,0x30,0x43,0x00,0x40,0x10,0x02,0x00,
5940xe9,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00,0x3e,0x00,0x63,0x30,
5950x16,0x09,0x00,0x08,0x23,0x30,0x43,0x00,0xd2,0xff,0x80,0x14,0x1f,0x00,0x62,0x30,
5960x40,0x10,0x02,0x00,0xf8,0xff,0x03,0x24,0x0e,0x09,0x00,0x08,0x23,0x30,0x62,0x00,
5970xcc,0xff,0x80,0x14,0x3e,0x00,0x63,0x30,0xf8,0xff,0x02,0x24,0x16,0x09,0x00,0x08,
5980x23,0x30,0x43,0x00,0xa0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x4c,0x00,0xb5,0xaf,
5990x5c,0x00,0xbf,0xaf,0x58,0x00,0xbe,0xaf,0x54,0x00,0xb7,0xaf,0x50,0x00,0xb6,0xaf,
6000x48,0x00,0xb4,0xaf,0x44,0x00,0xb3,0xaf,0x40,0x00,0xb2,0xaf,0x3c,0x00,0xb1,0xaf,
6010x38,0x00,0xb0,0xaf,0x68,0x15,0x55,0x24,0x25,0xb0,0x03,0x3c,0x04,0x01,0x62,0x34,
6020x00,0x00,0x43,0x8c,0x44,0x65,0xa7,0x8e,0x00,0x00,0x00,0x00,0x33,0x00,0xe3,0x10,
6030x48,0x65,0xa3,0xae,0x2b,0x10,0x67,0x00,0xa8,0x00,0x40,0x14,0x2b,0x10,0xe3,0x00,
6040xd1,0x00,0x40,0x14,0x02,0x80,0x02,0x3c,0x68,0x15,0x44,0x24,0x18,0x65,0x83,0x94,
6050x02,0x80,0x02,0x3c,0x21,0x88,0x00,0x00,0x19,0x00,0x40,0x1a,0x25,0x98,0x62,0x00,
6060x21,0xb8,0x80,0x00,0x21,0xb0,0x80,0x00,0x01,0x00,0x14,0x24,0x21,0x20,0x00,0x00,
6070x21,0x80,0x93,0x00,0x00,0x00,0x05,0x8e,0x00,0x00,0x00,0x00,0x07,0x00,0xa0,0x10,
6080x01,0x00,0x22,0x26,0x04,0x00,0x02,0x8e,0x00,0xf0,0x03,0x3c,0x00,0x20,0x04,0x3c,
6090x24,0x10,0x43,0x00,0x1e,0x00,0x44,0x10,0x06,0x00,0x22,0x26,0xff,0xff,0x51,0x30,
6100x82,0x16,0x05,0x00,0x01,0x00,0x42,0x30,0x34,0x00,0x54,0x10,0x00,0x00,0x00,0x00,
6110x80,0x20,0x11,0x00,0x2a,0x10,0x92,0x00,0xed,0xff,0x40,0x14,0x00,0x00,0x00,0x00,
6120xbd,0x4e,0x00,0x0c,0x21,0x20,0xc0,0x03,0x02,0x80,0x02,0x3c,0x08,0x04,0x44,0x24,
6130x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,
6140x25,0xb0,0x03,0x3c,0x04,0x01,0x62,0x34,0x00,0x00,0x43,0x8c,0x44,0x65,0xa7,0x8e,
6150x00,0x00,0x00,0x00,0xcf,0xff,0xe3,0x14,0x48,0x65,0xa3,0xae,0x25,0xb0,0x03,0x3c,
6160x00,0x01,0x62,0x34,0x00,0x00,0x47,0xac,0x66,0x09,0x00,0x08,0x44,0x65,0xa7,0xae,
6170xb0,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xb0,0x4c,0xe2,0xae,
6180x0c,0x00,0x04,0x8e,0x0c,0x00,0x02,0x24,0x3f,0x00,0x83,0x30,0x64,0x00,0x62,0x10,
6190x21,0x28,0xe0,0x02,0x3f,0x00,0x83,0x30,0x0d,0x00,0x02,0x24,0x59,0x00,0x62,0x10,
6200x00,0x00,0x00,0x00,0x3f,0x00,0x83,0x30,0x0e,0x00,0x02,0x24,0x04,0x00,0x62,0x10,
6210x00,0x00,0x00,0x00,0x00,0x00,0x05,0x8e,0x5b,0x09,0x00,0x08,0x06,0x00,0x22,0x26,
6220xbc,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xbc,0x4c,0xe2,0xae,
6230x00,0x00,0x05,0x8e,0x5b,0x09,0x00,0x08,0x06,0x00,0x22,0x26,0x00,0x40,0xc2,0x8e,
6240x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x0f,0x00,0x42,0x30,0x05,0x00,0x54,0x10,
6250xc2,0x13,0x05,0x00,0x1e,0x00,0x42,0x30,0x21,0x10,0x51,0x00,0x60,0x09,0x00,0x08,
6260xff,0xff,0x51,0x30,0x02,0x40,0xc2,0x92,0x00,0x00,0x00,0x00,0x1e,0x00,0x40,0x14,
6270x02,0x80,0x03,0x3c,0x04,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,
6280x0f,0x00,0x42,0x30,0x17,0x00,0x40,0x14,0x02,0x17,0x03,0x00,0x03,0x00,0x44,0x30,
6290x08,0x00,0x80,0x10,0x00,0xc0,0x02,0x3c,0x24,0x10,0x62,0x00,0x11,0x00,0x40,0x14,
6300x03,0x00,0x02,0x24,0x10,0x00,0x82,0x10,0x02,0x80,0x03,0x3c,0x0f,0x00,0x80,0x10,
6310x68,0x15,0x63,0x24,0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c,
6320x25,0xb0,0x02,0x3c,0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac,
6330xdc,0x08,0x00,0x0c,0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c,
6340x21,0x28,0x00,0x00,0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x02,0x40,0x62,0x90,
6350x00,0x00,0x00,0x00,0x85,0x00,0x54,0x10,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,
6360x68,0x15,0x84,0x24,0x02,0x40,0x83,0x90,0x02,0x00,0x02,0x24,0x68,0x00,0x62,0x10,
6370x00,0x00,0x00,0x00,0x25,0xb0,0x03,0x3c,0x4c,0x00,0x63,0x34,0x00,0x00,0x62,0x90,
6380x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,0x08,0x00,0x54,0x10,0x02,0x80,0x04,0x3c,
6390x00,0x00,0x05,0x8e,0x00,0x00,0x00,0x00,0xc2,0x13,0x05,0x00,0x1e,0x00,0x42,0x30,
6400x21,0x10,0x51,0x00,0x60,0x09,0x00,0x08,0xff,0xff,0x51,0x30,0xd0,0x02,0x02,0x24,
6410x68,0x15,0x84,0x24,0xdc,0x63,0x82,0xac,0x00,0x00,0x05,0x8e,0xd3,0x09,0x00,0x08,
6420xc2,0x13,0x05,0x00,0xb8,0x4c,0xa2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,
6430xb8,0x4c,0xa2,0xac,0x0c,0x00,0x04,0x8e,0x86,0x09,0x00,0x08,0x3f,0x00,0x83,0x30,
6440xb4,0x4c,0xe2,0x8e,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xb4,0x4c,0xe2,0xae,
6450x0c,0x00,0x04,0x8e,0x82,0x09,0x00,0x08,0x3f,0x00,0x83,0x30,0x4c,0x65,0xa2,0x8e,
6460xff,0xff,0x71,0x30,0x23,0x10,0x47,0x00,0xff,0xff,0x50,0x30,0x21,0x18,0x11,0x02,
6470xff,0xff,0x72,0x30,0xa1,0x4e,0x00,0x0c,0x21,0x20,0x40,0x02,0x76,0x00,0x40,0x10,
6480x21,0xf0,0x40,0x00,0x08,0x00,0x42,0x8c,0x44,0x65,0xa6,0x8e,0x21,0x38,0x00,0x02,
6490x21,0x18,0x52,0x00,0x21,0x28,0x40,0x00,0x08,0x00,0x04,0x24,0x14,0x65,0xa3,0xae,
6500x18,0x65,0xa2,0xae,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x4d,0x01,0x00,0x0c,
6510x08,0x00,0x04,0x24,0x18,0x65,0xa5,0x8e,0x25,0xb0,0x03,0x3c,0x24,0x10,0x02,0x3c,
6520x21,0x28,0xb0,0x00,0x00,0x01,0x70,0x34,0x00,0x00,0x02,0xae,0x21,0x38,0x20,0x02,
6530x08,0x00,0x04,0x24,0x24,0x10,0x06,0x3c,0x44,0x65,0xa2,0xae,0x10,0x01,0x00,0x0c,
6540x10,0x00,0xa0,0xaf,0x48,0x65,0xa3,0x8e,0x08,0x00,0x04,0x24,0x4d,0x01,0x00,0x0c,
6550x44,0x65,0xa3,0xae,0x44,0x65,0xa2,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xae,
6560x46,0x09,0x00,0x08,0x02,0x80,0x02,0x3c,0x23,0x10,0x67,0x00,0xff,0xff,0x52,0x30,
6570xa1,0x4e,0x00,0x0c,0x21,0x20,0x40,0x02,0x56,0x00,0x40,0x10,0x21,0xf0,0x40,0x00,
6580x08,0x00,0x42,0x8c,0x44,0x65,0xa6,0x8e,0x08,0x00,0x04,0x24,0x21,0x18,0x52,0x00,
6590x21,0x28,0x40,0x00,0x21,0x38,0x40,0x02,0x14,0x65,0xa3,0xae,0x18,0x65,0xa2,0xae,
6600x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x48,0x65,0xa3,0x8e,0x08,0x00,0x04,0x24,
6610x4d,0x01,0x00,0x0c,0x44,0x65,0xa3,0xae,0x44,0x65,0xa3,0x8e,0x25,0xb0,0x04,0x3c,
6620x00,0x01,0x82,0x34,0x00,0x00,0x43,0xac,0x46,0x09,0x00,0x08,0x02,0x80,0x02,0x3c,
6630x04,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,0x0f,0x00,0x42,0x30,
6640x08,0x00,0x42,0x28,0x93,0xff,0x40,0x10,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30,
6650x90,0xff,0x40,0x14,0x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c,
6660x25,0xb0,0x02,0x3c,0xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac,
6670xdc,0x08,0x00,0x0c,0x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c,
6680x21,0x28,0x00,0x00,0xca,0x09,0x00,0x08,0x25,0xb0,0x03,0x3c,0x04,0x00,0x03,0x8e,
6690x00,0x00,0x00,0x00,0x02,0x14,0x03,0x00,0x0f,0x00,0x42,0x30,0x08,0x00,0x42,0x28,
6700x06,0x00,0x40,0x10,0x00,0xc0,0x02,0x3c,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30,
6710x0c,0x00,0x40,0x10,0x80,0x10,0x11,0x00,0x00,0xc0,0x02,0x3c,0x24,0x10,0x62,0x00,
6720x6f,0xff,0x40,0x14,0x02,0x80,0x04,0x3c,0x02,0x17,0x03,0x00,0x03,0x00,0x42,0x30,
6730x03,0x00,0x03,0x24,0x6b,0xff,0x43,0x10,0x68,0x15,0x84,0x24,0x67,0xff,0x40,0x10,
6740x80,0x10,0x11,0x00,0x21,0x28,0x53,0x00,0xec,0xff,0xa3,0x8c,0x25,0xb0,0x02,0x3c,
6750xd4,0x02,0x42,0x34,0x21,0x20,0x00,0x02,0x00,0x00,0x43,0xac,0xdc,0x08,0x00,0x0c,
6760x00,0x00,0x00,0x00,0x21,0x20,0x40,0x00,0x8b,0x08,0x00,0x0c,0x21,0x28,0x00,0x00,
6770xc4,0x09,0x00,0x08,0x02,0x80,0x04,0x3c,0x25,0xb0,0x04,0x3c,0x44,0x44,0x02,0x3c,
6780xbc,0x02,0x83,0x34,0x44,0x44,0x42,0x34,0x00,0x00,0x62,0xac,0x67,0x09,0x00,0x08,
6790x02,0x80,0x02,0x3c,0x48,0x65,0xa5,0x8e,0x25,0xb0,0x04,0x3c,0x66,0x66,0x02,0x3c,
6800x00,0x01,0x83,0x34,0x66,0x66,0x42,0x34,0xbc,0x02,0x84,0x34,0x00,0x00,0x65,0xac,
6810x00,0x00,0x82,0xac,0x66,0x09,0x00,0x08,0x44,0x65,0xa5,0xae,0x00,0x60,0x02,0x40,
6820x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x02,0x80,0x03,0x3c,
6830xd8,0x8c,0x64,0xac,0x00,0x60,0x82,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
6840x02,0x80,0x02,0x3c,0xd8,0x8c,0x45,0x8c,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
6850x18,0x03,0x42,0x34,0x10,0x2a,0x63,0x24,0x00,0x00,0x43,0xac,0x04,0x00,0x02,0x24,
6860x1e,0x00,0xa2,0x10,0x05,0x00,0xa2,0x2c,0x10,0x00,0x40,0x10,0x05,0x00,0x02,0x24,
6870x03,0x00,0x02,0x24,0x08,0x00,0xa2,0x10,0x00,0x19,0x04,0x00,0x80,0x10,0x04,0x00,
6880x21,0x10,0x44,0x00,0xc0,0x10,0x02,0x00,0x23,0x10,0x44,0x00,0x00,0x11,0x02,0x00,
6890x21,0x10,0x44,0x00,0x40,0x19,0x02,0x00,0xff,0xff,0x63,0x24,0xfe,0xff,0x60,0x14,
6900x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xf3,0xff,0xa2,0x10,
6910x06,0x00,0x02,0x24,0xf2,0xff,0xa2,0x14,0x80,0x10,0x04,0x00,0x40,0x11,0x04,0x00,
6920x23,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,0x00,0x19,0x02,0x00,
6930x23,0x18,0x62,0x00,0x9a,0x0a,0x00,0x08,0x00,0x19,0x03,0x00,0x80,0x10,0x04,0x00,
6940x21,0x10,0x44,0x00,0xc0,0x10,0x02,0x00,0x23,0x10,0x44,0x00,0x00,0x11,0x02,0x00,
6950x21,0x10,0x44,0x00,0x9a,0x0a,0x00,0x08,0x00,0x19,0x02,0x00,0x02,0x80,0x02,0x3c,
6960xd8,0x8c,0x45,0x8c,0x00,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x18,0x03,0x42,0x34,
6970xcc,0x2a,0x63,0x24,0x00,0x00,0x43,0xac,0x05,0x00,0x02,0x24,0x10,0x00,0xa2,0x10,
6980x06,0x00,0xa2,0x2c,0x09,0x00,0x40,0x14,0x04,0x00,0x02,0x24,0x06,0x00,0x02,0x24,
6990x0f,0x00,0xa2,0x10,0x00,0x11,0x04,0x00,0xff,0xff,0x84,0x24,0xfe,0xff,0x80,0x14,
7000x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xfa,0xff,0xa2,0x14,
7010x80,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x40,0x20,0x02,0x00,
7020x80,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x80,0x20,0x02,0x00,
7030x23,0x10,0x44,0x00,0xc2,0x0a,0x00,0x08,0x40,0x20,0x02,0x00,0xff,0xff,0x85,0x30,
7040x21,0x30,0x00,0x00,0x25,0xb0,0x03,0x3c,0x2a,0xb0,0x04,0x3c,0xb4,0x00,0x63,0x34,
7050x01,0x00,0xa2,0x24,0x31,0x00,0x84,0x34,0x00,0x00,0x65,0xa0,0x00,0x00,0x85,0xa0,
7060xff,0xff,0x45,0x30,0x12,0x00,0xa0,0x10,0x01,0x00,0x03,0x24,0x28,0xb0,0x07,0x3c,
7070xe8,0x0a,0x00,0x08,0xff,0xff,0x08,0x24,0x00,0x00,0x83,0xa0,0x01,0x00,0x63,0x24,
7080xff,0xff,0x63,0x30,0x2b,0x10,0xa3,0x00,0x09,0x00,0x40,0x14,0x08,0x00,0xc6,0x24,
7090xf9,0xff,0x65,0x14,0x21,0x20,0xc7,0x00,0x01,0x00,0x63,0x24,0xff,0xff,0x63,0x30,
7100x2b,0x10,0xa3,0x00,0x00,0x00,0x88,0xa0,0xf9,0xff,0x40,0x10,0x08,0x00,0xc6,0x24,
7110x00,0x01,0xa2,0x2c,0x13,0x00,0x40,0x10,0x21,0x18,0xa0,0x00,0xff,0x00,0x08,0x24,
7120x28,0xb0,0x07,0x3c,0xfc,0x0a,0x00,0x08,0xff,0xff,0x09,0x24,0xff,0xff,0x43,0x30,
7130x00,0x00,0xa2,0xa0,0x00,0x01,0x62,0x2c,0x0a,0x00,0x40,0x10,0x08,0x00,0xc6,0x24,
7140x01,0x00,0x62,0x24,0xf9,0xff,0x68,0x14,0x21,0x28,0xc7,0x00,0x00,0x01,0x02,0x24,
7150xff,0xff,0x43,0x30,0x00,0x01,0x62,0x2c,0x00,0x00,0xa9,0xa0,0xf8,0xff,0x40,0x14,
7160x08,0x00,0xc6,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xd8,0xff,0xbd,0x27,
7170x24,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,
7180x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
7190x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x42,0x00,0x14,0x36,
7200xff,0xff,0x02,0x24,0x00,0x00,0x82,0xa2,0xd8,0x00,0x05,0x36,0x40,0x00,0x11,0x36,
7210xa8,0x00,0x13,0x36,0xa0,0x00,0x12,0x36,0x00,0x10,0x03,0x24,0xa4,0x00,0x10,0x36,
7220x00,0x80,0x02,0x3c,0x00,0x00,0x23,0xa6,0x00,0x00,0xa0,0xa0,0x00,0x00,0x40,0xae,
7230x00,0x00,0x00,0xae,0x00,0x00,0x62,0xae,0x00,0x00,0xa3,0x90,0x80,0xff,0x02,0x24,
7240xfd,0x00,0x04,0x24,0x25,0x18,0x62,0x00,0xfc,0x17,0x02,0x24,0x00,0x00,0xa3,0xa0,
7250x00,0x00,0x22,0xa6,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
7260x68,0x15,0x42,0x24,0x68,0x4b,0x45,0x8c,0x60,0x4b,0x43,0x8c,0x64,0x4b,0x44,0x8c,
7270xfc,0x37,0x02,0x24,0x00,0x00,0x43,0xae,0x00,0x00,0x04,0xae,0x00,0x00,0x65,0xae,
7280x00,0x00,0x22,0xa6,0x00,0x00,0x80,0xa2,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
7290x00,0x60,0x81,0x40,0x24,0x00,0xbf,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
7300x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
7310x28,0x00,0xbd,0x27,0xd0,0xff,0xbd,0x27,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,
7320x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,
7330x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
7340x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x40,0x00,0x05,0x36,
7350x00,0x00,0xa2,0x94,0x24,0xfa,0x03,0x24,0xa8,0x00,0x13,0x36,0x24,0x10,0x43,0x00,
7360x00,0x00,0xa2,0xa4,0xa0,0x00,0x12,0x36,0xa4,0x00,0x10,0x36,0x00,0x00,0x55,0x8e,
7370x00,0x00,0x16,0x8e,0x00,0x00,0x71,0x8e,0x00,0x80,0x14,0x3c,0xfc,0x37,0x02,0x24,
7380x00,0x00,0x40,0xae,0xfd,0x00,0x04,0x24,0x00,0x00,0x00,0xae,0x21,0x88,0x34,0x02,
7390x00,0x00,0x74,0xae,0x00,0x00,0xa2,0xa4,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,
7400x00,0x00,0x55,0xae,0x00,0x00,0x16,0xae,0x00,0x00,0x71,0xae,0x00,0x60,0x01,0x40,
7410x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,
7420x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,
7430x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
7440xd0,0xff,0xbd,0x27,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf,
7450x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,
7460x10,0x00,0xb0,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
7470x00,0x60,0x81,0x40,0x25,0xb0,0x10,0x3c,0x40,0x00,0x05,0x36,0x00,0x00,0xa2,0x94,
7480xaf,0xff,0x03,0x24,0xa8,0x00,0x13,0x36,0x24,0x10,0x43,0x00,0x00,0x00,0xa2,0xa4,
7490xa0,0x00,0x12,0x36,0xa4,0x00,0x10,0x36,0x00,0x00,0x55,0x8e,0x00,0x00,0x16,0x8e,
7500x00,0x00,0x71,0x8e,0x00,0x80,0x14,0x3c,0xfc,0x37,0x02,0x24,0x00,0x00,0x40,0xae,
7510xfd,0x00,0x04,0x24,0x00,0x00,0x00,0xae,0x21,0x88,0x34,0x02,0x00,0x00,0x74,0xae,
7520x00,0x00,0xa2,0xa4,0xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xae,
7530x00,0x00,0x16,0xae,0x00,0x00,0x71,0xae,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
7540x00,0x60,0x81,0x40,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,
7550x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
7560x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x00,0x60,0x01,0x40,
7570x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x25,0xb0,0x04,0x3c,
7580x40,0x00,0x84,0x34,0x00,0x00,0x82,0x94,0xd8,0xfd,0x03,0x24,0x24,0x10,0x43,0x00,
7590xfc,0x37,0x03,0x24,0x00,0x00,0x82,0xa4,0x00,0x00,0x83,0xa4,0x00,0x60,0x01,0x40,
7600x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
7610x00,0x00,0x82,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30,
7620x10,0x00,0x02,0x24,0x0c,0x00,0xc2,0x10,0x11,0x00,0xc3,0x28,0x06,0x00,0x60,0x10,
7630x20,0x00,0x02,0x24,0x08,0x00,0x02,0x24,0x0d,0x00,0xc2,0x10,0x00,0x00,0x00,0x00,
7640x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x06,0x00,0xc2,0x10,0x00,0x00,0x00,0x00,
7650x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xa4,0x08,0x00,0xe0,0x03,
7660x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
7670x00,0x00,0x85,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
7680x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x25,0xb0,0x02,0x3c,
7690x0a,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0xff,0xff,0xa5,0x24,0x00,0x2c,0x05,0x00,
7700xfd,0x00,0x63,0x30,0x03,0x2c,0x05,0x00,0xff,0xff,0x87,0x30,0x00,0x00,0x43,0xa0,
7710x1a,0x00,0xa0,0x04,0x00,0x00,0x00,0x00,0x21,0x30,0x40,0x00,0x07,0x10,0xa7,0x00,
7720x01,0x00,0x42,0x30,0xfd,0x00,0x64,0x30,0x00,0x00,0x42,0x38,0x02,0x00,0x63,0x34,
7730x0a,0x18,0x82,0x00,0x00,0x00,0xc3,0xa0,0x04,0x00,0x63,0x34,0x00,0x00,0xc3,0xa0,
7740x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,
7750xfb,0x00,0x63,0x30,0x00,0x00,0xc3,0xa0,0x04,0x00,0x02,0x24,0xff,0xff,0x42,0x24,
7760xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0xff,0xff,0xa2,0x24,0x00,0x2c,0x02,0x00,
7770x03,0x2c,0x05,0x00,0xea,0xff,0xa1,0x04,0x07,0x10,0xa7,0x00,0x08,0x00,0xe0,0x03,
7780x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,0x0a,0x00,0x42,0x34,0x00,0x00,0x43,0x90,
7790xff,0xff,0x84,0x24,0x00,0x24,0x04,0x00,0x03,0x24,0x04,0x00,0xff,0x00,0x65,0x30,
7800x1d,0x00,0x80,0x04,0x21,0x38,0x00,0x00,0x21,0x30,0x40,0x00,0x01,0x00,0x08,0x24,
7810x04,0x00,0xa5,0x34,0x00,0x00,0xc5,0xa0,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
7820xff,0x00,0x45,0x30,0x01,0x00,0xa3,0x30,0x05,0x00,0x60,0x10,0x04,0x00,0x02,0x24,
7830x04,0x10,0x88,0x00,0x25,0x10,0x47,0x00,0xff,0xff,0x47,0x30,0x04,0x00,0x02,0x24,
7840xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0xfb,0x00,0xa5,0x30,
7850x00,0x00,0xc5,0xa0,0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,
7860xff,0xff,0x42,0x24,0xff,0xff,0x82,0x24,0x00,0x24,0x02,0x00,0x03,0x24,0x04,0x00,
7870xe7,0xff,0x81,0x04,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0xe0,0x00,
7880xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x0a,0x00,0x10,0x36,
7890x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x00,0x00,0x02,0x92,0xff,0xff,0x91,0x30,
7900x03,0x00,0x05,0x24,0xc0,0x00,0x42,0x30,0x80,0x00,0x43,0x34,0x00,0x00,0x03,0xa2,
7910x04,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,0xfb,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,
7920x08,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,0x04,0x00,0x63,0x34,0x00,0x00,0x03,0xa2,
7930xfb,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,0xd7,0x0b,0x00,0x0c,0x06,0x00,0x04,0x24,
7940x42,0x20,0x11,0x00,0xd7,0x0b,0x00,0x0c,0x06,0x00,0x05,0x24,0xfd,0x0b,0x00,0x0c,
7950x10,0x00,0x04,0x24,0x00,0x00,0x03,0x92,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
7960xc0,0x00,0x63,0x30,0x00,0x00,0x03,0xa2,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
7970x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0xff,0xff,0xb1,0x30,
7980x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x1c,0x00,0xbf,0xaf,0x21,0x90,0xc0,0x00,
7990x0a,0x00,0x20,0x12,0xff,0xff,0x90,0x30,0x24,0x0c,0x00,0x0c,0x21,0x20,0x00,0x02,
8000xfe,0xff,0x23,0x26,0x02,0x00,0x04,0x26,0x00,0x00,0x42,0xa6,0xff,0xff,0x71,0x30,
8010xff,0xff,0x90,0x30,0xf8,0xff,0x20,0x16,0x02,0x00,0x52,0x26,0x1c,0x00,0xbf,0x8f,
8020x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
8030x20,0x00,0xbd,0x27,0x25,0xb0,0x03,0x3c,0x0a,0x00,0x68,0x34,0x00,0x00,0x02,0x91,
8040xff,0xff,0xa5,0x30,0xff,0x00,0x84,0x30,0x1f,0x00,0xa0,0x10,0xff,0x00,0x47,0x30,
8050x21,0x48,0x00,0x01,0x0c,0x00,0x6c,0x34,0x0b,0x00,0x6b,0x34,0xc0,0xff,0x0a,0x24,
8060x21,0x68,0x00,0x01,0x25,0x10,0xea,0x00,0xff,0x00,0x47,0x30,0x00,0x00,0x64,0xa1,
8070x00,0x00,0x27,0xa1,0x00,0x00,0x22,0x91,0x00,0x00,0x00,0x00,0xff,0x00,0x47,0x30,
8080xc0,0x00,0xe3,0x30,0x08,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x21,0x40,0xa0,0x01,
8090x00,0x00,0x02,0x91,0x00,0x00,0x00,0x00,0xff,0x00,0x47,0x30,0xc0,0x00,0xe3,0x30,
8100xfb,0xff,0x60,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0x8d,0xfc,0xff,0xa3,0x24,
8110x04,0x00,0x84,0x24,0xff,0xff,0x65,0x30,0x00,0x00,0xc2,0xac,0xff,0x00,0x84,0x30,
8120xe8,0xff,0xa0,0x14,0x04,0x00,0xc6,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
8130xff,0x00,0x84,0x30,0x21,0x68,0xe0,0x00,0xff,0xff,0xa5,0x30,0xc0,0x50,0x04,0x00,
8140x00,0x60,0x0c,0x40,0x01,0x00,0x81,0x35,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
8150x00,0x00,0xc2,0x90,0x01,0x00,0xc3,0x90,0x25,0xb0,0x07,0x3c,0x00,0x14,0x02,0x00,
8160x25,0x28,0xa2,0x00,0x00,0x1e,0x03,0x00,0x01,0x80,0x08,0x3c,0x25,0x20,0xa3,0x00,
8170x40,0x02,0xe9,0x34,0x25,0x18,0x48,0x01,0x44,0x02,0xe7,0x34,0x00,0x00,0xe4,0xac,
8180x00,0x00,0x23,0xad,0x03,0x00,0xc2,0x90,0x02,0x00,0xc4,0x90,0x04,0x00,0xc3,0x90,
8190x05,0x00,0xc5,0x90,0x00,0x12,0x02,0x00,0x25,0x20,0x82,0x00,0x00,0x1c,0x03,0x00,
8200x01,0x00,0x4a,0x25,0x25,0x20,0x83,0x00,0x00,0x2e,0x05,0x00,0x25,0x40,0x48,0x01,
8210x25,0x20,0x85,0x00,0x00,0x00,0xe4,0xac,0x01,0x00,0x4a,0x25,0x00,0x00,0x28,0xad,
8220x01,0x80,0x0b,0x3c,0x21,0x40,0x00,0x00,0x21,0x10,0xa8,0x01,0x01,0x00,0x43,0x90,
8230x00,0x00,0x45,0x90,0x02,0x00,0x44,0x90,0x03,0x00,0x46,0x90,0x00,0x1a,0x03,0x00,
8240x25,0x28,0xa3,0x00,0x00,0x24,0x04,0x00,0x25,0x28,0xa4,0x00,0x00,0x36,0x06,0x00,
8250x04,0x00,0x08,0x25,0x25,0x10,0x4b,0x01,0x25,0x20,0xa6,0x00,0x10,0x00,0x03,0x2d,
8260x00,0x00,0xe4,0xac,0x01,0x00,0x4a,0x25,0x00,0x00,0x22,0xad,0xee,0xff,0x60,0x14,
8270x00,0x00,0x00,0x00,0x00,0x60,0x8c,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
8280xff,0xff,0x84,0x30,0x42,0xb0,0x08,0x3c,0x80,0x10,0x04,0x00,0x21,0x10,0x48,0x00,
8290x04,0x00,0x46,0xac,0x00,0x00,0x07,0x91,0x40,0x18,0x04,0x00,0x03,0x00,0x06,0x24,
8300xff,0x00,0xe7,0x30,0x04,0x30,0x66,0x00,0x01,0x00,0x02,0x24,0x04,0x10,0x62,0x00,
8310x25,0x30,0xc7,0x00,0xff,0xff,0xa5,0x30,0x25,0x10,0x47,0x00,0x02,0x00,0xa0,0x14,
8320xff,0x00,0xc7,0x30,0xff,0x00,0x47,0x30,0x42,0xb0,0x02,0x3c,0x00,0x00,0x47,0xa0,
8330x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x42,0xb0,0x02,0x3c,0x03,0x00,0x47,0x34,
8340x00,0x00,0xe3,0x90,0xff,0x00,0x84,0x30,0x04,0x00,0x84,0x24,0xff,0x00,0x65,0x30,
8350x01,0x00,0x02,0x24,0x04,0x30,0x82,0x00,0x07,0x18,0x85,0x00,0x25,0xb0,0x02,0x3c,
8360xe8,0x03,0x42,0x34,0x01,0x00,0x63,0x30,0x21,0x20,0xc0,0x00,0x00,0x00,0x45,0xa0,
8370x02,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xe6,0xa0,0x08,0x00,0xe0,0x03,
8380x24,0x10,0x85,0x00,0x00,0x60,0x03,0x40,0x01,0x00,0x61,0x34,0x01,0x00,0x21,0x38,
8390x00,0x60,0x81,0x40,0x02,0x80,0x02,0x3c,0xdc,0x8c,0x42,0x24,0x04,0x00,0x45,0x8c,
8400x00,0x00,0x82,0xac,0x04,0x00,0x44,0xac,0x00,0x00,0xa4,0xac,0x04,0x00,0x85,0xac,
8410x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x14,0x00,0x83,0x90,
8420x01,0x00,0x02,0x24,0x08,0x00,0x86,0xac,0x18,0x00,0x85,0xac,0x00,0x00,0x84,0xac,
8430x03,0x00,0x62,0x10,0x04,0x00,0x84,0xac,0xed,0x0c,0x00,0x08,0x0c,0x00,0x80,0xac,
8440x0c,0x00,0x82,0x8c,0xed,0x0c,0x00,0x08,0x10,0x00,0x82,0xac,0x00,0x60,0x03,0x40,
8450x01,0x00,0x61,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x04,0x00,0x85,0x8c,
8460x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xac,0x04,0x00,0x45,0xac,
8470x00,0x00,0x84,0xac,0x04,0x00,0x84,0xac,0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,
8480x00,0x00,0x00,0x00,0xd0,0xff,0xbd,0x27,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf,
8490x20,0x00,0xb4,0xaf,0x14,0x00,0xb1,0xaf,0x2c,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,
8500x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x80,0x16,0x3c,0x02,0x80,0x14,0x3c,
8510x02,0x80,0x11,0x3c,0x02,0x80,0x15,0x3c,0xc4,0x7d,0x24,0x8e,0x25,0xb0,0x02,0x3c,
8520x54,0x34,0xc3,0x26,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0xdc,0x8c,0x90,0x8e,
8530x18,0x00,0x80,0x10,0xdc,0x8c,0x82,0x26,0x15,0x00,0x02,0x12,0x00,0x00,0x00,0x00,
8540x21,0x98,0x40,0x00,0x01,0x00,0x12,0x24,0x14,0x00,0x02,0x92,0x00,0x00,0x00,0x00,
8550x1d,0x00,0x52,0x10,0x00,0x00,0x00,0x00,0x09,0x00,0x40,0x14,0x00,0x00,0x00,0x00,
8560x0c,0x00,0x03,0x8e,0xc4,0x7d,0x22,0x8e,0x00,0x00,0x00,0x00,0x23,0x20,0x62,0x00,
8570x2b,0x10,0x43,0x00,0x0e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0xae,
8580x00,0x00,0x10,0x8e,0x00,0x00,0x00,0x00,0xef,0xff,0x13,0x16,0x00,0x00,0x00,0x00,
8590xc4,0x7d,0x20,0xae,0x08,0x0c,0xa4,0x26,0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,
8600x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0x22,0x0d,0x00,0x08,0x00,0x00,0x00,0x00,
8610x08,0x00,0x02,0x8e,0x18,0x00,0x04,0x8e,0x09,0xf8,0x40,0x00,0x00,0x00,0x00,0x00,
8620x3c,0x0d,0x00,0x08,0x0c,0x00,0x02,0xae,0x0c,0x00,0x03,0x8e,0xc4,0x7d,0x22,0x8e,
8630x00,0x00,0x00,0x00,0x23,0x20,0x62,0x00,0x2b,0x10,0x43,0x00,0xe7,0xff,0x40,0x14,
8640x00,0x00,0x00,0x00,0x08,0x00,0x02,0x8e,0x18,0x00,0x04,0x8e,0x09,0xf8,0x40,0x00,
8650x00,0x00,0x00,0x00,0x10,0x00,0x03,0x8e,0x3c,0x0d,0x00,0x08,0x0c,0x00,0x03,0xae,
8660xff,0x00,0xa5,0x30,0x25,0xb0,0x02,0x3c,0x21,0x28,0xa2,0x00,0xff,0x00,0x84,0x30,
8670x60,0x01,0xa4,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0x84,0x30,
8680x01,0x00,0x03,0x24,0x10,0x00,0x02,0x3c,0x04,0x18,0x83,0x00,0xf0,0x70,0x42,0x34,
8690x15,0x00,0x84,0x2c,0x06,0x00,0x80,0x10,0x24,0x28,0x62,0x00,0x0f,0x00,0x63,0x30,
8700x04,0x00,0xa0,0x14,0x01,0x00,0x02,0x24,0x02,0x00,0x60,0x14,0x02,0x00,0x02,0x24,
8710x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0xa5,0x30,
8720x04,0x00,0xa2,0x2c,0x14,0x00,0x40,0x10,0xff,0x00,0x84,0x30,0x02,0x80,0x03,0x3c,
8730x8e,0x7d,0x62,0x90,0x00,0x00,0x00,0x00,0xef,0xff,0x42,0x24,0xff,0x00,0x42,0x30,
8740x02,0x00,0x42,0x2c,0x0e,0x00,0x40,0x10,0x02,0x00,0x03,0x24,0x24,0x00,0x83,0x10,
8750x0f,0x10,0x02,0x3c,0x03,0x00,0x82,0x28,0x14,0x00,0x40,0x10,0x03,0x00,0x02,0x24,
8760x01,0x00,0x02,0x24,0x2f,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0xff,0x1f,0x02,0x3c,
8770x08,0x00,0xe0,0x03,0xff,0xff,0x42,0x34,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
8780x35,0x00,0x83,0x10,0x0f,0x1f,0x02,0x3c,0x03,0x00,0x82,0x28,0x16,0x00,0x40,0x10,
8790x03,0x00,0x02,0x24,0x01,0x00,0x02,0x24,0xf4,0xff,0x82,0x14,0x00,0x00,0x00,0x00,
8800x0f,0x1f,0x02,0x3c,0x08,0x00,0xe0,0x03,0x00,0x80,0x42,0x34,0xf0,0xff,0x82,0x14,
8810xff,0x1f,0x02,0x3c,0x01,0x00,0x02,0x24,0x29,0x00,0xa2,0x10,0x0f,0x10,0x02,0x3c,
8820x02,0x00,0xa2,0x28,0x1f,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x28,0x00,0xa3,0x10,
8830x00,0x00,0x00,0x00,0xe5,0xff,0xa4,0x14,0x00,0x00,0x00,0x00,0x0f,0x10,0x02,0x3c,
8840x08,0x00,0xe0,0x03,0x00,0xf0,0x42,0x34,0xe1,0xff,0x82,0x14,0xff,0x1f,0x02,0x3c,
8850x01,0x00,0x02,0x24,0x1c,0x00,0xa2,0x10,0x0f,0x00,0x02,0x3c,0x02,0x00,0xa2,0x28,
8860x0b,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x1c,0x00,0xa3,0x10,0x00,0x00,0x00,0x00,
8870xd6,0xff,0xa4,0x14,0x00,0x00,0x00,0x00,0x0f,0x00,0x02,0x3c,0x08,0x00,0xe0,0x03,
8880x00,0xf0,0x42,0x34,0x0f,0x10,0x02,0x3c,0x08,0x00,0xe0,0x03,0x00,0x80,0x42,0x34,
8890xce,0xff,0xa0,0x14,0x00,0x00,0x00,0x00,0x0f,0x00,0x02,0x3c,0x08,0x00,0xe0,0x03,
8900x15,0xf0,0x42,0x34,0xc9,0xff,0xa0,0x14,0x00,0x00,0x00,0x00,0x0f,0x10,0x02,0x3c,
8910x08,0x00,0xe0,0x03,0x15,0xf0,0x42,0x34,0x08,0x00,0xe0,0x03,0x00,0xf0,0x42,0x34,
8920x08,0x00,0xe0,0x03,0x10,0xf0,0x42,0x34,0x08,0x00,0xe0,0x03,0x10,0xf0,0x42,0x34,
8930x0f,0x10,0x02,0x3c,0x08,0x00,0xe0,0x03,0x05,0xf0,0x42,0x34,0x0f,0x00,0x02,0x3c,
8940x08,0x00,0xe0,0x03,0x05,0xf0,0x42,0x34,0xc0,0x40,0x04,0x00,0x21,0x18,0x04,0x01,
8950x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,0x80,0x18,0x03,0x00,
8960x68,0x15,0x42,0x24,0x21,0x18,0x62,0x00,0x74,0x51,0x66,0x8c,0x21,0x38,0x60,0x00,
8970x7a,0x51,0x60,0xa0,0x7b,0x51,0x60,0xa0,0x1c,0x00,0x05,0x24,0xdf,0x0d,0x00,0x08,
8980x01,0x00,0x03,0x24,0x08,0x00,0xa0,0x04,0x21,0x10,0x04,0x01,0x04,0x10,0xa3,0x00,
8990x24,0x10,0xc2,0x00,0xfb,0xff,0x40,0x10,0xff,0xff,0xa5,0x24,0x01,0x00,0xa5,0x24,
9000x7a,0x51,0xe5,0xa0,0x21,0x10,0x04,0x01,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,
9010x02,0x80,0x03,0x3c,0x80,0x10,0x02,0x00,0x68,0x15,0x63,0x24,0x21,0x18,0x43,0x00,
9020x74,0x51,0x66,0x8c,0x21,0x28,0x00,0x00,0xf3,0x0d,0x00,0x08,0x01,0x00,0x07,0x24,
9030x1d,0x00,0xa2,0x28,0x08,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x04,0x10,0xa7,0x00,
9040x24,0x10,0xc2,0x00,0xfa,0xff,0x40,0x10,0x01,0x00,0xa5,0x24,0xff,0xff,0xa5,0x24,
9050x08,0x00,0xe0,0x03,0x7b,0x51,0x65,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
9060xc8,0xff,0xbd,0x27,0x28,0x00,0xb6,0xaf,0x02,0x80,0x16,0x3c,0x30,0x00,0xbe,0xaf,
9070x2c,0x00,0xb7,0xaf,0x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x18,0x00,0xb2,0xaf,
9080x14,0x00,0xb1,0xaf,0x01,0x00,0x15,0x24,0x21,0x88,0x00,0x00,0x68,0x15,0xde,0x26,
9090x21,0xa0,0x00,0x00,0x21,0x90,0x00,0x00,0x25,0xb0,0x17,0x3c,0x34,0x00,0xbf,0xaf,
9100x1c,0x00,0xb3,0xaf,0x14,0x0e,0x00,0x08,0x10,0x00,0xb0,0xaf,0x01,0x00,0x31,0x26,
9110x20,0x00,0x22,0x2e,0x94,0x00,0x52,0x26,0x2e,0x00,0x40,0x10,0x94,0x00,0x94,0x26,
9120x68,0x15,0xc2,0x26,0x21,0x30,0x42,0x02,0x78,0x51,0xc5,0x8c,0x00,0x00,0x00,0x00,
9130x02,0x13,0x05,0x00,0x01,0x00,0x42,0x30,0xf4,0xff,0x55,0x14,0x42,0x1a,0x05,0x00,
9140x68,0x51,0xc2,0x8c,0x07,0x00,0x64,0x30,0x02,0x11,0x02,0x00,0x7f,0x00,0x43,0x30,
9150x2d,0x00,0x95,0x10,0x07,0x00,0xb3,0x30,0x02,0x00,0x82,0x28,0x3a,0x00,0x40,0x14,
9160x02,0x00,0x02,0x24,0x30,0x00,0x82,0x10,0x03,0x00,0x02,0x24,0x3c,0x00,0x82,0x10,
9170x1a,0x00,0x62,0x2c,0x21,0x80,0x9e,0x02,0x78,0x51,0x02,0x8e,0x04,0x00,0x63,0x2e,
9180x42,0x12,0x02,0x00,0x0a,0x00,0x60,0x10,0x07,0x00,0x44,0x30,0x73,0x0d,0x00,0x0c,
9190x21,0x28,0x60,0x02,0x80,0x20,0x13,0x00,0x70,0x51,0x02,0xae,0x21,0x20,0x97,0x00,
9200x84,0x01,0x83,0x8c,0x00,0x00,0x00,0x00,0x24,0x18,0x62,0x00,0x74,0x51,0x03,0xae,
9210xce,0x0d,0x00,0x0c,0x21,0x20,0x20,0x02,0x21,0x10,0x37,0x02,0x01,0x00,0x31,0x26,
9220x60,0x01,0x43,0x90,0x20,0x00,0x22,0x2e,0x94,0x00,0x52,0x26,0xd4,0xff,0x40,0x14,
9230x94,0x00,0x94,0x26,0x34,0x00,0xbf,0x8f,0x30,0x00,0xbe,0x8f,0x2c,0x00,0xb7,0x8f,
9240x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
9250x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,
9260x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x32,0x00,0x62,0x2c,0xda,0xff,0x40,0x10,
9270x21,0x80,0x9e,0x02,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x04,0x42,0x34,
9280x29,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,0x38,0x00,0x62,0x2c,0x12,0x00,0x40,0x14,
9290x14,0x00,0x62,0x2c,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x02,0x42,0x34,
9300x29,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,0xcb,0xff,0x80,0x14,0x21,0x80,0x9e,0x02,
9310xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x2a,0x0e,0x00,0x08,0x78,0x51,0xc2,0xac,
9320xc5,0xff,0x40,0x14,0x21,0x80,0x9e,0x02,0xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,
9330x54,0x0e,0x00,0x08,0x00,0x04,0x42,0x34,0xbf,0xff,0x40,0x10,0x21,0x80,0x9e,0x02,
9340xff,0xf1,0x03,0x24,0x24,0x10,0xa3,0x00,0x00,0x06,0x42,0x34,0x2a,0x0e,0x00,0x08,
9350x78,0x51,0xc2,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xd8,0xff,0xbd,0x27,
9360x10,0x00,0xb0,0xaf,0xc0,0x80,0x04,0x00,0x21,0x80,0x04,0x02,0x80,0x80,0x10,0x00,
9370x21,0x80,0x04,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x80,0x10,0x00,
9380x20,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x21,0x80,0x02,0x02,
9390x14,0x00,0xb1,0xaf,0x78,0x51,0x03,0x8e,0x25,0xb0,0x02,0x3c,0x80,0x01,0x53,0x34,
9400x07,0x00,0x63,0x30,0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x00,0x00,0x71,0x92,
9410x70,0x51,0x05,0x8e,0x84,0x01,0x62,0x8c,0x21,0x90,0x80,0x00,0xff,0x00,0x31,0x32,
9420x24,0x10,0x45,0x00,0xce,0x0d,0x00,0x0c,0x74,0x51,0x02,0xae,0x7a,0x51,0x04,0x92,
9430x5c,0x0d,0x00,0x0c,0xff,0x00,0x45,0x32,0x7a,0x51,0x04,0x92,0x63,0x0d,0x00,0x0c,
9440x00,0x00,0x00,0x00,0x01,0x00,0x42,0x38,0x04,0x00,0x03,0x24,0x0a,0x88,0x62,0x00,
9450x00,0x00,0x71,0xa2,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,
9460x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,
9470xff,0xff,0x84,0x30,0x00,0x02,0x82,0x30,0x07,0x00,0x03,0x24,0x0d,0x00,0x40,0x14,
9480x0b,0x00,0x84,0x30,0x0c,0x00,0x82,0x2c,0x0a,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
9490x02,0x80,0x03,0x3c,0x80,0x10,0x04,0x00,0xf0,0x91,0x63,0x24,0x21,0x10,0x43,0x00,
9500x00,0x00,0x44,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
9510x07,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x06,0x00,0x03,0x24,
9520x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x05,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,
9530x21,0x10,0x60,0x00,0x04,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
9540x03,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x02,0x00,0x03,0x24,
9550x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0x01,0x00,0x03,0x24,0x08,0x00,0xe0,0x03,
9560x21,0x10,0x60,0x00,0x21,0x18,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
9570xa0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x58,0x00,0xbe,0xaf,0x54,0x00,0xb7,0xaf,
9580x50,0x00,0xb6,0xaf,0x4c,0x00,0xb5,0xaf,0x48,0x00,0xb4,0xaf,0x40,0x00,0xb2,0xaf,
9590x3c,0x00,0xb1,0xaf,0x5c,0x00,0xbf,0xaf,0x44,0x00,0xb3,0xaf,0x38,0x00,0xb0,0xaf,
9600x20,0x92,0x42,0x24,0x00,0x00,0x53,0x8c,0x08,0x00,0x03,0x24,0x02,0x80,0x0b,0x3c,
9610x21,0x90,0x00,0x00,0x21,0xa0,0x00,0x00,0x21,0xb8,0x00,0x00,0x21,0xf0,0x00,0x00,
9620x21,0xa8,0x00,0x00,0x21,0xb0,0x00,0x00,0x21,0x88,0x60,0x02,0x10,0x00,0xa3,0xaf,
9630x14,0x00,0xa0,0xaf,0x18,0x00,0xa0,0xaf,0x1c,0x00,0xa0,0xaf,0x20,0x00,0xa0,0xaf,
9640x24,0x00,0xa0,0xaf,0x28,0x00,0xa0,0xaf,0x7a,0x0f,0x00,0x08,0x2c,0x00,0xa0,0xaf,
9650x44,0x51,0x22,0xae,0x60,0x51,0x24,0x8e,0x5c,0x51,0x27,0x8e,0x48,0x51,0x28,0x8e,
9660x4c,0x51,0x25,0x8e,0x54,0x51,0x26,0x8e,0x58,0x51,0x23,0x8e,0x21,0x38,0xe4,0x00,
9670x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,0x21,0x10,0x04,0x02,0x21,0x40,0x05,0x01,
9680x21,0x30,0xc3,0x00,0xca,0x44,0x42,0x90,0x44,0x51,0x2a,0x8e,0x0c,0x00,0xe0,0x10,
9690x21,0x48,0x00,0x00,0x2b,0x48,0x47,0x00,0x0b,0x00,0x20,0x15,0x02,0x80,0x02,0x3c,
9700x07,0x00,0x02,0x2e,0x59,0x01,0x40,0x14,0xc0,0x10,0x07,0x00,0x0c,0x00,0x02,0x24,
9710x55,0x01,0x02,0x12,0x0d,0x00,0x02,0x24,0x54,0x01,0x02,0x12,0xc0,0x10,0x07,0x00,
9720x92,0x00,0x20,0x11,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x18,0x10,0x00,
9730x21,0x18,0x62,0x00,0x21,0x20,0x30,0x02,0xb6,0x51,0x85,0x90,0xec,0x44,0x62,0x8c,
9740x00,0x00,0x00,0x00,0x04,0x10,0xa2,0x00,0x2b,0x10,0x4a,0x00,0x87,0x00,0x40,0x10,
9750x00,0x00,0x00,0x00,0xd4,0x51,0x22,0x8e,0x01,0x00,0x07,0x24,0x04,0x18,0x07,0x02,
9760x24,0x10,0x43,0x00,0xf0,0x00,0x40,0x10,0x1c,0x00,0x02,0x2e,0x21,0x28,0x30,0x02,
9770x7c,0x51,0xa6,0x90,0xb6,0x51,0xa2,0x90,0x0a,0x00,0x04,0x24,0xff,0x00,0xc3,0x30,
9780x04,0x20,0x44,0x00,0x2a,0x18,0x64,0x00,0xe7,0x00,0x60,0x10,0x1c,0x00,0x02,0x2e,
9790x01,0x00,0xc2,0x24,0xff,0x00,0x43,0x30,0x56,0x01,0x64,0x10,0x7c,0x51,0xa2,0xa0,
9800x68,0x15,0x65,0x25,0x80,0x10,0x10,0x00,0x21,0x10,0x45,0x00,0x60,0x45,0x44,0x8c,
9810xec,0x44,0x43,0x8c,0x21,0x30,0xc5,0x02,0x40,0x10,0x04,0x00,0x21,0x10,0x44,0x00,
9820x21,0x18,0x62,0x00,0x82,0x50,0x03,0x00,0x44,0x51,0xca,0xac,0x8c,0x65,0xa3,0x8c,
9830xff,0xff,0x02,0x34,0x07,0x00,0x62,0x10,0x21,0x20,0x00,0x02,0x21,0x20,0x00,0x02,
9840xff,0x00,0x45,0x32,0x5c,0x0d,0x00,0x0c,0x30,0x00,0xab,0xaf,0x30,0x00,0xab,0x8f,
9850x21,0x20,0x00,0x02,0x63,0x0d,0x00,0x0c,0x30,0x00,0xab,0xaf,0x10,0x00,0xa4,0x8f,
9860x01,0x00,0x42,0x38,0x04,0x00,0x03,0x24,0x0a,0x20,0x62,0x00,0x10,0x00,0xa4,0xaf,
9870x30,0x00,0xab,0x8f,0x11,0x00,0x40,0x16,0x68,0x15,0x62,0x25,0x58,0x51,0x47,0x8c,
9880x54,0x51,0x43,0x8c,0x4c,0x51,0x44,0x94,0x48,0x51,0x45,0x94,0x50,0x51,0x46,0x94,
9890x21,0x18,0x67,0x00,0x00,0x24,0x04,0x00,0x25,0xb0,0x02,0x3c,0x00,0x1c,0x03,0x00,
9900x21,0x28,0xa4,0x00,0x21,0x30,0xc3,0x00,0x6c,0x0c,0x44,0x34,0x68,0x0c,0x42,0x34,
9910x00,0x00,0x45,0xac,0x00,0x00,0x86,0xac,0x68,0x15,0x62,0x25,0x21,0x10,0x82,0x02,
9920x58,0x51,0x40,0xac,0x5c,0x51,0x40,0xac,0x60,0x51,0x40,0xac,0x48,0x51,0x40,0xac,
9930x4c,0x51,0x40,0xac,0x50,0x51,0x40,0xac,0x54,0x51,0x40,0xac,0x2c,0x00,0xa2,0x8f,
9940x28,0x00,0xa4,0x8f,0x01,0x00,0x52,0x26,0x94,0x00,0x42,0x24,0x2c,0x00,0xa2,0xaf,
9950x24,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,0x28,0x00,0xa4,0xaf,0x94,0x00,0x42,0x24,
9960x20,0x00,0xa4,0x8f,0x24,0x00,0xa2,0xaf,0x1c,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,
9970x20,0x00,0xa4,0xaf,0x94,0x00,0x42,0x24,0x18,0x00,0xa4,0x8f,0x1c,0x00,0xa2,0xaf,
9980x14,0x00,0xa2,0x8f,0x94,0x00,0x84,0x24,0x20,0x00,0x43,0x2a,0x94,0x00,0x42,0x24,
9990x94,0x00,0x31,0x26,0x94,0x00,0xd6,0x26,0x94,0x00,0xb5,0x26,0x18,0x00,0xa4,0xaf,
10000x14,0x00,0xa2,0xaf,0x94,0x00,0xde,0x27,0x94,0x00,0x73,0x26,0x94,0x00,0xf7,0x26,
10010xe5,0x00,0x60,0x10,0x94,0x00,0x94,0x26,0x78,0x51,0x22,0x8e,0x00,0x00,0x00,0x00,
10020x02,0x13,0x02,0x00,0x01,0x00,0x42,0x30,0xd3,0xff,0x40,0x10,0x25,0xb0,0x02,0x3c,
10030x21,0x10,0x42,0x02,0x60,0x01,0x44,0x90,0x60,0x51,0x23,0x8e,0x5c,0x51,0x26,0x8e,
10040xff,0x00,0x90,0x30,0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,0x21,0x10,0x04,0x02,
10050x73,0x44,0x44,0x90,0x56,0x44,0x45,0x90,0x44,0x51,0x27,0x8e,0x18,0x00,0x64,0x00,
10060x12,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xc5,0x00,
10070x12,0x30,0x00,0x00,0x21,0x30,0xc3,0x00,0x2b,0x10,0xe6,0x00,0x54,0xff,0x40,0x10,
10080x23,0x10,0xe6,0x00,0xe9,0x0e,0x00,0x08,0x44,0x51,0x20,0xae,0x62,0x00,0xe0,0x10,
10090x00,0x00,0x00,0x00,0x63,0x00,0x20,0x15,0x68,0x15,0x62,0x25,0x40,0x10,0x07,0x00,
10100x21,0x10,0x47,0x00,0x82,0x10,0x02,0x00,0x2b,0x10,0x46,0x00,0x99,0xff,0x40,0x10,
10110x21,0x20,0x00,0x02,0x68,0x15,0x68,0x25,0x21,0x20,0xa8,0x02,0x21,0x30,0x90,0x00,
10120xd4,0x51,0x83,0x8c,0x01,0x00,0x05,0x24,0x04,0x10,0x05,0x02,0x99,0x51,0xc7,0x90,
10130x27,0x10,0x02,0x00,0x24,0x18,0x62,0x00,0xd4,0x51,0x83,0xac,0x09,0x00,0xe5,0x10,
10140x7c,0x51,0xc0,0xa0,0x18,0x00,0xa2,0x8f,0x21,0x38,0x00,0x00,0x21,0x20,0x48,0x00,
10150x21,0x18,0x87,0x00,0x01,0x00,0xe7,0x24,0x1d,0x00,0xe2,0x28,0xfc,0xff,0x40,0x14,
10160xb6,0x51,0x60,0xa0,0x14,0x00,0xa4,0x8f,0x68,0x15,0x63,0x25,0x21,0x50,0x60,0x00,
10170x21,0x10,0x83,0x00,0x21,0x10,0x50,0x00,0x99,0x51,0x40,0xa0,0x02,0x80,0x03,0x3c,
10180x02,0x80,0x02,0x3c,0x4c,0x91,0x49,0x24,0xd8,0x90,0x68,0x24,0x21,0x38,0x00,0x00,
10190x80,0x18,0x07,0x00,0x21,0x10,0x69,0x00,0x21,0x20,0x68,0x00,0x00,0x00,0x46,0x8c,
10200x00,0x00,0x85,0x8c,0x01,0x00,0xe7,0x24,0x21,0x18,0x6a,0x00,0x1d,0x00,0xe2,0x28,
10210xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,0x60,0x45,0x66,0xac,0x14,0x00,0x00,0x12,
10220x68,0x15,0x63,0x25,0x7b,0x51,0x62,0x92,0xff,0xff,0x07,0x26,0x2a,0x10,0xe2,0x00,
10230x0e,0x00,0x40,0x14,0x02,0x80,0x0b,0x3c,0x68,0x15,0x62,0x25,0x21,0x10,0xc2,0x03,
10240x7b,0x51,0x45,0x90,0x74,0x51,0x44,0x8c,0x01,0x00,0x06,0x24,0x04,0x18,0xe6,0x00,
10250x24,0x10,0x83,0x00,0xb3,0x00,0x43,0x10,0x00,0x00,0x00,0x00,0xff,0xff,0xe7,0x24,
10260x2a,0x10,0xe5,0x00,0xfa,0xff,0x40,0x10,0x04,0x18,0xe6,0x00,0x68,0x15,0x63,0x25,
10270x80,0x10,0x10,0x00,0x21,0x10,0x43,0x00,0x60,0x45,0x45,0x8c,0xec,0x44,0x44,0x8c,
10280x02,0x80,0x03,0x3c,0x40,0x10,0x05,0x00,0x8e,0x7d,0x66,0x90,0x21,0x10,0x45,0x00,
10290x21,0x20,0x82,0x00,0x22,0x00,0x02,0x24,0x98,0x00,0xc2,0x10,0x82,0x50,0x04,0x00,
10300xd4,0x51,0x63,0x8e,0x01,0x00,0x02,0x24,0x04,0x10,0x02,0x02,0x25,0x18,0x62,0x00,
10310xd4,0x51,0x63,0xae,0x68,0x15,0x63,0x25,0x21,0x10,0xe3,0x02,0x44,0x51,0x4a,0xac,
10320x8c,0x65,0x64,0x8c,0xff,0xff,0x02,0x34,0x3c,0xff,0x82,0x14,0x21,0x20,0x00,0x02,
10330x39,0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x3e,0xff,0x20,0x11,0x21,0x20,0x00,0x02,
10340x68,0x15,0x62,0x25,0x80,0x18,0x10,0x00,0x21,0x18,0x62,0x00,0x60,0x45,0x64,0x8c,
10350x00,0x00,0x00,0x00,0x2b,0x20,0x44,0x01,0x36,0xff,0x80,0x10,0x21,0x20,0x00,0x02,
10360xa2,0x0f,0x00,0x08,0x68,0x15,0x68,0x25,0x1e,0xff,0x40,0x10,0x68,0x15,0x65,0x25,
10370x21,0x20,0x30,0x02,0x99,0x51,0x83,0x90,0x01,0x00,0x02,0x24,0x63,0x00,0x62,0x10,
10380x02,0x80,0x02,0x3c,0x2c,0x00,0xa3,0x8f,0x68,0x15,0x42,0x24,0x21,0x38,0x00,0x00,
10390x21,0x20,0x62,0x00,0x21,0x18,0x87,0x00,0x01,0x00,0xe7,0x24,0x1d,0x00,0xe2,0x28,
10400xfc,0xff,0x40,0x14,0xb6,0x51,0x60,0xa0,0x28,0x00,0xa3,0x8f,0x02,0x80,0x0b,0x3c,
10410x68,0x15,0x65,0x25,0x21,0x30,0x65,0x00,0xd4,0x51,0xc2,0x8c,0x01,0x00,0x03,0x24,
10420x04,0x18,0x03,0x02,0x27,0x18,0x03,0x00,0x21,0x20,0xd0,0x00,0x24,0x10,0x43,0x00,
10430x99,0x51,0x80,0xa0,0xd4,0x51,0xc2,0xac,0x12,0x00,0x00,0x16,0x7c,0x51,0x80,0xa0,
10440x7a,0x51,0xc2,0x90,0x00,0x00,0x00,0x00,0x0e,0x00,0x40,0x10,0x01,0x00,0x07,0x24,
10450x24,0x00,0xa4,0x8f,0x01,0x00,0x06,0x24,0x21,0x10,0x85,0x00,0x7a,0x51,0x44,0x90,
10460x74,0x51,0x45,0x8c,0x04,0x18,0xe6,0x00,0x24,0x10,0xa3,0x00,0x5b,0x00,0x43,0x10,
10470x00,0x00,0x00,0x00,0x01,0x00,0xe7,0x24,0x2a,0x10,0x87,0x00,0xfa,0xff,0x40,0x10,
10480x04,0x18,0xe6,0x00,0x20,0x00,0xa2,0x8f,0x02,0x80,0x0b,0x3c,0x68,0x15,0x64,0x25,
10490x21,0x18,0x44,0x00,0x7a,0x51,0x62,0x90,0x01,0x00,0x07,0x26,0x2a,0x10,0x47,0x00,
10500x0e,0x00,0x40,0x14,0x01,0x00,0x06,0x24,0x1c,0x00,0xa3,0x8f,0x00,0x00,0x00,0x00,
10510x21,0x10,0x64,0x00,0x7a,0x51,0x45,0x90,0x74,0x51,0x44,0x8c,0x04,0x18,0xe6,0x00,
10520x24,0x10,0x83,0x00,0x42,0x00,0x43,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0xe7,0x24,
10530x2a,0x10,0xa7,0x00,0xfa,0xff,0x40,0x10,0x04,0x18,0xe6,0x00,0x02,0x80,0x02,0x3c,
10540x8e,0x7d,0x44,0x90,0x22,0x00,0x03,0x24,0xd6,0xfe,0x83,0x14,0x68,0x15,0x65,0x25,
10550xee,0xff,0x02,0x26,0xff,0x00,0x42,0x30,0x02,0x00,0x42,0x2c,0x18,0x00,0x03,0x24,
10560x25,0x0f,0x00,0x08,0x0b,0x80,0x62,0x00,0xc0,0x10,0x07,0x00,0x23,0x10,0x47,0x00,
10570xc2,0x10,0x02,0x00,0x2b,0x10,0x48,0x00,0xb6,0xfe,0x40,0x14,0x00,0x00,0x00,0x00,
10580x04,0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x00,0xa3,0x8f,0x5c,0x00,0xbf,0x8f,
10590x58,0x00,0xbe,0x8f,0x54,0x00,0xb7,0x8f,0x50,0x00,0xb6,0x8f,0x4c,0x00,0xb5,0x8f,
10600x48,0x00,0xb4,0x8f,0x44,0x00,0xb3,0x8f,0x40,0x00,0xb2,0x8f,0x3c,0x00,0xb1,0x8f,
10610x38,0x00,0xb0,0x8f,0x25,0xb0,0x02,0x3c,0x80,0x01,0x42,0x34,0x60,0x00,0xbd,0x27,
10620x00,0x00,0x43,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x18,0x00,0x02,0x2e,
10630x0a,0x00,0x40,0x14,0x05,0x00,0x02,0x2e,0xb6,0x51,0x83,0x90,0x00,0x00,0x00,0x00,
10640x05,0x00,0x62,0x2c,0xa0,0xff,0x40,0x10,0x01,0x00,0x62,0x24,0x16,0x10,0x00,0x08,
10650xb6,0x51,0x82,0xa0,0x24,0x0f,0x00,0x08,0x99,0x51,0xa7,0xa0,0x04,0x00,0x40,0x10,
10660x00,0x00,0x00,0x00,0xb6,0x51,0x83,0x90,0x75,0x10,0x00,0x08,0x03,0x00,0x62,0x2c,
10670xb6,0x51,0x83,0x90,0x75,0x10,0x00,0x08,0x04,0x00,0x62,0x2c,0x13,0x00,0x02,0x24,
10680x67,0xff,0x02,0x16,0x68,0x15,0x63,0x25,0xf3,0x0f,0x00,0x08,0x21,0x10,0xe3,0x02,
10690xff,0x00,0xf0,0x30,0x4c,0x10,0x00,0x08,0x02,0x80,0x02,0x3c,0x35,0x10,0x00,0x08,
10700xff,0x00,0xf0,0x30,0xdf,0x0f,0x00,0x08,0xff,0x00,0xf0,0x30,0xd8,0xff,0xbd,0x27,
10710x02,0x80,0x02,0x3c,0x14,0x00,0xb1,0xaf,0x24,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf,
10720x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x45,0x24,
10730x05,0x65,0xa4,0x90,0x00,0x65,0xa3,0x8c,0xfc,0x64,0xa2,0x8c,0x21,0x88,0x64,0x00,
10740x2b,0x10,0x22,0x02,0x60,0x00,0x40,0x10,0x21,0x80,0xa0,0x00,0x02,0x80,0x14,0x3c,
10750x21,0x98,0xa0,0x00,0xa8,0x10,0x00,0x08,0x21,0x90,0xa0,0x00,0xfc,0x64,0x42,0x8e,
10760x10,0x00,0x31,0x26,0x2b,0x10,0x22,0x02,0x57,0x00,0x40,0x10,0x21,0x80,0x40,0x02,
10770x05,0x65,0x02,0x92,0xff,0xff,0x23,0x32,0x02,0x80,0x05,0x3c,0x10,0x00,0x42,0x24,
10780x25,0x28,0x65,0x00,0x2c,0x79,0x84,0x26,0x10,0x00,0x06,0x24,0x9f,0x45,0x00,0x0c,
10790x05,0x65,0x02,0xa2,0xc8,0x63,0x06,0x8e,0x00,0x00,0x00,0x00,0x42,0x24,0x06,0x00,
10800x1f,0x00,0x84,0x30,0xc0,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,
10810x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x38,0x50,0x00,0x78,0x51,0xe3,0x8c,
10820x00,0x00,0x00,0x00,0x02,0x1b,0x03,0x00,0x01,0x00,0x63,0x30,0xe3,0xff,0x60,0x10,
10830x25,0xb0,0x02,0x3c,0xc4,0x63,0x05,0x8e,0x21,0x10,0x82,0x00,0x60,0x01,0x44,0x90,
10840x82,0x1d,0x05,0x00,0x3f,0x00,0x63,0x30,0x04,0x00,0x0a,0x24,0x05,0x00,0x62,0x28,
10850x21,0x40,0x40,0x01,0x0b,0x40,0x62,0x00,0x07,0x00,0xa0,0x04,0xff,0x00,0x89,0x30,
10860x64,0x51,0xe2,0x8c,0x04,0x00,0x08,0x24,0x01,0x00,0x42,0x24,0x64,0x51,0xe2,0xac,
10870xc8,0x63,0x66,0x8e,0x00,0x00,0x00,0x00,0x02,0x13,0x06,0x00,0x1f,0x00,0x42,0x30,
10880x08,0x00,0x42,0x28,0xcd,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xc4,0x63,0x62,0x8e,
10890x00,0x00,0x00,0x00,0x3f,0x00,0x42,0x30,0xc8,0xff,0x49,0x14,0x00,0x00,0x00,0x00,
10900x29,0x00,0x00,0x11,0x01,0x00,0x02,0x24,0x2e,0x00,0x02,0x11,0x02,0x00,0x02,0x24,
10910x33,0x00,0x02,0x11,0x03,0x00,0x02,0x24,0x38,0x00,0x02,0x11,0x00,0x00,0x00,0x00,
10920x3b,0x00,0x0a,0x11,0x00,0x00,0x00,0x00,0x68,0x51,0xe2,0x8c,0x21,0x18,0x33,0x01,
10930x90,0x44,0x64,0x90,0x02,0x11,0x02,0x00,0x2b,0x10,0x44,0x00,0x3e,0x00,0x40,0x14,
10940x00,0x00,0x00,0x00,0x5c,0x51,0xe3,0x8c,0x80,0x10,0x09,0x00,0x21,0x10,0x49,0x00,
10950x01,0x00,0x63,0x24,0x21,0x10,0x53,0x00,0x5c,0x51,0xe3,0xac,0x21,0x10,0x48,0x00,
10960x34,0x43,0x44,0x90,0x44,0x51,0xe3,0x8c,0x00,0x00,0x00,0x00,0x21,0x18,0x64,0x00,
10970x44,0x51,0xe3,0xac,0xfc,0x64,0x42,0x8e,0x10,0x00,0x31,0x26,0x2b,0x10,0x22,0x02,
10980xab,0xff,0x40,0x14,0x21,0x80,0x40,0x02,0x24,0x00,0xbf,0x8f,0x20,0x00,0xb4,0x8f,
10990x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
11000x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x48,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,
11010x01,0x00,0x42,0x24,0x48,0x51,0xe2,0xac,0x01,0x00,0x02,0x24,0xd4,0xff,0x02,0x15,
11020x02,0x00,0x02,0x24,0x4c,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,
11030x4c,0x51,0xe2,0xac,0x02,0x00,0x02,0x24,0xcf,0xff,0x02,0x15,0x03,0x00,0x02,0x24,
11040x50,0x51,0xe2,0x8c,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0x50,0x51,0xe2,0xac,
11050x03,0x00,0x02,0x24,0xca,0xff,0x02,0x15,0x00,0x00,0x00,0x00,0x54,0x51,0xe2,0x8c,
11060x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xc7,0xff,0x0a,0x15,0x54,0x51,0xe2,0xac,
11070x58,0x51,0xe2,0x8c,0x21,0x18,0x33,0x01,0x01,0x00,0x42,0x24,0x58,0x51,0xe2,0xac,
11080x68,0x51,0xe2,0x8c,0x90,0x44,0x64,0x90,0x02,0x11,0x02,0x00,0x2b,0x10,0x44,0x00,
11090xc4,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x60,0x51,0xe3,0x8c,0x80,0x10,0x09,0x00,
11100x21,0x10,0x49,0x00,0x01,0x00,0x63,0x24,0x21,0x10,0x53,0x00,0x60,0x51,0xe3,0xac,
11110x21,0x10,0x48,0x00,0xc5,0x43,0x44,0x90,0x44,0x51,0xe3,0x8c,0x00,0x00,0x00,0x00,
11120x21,0x18,0x64,0x00,0xf9,0x10,0x00,0x08,0x44,0x51,0xe3,0xac,0x25,0xb0,0x02,0x3c,
11130x25,0xb0,0x05,0x3c,0x02,0x80,0x03,0x3c,0x58,0x00,0x4a,0x34,0x5c,0x00,0x4b,0x34,
11140x4c,0x00,0xa2,0x34,0x00,0x00,0x44,0x90,0x68,0x15,0x66,0x24,0xed,0x4a,0xc2,0x90,
11150x29,0xb0,0x07,0x3c,0x03,0x00,0x84,0x30,0x21,0x18,0xc0,0x00,0x0f,0x00,0x44,0x10,
11160x04,0x00,0xe8,0x34,0x07,0x00,0x80,0x14,0x58,0x0c,0xa9,0x34,0xe6,0x42,0xc2,0x90,
11170x1c,0x00,0x06,0x24,0x03,0x00,0x40,0x14,0x50,0x0c,0xa5,0x34,0x00,0x00,0xa6,0xa0,
11180x00,0x00,0x26,0xa1,0x00,0x00,0x42,0x8d,0xed,0x4a,0x64,0xa0,0x00,0x00,0xe2,0xac,
11190x00,0x00,0x62,0x8d,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xad,0x08,0x00,0xe0,0x03,
11200x21,0x10,0x00,0x00,0x25,0xb0,0x0d,0x3c,0xe8,0xff,0xbd,0x27,0x10,0x00,0xbf,0xaf,
11210x2d,0x0a,0xa7,0x35,0xa2,0x0d,0xa2,0x35,0xa4,0x0d,0xa3,0x35,0xa6,0x0d,0xa4,0x35,
11220xa8,0x0d,0xa5,0x35,0x00,0x00,0x48,0x94,0x00,0x00,0x69,0x94,0x00,0x00,0x8a,0x94,
11230x00,0x00,0xab,0x94,0x00,0x00,0xe3,0x90,0x5b,0x0a,0xa4,0x35,0x5c,0x0a,0xa6,0x35,
11240x00,0x2e,0x03,0x00,0x03,0x2e,0x05,0x00,0x40,0x00,0xa2,0x34,0x00,0x00,0xe2,0xa0,
11250x00,0x00,0x85,0x90,0x00,0x00,0xc3,0x90,0x02,0x80,0x0e,0x3c,0x68,0x15,0xcc,0x25,
11260xff,0xff,0x22,0x31,0xff,0x00,0xa5,0x30,0xff,0xff,0x04,0x31,0x21,0x20,0x82,0x00,
11270xff,0x00,0x63,0x30,0x00,0x40,0x87,0x8d,0x00,0x2a,0x05,0x00,0xff,0xff,0x46,0x31,
11280x21,0x28,0xa3,0x00,0xff,0xff,0x62,0x31,0x21,0x20,0x86,0x00,0x21,0x20,0x82,0x00,
11290xff,0xff,0xa3,0x30,0x64,0x0c,0xa2,0x35,0x00,0x00,0x45,0xa4,0x21,0x20,0x83,0x00,
11300x0f,0x00,0xe7,0x30,0x01,0x00,0x02,0x24,0xe0,0x42,0x84,0xad,0xd8,0x42,0x88,0xa5,
11310xda,0x42,0x89,0xa5,0xdc,0x42,0x8a,0xa5,0xde,0x42,0x8b,0xa5,0x07,0x00,0xe2,0x10,
11320xe4,0x42,0x85,0xa5,0xa8,0x56,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f,
11330x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x4c,0x00,0xa3,0x35,
11340x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,0x67,0x00,0x47,0x10,
11350x68,0x15,0xc4,0x25,0xe6,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x2d,0x00,0x40,0x10,
11360x01,0x00,0x03,0x24,0x68,0x15,0xc5,0x25,0xe6,0x42,0xa3,0x90,0xff,0x00,0x02,0x24,
11370xec,0xff,0x62,0x14,0x25,0xb0,0x03,0x3c,0xc8,0x42,0xa2,0x94,0xe0,0x42,0xa6,0x8c,
11380x50,0x0c,0x63,0x34,0x00,0x00,0x64,0x90,0x2b,0x10,0xc2,0x00,0x5e,0x00,0x40,0x14,
11390x7f,0x00,0x84,0x30,0xca,0x42,0xa2,0x94,0x00,0x00,0x00,0x00,0x2b,0x10,0xc2,0x00,
11400x09,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xcc,0x42,0xa2,0x94,0x00,0x00,0x00,0x00,
11410x2b,0x10,0xc2,0x00,0x02,0x00,0x40,0x10,0x02,0x00,0x82,0x24,0x01,0x00,0x82,0x24,
11420xff,0x00,0x44,0x30,0x68,0x15,0xc5,0x25,0xd0,0x42,0xa3,0x90,0x00,0x00,0x00,0x00,
11430x2b,0x10,0x64,0x00,0x4e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x21,0x20,0x60,0x00,
11440x68,0x15,0xc3,0x25,0xe0,0x42,0x62,0x8c,0x00,0x00,0x00,0x00,0xe9,0x03,0x42,0x2c,
11450x02,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0xd0,0x42,0x64,0x90,0x58,0x0c,0x43,0x34,
11460x50,0x0c,0x42,0x34,0x00,0x00,0x44,0xa0,0x00,0x00,0x64,0xa0,0x85,0x11,0x00,0x08,
11470x00,0x00,0x00,0x00,0x00,0x40,0x82,0x8c,0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,
11480x0f,0x00,0x42,0x30,0xd0,0xff,0x43,0x14,0x68,0x15,0xc5,0x25,0x25,0xb0,0x02,0x3c,
11490x4c,0x00,0x42,0x34,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x63,0x30,
11500xb8,0xff,0x60,0x10,0xff,0xff,0x02,0x34,0xdc,0x63,0x83,0x8c,0x00,0x00,0x00,0x00,
11510xb4,0xff,0x62,0x10,0x00,0x00,0x00,0x00,0xe0,0x42,0x83,0x8c,0x00,0x00,0x00,0x00,
11520x65,0x00,0x62,0x2c,0x3b,0x00,0x40,0x14,0x28,0x00,0x62,0x2c,0xd2,0x42,0x83,0x90,
11530x00,0x00,0x00,0x00,0x00,0x16,0x03,0x00,0x03,0x16,0x02,0x00,0xfe,0xff,0x42,0x24,
11540xfc,0xff,0x42,0x28,0x02,0x00,0x40,0x10,0xfe,0xff,0x62,0x24,0xfc,0xff,0x02,0x24,
11550xd2,0x42,0x82,0xa0,0x68,0x15,0xc4,0x25,0xdc,0x63,0x82,0x8c,0xd2,0x42,0x83,0x90,
11560xce,0x42,0x86,0x90,0x02,0x11,0x02,0x00,0x7f,0x00,0x42,0x30,0x0a,0x00,0x45,0x24,
11570x23,0x18,0xa3,0x00,0x00,0x2e,0x03,0x00,0x03,0x2e,0x05,0x00,0xff,0x00,0xc2,0x30,
11580x2a,0x10,0x45,0x00,0x17,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x00,0x2e,0x06,0x00,
11590x03,0x2e,0x05,0x00,0x58,0x0c,0x43,0x34,0x50,0x0c,0x42,0x34,0x00,0x00,0x45,0xa0,
11600x00,0x00,0x65,0xa0,0x85,0x11,0x00,0x08,0x00,0x00,0x00,0x00,0xe6,0x42,0x82,0x91,
11610x00,0x00,0x00,0x00,0x97,0xff,0x40,0x14,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x24,
11620x91,0x11,0x00,0x08,0xe6,0x42,0x82,0xa1,0xac,0x11,0x00,0x08,0xff,0xff,0x82,0x24,
11630xd1,0x42,0xa3,0x90,0x00,0x00,0x00,0x00,0x2b,0x10,0x83,0x00,0xb4,0x11,0x00,0x08,
11640x0b,0x20,0x62,0x00,0xcf,0x42,0x83,0x80,0x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,
11650x2a,0x10,0xa2,0x00,0x0b,0x28,0x62,0x00,0x25,0xb0,0x02,0x3c,0x58,0x0c,0x43,0x34,
11660x50,0x0c,0x42,0x34,0x00,0x00,0x45,0xa0,0x00,0x00,0x65,0xa0,0x85,0x11,0x00,0x08,
11670x00,0x00,0x00,0x00,0xcf,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xd2,0x42,0x83,0x90,
11680x00,0x00,0x00,0x00,0x00,0x16,0x03,0x00,0x03,0x16,0x02,0x00,0x02,0x00,0x42,0x24,
11690x0d,0x00,0x42,0x28,0x03,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xe0,0x11,0x00,0x08,
11700x0c,0x00,0x02,0x24,0xe0,0x11,0x00,0x08,0x02,0x00,0x62,0x24,0xc0,0xff,0xbd,0x27,
11710x18,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x28,0x00,0xb4,0xaf,0x24,0x00,0xb3,0xaf,
11720x1c,0x00,0xb1,0xaf,0x3c,0x00,0xbf,0xaf,0x38,0x00,0xbe,0xaf,0x34,0x00,0xb7,0xaf,
11730x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,0x20,0x00,0xb2,0xaf,0xd8,0x00,0x06,0x36,
11740x00,0x00,0xc3,0x90,0x02,0x80,0x02,0x3c,0x68,0x15,0x54,0x24,0x2a,0xb0,0x11,0x3c,
11750xa0,0xff,0x02,0x24,0x25,0x18,0x62,0x00,0x34,0x00,0x25,0x36,0xfe,0xff,0x02,0x24,
11760xbc,0x42,0x92,0x92,0x40,0x00,0x04,0x24,0x00,0x00,0xc3,0xa0,0x00,0x00,0xa2,0xa0,
11770xa1,0x4e,0x00,0x0c,0x00,0x96,0x12,0x00,0x21,0x98,0x40,0x00,0x6b,0x00,0x60,0x12,
11780x00,0x40,0x02,0x3c,0x08,0x00,0x63,0x8e,0xb0,0x03,0x02,0x36,0x21,0x20,0x60,0x02,
11790x00,0x00,0x43,0xac,0x3a,0x45,0x00,0x0c,0x21,0xb8,0x80,0x02,0x01,0x00,0x1e,0x24,
11800x42,0x00,0x16,0x36,0x03,0x0c,0x11,0x36,0x17,0x0e,0x15,0x36,0x04,0x00,0x14,0x24,
11810x2a,0xb0,0x03,0x3c,0x06,0x00,0x63,0x34,0x00,0x00,0x62,0x94,0x00,0x00,0x00,0x00,
11820x00,0xff,0x42,0x30,0x0a,0x00,0x40,0x18,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,
11830xc8,0x94,0x84,0x24,0x00,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x94,
11840x00,0x00,0x00,0x00,0x00,0xff,0x42,0x30,0xfc,0xff,0x40,0x1c,0x00,0x00,0x00,0x00,
11850x08,0x00,0x65,0x8e,0x20,0x10,0x06,0x3c,0x00,0xfe,0xc6,0x34,0x40,0x00,0x07,0x24,
11860x01,0x00,0x04,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xbe,0xaf,0x4d,0x01,0x00,0x0c,
11870x01,0x00,0x04,0x24,0x2a,0xb0,0x02,0x3c,0x05,0x00,0x42,0x34,0xff,0xff,0x03,0x24,
11880x00,0x00,0x5e,0xa0,0x00,0x00,0xc3,0xa2,0x00,0x00,0x22,0x92,0xc1,0x42,0xe5,0x92,
11890x2a,0xb0,0x04,0x3c,0x02,0x00,0x03,0x24,0x40,0x00,0x42,0x34,0x05,0x00,0x84,0x34,
11900x00,0x00,0x22,0xa2,0x00,0x00,0x83,0xa0,0xef,0xff,0x02,0x24,0x00,0x00,0xb0,0x92,
11910x64,0x00,0x04,0x24,0x00,0x00,0xa5,0xa2,0x00,0x00,0xc2,0xa2,0xb3,0x0a,0x00,0x0c,
11920x00,0x00,0x00,0x00,0x00,0x00,0x22,0x92,0xbf,0xff,0x03,0x24,0x84,0x03,0x04,0x24,
11930x24,0x10,0x43,0x00,0x00,0x00,0x22,0xa2,0xb3,0x0a,0x00,0x0c,0xff,0x00,0x10,0x32,
11940x25,0xb0,0x02,0x3c,0xf4,0x08,0x42,0x34,0x00,0x00,0x44,0x8c,0x00,0x00,0xb0,0xa2,
11950x00,0x00,0xc0,0xa2,0x00,0x00,0x22,0x92,0xbe,0x42,0xe3,0x92,0x1f,0x00,0x85,0x30,
11960x40,0x00,0x42,0x34,0x00,0x00,0x22,0xa2,0x00,0x80,0x02,0x3c,0xdf,0x07,0x42,0x34,
11970x2b,0x18,0xa3,0x00,0x09,0x00,0x60,0x10,0x24,0x20,0x82,0x00,0xbf,0x42,0xe2,0x92,
11980x00,0x00,0x00,0x00,0x2b,0x10,0x45,0x00,0x05,0x00,0x40,0x10,0x02,0x80,0x02,0x3c,
11990x01,0x00,0x02,0x3c,0x25,0x10,0xa2,0x00,0x21,0x90,0x42,0x02,0x02,0x80,0x02,0x3c,
12000x8e,0x7d,0x43,0x90,0x22,0x00,0x02,0x24,0x1c,0x00,0x62,0x10,0x92,0x00,0x02,0x24,
12010x1b,0x00,0x62,0x10,0x02,0x80,0x03,0x3c,0xff,0xff,0x94,0x26,0xb3,0x0a,0x00,0x0c,
12020xf4,0x01,0x04,0x24,0xab,0xff,0x81,0x06,0x2a,0xb0,0x03,0x3c,0x04,0x00,0x60,0x12,
12030x25,0xb0,0x02,0x3c,0xbd,0x4e,0x00,0x0c,0x21,0x20,0x60,0x02,0x25,0xb0,0x02,0x3c,
12040xd8,0x02,0x42,0x34,0x00,0x00,0x52,0xac,0x21,0x10,0x40,0x02,0x3c,0x00,0xbf,0x8f,
12050x38,0x00,0xbe,0x8f,0x34,0x00,0xb7,0x8f,0x30,0x00,0xb6,0x8f,0x2c,0x00,0xb5,0x8f,
12060x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
12070x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x40,0x00,0xbd,0x27,0x02,0x80,0x03,0x3c,
12080x68,0x15,0x63,0x24,0xbe,0x42,0x62,0x90,0xc0,0x07,0x83,0x30,0x82,0x19,0x03,0x00,
12090x2b,0x10,0x62,0x00,0xe0,0xff,0x40,0x10,0x02,0x80,0x04,0x3c,0x68,0x15,0x84,0x24,
12100xbf,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x2b,0x10,0x43,0x00,0xda,0xff,0x40,0x10,
12110x00,0x12,0x03,0x00,0x10,0x00,0x03,0x3c,0x25,0x10,0x43,0x00,0x9a,0x12,0x00,0x08,
12120x21,0x90,0x42,0x02,0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x0f,0x00,0x10,0x3c,
12130xff,0xff,0x05,0x36,0xf0,0xf8,0x06,0x34,0x14,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c,
12140x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,
12150x56,0x30,0x06,0x24,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,
12160x64,0x00,0x04,0x24,0x02,0x80,0x0b,0x3c,0x68,0x15,0x64,0x25,0x04,0x43,0x83,0x90,
12170x04,0x00,0x02,0x24,0x19,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,0x14,0x43,0x8a,0x8c,
12180x18,0x43,0x88,0x8c,0x25,0xb0,0x02,0x3c,0x1c,0x0e,0x49,0x34,0x00,0x0e,0x43,0x34,
12190x04,0x0e,0x44,0x34,0x08,0x0e,0x45,0x34,0x10,0x0e,0x46,0x34,0x14,0x0e,0x47,0x34,
12200x18,0x0e,0x42,0x34,0x00,0x00,0x6a,0xac,0x00,0x00,0x8a,0xac,0x00,0x00,0xa8,0xac,
12210x00,0x00,0xca,0xac,0x00,0x00,0xea,0xac,0x00,0x00,0x4a,0xac,0x00,0x00,0x2a,0xad,
12220x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x68,0x15,0x63,0x25,0x04,0x00,0x02,0x24,
12230x18,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x62,0xa0,0x00,0x0e,0x42,0x34,
12240x00,0x00,0x43,0x8c,0x14,0x43,0x8a,0x8c,0x00,0x00,0x00,0x00,0xe4,0xff,0x6a,0x14,
12250x00,0x00,0x00,0x00,0xec,0x12,0x00,0x08,0x00,0x00,0x00,0x00,0xe8,0xff,0xbd,0x27,
12260x10,0x00,0xb0,0xaf,0x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0xf0,0xf8,0x06,0x34,
12270x14,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c,0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,
12280x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,0x56,0x30,0x06,0x24,0xba,0x44,0x00,0x0c,
12290x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x02,0x80,0x04,0x3c,
12300x68,0x15,0x83,0x24,0x04,0x43,0x65,0x90,0x21,0x70,0x60,0x00,0x10,0x10,0x03,0x3c,
12310x25,0xb0,0x02,0x3c,0x10,0x10,0x66,0x34,0x01,0x00,0x03,0x24,0x1c,0x0e,0x4d,0x34,
12320x00,0x0e,0x4a,0x34,0x04,0x0e,0x4b,0x34,0x08,0x0e,0x4c,0x34,0x10,0x0e,0x47,0x34,
12330x14,0x0e,0x48,0x34,0x0f,0x00,0xa3,0x10,0x18,0x0e,0x49,0x34,0x10,0x10,0x02,0x24,
12340x00,0x00,0x46,0xad,0x00,0x00,0x66,0xad,0x00,0x00,0x82,0xad,0x00,0x00,0xe6,0xac,
12350x00,0x00,0x06,0xad,0x00,0x00,0x26,0xad,0x00,0x00,0xa6,0xad,0x14,0x00,0xbf,0x8f,
12360x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,0x18,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,
12370x04,0x43,0xc2,0xa1,0x00,0x00,0x44,0x8d,0x00,0x00,0x00,0x00,0xf0,0xff,0x86,0x14,
12380x10,0x10,0x02,0x24,0x23,0x13,0x00,0x08,0x00,0x00,0x00,0x00,0xe0,0xff,0xbd,0x27,
12390x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x01,0x00,0x11,0x3c,0x0f,0x00,0x10,0x3c,
12400xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0x18,0x00,0xbf,0xaf,0xba,0x44,0x00,0x0c,
12410x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,
12420x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0x02,0x80,0x10,0x3c,
12430xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x68,0x15,0x04,0x26,0x04,0x43,0x82,0x90,
12440x00,0x00,0x00,0x00,0x0d,0x00,0x40,0x14,0x25,0xb0,0x02,0x3c,0x00,0x0e,0x42,0x34,
12450x00,0x00,0x43,0x8c,0xec,0x42,0x8f,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x6f,0x14,
12460x68,0x15,0x02,0x26,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
12470x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x40,0xa0,0xec,0x42,0x8f,0x8c,
12480xe8,0x42,0x88,0x8c,0xf0,0x42,0x8a,0x8c,0xf4,0x42,0x8b,0x8c,0xf8,0x42,0x8c,0x8c,
12490xfc,0x42,0x8d,0x8c,0x25,0xb0,0x02,0x3c,0x00,0x43,0x8e,0x8c,0x1c,0x0e,0x49,0x34,
12500x08,0x0e,0x43,0x34,0x00,0x0e,0x44,0x34,0x04,0x0e,0x45,0x34,0x10,0x0e,0x46,0x34,
12510x14,0x0e,0x47,0x34,0x18,0x0e,0x42,0x34,0x00,0x00,0x68,0xac,0x18,0x00,0xbf,0x8f,
12520x00,0x00,0x8f,0xac,0x14,0x00,0xb1,0x8f,0x00,0x00,0xaa,0xac,0x00,0x00,0xcb,0xac,
12530x00,0x00,0xec,0xac,0x00,0x00,0x4d,0xac,0x68,0x15,0x02,0x26,0x10,0x00,0xb0,0x8f,
12540x20,0x00,0xbd,0x27,0x00,0x00,0x2e,0xad,0x08,0x00,0xe0,0x03,0x04,0x43,0x40,0xa0,
12550xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x01,0x00,0x11,0x3c,
12560x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0x18,0x00,0xbf,0xaf,
12570xba,0x44,0x00,0x0c,0x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
12580xff,0xff,0x05,0x36,0x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,
12590xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x02,0x80,0x18,0x3c,0x68,0x15,0x05,0x27,
12600x04,0x43,0xa3,0x90,0x03,0x00,0x02,0x24,0x2a,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,
12610xec,0x42,0xaf,0x8c,0x08,0x43,0xa3,0x8c,0xe8,0x42,0xa2,0x8c,0xf0,0x42,0xac,0x8c,
12620xf4,0x42,0xad,0x8c,0xf8,0x42,0xa9,0x8c,0xfc,0x42,0xaa,0x8c,0x00,0x43,0xab,0x8c,
12630x21,0x70,0x43,0x00,0xff,0xff,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xff,0x00,0x42,0x34,
12640x00,0xff,0xc4,0x31,0x04,0x0e,0x65,0x34,0x10,0x0e,0x66,0x34,0x14,0x0e,0x67,0x34,
12650x18,0x0e,0x68,0x34,0x24,0x80,0xc2,0x01,0x08,0x0e,0x71,0x34,0x00,0x0e,0x62,0x34,
12660x01,0x3f,0x84,0x2c,0x1c,0x0e,0x63,0x34,0x00,0x00,0x4f,0xac,0x00,0x00,0xac,0xac,
12670x00,0x00,0xcd,0xac,0x00,0x00,0xe9,0xac,0x00,0x00,0x0a,0xad,0x00,0x00,0x6b,0xac,
12680x0a,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0xae,0x18,0x00,0xbf,0x8f,
12690x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x68,0x15,0x03,0x27,0x03,0x00,0x02,0x24,
12700x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x04,0x43,0x62,0xa0,0xa6,0x13,0x00,0x08,
12710x00,0x3f,0x0e,0x36,0x00,0x0e,0x42,0x34,0x00,0x00,0x43,0x8c,0xec,0x42,0xaf,0x8c,
12720x00,0x00,0x00,0x00,0xd3,0xff,0x6f,0x14,0x00,0x00,0x00,0x00,0xa7,0x13,0x00,0x08,
12730x00,0x00,0x00,0x00,0xd0,0xff,0xbd,0x27,0x18,0x00,0xb2,0xaf,0x02,0x80,0x12,0x3c,
12740x24,0x00,0xb5,0xaf,0x20,0x00,0xb4,0xaf,0x28,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,
12750x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x44,0x26,0x02,0x80,0x14,0x3c,
12760x00,0x40,0x85,0x8c,0xdc,0x63,0x83,0x8c,0x8e,0x7d,0x86,0x92,0x25,0xb0,0x02,0x3c,
12770x0f,0x0c,0x42,0x34,0x00,0x00,0x46,0xa0,0x02,0x19,0x03,0x00,0xf0,0xf0,0xa5,0x30,
12780x00,0x10,0x02,0x24,0x04,0x43,0x93,0x90,0x71,0x00,0xa2,0x10,0x7f,0x00,0x75,0x30,
12790x25,0xb0,0x09,0x3c,0x4c,0x00,0x23,0x35,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,
12800x03,0x00,0x42,0x30,0x09,0x00,0x40,0x10,0x68,0x15,0x45,0x26,0x68,0x15,0x4a,0x26,
12810x00,0x40,0x42,0x8d,0x00,0x00,0x00,0x00,0x02,0x13,0x02,0x00,0x0f,0x00,0x42,0x30,
12820x33,0x00,0x40,0x10,0x00,0x0e,0x25,0x35,0x68,0x15,0x45,0x26,0x04,0x43,0xa2,0x8c,
12830x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x0f,0x00,0x40,0x14,0x68,0x15,0x4a,0x26,
12840x25,0xb0,0x02,0x3c,0x84,0x01,0x42,0x34,0x00,0x00,0x44,0x8c,0x0d,0x00,0x03,0x24,
12850x7e,0x00,0x83,0x10,0x3e,0x00,0x02,0x24,0x4a,0x00,0x03,0x24,0x1f,0x43,0xa2,0xa0,
12860x1c,0x43,0xa3,0xa0,0x45,0x00,0x02,0x24,0x43,0x00,0x03,0x24,0x1d,0x43,0xa2,0xa0,
12870x1e,0x43,0xa3,0xa0,0x68,0x15,0x4a,0x26,0xdc,0x63,0x4c,0x8d,0x04,0x40,0x42,0x8d,
12880x00,0x40,0x4b,0x8d,0x1e,0x43,0x4d,0x91,0x1c,0x43,0x4e,0x91,0x25,0xb0,0x09,0x3c,
12890x02,0x11,0x02,0x00,0x60,0x0c,0x27,0x35,0x02,0x19,0x0c,0x00,0x98,0x0c,0x24,0x35,
12900x00,0x00,0xe3,0xa0,0x66,0x0c,0x25,0x35,0x00,0x00,0x82,0xa0,0x67,0x0c,0x26,0x35,
12910xf0,0xf0,0x68,0x31,0x10,0x10,0x02,0x24,0x00,0x00,0xad,0xa0,0x00,0x00,0xce,0xa0,
12920x43,0x00,0x02,0x11,0xff,0xff,0x02,0x34,0x28,0x00,0xbf,0x8f,0x24,0x00,0xb5,0x8f,
12930x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
12940x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
12950x00,0x00,0xa2,0x8c,0x00,0x00,0x00,0x00,0x5d,0x00,0x40,0x10,0x10,0x0e,0x28,0x35,
12960x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
12970x08,0x0e,0x22,0x35,0x04,0x0e,0x24,0x35,0x00,0x00,0x43,0x8c,0x00,0x00,0xa5,0x8c,
12980x00,0x00,0x82,0x8c,0xe8,0x42,0x43,0xad,0xec,0x42,0x45,0xad,0xf0,0x42,0x42,0xad,
12990x14,0x0e,0x24,0x35,0x18,0x0e,0x22,0x35,0x1c,0x0e,0x25,0x35,0x00,0x00,0x08,0x8d,
13000x8e,0x7d,0x8b,0x92,0x00,0x00,0x86,0x8c,0x00,0xff,0x63,0x30,0x00,0x00,0x47,0x8c,
13010x00,0x00,0xa4,0x8c,0x9a,0x0c,0x22,0x35,0x02,0x1a,0x03,0x00,0x00,0x00,0x43,0xa0,
13020x22,0x00,0x02,0x24,0xf4,0x42,0x48,0xad,0xf8,0x42,0x46,0xad,0xfc,0x42,0x47,0xad,
13030x58,0x00,0x62,0x11,0x00,0x43,0x44,0xad,0x92,0x00,0x02,0x24,0x56,0x00,0x62,0x11,
13040x0d,0x08,0x22,0x35,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
13050x68,0x15,0x44,0x26,0x00,0x40,0x83,0x8c,0xff,0xff,0x02,0x3c,0xff,0x0f,0x42,0x34,
13060x24,0x18,0x62,0x00,0x00,0x10,0x63,0x34,0xde,0x13,0x00,0x08,0x00,0x40,0x83,0xac,
13070x01,0x00,0x02,0x24,0x35,0x00,0x62,0x12,0x04,0x00,0x02,0x24,0x33,0x00,0x62,0x12,
13080x68,0x15,0x43,0x26,0xff,0xff,0x02,0x24,0xd0,0x13,0x00,0x08,0x04,0x43,0x62,0xa0,
13090xbd,0xff,0x82,0x11,0x02,0x12,0x0b,0x00,0x0f,0x00,0x48,0x30,0x01,0x00,0x03,0x24,
13100xb9,0xff,0x03,0x15,0x4c,0x00,0x23,0x35,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,
13110x03,0x00,0x42,0x30,0xb4,0xff,0x40,0x10,0x03,0x00,0x02,0x24,0x5f,0x00,0x62,0x12,
13120x04,0x00,0x62,0x2a,0x45,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x64,0x00,0x60,0x12,
13130xff,0x00,0xa2,0x31,0xac,0xff,0x68,0x16,0xff,0x00,0xc2,0x31,0x2b,0x10,0xa2,0x02,
13140x52,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x1f,0x43,0x42,0x91,0x00,0x00,0x00,0x00,
13150x2b,0x10,0x55,0x00,0x44,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x2f,0x13,0x00,0x0c,
13160x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x3b,0x00,0x02,0x24,
13170x46,0x00,0x03,0x24,0x1f,0x43,0xa2,0xa0,0x1c,0x43,0xa3,0xa0,0x41,0x00,0x02,0x24,
13180x40,0x00,0x03,0x24,0x1d,0x43,0xa2,0xa0,0xf1,0x13,0x00,0x08,0x1e,0x43,0xa3,0xa0,
13190x00,0x00,0x03,0x8d,0x3f,0x3f,0x02,0x3c,0x3f,0x3f,0x42,0x34,0xa0,0xff,0x62,0x14,
13200x00,0x00,0x00,0x00,0xdf,0x13,0x00,0x08,0x68,0x15,0x45,0x26,0x0f,0x00,0x10,0x3c,
13210x01,0x00,0x11,0x3c,0xff,0xff,0x05,0x36,0xf4,0x98,0x26,0x36,0xba,0x44,0x00,0x0c,
13220x15,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xff,0xff,0x05,0x36,
13230x56,0x30,0x26,0x36,0xba,0x44,0x00,0x0c,0x1a,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,
13240x64,0x00,0x04,0x24,0x68,0x15,0x43,0x26,0xff,0xff,0x02,0x24,0xd0,0x13,0x00,0x08,
13250x04,0x43,0x62,0xa0,0x0d,0x08,0x22,0x35,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,
13260x0f,0x00,0x63,0x30,0x08,0x00,0x62,0x2c,0x0f,0x00,0x63,0x38,0xa5,0xff,0x40,0x14,
13270x01,0x00,0x65,0x24,0x00,0x16,0x05,0x00,0x00,0x24,0x05,0x00,0x00,0x1a,0x05,0x00,
13280x25,0x10,0x44,0x00,0x25,0x10,0x43,0x00,0x25,0x10,0x45,0x00,0x25,0x18,0x65,0x00,
13290x18,0x43,0x43,0xad,0x35,0x14,0x00,0x08,0x14,0x43,0x42,0xad,0x04,0x00,0x02,0x24,
13300x0d,0x00,0x62,0x12,0xff,0x00,0x02,0x24,0x67,0xff,0x62,0x16,0xff,0x00,0xa2,0x31,
13310x2b,0x10,0xa2,0x02,0x1d,0x00,0x40,0x14,0xff,0x00,0xc2,0x31,0x2b,0x10,0xa2,0x02,
13320x0a,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xfb,0x12,0x00,0x0c,0x00,0x00,0x00,0x00,
13330x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x1d,0x43,0x42,0x91,0x00,0x00,0x00,0x00,
13340x2b,0x10,0x55,0x00,0xf8,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0xc5,0x12,0x00,0x0c,
13350x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x20,0x43,0x42,0x91,
13360x00,0x00,0x00,0x00,0x2b,0x10,0xa2,0x02,0xac,0xff,0x40,0x10,0x00,0x00,0x00,0x00,
13370x70,0x13,0x00,0x0c,0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,
13380x2b,0x10,0xa2,0x02,0xe8,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x21,0x43,0x42,0x91,
13390x00,0x00,0x00,0x00,0x2b,0x10,0x55,0x00,0xa0,0xff,0x40,0x14,0x00,0x00,0x00,0x00,
13400x70,0x13,0x00,0x0c,0x00,0x00,0x00,0x00,0x06,0x14,0x00,0x08,0x00,0x00,0x00,0x00,
13410x02,0x80,0x08,0x3c,0x68,0x15,0x05,0x25,0xdc,0x63,0xa4,0x8c,0xe6,0x42,0xa3,0x90,
13420x02,0x11,0x04,0x00,0x1f,0x00,0x60,0x14,0x7f,0x00,0x46,0x30,0x25,0xb0,0x07,0x3c,
13430x4c,0x00,0xe2,0x34,0x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x19,0x00,0x60,0x10,
13440x00,0x00,0x00,0x00,0xff,0xff,0x02,0x34,0x16,0x00,0x82,0x10,0x00,0x00,0x00,0x00,
13450x00,0x08,0xe3,0x34,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,
13460x12,0x00,0x40,0x10,0x4b,0x00,0xc2,0x2c,0x29,0x00,0x40,0x10,0x01,0x00,0x04,0x24,
13470xd8,0xff,0xc2,0x24,0x1e,0x00,0x42,0x2c,0x2f,0x00,0x40,0x10,0x23,0x00,0xc2,0x2c,
13480x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x00,0x00,0x00,0x00,0x29,0x00,0x40,0x10,
13490x25,0xb0,0x02,0x3c,0x20,0x00,0x03,0x24,0x87,0x0c,0x42,0x34,0x00,0x00,0x43,0xa0,
13500xd3,0x42,0x80,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x0f,0x00,0x40,0x10,
13510x01,0x00,0x04,0x24,0xd8,0xff,0xc2,0x24,0x1e,0x00,0x42,0x2c,0x2c,0x00,0x40,0x10,
13520x23,0x00,0xc2,0x2c,0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x00,0x00,0x00,0x00,
13530x26,0x00,0x40,0x10,0x25,0xb0,0x02,0x3c,0x44,0x00,0x03,0x24,0x30,0x0c,0x42,0x34,
13540x00,0x00,0x43,0xa0,0xed,0x14,0x00,0x08,0xd3,0x42,0x80,0xa0,0xd3,0x42,0xa2,0x90,
13550x00,0x00,0x00,0x00,0xef,0xff,0x44,0x10,0x30,0x0c,0xe3,0x34,0x43,0x00,0x02,0x24,
13560xd3,0x42,0xa4,0xa0,0x00,0x00,0x62,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
13570xd3,0x42,0xa2,0x90,0x00,0x00,0x00,0x00,0xd5,0xff,0x44,0x10,0x87,0x0c,0xe3,0x34,
13580x10,0x00,0x02,0x24,0xd3,0x42,0xa4,0xa0,0x00,0x00,0x62,0xa0,0x06,0x15,0x00,0x08,
13590x00,0x00,0x00,0x00,0x23,0x00,0xc2,0x2c,0xda,0xff,0x40,0x10,0x00,0x00,0x00,0x00,
13600x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,0x02,0x00,0x03,0x24,0xd5,0xff,0x43,0x10,
13610x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,0x87,0x0c,0x42,0x34,0xd3,0x42,0x83,0xa0,
13620x00,0x00,0x40,0xa0,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x23,0x00,0xc2,0x2c,
13630xcc,0xff,0x40,0x10,0x00,0x00,0x00,0x00,0x68,0x15,0x04,0x25,0xd3,0x42,0x82,0x90,
13640x02,0x00,0x03,0x24,0xc7,0xff,0x43,0x10,0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,
13650xd3,0x42,0x83,0xa0,0x30,0x0c,0x42,0x34,0x42,0x00,0x03,0x24,0x00,0x00,0x43,0xa0,
13660x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x45,0x24,
13670xd5,0x42,0xa3,0x90,0x02,0x00,0x02,0x24,0x03,0x00,0x62,0x10,0x00,0x00,0x00,0x00,
13680x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0xdc,0x63,0xa2,0x8c,0x25,0xb0,0x03,0x3c,
13690x0a,0x0a,0x68,0x34,0x02,0x11,0x02,0x00,0x7f,0x00,0x42,0x30,0x1a,0x00,0x44,0x2c,
13700x14,0x00,0x42,0x2c,0x01,0x0a,0x66,0x34,0x0b,0x00,0x40,0x14,0x2e,0x0a,0x67,0x34,
13710xf3,0xff,0x80,0x14,0x00,0x00,0x00,0x00,0xd4,0x42,0xa4,0x90,0x01,0x00,0x02,0x24,
13720x01,0x0a,0x67,0x34,0x0f,0x00,0x82,0x10,0x2e,0x0a,0x66,0x34,0xd4,0x42,0xa0,0xa0,
13730x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x40,0x00,0x02,0x24,0x00,0x00,0xc2,0xa0,
13740x01,0x00,0x03,0x24,0xdf,0xff,0x02,0x24,0xd4,0x42,0xa3,0xa0,0x00,0x00,0xe2,0xa0,
13750x03,0x00,0x03,0x24,0x21,0x10,0x00,0x00,0x00,0x00,0x03,0xa1,0x08,0x00,0xe0,0x03,
13760x00,0x00,0x00,0x00,0x47,0x00,0x02,0x24,0x00,0x00,0xe2,0xa0,0xd3,0xff,0x03,0x24,
13770x83,0xff,0x02,0x24,0x00,0x00,0xc3,0xa0,0x00,0x00,0x02,0xa1,0x48,0x15,0x00,0x08,
13780xd4,0x42,0xa0,0xa0,0xd0,0xff,0xbd,0x27,0x1c,0x00,0xb1,0xaf,0x28,0x00,0xbf,0xaf,
13790x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,0xff,0xff,0x11,0x24,
13800x02,0x80,0x13,0x3c,0x41,0xb0,0x02,0x3c,0x68,0x15,0x66,0x26,0x04,0x00,0x42,0x34,
13810x00,0x00,0x47,0x8c,0x00,0x4b,0xc5,0x8c,0x02,0x80,0x03,0x3c,0x96,0x7d,0x64,0x90,
13820xfc,0x4a,0xc8,0x8c,0x02,0x80,0x02,0x3c,0xb8,0x7d,0x49,0x90,0x25,0xb0,0x0a,0x3c,
13830x25,0x90,0xa7,0x00,0xb0,0x03,0x42,0x35,0x00,0x00,0x52,0xac,0x00,0x24,0x04,0x00,
13840x00,0x00,0x48,0xac,0x84,0x02,0x43,0x35,0x8c,0x02,0x45,0x35,0x01,0x00,0x02,0x24,
13850x00,0x00,0x72,0xac,0x00,0x00,0xa4,0xac,0xb9,0x04,0x22,0x11,0x00,0x4b,0xd2,0xac,
13860x68,0x15,0x66,0x26,0xfc,0x4a,0xc2,0x8c,0x00,0x00,0x00,0x00,0x24,0x28,0x52,0x00,
13870x01,0x00,0xa3,0x30,0x09,0x00,0x60,0x10,0x04,0x00,0xa2,0x30,0x00,0x4b,0xc2,0x8c,
13880x25,0xb0,0x03,0x3c,0x01,0x00,0x04,0x24,0x01,0x00,0x42,0x38,0xb0,0x03,0x63,0x34,
13890x00,0x00,0x64,0xac,0x00,0x4b,0xc2,0xac,0x04,0x00,0xa2,0x30,0x09,0x00,0x40,0x10,
13900x08,0x00,0xa2,0x30,0x00,0x4b,0xc2,0x8c,0x25,0xb0,0x03,0x3c,0x04,0x00,0x04,0x24,
13910x04,0x00,0x42,0x38,0xb0,0x03,0x63,0x34,0x00,0x00,0x64,0xac,0x00,0x4b,0xc2,0xac,
13920x08,0x00,0xa2,0x30,0x0e,0x00,0x40,0x10,0x68,0x15,0x64,0x26,0xc9,0x64,0xc2,0x90,
13930x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,
13940x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0xc0,0xa0,0x00,0x4b,0xc2,0x8c,
13950x00,0x00,0x00,0x00,0x08,0x00,0x42,0x38,0x00,0x4b,0xc2,0xac,0x68,0x15,0x64,0x26,
13960xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x10,0x00,0x42,0x30,
13970x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,
13980x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,
13990x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,
14000x10,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,
14010x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x20,0x00,0x42,0x30,0x0e,0x00,0x40,0x10,
14020x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,
14030x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,
14040xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x20,0x00,0x42,0x38,
14050x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,
14060x24,0x10,0x52,0x00,0x40,0x00,0x42,0x30,0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
14070xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,
14080x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,
14090x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x40,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,
14100x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,
14110x80,0x00,0x42,0x30,0x0e,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,
14120x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,
14130x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,
14140x00,0x00,0x00,0x00,0x80,0x00,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,
14150xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x01,0x42,0x30,
14160x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,
14170x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,
14180x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,
14190x00,0x01,0x42,0x38,0x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,
14200x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x02,0x42,0x30,0x0e,0x00,0x40,0x10,
14210x00,0x00,0x00,0x00,0xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,
14220x2a,0xb0,0x02,0x3c,0x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,
14230xc9,0x64,0x80,0xa0,0x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x38,
14240x00,0x4b,0x82,0xac,0x68,0x15,0x64,0x26,0xfc,0x4a,0x82,0x8c,0x00,0x00,0x00,0x00,
14250x24,0x10,0x52,0x00,0x00,0x04,0x42,0x30,0x0d,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
14260xc9,0x64,0x82,0x90,0x00,0x00,0x00,0x00,0x05,0x00,0x40,0x18,0x2a,0xb0,0x02,0x3c,
14270x02,0x00,0x03,0x24,0x01,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0xc9,0x64,0x80,0xa0,
14280x00,0x4b,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x04,0x42,0x38,0x00,0x4b,0x82,0xac,
14290x68,0x15,0x63,0x26,0xfc,0x4a,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,
14300x00,0x08,0x42,0x30,0x3a,0x00,0x40,0x10,0x2a,0xb0,0x05,0x3c,0x00,0x00,0xa8,0x8c,
14310xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,0x31,0x00,0x82,0x10,0x00,0x80,0x02,0x31,
14320x08,0x04,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,
14330x05,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xc9,0x64,0x62,0x90,0x00,0x00,0x00,0x00,
14340x0b,0x00,0x40,0x18,0xff,0x00,0x02,0x24,0x08,0x64,0x62,0x90,0x20,0xb0,0x03,0x3c,
14350x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,0x0c,0x00,0x48,0x8c,0x25,0xb0,0x03,0x3c,
14360xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,0xff,0x00,0x04,0x31,0xff,0x00,0x02,0x24,
14370x1a,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0xc0,0x64,0x05,0x8e,
14380x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,
14390x54,0x64,0x03,0xae,0x21,0x20,0x00,0x00,0x08,0x64,0x08,0xa2,0x20,0x00,0x07,0x24,
14400x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x4a,0x05,0x8e,0x02,0x80,0x06,0x3c,
14410x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,0x24,0x28,0xa2,0x00,0x25,0xb0,0x02,0x3c,
14420x04,0x00,0x84,0x34,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,
14430x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,0xfc,0x4a,0x05,0xae,0x68,0x15,0x63,0x26,
14440x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x08,0x42,0x38,0x00,0x4b,0x62,0xac,
14450x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,
14460x00,0x10,0x42,0x30,0x38,0x00,0x40,0x10,0x2a,0xb0,0x02,0x3c,0x08,0x00,0x43,0x34,
14470x00,0x00,0x68,0x8c,0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,0x2c,0x00,0x82,0x10,
14480x00,0x80,0x02,0x31,0xca,0x03,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,
14490x24,0x10,0x02,0x01,0x0b,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x10,0x64,0xa2,0x90,
14500x20,0xb0,0x03,0x3c,0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,0x0c,0x00,0x48,0x8c,
14510x25,0xb0,0x03,0x3c,0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,0xff,0x00,0x04,0x31,
14520xff,0x00,0x02,0x24,0x1a,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
14530xd8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
14540x21,0x30,0x60,0x00,0x6c,0x64,0x03,0xae,0x01,0x00,0x04,0x24,0x10,0x64,0x08,0xa2,
14550x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0xfc,0x4a,0x05,0x8e,
14560x02,0x80,0x06,0x3c,0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,0x24,0x28,0xa2,0x00,
14570x25,0xb0,0x02,0x3c,0x10,0x00,0x84,0x34,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,
14580x00,0x00,0x44,0xac,0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,0xfc,0x4a,0x05,0xae,
14590x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x10,0x42,0x38,
14600x00,0x4b,0x62,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x00,0x00,0x00,0x00,
14610x24,0x10,0x52,0x00,0x00,0x20,0x42,0x30,0x37,0x00,0x40,0x10,0x2a,0xb0,0x02,0x3c,
14620x04,0x00,0x43,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x02,0x24,0xff,0x00,0x04,0x31,
14630xab,0x03,0x82,0x10,0x00,0x80,0x02,0x31,0x90,0x03,0x40,0x14,0x00,0x80,0x02,0x3c,
14640x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x0b,0x00,0x40,0x10,0xff,0x00,0x02,0x24,
14650x0c,0x64,0xa2,0x90,0x20,0xb0,0x03,0x3c,0x00,0x12,0x02,0x00,0x21,0x10,0x43,0x00,
14660x0c,0x00,0x48,0x8c,0x25,0xb0,0x03,0x3c,0xb0,0x03,0x63,0x34,0x00,0x00,0x68,0xac,
14670xff,0x00,0x04,0x31,0xff,0x00,0x02,0x24,0x1a,0x00,0x82,0x10,0xff,0x00,0x03,0x31,
14680x68,0x15,0x70,0x26,0xcc,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,
14690x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0x60,0x64,0x03,0xae,0x01,0x00,0x04,0x24,
14700x0c,0x64,0x08,0xa2,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
14710xfc,0x4a,0x05,0x8e,0x02,0x80,0x06,0x3c,0x6c,0x7e,0xc4,0x8c,0xff,0xc7,0x02,0x24,
14720x24,0x28,0xa2,0x00,0x25,0xb0,0x02,0x3c,0x20,0x00,0x84,0x34,0x80,0x03,0x42,0x34,
14730x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x65,0xac,0x6c,0x7e,0xc4,0xac,
14740xfc,0x4a,0x05,0xae,0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,
14750x00,0x20,0x42,0x38,0x00,0x4b,0x62,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,
14760x00,0x00,0x00,0x00,0x24,0x10,0x52,0x00,0x00,0x80,0x42,0x30,0x59,0x00,0x40,0x10,
14770x2a,0xb0,0x06,0x3c,0x0c,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,
14780xff,0x00,0x04,0x31,0x78,0x03,0x87,0x10,0x00,0x80,0x02,0x31,0x24,0x00,0x40,0x14,
14790x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x22,0x00,0x40,0x10,
14800xff,0x00,0x02,0x24,0x40,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
14810xff,0x00,0x44,0x30,0x0f,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xe8,0x63,0xa4,0xa0,
14820x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x09,0x00,0x83,0x10,
14830x68,0x15,0x62,0x26,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,
14840x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xe8,0x63,0xe3,0xa0,
14850x68,0x15,0x62,0x26,0xe8,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,
14860x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
14870xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0x16,0x17,0x00,0x08,0xff,0x00,0x02,0x24,
14880x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x24,0x00,0x82,0x10,0x68,0x15,0x70,0x26,
14890xff,0x00,0x03,0x31,0x90,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,
14900x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0xe8,0x63,0x08,0xa2,0x24,0x64,0x03,0xae,
14910x03,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
14920x02,0x80,0x0a,0x3c,0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,
14930xfc,0x4a,0x06,0x8e,0x01,0x00,0x08,0x3c,0x80,0xff,0x02,0x24,0x25,0x38,0xe2,0x00,
14940x00,0x80,0x03,0x35,0x80,0x00,0xa5,0x34,0x27,0x18,0x03,0x00,0x00,0x26,0x07,0x00,
14950x25,0xb0,0x02,0x3c,0x24,0x30,0xc3,0x00,0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,
14960x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x27,0x88,0x08,0x00,0x00,0x00,0x66,0xac,
14970x6c,0x7e,0x25,0xad,0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x63,0x26,
14980x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x80,0x42,0x38,0x00,0x4b,0x62,0xac,
14990x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x01,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,
15000x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x56,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,
15010x10,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,
15020x23,0x03,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
15030x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
15040xff,0x00,0x02,0x24,0x41,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
15050xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xec,0x63,0xa4,0xa0,
15060x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
15070x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
15080xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xec,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,
15090xec,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
15100x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
15110x00,0x00,0x48,0xac,0x75,0x17,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
15120xff,0x00,0x02,0x24,0x22,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
15130x90,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
15140x21,0x30,0x60,0x00,0xec,0x63,0x08,0xa2,0x24,0x64,0x03,0xae,0x03,0x00,0x04,0x24,
15150x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c,
15160x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e,
15170x01,0x00,0x02,0x3c,0x00,0x80,0x42,0x34,0x40,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,
15180x24,0x30,0xc2,0x00,0x80,0x00,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,
15190x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,
15200x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,
15210x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x01,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,
15220x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x02,0x00,0x03,0x3c,
15230x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,
15240x14,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,
15250xcc,0x02,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
15260x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
15270xff,0x00,0x02,0x24,0x42,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
15280xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xf0,0x63,0xa4,0xa0,
15290x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
15300x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
15310xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xf0,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,
15320xf0,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
15330x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
15340x00,0x00,0x48,0xac,0xd1,0x17,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
15350xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
15360x9c,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
15370x21,0x30,0x60,0x00,0xf0,0x63,0x08,0xa2,0x30,0x64,0x03,0xae,0x04,0x00,0x04,0x24,
15380x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c,
15390x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e,
15400x06,0x00,0x02,0x3c,0x20,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,
15410x00,0x01,0xa5,0x34,0x25,0xb0,0x03,0x3c,0x04,0x00,0x02,0x3c,0x00,0x26,0x07,0x00,
15420x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34,
15430x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad,
15440x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26,
15450x00,0x4b,0x43,0x8c,0x02,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,
15460x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x04,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,
15470x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x58,0x00,0x40,0x10,0x25,0xb0,0x03,0x3c,
15480xb0,0x03,0x62,0x34,0x2a,0xb0,0x09,0x3c,0x00,0x00,0x51,0xac,0x18,0x00,0x26,0x35,
15490x00,0x00,0xc8,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,0x3a,0x02,0x87,0x10,
15500x04,0x00,0x02,0x24,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,
15510x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,
15520x43,0x00,0x26,0x35,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,
15530x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xf4,0x63,0xa4,0xa0,0x00,0x00,0xc2,0x90,
15540xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,
15550x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,
15560xff,0x00,0x44,0x30,0xf4,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,0xf4,0x63,0x43,0x90,
15570x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,
15580x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,
15590x34,0x18,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0xc2,0xac,0xff,0x00,0x02,0x24,
15600x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0x9c,0x64,0x05,0x8e,
15610x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,
15620xf4,0x63,0x08,0xa2,0x30,0x64,0x03,0xae,0x04,0x00,0x04,0x24,0x20,0x00,0x07,0x24,
15630x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c,0x7c,0x7e,0x27,0x91,
15640x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e,0x06,0x00,0x02,0x3c,
15650x10,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,0x00,0x01,0xa5,0x34,
15660x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,0x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,
15670x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,
15680x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,
15690x04,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,
15700xfc,0x4a,0xa2,0x8c,0x08,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,
15710x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,0x1c,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,
15720xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,0x13,0x02,0x87,0x10,0x25,0xb0,0x02,0x3c,
15730x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,
15740x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x44,0x00,0xc6,0x34,
15750x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,
15760x68,0x15,0x62,0x26,0xf8,0x63,0xa4,0xa0,0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,
15770xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,
15780x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,
15790xf8,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,0xf8,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,
15800x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,
15810xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0x8f,0x18,0x00,0x08,
15820xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,
15830x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,0xa8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,
15840x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0xf8,0x63,0x08,0xa2,
15850x3c,0x64,0x03,0xae,0x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,
15860x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c,0x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,
15870x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e,0x18,0x00,0x02,0x3c,0x08,0x00,0xe7,0x34,
15880x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,0x00,0x02,0xa5,0x34,0x25,0xb0,0x03,0x3c,
15890x10,0x00,0x02,0x3c,0x00,0x26,0x07,0x00,0x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,
15900x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34,0x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,
15910x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad,0x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,
15920x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x08,0x00,0x04,0x3c,
15930x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,
15940x10,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,0x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,
15950x58,0x00,0x40,0x10,0x25,0xb0,0x06,0x3c,0xb0,0x03,0xc2,0x34,0x2a,0xb0,0x09,0x3c,
15960x00,0x00,0x51,0xac,0x20,0x00,0x23,0x35,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,
15970xff,0x00,0x04,0x31,0x80,0x01,0x87,0x10,0x90,0x03,0xc2,0x34,0x00,0x80,0x02,0x31,
15980x23,0x00,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,
15990x21,0x00,0x40,0x10,0xff,0x00,0x02,0x24,0x45,0x00,0x26,0x35,0x00,0x00,0xc2,0x90,
16000x00,0x00,0x00,0x00,0xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,
16010x04,0x64,0xa4,0xa0,0x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,
16020x07,0x00,0x83,0x10,0x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,
16030x21,0x18,0x80,0x00,0xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0x04,0x64,0xe3,0xa0,
16040x68,0x15,0x62,0x26,0x04,0x64,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,
16050x21,0x18,0x62,0x00,0x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,
16060xff,0x00,0x04,0x31,0x00,0x00,0x48,0xac,0xf2,0x18,0x00,0x08,0xff,0x00,0x02,0x24,
16070x00,0x00,0x62,0xac,0xff,0x00,0x02,0x24,0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,
16080xff,0x00,0x03,0x31,0xa8,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,
16090x21,0x18,0x62,0x00,0x21,0x30,0x60,0x00,0x04,0x64,0x08,0xa2,0x3c,0x64,0x03,0xae,
16100x05,0x00,0x04,0x24,0x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,
16110x02,0x80,0x09,0x3c,0x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,
16120xfc,0x4a,0x06,0x8e,0x18,0x00,0x02,0x3c,0x01,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,
16130x24,0x30,0xc2,0x00,0x00,0x02,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,
16140x25,0x20,0x85,0x00,0x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,
16150x00,0x00,0x66,0xac,0x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,
16160x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x10,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,
16170x00,0x4b,0x43,0xac,0x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x20,0x00,0x03,0x3c,
16180x24,0x10,0x52,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x2a,0xb0,0x06,0x3c,
16190x24,0x00,0xc3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x07,0x24,0xff,0x00,0x04,0x31,
16200x28,0x01,0x87,0x10,0x25,0xb0,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
16210x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
16220xff,0x00,0x02,0x24,0x46,0x00,0xc6,0x34,0x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,
16230xff,0x00,0x44,0x30,0x0e,0x00,0x87,0x10,0x68,0x15,0x62,0x26,0xfc,0x63,0xa4,0xa0,
16240x00,0x00,0xc2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
16250x21,0x38,0xa0,0x00,0x21,0x28,0xc0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
16260xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0xfc,0x63,0xe3,0xa0,0x68,0x15,0x62,0x26,
16270xfc,0x63,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
16280x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
16290x00,0x00,0x48,0xac,0x4d,0x19,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
16300xff,0x00,0x02,0x24,0x25,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
16310xb4,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
16320x21,0x30,0x60,0x00,0xfc,0x63,0x08,0xa2,0x48,0x64,0x03,0xae,0x06,0x00,0x04,0x24,
16330x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x0a,0x3c,
16340x7c,0x7e,0x47,0x91,0x02,0x80,0x09,0x3c,0x6c,0x7e,0x25,0x8d,0xfc,0x4a,0x06,0x8e,
16350x60,0x00,0x02,0x3c,0x04,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,
16360x00,0x04,0xa5,0x34,0x25,0xb0,0x03,0x3c,0x40,0x00,0x02,0x3c,0x00,0x26,0x07,0x00,
16370x26,0x88,0x22,0x02,0xb0,0x03,0x68,0x34,0x25,0x20,0x85,0x00,0x80,0x03,0x63,0x34,
16380x41,0xb0,0x02,0x3c,0x00,0x00,0x64,0xac,0x00,0x00,0x46,0xac,0x6c,0x7e,0x25,0xad,
16390x7c,0x7e,0x47,0xa1,0xfc,0x4a,0x06,0xae,0x00,0x00,0x11,0xad,0x68,0x15,0x62,0x26,
16400x00,0x4b,0x43,0x8c,0x20,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,
16410x68,0x15,0x65,0x26,0xfc,0x4a,0xa2,0x8c,0x40,0x00,0x03,0x3c,0x24,0x10,0x52,0x00,
16420x24,0x10,0x51,0x00,0x24,0x10,0x43,0x00,0x5a,0x00,0x40,0x10,0x68,0x15,0x70,0x26,
16430x25,0xb0,0x02,0x3c,0x2a,0xb0,0x07,0x3c,0xb0,0x03,0x42,0x34,0x00,0x00,0x51,0xac,
16440x28,0x00,0xe3,0x34,0x00,0x00,0x68,0x8c,0xff,0x00,0x06,0x24,0xff,0x00,0x04,0x31,
16450xc9,0x00,0x86,0x10,0x25,0xbd,0x02,0x3c,0x00,0x80,0x02,0x31,0x23,0x00,0x40,0x14,
16460x00,0x80,0x02,0x3c,0x00,0xff,0x02,0x3c,0x24,0x10,0x02,0x01,0x21,0x00,0x40,0x10,
16470xff,0x00,0x02,0x24,0x47,0x00,0xe7,0x34,0x00,0x00,0xe2,0x90,0x00,0x00,0x00,0x00,
16480xff,0x00,0x44,0x30,0x0e,0x00,0x86,0x10,0x68,0x15,0x62,0x26,0x00,0x64,0xa4,0xa0,
16490x00,0x00,0xe2,0x90,0xff,0x00,0x83,0x30,0xff,0x00,0x44,0x30,0x07,0x00,0x83,0x10,
16500x21,0x30,0xa0,0x00,0x21,0x28,0xe0,0x00,0x00,0x00,0xa2,0x90,0x21,0x18,0x80,0x00,
16510xfd,0xff,0x62,0x14,0xff,0x00,0x44,0x30,0x00,0x64,0xc3,0xa0,0x68,0x15,0x62,0x26,
16520x00,0x64,0x43,0x90,0x20,0xb0,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
16530x0c,0x00,0x68,0x8c,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0xff,0x00,0x04,0x31,
16540x00,0x00,0x48,0xac,0xb1,0x19,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
16550xff,0x00,0x02,0x24,0x21,0x00,0x82,0x10,0x68,0x15,0x70,0x26,0xff,0x00,0x03,0x31,
16560xb4,0x64,0x05,0x8e,0x20,0x10,0x02,0x3c,0x00,0x1a,0x03,0x00,0x21,0x18,0x62,0x00,
16570x21,0x30,0x60,0x00,0x00,0x64,0x08,0xa2,0x48,0x64,0x03,0xae,0x06,0x00,0x04,0x24,
16580x20,0x00,0x07,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xa0,0xaf,0x02,0x80,0x09,0x3c,
16590x7c,0x7e,0x27,0x91,0x02,0x80,0x08,0x3c,0x6c,0x7e,0x05,0x8d,0xfc,0x4a,0x06,0x8e,
16600x60,0x00,0x02,0x3c,0x02,0x00,0xe7,0x34,0x27,0x10,0x02,0x00,0x24,0x30,0xc2,0x00,
16610x00,0x04,0xa5,0x34,0x00,0x26,0x07,0x00,0x25,0xb0,0x02,0x3c,0x25,0x20,0x85,0x00,
16620x80,0x03,0x42,0x34,0x41,0xb0,0x03,0x3c,0x00,0x00,0x44,0xac,0x00,0x00,0x66,0xac,
16630x6c,0x7e,0x05,0xad,0x7c,0x7e,0x27,0xa1,0xfc,0x4a,0x06,0xae,0x68,0x15,0x62,0x26,
16640x00,0x4b,0x43,0x8c,0x40,0x00,0x04,0x3c,0x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,
16650x68,0x15,0x70,0x26,0xfc,0x4a,0x06,0x8e,0x00,0x04,0x11,0x3c,0x24,0x10,0xd2,0x00,
16660x24,0x10,0x51,0x00,0x4c,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x24,0x28,0xd2,0x00,
16670x00,0x08,0x04,0x3c,0x24,0x10,0xa4,0x00,0x08,0x00,0x40,0x10,0x80,0x00,0x07,0x3c,
16680x00,0x4b,0x03,0x8e,0x25,0xb0,0x02,0x3c,0xb0,0x03,0x42,0x34,0x26,0x18,0x64,0x00,
16690x00,0x00,0x44,0xac,0x00,0x4b,0x03,0xae,0x80,0x00,0x07,0x3c,0x24,0x10,0xa7,0x00,
16700x21,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x4b,0x03,0x8e,0x25,0xb0,0x08,0x3c,
16710xb0,0x03,0x09,0x35,0x2a,0xb0,0x02,0x3c,0x00,0x00,0x23,0xad,0x36,0x00,0x42,0x34,
16720x00,0x00,0x43,0x90,0x23,0xb0,0x04,0x3c,0xff,0x1f,0x02,0x3c,0xc0,0x18,0x03,0x00,
16730xf0,0x07,0x63,0x30,0x5c,0x65,0x05,0x8e,0x21,0x18,0x64,0x00,0xff,0xff,0x42,0x34,
16740x24,0x18,0x62,0x00,0x59,0x00,0x65,0x10,0x60,0x65,0x03,0xae,0x02,0x80,0x05,0x3c,
16750x6c,0x7e,0xa3,0x8c,0x27,0x20,0x07,0x00,0x24,0x20,0xc4,0x00,0x00,0x08,0x63,0x34,
16760x41,0xb0,0x02,0x3c,0x00,0x00,0x23,0xad,0x00,0x00,0x44,0xac,0x6c,0x7e,0xa3,0xac,
16770xfc,0x4a,0x04,0xae,0x68,0x15,0x62,0x26,0x00,0x4b,0x43,0x8c,0x80,0x00,0x04,0x3c,
16780x26,0x18,0x64,0x00,0x00,0x4b,0x43,0xac,0x68,0x15,0x66,0x26,0xfc,0x4a,0xc3,0x8c,
16790x00,0x01,0x04,0x3c,0x24,0x28,0x72,0x00,0x24,0x10,0xa4,0x00,0x06,0x00,0x40,0x10,
16800x25,0xb0,0x02,0x3c,0x00,0x4b,0xc3,0x8c,0xb0,0x03,0x42,0x34,0x26,0x18,0x64,0x00,
16810x00,0x00,0x44,0xac,0x00,0x4b,0xc3,0xac,0x00,0x02,0x04,0x3c,0x24,0x10,0xa4,0x00,
16820x06,0x00,0x40,0x10,0x25,0xb0,0x03,0x3c,0x00,0x4b,0xc2,0x8c,0xb0,0x03,0x63,0x34,
16830x26,0x10,0x44,0x00,0x00,0x4b,0xc2,0xac,0x00,0x00,0x64,0xac,0x28,0x00,0xbf,0x8f,
16840x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,0x18,0x00,0xb0,0x8f,
16850x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0x5b,0x4e,0x00,0x0c,0x07,0x00,0x04,0x24,
16860x00,0x4b,0x03,0x8e,0xfc,0x4a,0x06,0x8e,0x25,0xb0,0x02,0x3c,0x26,0x18,0x71,0x00,
16870xb0,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0xdf,0x19,0x00,0x08,0x00,0x4b,0x03,0xae,
16880x56,0x01,0x42,0x35,0x00,0x00,0x43,0x94,0x00,0x00,0x00,0x00,0x44,0xfb,0x60,0x10,
16890x00,0x00,0x00,0x00,0x5b,0x4e,0x00,0x0c,0x07,0x00,0x04,0x24,0x7d,0x15,0x00,0x08,
16900x68,0x15,0x66,0x26,0x00,0x00,0xa2,0xac,0x48,0x16,0x00,0x08,0xff,0x00,0x02,0x24,
16910x00,0x00,0x62,0xac,0x85,0x16,0x00,0x08,0xff,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
16920xc2,0x16,0x00,0x08,0xff,0x00,0x02,0x24,0x90,0x03,0x63,0x34,0x00,0x00,0x62,0xac,
16930x57,0x18,0x00,0x08,0x68,0x15,0x62,0x26,0x00,0x00,0x40,0xac,0x15,0x19,0x00,0x08,
16940x68,0x15,0x62,0x26,0x02,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
16950x74,0x19,0x00,0x08,0x68,0x15,0x62,0x26,0x01,0x00,0x03,0x24,0x90,0x03,0x42,0x34,
16960x00,0x00,0x43,0xac,0xd4,0x19,0x00,0x08,0x68,0x15,0x62,0x26,0xd0,0x03,0x03,0x35,
16970x80,0x00,0x02,0x24,0x00,0x00,0x62,0xac,0x0a,0x1a,0x00,0x08,0x68,0x15,0x62,0x26,
16980x25,0xb0,0x02,0x3c,0x07,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
16990x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,0x00,0x00,0x00,0x00,0x00,0x20,0x42,0x38,
17000xe2,0x16,0x00,0x08,0x00,0x4b,0x62,0xac,0x25,0xb0,0x02,0x3c,0x07,0x00,0x03,0x24,
17010x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x68,0x15,0x63,0x26,0x00,0x4b,0x62,0x8c,
17020x00,0x00,0x00,0x00,0x00,0x80,0x42,0x38,0x40,0x17,0x00,0x08,0x00,0x4b,0x62,0xac,
17030x06,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,0x99,0x17,0x00,0x08,
17040x68,0x15,0x62,0x26,0x05,0x00,0x03,0x24,0x90,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
17050xf8,0x17,0x00,0x08,0x68,0x15,0x62,0x26,0x03,0x00,0x03,0x24,0x90,0x03,0x42,0x34,
17060x00,0x00,0x43,0xac,0xb6,0x18,0x00,0x08,0x68,0x15,0x62,0x26,0x25,0xb0,0x0d,0x3c,
17070x00,0x80,0x02,0x3c,0x18,0x03,0xa4,0x35,0xfc,0x69,0x42,0x24,0x02,0x80,0x03,0x3c,
17080x41,0xb0,0x08,0x3c,0x00,0x00,0x82,0xac,0x68,0x15,0x6a,0x24,0x0a,0x00,0x02,0x35,
17090x00,0x00,0x44,0x94,0x0a,0x4b,0x43,0x95,0x08,0x4b,0x4b,0x95,0x25,0x18,0x64,0x00,
17100xff,0xff,0x6c,0x30,0x24,0x10,0x8b,0x01,0x02,0x00,0x42,0x30,0x4d,0x00,0x40,0x10,
17110x02,0x00,0x64,0x38,0x02,0x00,0x02,0x24,0xc0,0x03,0xa3,0x35,0x00,0x00,0x62,0xac,
17120x0a,0x4b,0x44,0xa5,0x24,0x38,0x8b,0x01,0x04,0x00,0xe2,0x30,0x0a,0x00,0x40,0x10,
17130x08,0x00,0xe2,0x30,0x0a,0x4b,0x43,0x95,0x0c,0x00,0x04,0x35,0xc0,0x03,0xa5,0x35,
17140x04,0x00,0x63,0x38,0x04,0x00,0x02,0x24,0x00,0x00,0x86,0x8c,0x00,0x00,0xa2,0xac,
17150x0a,0x4b,0x43,0xa5,0x08,0x00,0xe2,0x30,0x08,0x00,0x40,0x10,0x10,0x00,0xe2,0x30,
17160x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,0x08,0x00,0x03,0x24,0x08,0x00,0x42,0x38,
17170x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,0x10,0x00,0xe2,0x30,0x08,0x00,0x40,0x10,
17180x20,0x00,0xe2,0x30,0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,0x10,0x00,0x03,0x24,
17190x10,0x00,0x42,0x38,0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,0x20,0x00,0xe2,0x30,
17200x08,0x00,0x40,0x10,0x80,0x00,0xe2,0x30,0x0a,0x4b,0x42,0x95,0xc0,0x03,0xa4,0x35,
17210x20,0x00,0x03,0x24,0x20,0x00,0x42,0x38,0x00,0x00,0x83,0xac,0x0a,0x4b,0x42,0xa5,
17220x80,0x00,0xe2,0x30,0x15,0x00,0x40,0x10,0x24,0x10,0x8b,0x01,0x02,0x80,0x09,0x3c,
17230x0a,0x4b,0x46,0x95,0x6c,0x7e,0x25,0x8d,0x08,0x00,0x02,0x3c,0x7f,0xff,0x04,0x24,
17240x24,0x20,0x64,0x01,0x25,0x28,0xa2,0x00,0x80,0x00,0xc6,0x38,0xb0,0x03,0xa7,0x35,
17250x08,0x00,0x08,0x35,0xc0,0x03,0xa3,0x35,0x80,0x00,0x02,0x24,0x00,0x00,0x62,0xac,
17260x21,0x58,0x80,0x00,0x00,0x00,0xe5,0xac,0x0a,0x4b,0x46,0xa5,0x6c,0x7e,0x25,0xad,
17270x00,0x00,0x04,0xa5,0x08,0x4b,0x44,0xa5,0x24,0x10,0x8b,0x01,0x00,0x30,0x42,0x30,
17280x06,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x0a,0x4b,0x42,0x95,0x00,0x00,0x00,0x00,
17290x00,0x10,0x42,0x38,0x00,0x20,0x42,0x34,0x0a,0x4b,0x42,0xa5,0x08,0x00,0xe0,0x03,
17300x00,0x00,0x00,0x00,0x95,0x1a,0x00,0x08,0x0a,0x4b,0x43,0xa5,0xf8,0xff,0xbd,0x27,
17310x04,0x00,0xb1,0xaf,0x00,0x00,0xb0,0xaf,0x00,0x40,0x02,0x40,0x00,0x68,0x08,0x40,
17320x00,0x70,0x02,0x40,0x00,0x60,0x09,0x40,0x25,0xb0,0x05,0x3c,0x00,0x80,0x02,0x3c,
17330x18,0x03,0xa3,0x34,0x7c,0x6b,0x42,0x24,0x00,0x00,0x62,0xac,0x80,0x00,0x87,0x8c,
17340x7c,0x02,0xa2,0x34,0x84,0x02,0xa3,0x34,0x88,0x02,0xa6,0x34,0x00,0x00,0x47,0xac,
17350x00,0x00,0x68,0xac,0x00,0x00,0xc9,0xac,0x74,0x00,0x83,0x8c,0x8c,0x02,0xa2,0x34,
17360x90,0x02,0xa7,0x34,0x00,0x00,0x43,0xac,0x08,0x00,0x86,0x8c,0x94,0x02,0xa8,0x34,
17370x98,0x02,0xa9,0x34,0x00,0x00,0xe6,0xac,0x0c,0x00,0x82,0x8c,0x9c,0x02,0xa6,0x34,
17380xa0,0x02,0xa7,0x34,0x00,0x00,0x02,0xad,0x10,0x00,0x83,0x8c,0xa4,0x02,0xa8,0x34,
17390xa8,0x02,0xaa,0x34,0x00,0x00,0x23,0xad,0x14,0x00,0x82,0x8c,0xac,0x02,0xa9,0x34,
17400xb0,0x02,0xab,0x34,0x00,0x00,0xc2,0xac,0x18,0x00,0x83,0x8c,0xb4,0x02,0xa6,0x34,
17410xb8,0x02,0xac,0x34,0x00,0x00,0xe3,0xac,0x1c,0x00,0x82,0x8c,0xbc,0x02,0xa7,0x34,
17420xc0,0x02,0xad,0x34,0x00,0x00,0x02,0xad,0x20,0x00,0x83,0x8c,0xc4,0x02,0xa8,0x34,
17430xc8,0x02,0xae,0x34,0x00,0x00,0x43,0xad,0x24,0x00,0x82,0x8c,0xcc,0x02,0xaa,0x34,
17440xd0,0x02,0xaf,0x34,0x00,0x00,0x22,0xad,0x28,0x00,0x83,0x8c,0xd4,0x02,0xa9,0x34,
17450xd8,0x02,0xb0,0x34,0x00,0x00,0x63,0xad,0x2c,0x00,0x82,0x8c,0x70,0x02,0xab,0x34,
17460x74,0x02,0xb1,0x34,0x00,0x00,0xc2,0xac,0x30,0x00,0x83,0x8c,0x78,0x02,0xa5,0x34,
17470x00,0x00,0x83,0xad,0x34,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0xac,
17480x38,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xad,0x3c,0x00,0x82,0x8c,
17490x00,0x00,0x00,0x00,0x00,0x00,0x02,0xad,0x40,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,
17500x00,0x00,0xc3,0xad,0x44,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xad,
17510x48,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xe3,0xad,0x4c,0x00,0x82,0x8c,
17520x00,0x00,0x00,0x00,0x00,0x00,0x22,0xad,0x50,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,
17530x00,0x00,0x03,0xae,0x54,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xad,
17540x58,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0xae,0x5c,0x00,0x82,0x8c,
17550x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xac,0x42,0x1b,0x00,0x08,0x00,0x00,0x00,0x00,
17560x00,0x80,0x1b,0x3c,0x10,0x6d,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,
17570x00,0x00,0x5b,0xaf,0x21,0xd8,0xa0,0x03,0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00,
17580x08,0x00,0x7b,0x27,0x04,0x00,0x61,0xaf,0x08,0x00,0x62,0xaf,0x0c,0x00,0x63,0xaf,
17590x10,0x00,0x64,0xaf,0x14,0x00,0x65,0xaf,0x18,0x00,0x66,0xaf,0x1c,0x00,0x67,0xaf,
17600x20,0x00,0x68,0xaf,0x24,0x00,0x69,0xaf,0x28,0x00,0x6a,0xaf,0x2c,0x00,0x6b,0xaf,
17610x30,0x00,0x6c,0xaf,0x34,0x00,0x6d,0xaf,0x38,0x00,0x6e,0xaf,0x3c,0x00,0x6f,0xaf,
17620x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0x70,0xaf,
17630x44,0x00,0x71,0xaf,0x48,0x00,0x72,0xaf,0x4c,0x00,0x73,0xaf,0x50,0x00,0x74,0xaf,
17640x54,0x00,0x75,0xaf,0x58,0x00,0x76,0xaf,0x5c,0x00,0x77,0xaf,0x60,0x00,0x78,0xaf,
17650x64,0x00,0x79,0xaf,0x68,0x00,0x7c,0xaf,0x6c,0x00,0x7d,0xaf,0x70,0x00,0x7e,0xaf,
17660x74,0x00,0x7f,0xaf,0x78,0x00,0x68,0xaf,0x7c,0x00,0x69,0xaf,0x80,0x00,0x6a,0xaf,
17670x00,0x68,0x1a,0x40,0x25,0xb0,0x1b,0x3c,0x1c,0x03,0x7b,0x37,0x00,0x00,0x00,0x00,
17680x00,0x00,0x7a,0xaf,0x7f,0x00,0x5b,0x33,0x30,0x00,0x60,0x13,0x00,0x00,0x00,0x00,
17690x25,0xb0,0x1b,0x3c,0x30,0x03,0x7b,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0xaf,
17700x00,0x00,0x00,0x00,0x21,0xd8,0xa0,0x03,0x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00,
17710x08,0x00,0x7b,0x27,0x04,0x00,0x61,0xaf,0x08,0x00,0x62,0xaf,0x0c,0x00,0x63,0xaf,
17720x10,0x00,0x64,0xaf,0x14,0x00,0x65,0xaf,0x18,0x00,0x66,0xaf,0x1c,0x00,0x67,0xaf,
17730x20,0x00,0x68,0xaf,0x24,0x00,0x69,0xaf,0x28,0x00,0x6a,0xaf,0x2c,0x00,0x6b,0xaf,
17740x30,0x00,0x6c,0xaf,0x34,0x00,0x6d,0xaf,0x38,0x00,0x6e,0xaf,0x3c,0x00,0x6f,0xaf,
17750x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x00,0x70,0x0a,0x40,0x40,0x00,0x70,0xaf,
17760x44,0x00,0x71,0xaf,0x48,0x00,0x72,0xaf,0x4c,0x00,0x73,0xaf,0x50,0x00,0x74,0xaf,
17770x54,0x00,0x75,0xaf,0x58,0x00,0x76,0xaf,0x5c,0x00,0x77,0xaf,0x60,0x00,0x78,0xaf,
17780x64,0x00,0x79,0xaf,0x68,0x00,0x7c,0xaf,0x6c,0x00,0x7d,0xaf,0x70,0x00,0x7e,0xaf,
17790x74,0x00,0x7f,0xaf,0x78,0x00,0x68,0xaf,0x7c,0x00,0x69,0xaf,0x80,0x00,0x6a,0xaf,
17800xdf,0x1a,0x00,0x08,0x21,0x20,0x60,0x03,0x00,0x00,0x00,0x00,0x25,0xb0,0x08,0x3c,
17810x20,0x03,0x08,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0xad,0x00,0x04,0x5b,0x33,
17820x0a,0x00,0x60,0x13,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x3c,0x74,0x55,0x08,0x25,
17830x00,0x00,0x00,0x00,0x25,0xb0,0x1b,0x3c,0x24,0x03,0x7b,0x37,0x00,0x00,0x00,0x00,
17840x00,0x00,0x68,0xaf,0x09,0xf8,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x5b,0x33,
17850x25,0xb0,0x08,0x3c,0x28,0x03,0x08,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xad,
17860x06,0x00,0x60,0x13,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x3c,0xfc,0x69,0x08,0x25,
17870x00,0x00,0x00,0x00,0x09,0xf8,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x80,0x1a,0x3c,
17880x6c,0x7e,0x5a,0x27,0x04,0x00,0x5b,0x97,0x25,0xb0,0x08,0x3c,0x30,0x03,0x08,0x35,
17890x00,0x00,0x00,0x00,0x00,0x00,0x1b,0xad,0x18,0x00,0x60,0x13,0x00,0x00,0x00,0x00,
17900x08,0xec,0x9b,0x27,0x00,0x00,0x00,0x00,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b,
17910x7c,0x00,0x62,0x7b,0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b,
17920x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b,
17930xfc,0x01,0x6e,0x7b,0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b,
17940xfc,0x02,0x76,0x7b,0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b,
17950x80,0x00,0x7b,0x8f,0x2f,0x1c,0x00,0x08,0x00,0x00,0x00,0x00,0x21,0xd8,0xa0,0x03,
17960x82,0xda,0x1b,0x00,0x80,0xda,0x1b,0x00,0x08,0x00,0x7b,0x27,0x08,0x00,0x5b,0xaf,
17970xfc,0xef,0x9d,0x27,0x00,0x00,0x4a,0x8f,0x00,0x00,0x00,0x00,0x21,0x00,0x40,0x11,
17980x00,0x00,0x00,0x00,0x02,0x80,0x08,0x3c,0xcc,0x7d,0x08,0x25,0x21,0x48,0x00,0x00,
17990x21,0x58,0x00,0x00,0x01,0x00,0x6b,0x25,0x1a,0x00,0x40,0x11,0x24,0x70,0x4b,0x01,
18000x14,0x00,0xc0,0x11,0x01,0x00,0x04,0x24,0x00,0x00,0x00,0x00,0x04,0x00,0x44,0xa3,
18010x26,0x50,0x4b,0x01,0x00,0x00,0x4a,0xaf,0x80,0x80,0x09,0x00,0x21,0x80,0x08,0x02,
18020x00,0x00,0x10,0x8e,0x00,0x00,0x00,0x00,0x09,0xf8,0x00,0x02,0x00,0x00,0x00,0x00,
18030x00,0x80,0x1b,0x3c,0xe8,0x6f,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,
18040x00,0x00,0x5b,0xaf,0x02,0x80,0x1a,0x3c,0x6c,0x7e,0x5a,0x27,0xe1,0xff,0x00,0x10,
18050x00,0x00,0x00,0x00,0x01,0x00,0x29,0x25,0x40,0x58,0x0b,0x00,0xf2,0x1b,0x00,0x08,
18060x00,0x00,0x00,0x00,0x02,0x80,0x1b,0x3c,0x6c,0x7e,0x7b,0x27,0x21,0x60,0x00,0x00,
18070x04,0x00,0x6c,0xa7,0x08,0x00,0x7a,0x8f,0x00,0x00,0x00,0x00,0xf8,0xff,0x5a,0x27,
18080x00,0x00,0x5a,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0x5a,0x27,0x84,0x00,0x44,0x8f,
18090x00,0x00,0x00,0x00,0xf9,0xff,0x80,0x10,0x00,0x00,0x00,0x00,0x04,0x00,0x41,0x8f,
18100xfc,0x03,0x50,0x7b,0x7c,0x00,0x42,0x7b,0xbc,0x00,0x44,0x7b,0xfc,0x00,0x46,0x7b,
18110x3c,0x01,0x48,0x7b,0x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x4a,0x7b,
18120xbc,0x01,0x4c,0x7b,0xfc,0x01,0x4e,0x7b,0x3c,0x02,0x50,0x7b,0x7c,0x02,0x52,0x7b,
18130xbc,0x02,0x54,0x7b,0xfc,0x02,0x56,0x7b,0x3c,0x03,0x58,0x7b,0x7c,0x03,0x5c,0x7b,
18140xbc,0x03,0x5e,0x7b,0x80,0x00,0x5b,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0x60,0x03,
18150x10,0x00,0x00,0x42,0x00,0x60,0x05,0x40,0x42,0x28,0x05,0x00,0x40,0x28,0x05,0x00,
18160x00,0x60,0x85,0x40,0x04,0x00,0x81,0xac,0x08,0x00,0x82,0xac,0x0c,0x00,0x83,0xac,
18170x20,0x00,0x88,0xac,0x24,0x00,0x89,0xac,0x28,0x00,0x8a,0xac,0x2c,0x00,0x8b,0xac,
18180x30,0x00,0x8c,0xac,0x34,0x00,0x8d,0xac,0x38,0x00,0x8e,0xac,0x3c,0x00,0x8f,0xac,
18190x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,0x40,0x00,0x90,0xac,0x44,0x00,0x91,0xac,
18200x48,0x00,0x92,0xac,0x4c,0x00,0x93,0xac,0x50,0x00,0x94,0xac,0x54,0x00,0x95,0xac,
18210x58,0x00,0x96,0xac,0x5c,0x00,0x97,0xac,0x60,0x00,0x98,0xac,0x64,0x00,0x99,0xac,
18220x68,0x00,0x9c,0xac,0x6c,0x00,0x9d,0xac,0x70,0x00,0x9e,0xac,0x74,0x00,0x9f,0xac,
18230x78,0x00,0x88,0xac,0x7c,0x00,0x89,0xac,0x80,0x00,0x9f,0xac,0xf8,0xff,0x84,0x24,
18240x00,0x00,0x84,0x8c,0x00,0x00,0x00,0x00,0x08,0x00,0x84,0x24,0x84,0x00,0x86,0x8c,
18250x00,0x00,0x00,0x00,0xf9,0xff,0xc0,0x10,0x00,0x00,0x00,0x00,0x21,0xd8,0x80,0x00,
18260x01,0x00,0xba,0x24,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b,0x7c,0x00,0x62,0x7b,
18270xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b,0x13,0x00,0x00,0x02,
18280x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b,0xfc,0x01,0x6e,0x7b,
18290x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b,0xfc,0x02,0x76,0x7b,
18300x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b,0x80,0x00,0x7b,0x8f,
18310x00,0x00,0x00,0x00,0x08,0x00,0x60,0x03,0x00,0x60,0x9a,0x40,0x00,0x60,0x05,0x40,
18320x42,0x28,0x05,0x00,0x40,0x28,0x05,0x00,0x00,0x60,0x85,0x40,0x04,0x00,0x81,0xac,
18330x08,0x00,0x82,0xac,0x0c,0x00,0x83,0xac,0x20,0x00,0x88,0xac,0x24,0x00,0x89,0xac,
18340x28,0x00,0x8a,0xac,0x2c,0x00,0x8b,0xac,0x30,0x00,0x8c,0xac,0x34,0x00,0x8d,0xac,
18350x38,0x00,0x8e,0xac,0x3c,0x00,0x8f,0xac,0x12,0x40,0x00,0x00,0x10,0x48,0x00,0x00,
18360x40,0x00,0x90,0xac,0x44,0x00,0x91,0xac,0x48,0x00,0x92,0xac,0x4c,0x00,0x93,0xac,
18370x50,0x00,0x94,0xac,0x54,0x00,0x94,0xac,0x58,0x00,0x96,0xac,0x5c,0x00,0x96,0xac,
18380x60,0x00,0x98,0xac,0x64,0x00,0x99,0xac,0x68,0x00,0x9c,0xac,0x6c,0x00,0x9d,0xac,
18390x70,0x00,0x9e,0xac,0x78,0x00,0x88,0xac,0x7c,0x00,0x89,0xac,0x80,0x00,0x9f,0xac,
18400x84,0x00,0x80,0xac,0xf8,0xff,0x84,0x24,0x00,0x00,0x84,0x8c,0x00,0x00,0x00,0x00,
18410x08,0x00,0x84,0x24,0x84,0x00,0x86,0x8c,0xfa,0xff,0xc0,0x10,0x00,0x00,0x00,0x00,
18420x21,0xd8,0x80,0x00,0x01,0x00,0xba,0x24,0x04,0x00,0x61,0x8f,0xfc,0x03,0x70,0x7b,
18430x7c,0x00,0x62,0x7b,0xbc,0x00,0x64,0x7b,0xfc,0x00,0x66,0x7b,0x3c,0x01,0x68,0x7b,
18440x13,0x00,0x00,0x02,0x11,0x00,0x20,0x02,0x7c,0x01,0x6a,0x7b,0xbc,0x01,0x6c,0x7b,
18450xfc,0x01,0x6e,0x7b,0x3c,0x02,0x70,0x7b,0x7c,0x02,0x72,0x7b,0xbc,0x02,0x74,0x7b,
18460xfc,0x02,0x76,0x7b,0x3c,0x03,0x78,0x7b,0x7c,0x03,0x7c,0x7b,0xbc,0x03,0x7e,0x7b,
18470x80,0x00,0x7b,0x8f,0x08,0x00,0x60,0x03,0x00,0x60,0x9a,0x40,0x00,0x00,0x00,0x00,
18480x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18490x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18500x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18510x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18520x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18530x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18540x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18550x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18560x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18570x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18580x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18590x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18600x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18610x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18630x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18640x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18650x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18660x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18670xc6,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x1b,0x3c,0x00,0x00,0x7b,0x27,
18680x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf,0x00,0x00,0x05,0x24,
18690x03,0x00,0xa4,0x24,0x00,0xa0,0x80,0x40,0x00,0xa0,0x84,0x40,0x01,0x80,0x04,0x3c,
18700x98,0x03,0x84,0x24,0x08,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18710x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18720x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18730x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18740x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18750x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18760x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18770x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18780x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18790x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18800x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18810x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18820x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18830x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18840x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18850x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18860x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18870x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18880x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18890x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18900x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18910x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18920x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18930x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18940x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18950x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18960x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18970x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18980x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18990x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19000x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19010x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19020x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19030x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19040x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19050x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19060x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19070x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19080x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19090x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19100x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19140x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19150x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19160x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19170x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19180x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19190x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19200x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19210x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19220x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19230x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19240x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19250x01,0x80,0x1b,0x3c,0x98,0x03,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,
19260x00,0x00,0x5b,0xaf,0x02,0x80,0x1a,0x3c,0x00,0x00,0x5a,0x27,0xfc,0x03,0x5d,0x27,
19270x02,0x80,0x1c,0x3c,0x00,0x14,0x9c,0x27,0x00,0xf0,0x08,0x3c,0x00,0x0c,0x08,0x35,
19280x00,0x60,0x88,0x40,0x02,0x80,0x04,0x3c,0x00,0x00,0x84,0x24,0xff,0x7f,0x05,0x3c,
19290xff,0xff,0xa5,0x34,0x24,0x20,0x85,0x00,0x00,0x20,0x84,0x4c,0xff,0xff,0x05,0x34,
19300x21,0x28,0xa4,0x00,0x00,0x28,0x85,0x4c,0x00,0x80,0x04,0x3c,0x00,0x00,0x84,0x24,
19310xff,0x7f,0x05,0x3c,0xff,0xff,0xa5,0x34,0x24,0x20,0x85,0x00,0x00,0x00,0x84,0x4c,
19320xff,0x7f,0x06,0x24,0x21,0x30,0xc4,0x00,0x24,0x30,0xc5,0x00,0x00,0x08,0x86,0x4c,
19330x00,0xa0,0x04,0x40,0x10,0x00,0x84,0x34,0x00,0xa0,0x84,0x40,0x01,0x80,0x1b,0x3c,
19340x24,0x04,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf,
19350x00,0x00,0x00,0x00,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x85,0x84,
19360x20,0x00,0x06,0x24,0x25,0x28,0xa6,0x00,0x00,0x00,0x85,0xa4,0x01,0x80,0x1b,0x3c,
19370x54,0x04,0x7b,0x27,0x25,0xb0,0x1a,0x3c,0x18,0x03,0x5a,0x27,0x00,0x00,0x5b,0xaf,
19380x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x85,0x8c,0x00,0x00,0x00,0x00,
19390x10,0x00,0xa5,0x30,0xfc,0xff,0xa0,0x10,0x00,0x00,0x00,0x00,0xff,0x1f,0x07,0x3c,
19400xff,0xff,0xe7,0x34,0x02,0x80,0x05,0x3c,0x88,0x7d,0xa5,0x24,0xff,0xff,0xa5,0x30,
19410x40,0xb0,0x04,0x3c,0x25,0x28,0xa4,0x00,0x24,0x28,0xa7,0x00,0x21,0x30,0x00,0x00,
19420x43,0xb0,0x02,0x3c,0x00,0x80,0x04,0x3c,0x40,0x00,0x84,0x34,0x00,0x00,0x45,0xac,
19430x04,0x00,0x46,0xac,0x08,0x00,0x44,0xac,0x4e,0x58,0x00,0x08,0x00,0x00,0x00,0x00,
19440x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x09,0x00,0x02,0x24,0xff,0xff,0x42,0x24,
19450xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0x08,0x00,0xe0,0x03,0x01,0x00,0x42,0x24,
19460x00,0x60,0x02,0x40,0x01,0x00,0x41,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
19470x08,0x00,0xe0,0x03,0x00,0x00,0x82,0xac,0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,
19480x21,0x18,0x40,0x00,0x00,0x60,0x83,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x82,0xac,
19490x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,
19500x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
19510x00,0x60,0x81,0x40,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,
19520x25,0xb0,0x02,0x3c,0x44,0x05,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
19530x04,0x00,0x85,0x8c,0x00,0x80,0x03,0x3c,0x01,0x00,0x02,0x24,0x25,0x28,0xa3,0x00,
19540x00,0x00,0xa4,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,
19550x25,0xb0,0x02,0x3c,0x74,0x05,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
19560x04,0x00,0x82,0x8c,0x02,0x00,0x83,0x94,0x00,0x80,0x07,0x3c,0x25,0x28,0x47,0x00,
19570x00,0x00,0xa2,0x8c,0x10,0x00,0x02,0x24,0x13,0x00,0x62,0x10,0x11,0x00,0x66,0x28,
19580x06,0x00,0xc0,0x10,0x20,0x00,0x02,0x24,0x08,0x00,0x02,0x24,0x17,0x00,0x62,0x10,
19590x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0xfd,0xff,0x62,0x14,
19600x00,0x00,0x00,0x00,0x08,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xac,
19610x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x25,0x10,0x47,0x00,0x00,0x00,0x42,0x8c,
19620x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,
19630x00,0x00,0xa2,0xa4,0x04,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,0x25,0x18,0x67,0x00,
19640x00,0x00,0x62,0x94,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0x82,0x8c,
19650x00,0x00,0x00,0x00,0x00,0x00,0xa2,0xa0,0x04,0x00,0x83,0x8c,0x00,0x00,0x00,0x00,
19660x25,0x18,0x67,0x00,0x00,0x00,0x62,0x90,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
19670xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,0x1c,0x00,0xbf,0xaf,
19680x18,0x00,0xb2,0xaf,0x10,0x00,0xb0,0xaf,0x68,0x15,0x31,0x26,0xe4,0x64,0x30,0x96,
19690x02,0x80,0x02,0x3c,0x01,0x80,0x03,0x3c,0x25,0x80,0x02,0x02,0x25,0xb0,0x02,0x3c,
19700x38,0x06,0x63,0x24,0x18,0x03,0x42,0x34,0x60,0x00,0x04,0x26,0x80,0x00,0x05,0x26,
19710x00,0x00,0x43,0xac,0xab,0x45,0x00,0x0c,0x03,0x00,0x06,0x24,0x21,0x20,0x00,0x02,
19720x21,0x28,0x00,0x00,0x97,0x45,0x00,0x0c,0x08,0x00,0x06,0x24,0xe4,0x64,0x22,0x8e,
19730x0c,0x00,0x03,0x24,0x0c,0x00,0x43,0xae,0x08,0x00,0x42,0xae,0x12,0x00,0x02,0x24,
19740x14,0x00,0x42,0xae,0x21,0x20,0x40,0x02,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,
19750x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x8b,0x07,0x00,0x08,0x20,0x00,0xbd,0x27,
19760x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19770x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19780x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19790x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19800x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19810x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
19820x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19830x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19840x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19850x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
19860x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
19870x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19880x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19890x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
19900x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
19910x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,0x02,0x80,0x02,0x3c,0x21,0x48,0x80,0x00,
19920x68,0x15,0x48,0x24,0x21,0x38,0x00,0x00,0x21,0x28,0x27,0x01,0x00,0x00,0xa2,0x90,
19930x21,0x20,0xe8,0x00,0x01,0x00,0xe7,0x24,0x38,0x4c,0x82,0xa0,0x1e,0x00,0xa3,0x90,
19940x1e,0x00,0xe6,0x28,0x56,0x4c,0x83,0xa0,0x3c,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,
19950x74,0x4c,0x82,0xa0,0x5a,0x00,0xa3,0x90,0xf3,0xff,0xc0,0x14,0x92,0x4c,0x83,0xa0,
19960x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
19970x20,0xbd,0x03,0x3c,0x58,0x00,0x63,0x34,0x00,0x00,0x62,0x90,0x0f,0x27,0x07,0x24,
19980x20,0x00,0x42,0x34,0x00,0x00,0x62,0xa0,0xff,0xff,0xe7,0x24,0xff,0xff,0xe1,0x04,
19990xff,0xff,0xe7,0x24,0x62,0xbd,0x04,0x3c,0x24,0x10,0x82,0x34,0x00,0x00,0x40,0xa0,
20000x28,0x10,0x83,0x34,0x0c,0x11,0x86,0x34,0x0e,0x00,0x02,0x24,0x00,0x00,0x60,0xa0,
20010x00,0x11,0x85,0x34,0x00,0x00,0xc2,0xa0,0x00,0x00,0xa7,0x8c,0xdf,0xff,0x02,0x24,
20020x10,0x00,0x86,0x34,0x24,0x38,0xe2,0x00,0x49,0x0c,0x03,0x24,0xcf,0xff,0x02,0x24,
20030x00,0x00,0xc3,0xac,0x04,0x00,0x84,0x34,0x00,0x00,0xa7,0xac,0x24,0x38,0xe2,0x00,
20040x41,0x0c,0x02,0x24,0x00,0x00,0xa7,0xac,0x00,0x00,0x80,0xac,0x00,0x00,0xc2,0xac,
20050x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0xd0,0xff,0xbd,0x27,0x25,0xb0,0x03,0x3c,
20060x01,0x80,0x02,0x3c,0xb0,0x03,0x68,0x34,0x1c,0x00,0xb1,0xaf,0x18,0x03,0x63,0x34,
20070xd8,0xff,0x91,0x24,0xa0,0x08,0x42,0x24,0x00,0x00,0x62,0xac,0x28,0x00,0xbf,0xaf,
20080x00,0x00,0x11,0xad,0x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x18,0x00,0xb0,0xaf,
20090x02,0x80,0x13,0x3c,0x00,0x00,0x23,0x96,0x68,0x15,0x73,0x26,0xff,0xff,0x32,0x32,
20100x40,0x10,0x02,0x3c,0x78,0x64,0x65,0x8e,0x25,0x90,0x42,0x02,0x02,0x80,0x10,0x3c,
20110x8c,0x96,0x10,0x26,0x20,0x00,0x42,0x26,0x00,0x00,0x03,0xad,0x20,0x00,0x06,0x24,
20120x00,0x00,0x02,0xad,0x21,0x38,0x00,0x02,0x0c,0x00,0x03,0xae,0x0a,0x00,0x04,0x24,
20130x64,0x01,0x00,0x0c,0x08,0x00,0x02,0xae,0x04,0x00,0x23,0x8e,0xff,0xe0,0x02,0x24,
20140x28,0x00,0x04,0x24,0x24,0x18,0x62,0x00,0x00,0x10,0x63,0x34,0x02,0x00,0x24,0xa2,
20150x04,0x00,0x23,0xae,0x0c,0x00,0x02,0x8e,0x0a,0x00,0x04,0x24,0xf8,0xff,0x42,0x24,
20160x4d,0x01,0x00,0x0c,0x00,0x00,0x22,0xa6,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
20170x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0c,0x00,0x07,0x8e,0x20,0x10,0x06,0x3c,
20180x21,0x28,0x40,0x02,0x20,0x00,0xe7,0x24,0x00,0xfe,0xc6,0x34,0xff,0xff,0xe7,0x30,
20190x01,0x00,0x11,0x24,0x0a,0x00,0x04,0x24,0x10,0x01,0x00,0x0c,0x10,0x00,0xb1,0xaf,
20200xd5,0x4a,0x63,0x92,0x2a,0xb0,0x10,0x3c,0x32,0x00,0x02,0x36,0x01,0x00,0x63,0x24,
20210x00,0x00,0x43,0xa0,0x4d,0x01,0x00,0x0c,0x0a,0x00,0x04,0x24,0xc9,0x64,0x62,0x92,
20220x00,0x00,0x00,0x00,0x01,0x00,0x42,0x24,0xc9,0x64,0x62,0xa2,0x00,0x60,0x01,0x40,
20230x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x01,0x00,0x10,0x36,0x00,0x00,0x11,0xa2,
20240x28,0x00,0xbf,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
20250x18,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
20260x25,0xb0,0x05,0x3c,0x01,0x80,0x03,0x3c,0x21,0x38,0x80,0x00,0x18,0x03,0xa2,0x34,
20270xe8,0x09,0x63,0x24,0x01,0x00,0x04,0x24,0x00,0x00,0x43,0xac,0x35,0x00,0xe4,0x10,
20280x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x10,0x20,0x08,0xa2,0x34,0x02,0x00,0x02,0x24,
20290x83,0x00,0xe2,0x10,0x03,0x00,0x02,0x24,0x5a,0x00,0xe2,0x10,0x00,0x00,0x00,0x00,
20300x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x03,0x3c,0x00,0x00,0x44,0x8c,
20310x68,0x15,0x66,0x24,0x70,0x08,0x02,0x24,0xe0,0x08,0x03,0x24,0x74,0x4b,0xc2,0xac,
20320x40,0x08,0x02,0x24,0x78,0x4b,0xc3,0xac,0x84,0x4b,0xc2,0xac,0x78,0x08,0x03,0x24,
20330x0c,0x08,0x02,0x24,0x88,0x4b,0xc3,0xac,0x8c,0x4b,0xc2,0xac,0x10,0x08,0x03,0x24,
20340x20,0x08,0x02,0x24,0x90,0x4b,0xc3,0xac,0x94,0x4b,0xc2,0xac,0x24,0x08,0x03,0x24,
20350x58,0x08,0x02,0x24,0x98,0x4b,0xc3,0xac,0x9c,0x4b,0xc2,0xac,0x50,0x0c,0x03,0x24,
20360x54,0x0c,0x02,0x24,0xa0,0x4b,0xc3,0xac,0xa4,0x4b,0xc2,0xac,0x14,0x0c,0x03,0x24,
20370x10,0x0c,0x02,0x24,0x60,0x08,0x05,0x24,0xa8,0x4b,0xc3,0xac,0xac,0x4b,0xc2,0xac,
20380x80,0x0c,0x03,0x24,0x84,0x0c,0x02,0x24,0x00,0x01,0x84,0x30,0xb4,0x4b,0xc2,0xac,
20390x80,0x4b,0xc5,0xac,0xb0,0x4b,0xc3,0xac,0x71,0x4b,0xc0,0xa0,0x7c,0x4b,0xc5,0xac,
20400x02,0x00,0x80,0x10,0xa0,0x08,0x02,0x24,0xb8,0x08,0x02,0x24,0x08,0x00,0xe0,0x03,
20410xb8,0x4b,0xc2,0xac,0x28,0x08,0xa2,0x34,0x02,0x80,0x03,0x3c,0x00,0x00,0x44,0x8c,
20420x68,0x15,0x66,0x24,0x70,0x08,0x02,0x24,0xe0,0x08,0x03,0x24,0x74,0x4b,0xc2,0xac,
20430x44,0x08,0x02,0x24,0x78,0x4b,0xc3,0xac,0x84,0x4b,0xc2,0xac,0x78,0x08,0x03,0x24,
20440x0c,0x08,0x02,0x24,0x88,0x4b,0xc3,0xac,0x8c,0x4b,0xc2,0xac,0x14,0x08,0x03,0x24,
20450x28,0x08,0x02,0x24,0x90,0x4b,0xc3,0xac,0x94,0x4b,0xc2,0xac,0x2c,0x08,0x03,0x24,
20460x58,0x08,0x02,0x24,0x98,0x4b,0xc3,0xac,0x9c,0x4b,0xc2,0xac,0x58,0x0c,0x03,0x24,
20470x5c,0x0c,0x02,0x24,0xa0,0x4b,0xc3,0xac,0xa4,0x4b,0xc2,0xac,0x1c,0x0c,0x03,0x24,
20480x18,0x0c,0x02,0x24,0x64,0x08,0x05,0x24,0xa8,0x4b,0xc3,0xac,0xac,0x4b,0xc2,0xac,
20490x88,0x0c,0x03,0x24,0x8c,0x0c,0x02,0x24,0x00,0x01,0x84,0x30,0xb4,0x4b,0xc2,0xac,
20500x71,0x4b,0xc7,0xa0,0x80,0x4b,0xc5,0xac,0xb0,0x4b,0xc3,0xac,0x7c,0x4b,0xc5,0xac,
20510xd6,0xff,0x80,0x10,0xa4,0x08,0x02,0x24,0xbc,0x08,0x02,0x24,0x08,0x00,0xe0,0x03,
20520xb8,0x4b,0xc2,0xac,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0xac,0x08,0x03,0x24,
20530xb8,0x4b,0x43,0xac,0x74,0x08,0x03,0x24,0xe4,0x08,0x04,0x24,0x74,0x4b,0x43,0xac,
20540x4c,0x08,0x03,0x24,0x78,0x4b,0x44,0xac,0x84,0x4b,0x43,0xac,0x7c,0x08,0x04,0x24,
20550x0c,0x08,0x03,0x24,0x88,0x4b,0x44,0xac,0x8c,0x4b,0x43,0xac,0x1c,0x08,0x04,0x24,
20560x38,0x08,0x03,0x24,0x90,0x4b,0x44,0xac,0x94,0x4b,0x43,0xac,0x3c,0x08,0x04,0x24,
20570x5c,0x08,0x03,0x24,0x98,0x4b,0x44,0xac,0x9c,0x4b,0x43,0xac,0x68,0x0c,0x04,0x24,
20580x6c,0x0c,0x03,0x24,0xa0,0x4b,0x44,0xac,0xa4,0x4b,0x43,0xac,0x2c,0x0c,0x04,0x24,
20590x28,0x0c,0x03,0x24,0x6c,0x08,0x05,0x24,0xa8,0x4b,0x44,0xac,0xac,0x4b,0x43,0xac,
20600x98,0x0c,0x04,0x24,0x9c,0x0c,0x03,0x24,0x71,0x4b,0x47,0xa0,0x80,0x4b,0x45,0xac,
20610xb0,0x4b,0x44,0xac,0xb4,0x4b,0x43,0xac,0x08,0x00,0xe0,0x03,0x7c,0x4b,0x45,0xac,
20620x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0xa8,0x08,0x03,0x24,0xb8,0x4b,0x43,0xac,
20630x74,0x08,0x03,0x24,0xe4,0x08,0x04,0x24,0x74,0x4b,0x43,0xac,0x48,0x08,0x03,0x24,
20640x78,0x4b,0x44,0xac,0x84,0x4b,0x43,0xac,0x7c,0x08,0x04,0x24,0x0c,0x08,0x03,0x24,
20650x88,0x4b,0x44,0xac,0x8c,0x4b,0x43,0xac,0x18,0x08,0x04,0x24,0x30,0x08,0x03,0x24,
20660x90,0x4b,0x44,0xac,0x94,0x4b,0x43,0xac,0x34,0x08,0x04,0x24,0x5c,0x08,0x03,0x24,
20670x98,0x4b,0x44,0xac,0x9c,0x4b,0x43,0xac,0x60,0x0c,0x04,0x24,0x64,0x0c,0x03,0x24,
20680xa0,0x4b,0x44,0xac,0xa4,0x4b,0x43,0xac,0x24,0x0c,0x04,0x24,0x20,0x0c,0x03,0x24,
20690x68,0x08,0x05,0x24,0xa8,0x4b,0x44,0xac,0xac,0x4b,0x43,0xac,0x90,0x0c,0x04,0x24,
20700x94,0x0c,0x03,0x24,0x71,0x4b,0x47,0xa0,0x80,0x4b,0x45,0xac,0xb0,0x4b,0x44,0xac,
20710xb4,0x4b,0x43,0xac,0x08,0x00,0xe0,0x03,0x7c,0x4b,0x45,0xac,0x36,0x43,0x00,0x08,
20720x21,0x18,0x00,0x00,0x20,0x00,0x62,0x2c,0x06,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
20730x06,0x10,0x64,0x00,0x01,0x00,0x42,0x30,0xfa,0xff,0x40,0x10,0x01,0x00,0x63,0x24,
20740xff,0xff,0x63,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,0xd8,0xff,0xbd,0x27,
20750x25,0xb0,0x02,0x3c,0x18,0x00,0xb2,0xaf,0x21,0x90,0x82,0x00,0xff,0xff,0x02,0x24,
20760x1c,0x00,0xb3,0xaf,0x14,0x00,0xb1,0xaf,0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,
20770x21,0x88,0xa0,0x00,0x21,0x20,0xa0,0x00,0x21,0x18,0x40,0x02,0x10,0x00,0xa2,0x10,
20780x21,0x98,0xc0,0x00,0x00,0x00,0x50,0x8e,0x31,0x43,0x00,0x0c,0x00,0x00,0x00,0x00,
20790x04,0x10,0x53,0x00,0x27,0x18,0x11,0x00,0x25,0x18,0x62,0x00,0x24,0x18,0x70,0x00,
20800x00,0x00,0x43,0xae,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,
20810x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,
20820x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
20830x10,0x00,0xb0,0x8f,0x28,0x00,0xbd,0x27,0x00,0x00,0x66,0xac,0x08,0x00,0xe0,0x03,
20840x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x21,0x30,0x80,0x00,0xec,0x60,0x44,0x8c,
20850x3d,0x43,0x00,0x08,0xff,0xff,0x05,0x24,0xe0,0xff,0xbd,0x27,0x25,0xb0,0x02,0x3c,
20860x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x21,0x20,0x82,0x00,
20870x00,0x00,0x90,0x8c,0x21,0x88,0xa0,0x00,0x31,0x43,0x00,0x0c,0x21,0x20,0xa0,0x00,
20880x24,0x80,0x11,0x02,0x06,0x10,0x50,0x00,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
20890x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xd0,0xff,0xbd,0x27,
20900x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,0x28,0x00,0xbf,0xaf,0x20,0x00,0xb4,0xaf,
20910x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x24,0x00,0xb5,0xaf,0x10,0x00,0xb0,0xaf,
20920x68,0x15,0x31,0x26,0x98,0x4b,0x22,0x8e,0x25,0xb0,0x12,0x3c,0x24,0x08,0x53,0x36,
20930x21,0x10,0x52,0x00,0x00,0x00,0x70,0x8e,0x00,0x00,0x55,0x8c,0x7f,0x80,0x03,0x3c,
20940xff,0x7f,0x02,0x3c,0xff,0xff,0x63,0x34,0xff,0xff,0x42,0x34,0x24,0x10,0x02,0x02,
20950x24,0x18,0xa3,0x02,0xc0,0x25,0x04,0x00,0x25,0x18,0x64,0x00,0x00,0x80,0x14,0x3c,
20960x00,0x00,0x62,0xae,0x01,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0x25,0xa8,0x74,0x00,
20970x98,0x4b,0x22,0x8e,0x25,0x80,0x14,0x02,0x01,0x00,0x04,0x24,0x21,0x10,0x52,0x00,
20980x00,0x00,0x55,0xac,0x84,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xae,
20990x84,0x0a,0x00,0x0c,0x01,0x00,0x04,0x24,0xb8,0x4b,0x24,0x8e,0x0f,0x00,0x05,0x3c,
21000x28,0x00,0xbf,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
21010x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0xff,0xff,0xa5,0x34,
21020x68,0x43,0x00,0x08,0x30,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,
21030x02,0x80,0x11,0x3c,0x10,0x00,0xb0,0xaf,0x18,0x00,0xbf,0xaf,0x68,0x15,0x27,0x26,
21040x73,0x4b,0xe5,0x90,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,0xb0,0x0e,0x63,0x24,
21050x18,0x03,0x42,0x34,0x02,0x00,0x06,0x24,0x00,0x00,0x43,0xac,0x34,0x00,0xa6,0x10,
21060x21,0x80,0x80,0x00,0x03,0x00,0x03,0x24,0x3a,0x00,0xa3,0x10,0x2e,0x00,0x02,0x2e,
21070x10,0x00,0x02,0x2e,0x07,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0xff,0x00,0x04,0x32,
21080x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x79,0x43,0x00,0x08,
21090x20,0x00,0xbd,0x27,0xfa,0xff,0xa6,0x14,0xff,0x00,0x04,0x32,0x71,0x4b,0xe4,0x90,
21100x01,0x00,0x02,0x24,0x33,0x00,0x82,0x10,0x02,0x00,0x82,0x28,0x38,0x00,0x40,0x14,
21110x00,0x00,0x00,0x00,0x38,0x00,0x85,0x10,0x68,0x15,0x22,0x26,0x2e,0x00,0x83,0x10,
21120x00,0x00,0x00,0x00,0x00,0x08,0x04,0x24,0x68,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,
21130xff,0xfc,0x06,0x3c,0xff,0xff,0xc6,0x34,0x24,0x30,0x46,0x00,0x00,0x08,0x04,0x24,
21140x3d,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,0x68,0x15,0x22,0x26,0x71,0x4b,0x44,0x90,
21150x01,0x00,0x03,0x24,0x07,0x00,0x83,0x10,0x02,0x00,0x82,0x28,0x2c,0x00,0x40,0x14,
21160x02,0x00,0x02,0x24,0x2c,0x00,0x82,0x10,0x03,0x00,0x02,0x24,0xdb,0xff,0x82,0x14,
21170x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,
21180x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,0xc2,0x43,0x00,0x08,0xff,0x00,0x04,0x32,
21190x25,0x00,0x82,0x2c,0xcc,0xff,0x40,0x14,0x03,0x00,0x03,0x24,0x18,0x00,0xbf,0x8f,
21200x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,
21210x20,0x00,0xbd,0x27,0xc7,0xff,0x40,0x14,0x10,0x00,0x02,0x2e,0x18,0x00,0xbf,0x8f,
21220x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,
21230x20,0x00,0xbd,0x27,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,
21240x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,0xd4,0x43,0x00,0x08,0x00,0x08,0x04,0x24,
21250xcc,0xff,0x80,0x14,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,
21260x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,0xd4,0x43,0x00,0x08,0x00,0x08,0x04,0x24,
21270xb2,0xff,0x80,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,
21280x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,0xc2,0x43,0x00,0x08,
21290xff,0x00,0x04,0x32,0xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x02,0x80,0x11,0x3c,
21300x68,0x15,0x28,0x26,0x73,0x4b,0x06,0x91,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
21310x5c,0x10,0x63,0x24,0x18,0x03,0x42,0x34,0x02,0x00,0x07,0x24,0x18,0x00,0xb2,0xaf,
21320x10,0x00,0xb0,0xaf,0x1c,0x00,0xbf,0xaf,0x00,0x00,0x43,0xac,0x21,0x90,0xa0,0x00,
21330x39,0x00,0xc7,0x10,0xff,0x00,0x90,0x30,0x03,0x00,0x03,0x24,0x3f,0x00,0xc3,0x10,
21340x2e,0x00,0x02,0x2e,0x10,0x00,0x02,0x2e,0x0c,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
21350x0f,0x00,0x04,0x3c,0xff,0xff,0x84,0x34,0x24,0x20,0x44,0x02,0x00,0x15,0x10,0x00,
21360x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
21370x25,0x20,0x44,0x00,0x63,0x43,0x00,0x08,0x20,0x00,0xbd,0x27,0xf5,0xff,0xc7,0x14,
21380x0f,0x00,0x04,0x3c,0x71,0x4b,0x04,0x91,0x01,0x00,0x02,0x24,0x33,0x00,0x82,0x10,
21390x02,0x00,0x82,0x28,0x38,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x38,0x00,0x86,0x10,
21400x68,0x15,0x22,0x26,0x2e,0x00,0x83,0x10,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x24,
21410x68,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,0xff,0xfc,0x06,0x3c,0xff,0xff,0xc6,0x34,
21420x24,0x30,0x46,0x00,0x00,0x08,0x04,0x24,0x3d,0x43,0x00,0x0c,0xff,0xff,0x05,0x24,
21430x68,0x15,0x22,0x26,0x71,0x4b,0x44,0x90,0x01,0x00,0x03,0x24,0x07,0x00,0x83,0x10,
21440x02,0x00,0x82,0x28,0x2c,0x00,0x40,0x14,0x02,0x00,0x02,0x24,0x2c,0x00,0x82,0x10,
21450x03,0x00,0x02,0x24,0xd6,0xff,0x82,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x22,0x26,
21460x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,0x3d,0x43,0x00,0x0c,0x21,0x30,0x00,0x00,
21470x2f,0x44,0x00,0x08,0x0f,0x00,0x04,0x3c,0x25,0x00,0x02,0x2e,0xc7,0xff,0x40,0x14,
21480x03,0x00,0x03,0x24,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
21490x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xc1,0xff,0x40,0x14,
21500x00,0x00,0x00,0x00,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
21510x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x68,0x15,0x22,0x26,
21520x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x3c,0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,
21530x46,0x44,0x00,0x08,0x00,0x08,0x04,0x24,0xcc,0xff,0x80,0x14,0x68,0x15,0x22,0x26,
21540x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,0x0f,0x00,0x06,0x24,
21550x46,0x44,0x00,0x08,0x00,0x08,0x04,0x24,0xad,0xff,0x80,0x14,0x00,0x00,0x00,0x00,
21560x68,0x15,0x22,0x26,0x74,0x4b,0x44,0x8c,0x0f,0x00,0x05,0x24,0x3d,0x43,0x00,0x0c,
21570x21,0x30,0x00,0x00,0x2f,0x44,0x00,0x08,0x0f,0x00,0x04,0x3c,0xe8,0xff,0xbd,0x27,
21580x10,0x00,0xb0,0xaf,0x21,0x80,0x80,0x00,0x14,0x00,0xbf,0xaf,0x79,0x43,0x00,0x0c,
21590x21,0x20,0x00,0x00,0x40,0x01,0x44,0x34,0x21,0x18,0x40,0x00,0x1f,0x00,0x02,0x2e,
21600x00,0x23,0x04,0x00,0x10,0x00,0x40,0x10,0x10,0x00,0x05,0x2e,0x00,0x01,0x64,0x34,
21610x06,0x00,0xa0,0x10,0x00,0x23,0x04,0x00,0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,
21620x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x63,0x43,0x00,0x0c,
21630xf1,0xff,0x10,0x26,0x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,
21640x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x63,0x43,0x00,0x0c,0xe2,0xff,0x10,0x26,
21650x21,0x10,0x00,0x02,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
21660x18,0x00,0xbd,0x27,0x25,0xb0,0x02,0x3c,0x27,0x38,0x05,0x00,0x21,0x40,0x82,0x00,
21670xff,0xff,0x02,0x24,0x07,0x00,0xa2,0x10,0x25,0x38,0xe6,0x00,0x00,0x00,0x02,0x8d,
21680x00,0x00,0x00,0x00,0x24,0x10,0xe2,0x00,0x00,0x00,0x02,0xad,0x08,0x00,0xe0,0x03,
21690x00,0x00,0x00,0x00,0x00,0x00,0x06,0xad,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21700x01,0x80,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xe8,0x12,0x42,0x24,0x18,0x03,0x63,0x34,
21710xd8,0xff,0xbd,0x27,0x00,0x00,0x62,0xac,0x0f,0x00,0x02,0x3c,0x14,0x00,0xb1,0xaf,
21720xff,0xff,0x42,0x34,0x21,0x88,0xa0,0x00,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,
21730x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x21,0x90,0xc0,0x00,0x21,0x28,0xc0,0x00,
21740x0a,0x00,0x22,0x12,0x21,0x98,0x80,0x00,0xac,0x43,0x00,0x0c,0x00,0x00,0x00,0x00,
21750x21,0x20,0x20,0x02,0x31,0x43,0x00,0x0c,0x21,0x80,0x40,0x00,0x04,0x10,0x52,0x00,
21760x27,0x28,0x11,0x00,0x25,0x28,0xa2,0x00,0x24,0x28,0xb0,0x00,0xff,0x00,0x64,0x32,
21770x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
21780x10,0x00,0xb0,0x8f,0x17,0x44,0x00,0x08,0x28,0x00,0xbd,0x27,0x01,0x80,0x03,0x3c,
21790x25,0xb0,0x02,0x3c,0x74,0x13,0x63,0x24,0x18,0x03,0x42,0x34,0xe0,0xff,0xbd,0x27,
21800x00,0x00,0x43,0xac,0x18,0x00,0xbf,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,
21810xac,0x43,0x00,0x0c,0x21,0x88,0xa0,0x00,0x21,0x80,0x40,0x00,0x31,0x43,0x00,0x0c,
21820x21,0x20,0x20,0x02,0x24,0x80,0x11,0x02,0x06,0x10,0x50,0x00,0x18,0x00,0xbf,0x8f,
21830x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
21840x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21850x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21860x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
21870x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21880x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21890x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21900x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
21910x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
21920x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
21930x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21940x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21950x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x01,0x00,0x02,0x24,
21960x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
21970x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
21980x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
21990x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
22000x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
22010x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
22020xc8,0xff,0xbd,0x27,0x2c,0x00,0xb1,0xaf,0xff,0xff,0x05,0x24,0x21,0x88,0x80,0x00,
22030x02,0x00,0x06,0x24,0x10,0x00,0xa4,0x27,0x34,0x00,0xbf,0xaf,0x30,0x00,0xb2,0xaf,
22040x97,0x45,0x00,0x0c,0x28,0x00,0xb0,0xaf,0x08,0x00,0x30,0x96,0x02,0x80,0x02,0x3c,
22050x21,0x28,0x00,0x00,0x25,0x80,0x02,0x02,0x21,0x20,0x00,0x02,0x97,0x45,0x00,0x0c,
22060x10,0x00,0x06,0x24,0x20,0x00,0x02,0x96,0x24,0x00,0x04,0x26,0x10,0x00,0xa5,0x27,
22070x03,0xff,0x42,0x30,0xc8,0x00,0x42,0x34,0x20,0x00,0x02,0xa6,0x9f,0x45,0x00,0x0c,
22080x06,0x00,0x06,0x24,0x25,0xb0,0x03,0x3c,0x50,0x00,0x62,0x34,0x00,0x00,0x44,0x8c,
22090x54,0x00,0x65,0x34,0x58,0x00,0x66,0x34,0x18,0x00,0xa4,0xaf,0x00,0x00,0xa2,0x8c,
22100x5c,0x00,0x63,0x34,0x2a,0x00,0x04,0x26,0x1c,0x00,0xa2,0xaf,0x00,0x00,0xc7,0x8c,
22110x18,0x00,0xa5,0x27,0x06,0x00,0x06,0x24,0x20,0x00,0xa7,0xaf,0x00,0x00,0x62,0x8c,
22120x1a,0x00,0x12,0x24,0x9f,0x45,0x00,0x0c,0x24,0x00,0xa2,0xaf,0x30,0x00,0x04,0x26,
22130x20,0x00,0xa5,0x27,0x9f,0x45,0x00,0x0c,0x06,0x00,0x06,0x24,0x13,0x00,0x03,0x24,
22140x14,0x00,0x23,0xae,0x0c,0x00,0x32,0xae,0x08,0x00,0x05,0x8e,0x04,0x00,0x04,0x8e,
22150xff,0xdf,0x02,0x3c,0x14,0x00,0x06,0x8e,0xff,0xff,0x42,0x34,0x10,0x00,0x07,0x8e,
22160xff,0xe0,0x03,0x24,0x24,0x28,0xa2,0x00,0x00,0x40,0x02,0x3c,0x24,0x20,0x83,0x00,
22170x25,0x28,0xa2,0x00,0xff,0x81,0x03,0x24,0xfe,0xff,0x02,0x3c,0x24,0x30,0xc3,0x00,
22180xff,0xff,0x42,0x34,0x00,0x12,0x84,0x34,0x00,0x80,0x03,0x3c,0x24,0x20,0x82,0x00,
22190x25,0x38,0xe3,0x00,0x00,0x26,0xc6,0x34,0x80,0x00,0xa5,0x34,0x20,0x00,0x02,0x24,
22200x00,0x00,0x12,0xa6,0x10,0x00,0x07,0xae,0x02,0x00,0x02,0xa2,0x14,0x00,0x06,0xae,
22210x04,0x00,0x04,0xae,0x08,0x00,0x05,0xae,0x34,0x00,0xbf,0x8f,0x30,0x00,0xb2,0x8f,
22220x2c,0x00,0xb1,0x8f,0x28,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,
22230x93,0x45,0x00,0x08,0xff,0x00,0xa5,0x30,0x00,0x00,0x85,0xa0,0xff,0xff,0xc6,0x24,
22240x01,0x00,0x84,0x24,0xfc,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
22250x00,0x00,0x00,0x00,0x05,0x00,0xc0,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,
22260xff,0xff,0xc6,0x24,0xfd,0xff,0xc0,0x14,0x04,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,
22270x00,0x00,0x00,0x00,0x21,0x38,0x80,0x00,0x08,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24,
22280xff,0xff,0x06,0x24,0x00,0x00,0xa2,0x90,0xff,0xff,0x63,0x24,0x01,0x00,0xa5,0x24,
22290x00,0x00,0xe2,0xa0,0xfb,0xff,0x66,0x14,0x01,0x00,0xe7,0x24,0x08,0x00,0xe0,0x03,
22300x21,0x10,0x80,0x00,0x21,0x38,0x80,0x00,0x08,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24,
22310xff,0xff,0x06,0x24,0x00,0x00,0xa2,0x8c,0xff,0xff,0x63,0x24,0x04,0x00,0xa5,0x24,
22320x00,0x00,0xe2,0xac,0xfb,0xff,0x66,0x14,0x04,0x00,0xe7,0x24,0x08,0x00,0xe0,0x03,
22330x21,0x10,0x80,0x00,0x2b,0x10,0xa4,0x00,0x0d,0x00,0x40,0x14,0xff,0xff,0x02,0x24,
22340xff,0xff,0xc6,0x24,0x08,0x00,0xc2,0x10,0x21,0x18,0x80,0x00,0xff,0xff,0x07,0x24,
22350x00,0x00,0xa2,0x90,0xff,0xff,0xc6,0x24,0x01,0x00,0xa5,0x24,0x00,0x00,0x62,0xa0,
22360xfb,0xff,0xc7,0x14,0x01,0x00,0x63,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,
22370x21,0x28,0xa6,0x00,0x21,0x18,0x86,0x00,0xff,0xff,0xc6,0x24,0xfa,0xff,0xc2,0x10,
22380x00,0x00,0x00,0x00,0xff,0xff,0x07,0x24,0xff,0xff,0xa5,0x24,0x00,0x00,0xa2,0x90,
22390xff,0xff,0x63,0x24,0xff,0xff,0xc6,0x24,0xfb,0xff,0xc7,0x14,0x00,0x00,0x62,0xa0,
22400x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0x0c,0x00,0xc0,0x10,0x00,0x00,0x00,0x00,
22410x00,0x00,0x82,0x90,0x00,0x00,0xa3,0x90,0x01,0x00,0x84,0x24,0x23,0x10,0x43,0x00,
22420x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x04,0x00,0x40,0x14,0x01,0x00,0xa5,0x24,
22430xff,0xff,0xc6,0x24,0xf6,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
22440x21,0x10,0xc0,0x00,0xea,0x45,0x00,0x08,0x21,0x18,0x86,0x00,0x00,0x00,0x82,0x90,
22450x00,0x00,0x00,0x00,0x04,0x00,0x45,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,
22460xfa,0xff,0x83,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,
22470x09,0x00,0xc0,0x10,0xff,0xff,0xc3,0x24,0xff,0x00,0xa5,0x30,0xff,0xff,0x06,0x24,
22480x00,0x00,0x82,0x90,0xff,0xff,0x63,0x24,0x05,0x00,0x45,0x10,0x01,0x00,0x84,0x24,
22490xfb,0xff,0x66,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,
22500x08,0x00,0xe0,0x03,0xff,0xff,0x82,0x24,0x21,0x38,0x00,0x00,0x1f,0x00,0xc0,0x10,
22510x21,0x18,0x00,0x00,0x02,0x80,0x02,0x3c,0x80,0x95,0x4b,0x24,0x00,0x00,0x87,0x90,
22520x00,0x00,0xa3,0x90,0xff,0xff,0xc6,0x24,0x01,0x00,0x84,0x24,0x21,0x10,0xeb,0x00,
22530x16,0x00,0xe0,0x10,0x01,0x00,0xa5,0x24,0x14,0x00,0x60,0x10,0x21,0x48,0x6b,0x00,
22540x10,0x00,0xe3,0x10,0x20,0x00,0xe8,0x24,0x00,0x00,0x42,0x90,0x00,0x00,0x00,0x00,
22550x01,0x00,0x42,0x30,0x02,0x00,0x40,0x10,0x20,0x00,0x6a,0x24,0xff,0x00,0x07,0x31,
22560x00,0x00,0x22,0x91,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,0x02,0x00,0x40,0x10,
22570xff,0x00,0xe7,0x30,0xff,0x00,0x43,0x31,0xff,0x00,0x63,0x30,0x03,0x00,0xe3,0x14,
22580x00,0x00,0x00,0x00,0xe5,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
22590x23,0x10,0xe3,0x00,0x21,0x18,0x80,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,
22600x00,0x00,0x82,0xa0,0xfc,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,
22610x21,0x10,0x60,0x00,0x21,0x38,0x80,0x00,0xff,0xff,0x03,0x24,0xff,0xff,0xc6,0x24,
22620x06,0x00,0xc3,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,
22630x00,0x00,0x82,0xa0,0xf9,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,
22640x21,0x10,0xe0,0x00,0x00,0x00,0x82,0x80,0x39,0x46,0x00,0x08,0x21,0x18,0x80,0x00,
22650x01,0x00,0x84,0x24,0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,0xfc,0xff,0x40,0x14,
22660x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,0x00,0x00,0x82,0xa0,
22670xfc,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
22680x12,0x00,0xc0,0x10,0x21,0x18,0x80,0x00,0x00,0x00,0x82,0x80,0x4a,0x46,0x00,0x08,
22690x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,
22700xfc,0xff,0x40,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xa2,0x90,0x01,0x00,0xa5,0x24,
22710x00,0x00,0x82,0xa0,0x05,0x00,0x40,0x10,0x01,0x00,0x84,0x24,0xff,0xff,0xc6,0x24,
22720xf9,0xff,0xc0,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,0x08,0x00,0xe0,0x03,
22730x21,0x10,0x60,0x00,0x00,0x00,0x83,0x90,0x00,0x00,0xa2,0x90,0x01,0x00,0x84,0x24,
22740x23,0x10,0x62,0x00,0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x03,0x00,0x40,0x14,
22750x01,0x00,0xa5,0x24,0xf7,0xff,0x60,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
22760x00,0x00,0x00,0x00,0x21,0x10,0x00,0x00,0x0b,0x00,0xc0,0x10,0x00,0x00,0x00,0x00,
22770x00,0x00,0xa2,0x90,0x00,0x00,0x83,0x90,0xff,0xff,0xc6,0x24,0x23,0x10,0x62,0x00,
22780x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x03,0x00,0x40,0x14,0x01,0x00,0xa5,0x24,
22790xf5,0xff,0x60,0x14,0x01,0x00,0x84,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
22800x00,0x00,0x83,0x80,0x00,0x2e,0x05,0x00,0x21,0x10,0x80,0x00,0x7b,0x46,0x00,0x08,
22810x03,0x2e,0x05,0x00,0x07,0x00,0x60,0x10,0x01,0x00,0x42,0x24,0x00,0x00,0x43,0x80,
22820x00,0x00,0x00,0x00,0xfb,0xff,0x65,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
22830x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x00,0x00,0x00,0x82,0x80,
22840x87,0x46,0x00,0x08,0x21,0x18,0x80,0x00,0x01,0x00,0x63,0x24,0x00,0x00,0x62,0x80,
22850x00,0x00,0x00,0x00,0xfc,0xff,0x40,0x14,0x23,0x10,0x64,0x00,0x08,0x00,0xe0,0x03,
22860x00,0x00,0x00,0x00,0xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x21,0x80,0xa0,0x00,
22870x14,0x00,0xb1,0xaf,0x18,0x00,0xbf,0xaf,0x21,0x88,0x80,0x00,0x81,0x46,0x00,0x0c,
22880x00,0x86,0x10,0x00,0x21,0x18,0x51,0x00,0x03,0x86,0x10,0x00,0x00,0x00,0x62,0x80,
22890x00,0x00,0x00,0x00,0x0a,0x00,0x50,0x10,0x21,0x10,0x60,0x00,0xff,0xff,0x63,0x24,
22900x2b,0x10,0x71,0x00,0xf9,0xff,0x40,0x10,0x21,0x10,0x00,0x00,0x18,0x00,0xbf,0x8f,
22910x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
22920x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,
22930x20,0x00,0xbd,0x27,0x21,0x30,0x80,0x00,0x0d,0x00,0xa0,0x10,0xff,0xff,0xa3,0x24,
22940x00,0x00,0x82,0x80,0x00,0x00,0x00,0x00,0x09,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
22950xff,0xff,0x05,0x24,0xff,0xff,0x63,0x24,0x05,0x00,0x65,0x10,0x01,0x00,0xc6,0x24,
22960x00,0x00,0xc2,0x80,0x00,0x00,0x00,0x00,0xfa,0xff,0x40,0x14,0x00,0x00,0x00,0x00,
22970x08,0x00,0xe0,0x03,0x23,0x10,0xc4,0x00,0x00,0x00,0x82,0x90,0x00,0x00,0x00,0x00,
22980x19,0x00,0x40,0x10,0x21,0x40,0x00,0x00,0x00,0x00,0xa9,0x80,0x00,0x00,0x00,0x00,
22990x17,0x00,0x20,0x11,0x21,0x30,0xa0,0x00,0x00,0x3e,0x02,0x00,0x03,0x3e,0x07,0x00,
23000x21,0x18,0x20,0x01,0x15,0x00,0xe3,0x10,0x00,0x00,0x00,0x00,0x01,0x00,0xc6,0x24,
23010x00,0x00,0xc2,0x90,0x00,0x00,0x00,0x00,0x00,0x1e,0x02,0x00,0x03,0x1e,0x03,0x00,
23020xf8,0xff,0x60,0x14,0x00,0x16,0x02,0x00,0x03,0x16,0x02,0x00,0x06,0x00,0x40,0x10,
23030x00,0x00,0x00,0x00,0x01,0x00,0x84,0x24,0x00,0x00,0x82,0x90,0x00,0x00,0x00,0x00,
23040xeb,0xff,0x40,0x14,0x01,0x00,0x08,0x25,0x08,0x00,0xe0,0x03,0x21,0x10,0x00,0x01,
23050x00,0x00,0xa2,0x90,0xcc,0x46,0x00,0x08,0x00,0x16,0x02,0x00,0x00,0x00,0xc2,0x90,
23060xcc,0x46,0x00,0x08,0x00,0x16,0x02,0x00,0x00,0x00,0x87,0x90,0x00,0x00,0x00,0x00,
23070x14,0x00,0xe0,0x10,0x21,0x10,0x80,0x00,0x00,0x00,0xa4,0x90,0x00,0x00,0x00,0x00,
23080x00,0x1e,0x04,0x00,0x03,0x1e,0x03,0x00,0x09,0x00,0x60,0x10,0x21,0x30,0xa0,0x00,
23090x00,0x3e,0x07,0x00,0x03,0x3e,0x07,0x00,0x0b,0x00,0xe3,0x10,0x01,0x00,0xc6,0x24,
23100x00,0x00,0xc3,0x80,0x00,0x00,0x00,0x00,0xfb,0xff,0x60,0x14,0x00,0x00,0x00,0x00,
23110x01,0x00,0x42,0x24,0x00,0x00,0x47,0x90,0x00,0x00,0x00,0x00,0xf0,0xff,0xe0,0x14,
23120x00,0x00,0x00,0x00,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
23130xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x18,0x00,0xbf,0xaf,
23140x21,0x80,0x80,0x00,0x1d,0x00,0x80,0x10,0x21,0x88,0xa0,0x00,0xb8,0x46,0x00,0x0c,
23150x21,0x20,0x00,0x02,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,0x21,0x28,0x20,0x02,
23160x21,0x20,0x00,0x02,0x22,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xdc,0x46,0x00,0x0c,
23170x00,0x00,0x00,0x00,0x05,0x00,0x40,0x10,0x21,0x18,0x40,0x00,0x00,0x00,0x42,0x80,
23180x00,0x00,0x00,0x00,0x0a,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
23190xa8,0x96,0x43,0xac,0x21,0x18,0x00,0x02,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,
23200x10,0x00,0xb0,0x8f,0x21,0x10,0x60,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
23210x00,0x00,0x60,0xa0,0x0d,0x47,0x00,0x08,0x01,0x00,0x63,0x24,0x02,0x80,0x02,0x3c,
23220xa8,0x96,0x50,0x8c,0x00,0x00,0x00,0x00,0xf3,0xff,0x00,0x12,0x21,0x18,0x00,0x00,
23230xb8,0x46,0x00,0x0c,0x21,0x20,0x00,0x02,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,
23240x21,0x28,0x20,0x02,0x21,0x20,0x00,0x02,0xe0,0xff,0x40,0x14,0x21,0x18,0x00,0x00,
23250x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x02,0x80,0x02,0x3c,
23260xa8,0x96,0x40,0xac,0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
23270xe0,0xff,0xbd,0x27,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x1c,0x00,0xbf,0xaf,
23280x10,0x00,0xb0,0xaf,0x00,0x00,0x90,0x8c,0x21,0x90,0x80,0x00,0x21,0x88,0xa0,0x00,
23290x21,0x18,0x00,0x00,0x0f,0x00,0x00,0x12,0x21,0x20,0x00,0x02,0xb8,0x46,0x00,0x0c,
23300x00,0x00,0x00,0x00,0x21,0x80,0x02,0x02,0x00,0x00,0x02,0x82,0x21,0x28,0x20,0x02,
23310x21,0x20,0x00,0x02,0x07,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xdc,0x46,0x00,0x0c,
23320x00,0x00,0x00,0x00,0x21,0x18,0x40,0x00,0x09,0x00,0x40,0x14,0x00,0x00,0x42,0xae,
23330x21,0x18,0x00,0x02,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
23340x10,0x00,0xb0,0x8f,0x21,0x10,0x60,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
23350x00,0x00,0x42,0x80,0x00,0x00,0x00,0x00,0xf5,0xff,0x40,0x10,0x01,0x00,0x64,0x24,
23360x00,0x00,0x60,0xa0,0x46,0x47,0x00,0x08,0x00,0x00,0x44,0xae,0xd8,0xff,0xbd,0x27,
23370x14,0x00,0xb1,0xaf,0x21,0x88,0x80,0x00,0x21,0x20,0xa0,0x00,0x1c,0x00,0xb3,0xaf,
23380x18,0x00,0xb2,0xaf,0x20,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x81,0x46,0x00,0x0c,
23390x21,0x98,0xa0,0x00,0x21,0x90,0x40,0x00,0x08,0x00,0x40,0x16,0x21,0x10,0x20,0x02,
23400x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
23410x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x81,0x46,0x00,0x0c,
23420x21,0x20,0x20,0x02,0x21,0x80,0x40,0x00,0x2a,0x10,0x52,0x00,0x0a,0x00,0x40,0x14,
23430x00,0x00,0x00,0x00,0x21,0x20,0x20,0x02,0x21,0x28,0x60,0x02,0x21,0x30,0x40,0x02,
23440xd4,0x45,0x00,0x0c,0xff,0xff,0x10,0x26,0x0b,0x00,0x40,0x10,0x2a,0x18,0x12,0x02,
23450xf8,0xff,0x60,0x10,0x01,0x00,0x31,0x26,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,
23460x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,
23470x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0x62,0x47,0x00,0x08,0x21,0x10,0x20,0x02,
23480x01,0x80,0x02,0x3c,0xc0,0xff,0xbd,0x27,0x08,0x1e,0x44,0x24,0x25,0xb0,0x02,0x3c,
23490x28,0x00,0xb4,0xaf,0x02,0x80,0x03,0x3c,0x25,0xb0,0x14,0x3c,0x18,0x03,0x42,0x34,
23500x38,0x00,0xbe,0xaf,0x34,0x00,0xb7,0xaf,0x30,0x00,0xb6,0xaf,0x2c,0x00,0xb5,0xaf,
23510x24,0x00,0xb3,0xaf,0x3c,0x00,0xbf,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,
23520x18,0x00,0xb0,0xaf,0x68,0x15,0x73,0x24,0x00,0x00,0x44,0xac,0x02,0x80,0x16,0x3c,
23530x02,0x80,0x15,0x3c,0xc4,0x02,0x9e,0x36,0x64,0x03,0x97,0x36,0x01,0x80,0x04,0x3c,
23540x08,0x1e,0x82,0x24,0x18,0x03,0x83,0x36,0x00,0x00,0x62,0xac,0xa0,0x02,0x87,0x36,
23550x00,0x00,0xe4,0x8c,0xd8,0x63,0x63,0x8e,0xff,0x0f,0x02,0x3c,0xff,0xff,0x46,0x34,
23560x24,0x80,0x86,0x00,0x01,0x00,0x05,0x3c,0x01,0x00,0x63,0x24,0x2b,0x10,0xb0,0x00,
23570x07,0x00,0x40,0x10,0xd8,0x63,0x63,0xae,0xa4,0x02,0x82,0x36,0x00,0x00,0x51,0x8c,
23580x00,0xb0,0x03,0x3c,0x25,0x80,0x03,0x02,0x00,0x00,0x11,0xae,0x00,0x00,0xe0,0xac,
23590xb0,0x02,0x84,0x36,0x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x24,0x80,0x46,0x00,
23600x2b,0x18,0xb0,0x00,0x08,0x00,0x60,0x10,0xc0,0x02,0x82,0x36,0x00,0xb0,0x02,0x3c,
23610x25,0x80,0x02,0x02,0x00,0x00,0x11,0x8e,0xb4,0x02,0x82,0x36,0x00,0x00,0x51,0xac,
23620x00,0x00,0x80,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x50,0x8c,0xff,0x00,0x08,0x3c,
23630xff,0xff,0x02,0x35,0x2b,0x10,0x50,0x00,0x47,0x00,0x40,0x10,0x00,0x00,0x00,0x00,
23640x00,0x00,0x82,0x8e,0x00,0xff,0x06,0x3c,0xac,0x02,0x84,0x36,0x01,0x00,0x45,0x24,
23650xbc,0x02,0x83,0x36,0xff,0x00,0xc2,0x34,0x00,0xfd,0x07,0x3c,0x00,0x00,0x85,0xac,
23660x00,0x00,0x70,0xac,0x24,0x18,0x02,0x02,0x07,0x00,0xe2,0x34,0x00,0x00,0x85,0x8c,
23670x52,0x03,0x62,0x10,0x25,0xb0,0x12,0x3c,0x2b,0x10,0x43,0x00,0xa2,0x00,0x40,0x14,
23680xa4,0x00,0xe2,0x34,0x00,0xf8,0x04,0x3c,0x15,0x00,0x82,0x34,0x57,0x03,0x62,0x10,
23690x2b,0x10,0x43,0x00,0xc8,0x00,0x40,0x14,0x00,0xf9,0x05,0x3c,0x00,0xf0,0x05,0x3c,
23700x20,0x00,0xa2,0x34,0x67,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x20,0x01,0x40,0x14,
23710x10,0x00,0x82,0x34,0x70,0x03,0x65,0x10,0x2b,0x10,0xa3,0x00,0xc8,0x01,0x40,0x14,
23720x02,0x00,0xa2,0x34,0x00,0xd0,0x02,0x3c,0x2a,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,
23730xaf,0x02,0x40,0x14,0x00,0xe0,0x02,0x3c,0x00,0xc0,0x02,0x3c,0xbb,0x03,0x62,0x10,
23740xff,0x00,0x03,0x3c,0x00,0xf0,0x02,0x3c,0x24,0x30,0x02,0x02,0x18,0x00,0xc2,0x10,
23750x02,0x1d,0x10,0x00,0x00,0x70,0x05,0x3c,0x24,0x10,0x05,0x02,0x02,0x4f,0x02,0x00,
23760x0f,0x00,0x02,0x3c,0xff,0xff,0x42,0x34,0x00,0x50,0x07,0x3c,0xff,0x00,0x68,0x30,
23770xff,0x00,0x04,0x32,0x96,0x01,0xc7,0x10,0x24,0x18,0x02,0x02,0x2b,0x10,0xe6,0x00,
23780x8a,0x01,0x40,0x14,0x00,0x80,0x02,0x3c,0x00,0x20,0x02,0x3c,0x1a,0x03,0xc2,0x10,
23790x2b,0x10,0x46,0x00,0x82,0x02,0x40,0x14,0x00,0x30,0x02,0x3c,0x17,0x03,0xc0,0x10,
23800x80,0x10,0x08,0x00,0x00,0x10,0x02,0x3c,0x14,0x03,0xc2,0x10,0x80,0x10,0x08,0x00,
23810xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
23820x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x00,0x00,0xe2,0x92,0x25,0xb0,0x07,0x3c,
23830xc8,0x7d,0xc2,0xa2,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
23840xc8,0x7d,0xc2,0x92,0x00,0x00,0x00,0x00,0x01,0x00,0x42,0x30,0x4e,0x00,0x40,0x10,
23850x02,0x80,0x03,0x3c,0x00,0x40,0x62,0x8e,0xf0,0xff,0x03,0x24,0xd7,0x42,0x60,0xa2,
23860x24,0x10,0x43,0x00,0x01,0x00,0x42,0x34,0x00,0x40,0x62,0xae,0xc8,0x7d,0xc2,0x92,
23870x00,0x00,0x00,0x00,0x02,0x00,0x42,0x30,0x3d,0x00,0x40,0x10,0x0f,0xff,0x03,0x24,
23880x00,0x40,0x62,0x8e,0x00,0x00,0x00,0x00,0x24,0x10,0x43,0x00,0x10,0x00,0x42,0x34,
23890x00,0x40,0x62,0xae,0xc8,0x7d,0xc2,0x92,0x00,0x00,0x00,0x00,0x04,0x00,0x42,0x30,
23900x30,0x00,0x40,0x10,0xff,0xf0,0x03,0x24,0x00,0x40,0x62,0x8e,0x00,0x00,0x00,0x00,
23910x24,0x10,0x43,0x00,0x00,0x01,0x42,0x34,0x25,0xb0,0x05,0x3c,0x00,0x40,0x62,0xae,
23920x4c,0x00,0xa3,0x34,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x42,0x30,
23930x05,0x00,0x40,0x14,0xff,0xff,0x02,0x3c,0x00,0x40,0x63,0x8e,0xff,0x0f,0x42,0x34,
23940x24,0x18,0x62,0x00,0x00,0x40,0x63,0xae,0x00,0x7b,0xa4,0x8e,0x01,0x80,0x06,0x3c,
23950x08,0x1f,0xc2,0x24,0x18,0x03,0xa3,0x34,0x00,0x7b,0xa6,0x26,0x00,0x00,0x62,0xac,
23960x10,0x00,0x86,0x10,0x02,0x80,0x02,0x3c,0xbf,0x00,0xb2,0x34,0x68,0x15,0x51,0x24,
23970x21,0x80,0xc0,0x00,0x00,0x00,0x42,0x92,0x00,0x00,0x00,0x00,0x04,0x00,0x42,0x2c,
23980x09,0x00,0x40,0x10,0x02,0x80,0x07,0x3c,0x98,0x65,0x24,0x8e,0x8b,0x07,0x00,0x0c,
23990x00,0x00,0x00,0x00,0x00,0x7b,0xa2,0x8e,0x00,0x00,0x00,0x00,0xf5,0xff,0x50,0x14,
24000x00,0x00,0x00,0x00,0x02,0x80,0x07,0x3c,0x08,0x08,0xe4,0x24,0x21,0x28,0x00,0x00,
24010x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0x9a,0x47,0x00,0x08,
24020x01,0x80,0x04,0x3c,0x00,0x40,0x62,0x8e,0x30,0x48,0x00,0x08,0x24,0x10,0x43,0x00,
24030x00,0x40,0x62,0x8e,0x04,0x43,0x64,0x92,0x24,0x10,0x43,0x00,0x00,0x40,0x62,0xae,
24040x27,0x48,0x00,0x08,0x04,0x43,0x64,0xae,0x68,0x15,0x66,0x24,0x00,0x40,0xc2,0x8c,
24050xd7,0x42,0xc4,0x90,0xf0,0xff,0x03,0x24,0x24,0x10,0x43,0x00,0xb3,0xff,0x80,0x14,
24060x00,0x40,0xc2,0xac,0x1c,0x00,0x04,0x24,0x58,0x0c,0xe5,0x34,0x50,0x0c,0xe3,0x34,
24070x01,0x00,0x02,0x24,0xd7,0x42,0xc2,0xa0,0x00,0x00,0x64,0xa0,0x00,0x00,0xa4,0xa0,
24080x1d,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xb2,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,
24090x3f,0x00,0x40,0x14,0xaf,0x00,0xe2,0x34,0x20,0x00,0xe2,0x34,0xc0,0x02,0x62,0x10,
24100x2b,0x10,0x43,0x00,0xe3,0x00,0x40,0x14,0x29,0x00,0xe2,0x34,0x15,0x00,0xe2,0x34,
24110x0c,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x9d,0x01,0x40,0x14,0x17,0x00,0xe2,0x34,
24120x09,0x00,0xe2,0x34,0xd8,0x03,0x62,0x10,0x2b,0x10,0x62,0x00,0x81,0x02,0x40,0x14,
24130x14,0x00,0xe2,0x34,0x64,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,0xff,0x00,0x07,0x3c,
24140x00,0xff,0xe7,0x34,0x24,0x10,0x07,0x02,0x7a,0xff,0x40,0x10,0xc0,0x02,0x82,0x36,
24150x04,0x43,0x64,0x92,0xff,0x00,0x02,0x3c,0x24,0x10,0x02,0x02,0x00,0xff,0x03,0x32,
24160x02,0x14,0x02,0x00,0x02,0x1a,0x03,0x00,0xfb,0xff,0x45,0x24,0x1c,0x43,0x62,0xa2,
24170x00,0x01,0x84,0x34,0xfb,0xff,0x66,0x24,0xc0,0x02,0x82,0x36,0x04,0x43,0x64,0xae,
24180x1d,0x43,0x65,0xa2,0x1f,0x43,0x66,0xa2,0x1e,0x43,0x63,0xa2,0x00,0x00,0x40,0xac,
24190x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x05,0x00,0xa2,0x34,0x91,0x02,0x62,0x10,
24200x2b,0x10,0x43,0x00,0x8e,0x00,0x40,0x14,0x00,0x00,0x00,0x00,0xde,0x02,0x65,0x10,
24210x2b,0x10,0xa3,0x00,0x32,0x01,0x40,0x14,0x02,0x00,0xa2,0x34,0x17,0x00,0x82,0x34,
24220x61,0x04,0x62,0x10,0x2b,0x10,0x62,0x00,0xa9,0x03,0x40,0x14,0x18,0x00,0x82,0x34,
24230x3d,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,0x74,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00,
24240xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
24250xa8,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0x95,0x00,0x40,0x14,0x0c,0x00,0xc2,0x34,
24260xaa,0x00,0xe2,0x34,0xdc,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xd9,0x00,0x40,0x14,
24270xac,0x00,0xe2,0x34,0xa6,0x00,0xe2,0x34,0x1c,0x04,0x62,0x10,0x2b,0x10,0x62,0x00,
24280x69,0x03,0x40,0x14,0xa7,0x00,0xe2,0x34,0x27,0xff,0x62,0x14,0x00,0xf0,0x02,0x3c,
24290x00,0xff,0x02,0x32,0xff,0x00,0x04,0x3c,0x02,0x8a,0x02,0x00,0x24,0x18,0x04,0x02,
24300x01,0x00,0x02,0x24,0xa6,0x04,0x22,0x12,0x02,0x1c,0x03,0x00,0x02,0x00,0x02,0x24,
24310xc9,0x04,0x22,0x12,0x03,0x00,0x02,0x24,0xdf,0x04,0x22,0x12,0x04,0x00,0x02,0x24,
24320xd1,0x04,0x22,0x12,0x08,0x00,0x02,0x24,0x2e,0x05,0x22,0x12,0x09,0x00,0x02,0x24,
24330x1e,0x05,0x22,0x12,0x0a,0x00,0x02,0x24,0x0e,0x05,0x22,0x12,0x0b,0x00,0x02,0x24,
24340xfe,0x04,0x22,0x12,0x0c,0x00,0x02,0x24,0x5e,0x05,0x22,0x12,0x0d,0x00,0x02,0x24,
24350x4e,0x05,0x22,0x12,0x0e,0x00,0x02,0x24,0x3e,0x05,0x22,0x12,0x0f,0x00,0x02,0x24,
24360x2e,0x05,0x22,0x12,0x10,0x00,0x02,0x24,0x22,0xff,0x22,0x16,0xc0,0x02,0x82,0x36,
24370xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
24380x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,0x4c,0x51,0x43,0x94,0x48,0x51,0x44,0x94,
24390x25,0xb0,0x06,0x3c,0x00,0x1c,0x03,0x00,0x21,0x20,0x83,0x00,0x00,0x00,0xc4,0xaf,
24400x58,0x51,0x45,0x8c,0x54,0x51,0x43,0x8c,0x50,0x51,0x44,0x94,0xc8,0x02,0xc6,0x34,
24410x21,0x18,0x65,0x00,0x00,0x1c,0x03,0x00,0x21,0x20,0x83,0x00,0xc0,0x02,0x82,0x36,
24420x00,0x00,0xc4,0xac,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
24430x66,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xbf,0x00,0x40,0x14,0x12,0x00,0x82,0x34,
24440x00,0xf1,0x04,0x3c,0x01,0x00,0x82,0x34,0xc1,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,
24450xb7,0x01,0x40,0x14,0x02,0x00,0x82,0x34,0xe3,0xfe,0x64,0x14,0x00,0xf0,0x02,0x3c,
24460xff,0x00,0x04,0x3c,0x00,0xff,0x84,0x34,0x24,0x10,0x04,0x02,0x02,0x8a,0x02,0x00,
24470x80,0x1a,0x11,0x00,0x00,0xf4,0x63,0x24,0x94,0x00,0x82,0x36,0x00,0x00,0x51,0xa4,
24480x26,0xb0,0x04,0x3c,0x42,0x89,0x03,0x00,0x98,0x00,0x86,0x36,0xff,0x01,0x02,0x24,
24490x10,0x00,0x03,0x24,0x9a,0x00,0x85,0x36,0x00,0x00,0xa2,0xa4,0x7c,0x00,0x89,0x34,
24500x00,0x00,0xc3,0xa4,0x01,0x00,0x02,0x24,0x04,0x00,0x03,0x24,0x96,0x00,0x87,0x36,
24510x7a,0x00,0x84,0x34,0xb0,0x03,0x88,0x36,0x25,0xb0,0x06,0x3c,0x00,0x00,0xe2,0xa4,
24520x44,0x00,0xc6,0x34,0x00,0x00,0x83,0xa0,0x00,0x00,0x11,0xad,0x00,0x00,0x31,0xa5,
24530x00,0x00,0xc3,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x00,0xc3,0xa4,
24540x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,0x00,0x00,0xc2,0xa4,
24550xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
24560x65,0x01,0x67,0x10,0x2b,0x10,0xe3,0x00,0xc5,0x00,0x40,0x14,0x02,0x00,0xe2,0x34,
24570x07,0x00,0xa2,0x34,0xfc,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xa9,0x01,0x40,0x14,
24580x20,0x00,0xa2,0x34,0xb0,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,0xff,0x00,0x03,0x3c,
24590x00,0xff,0x63,0x34,0x24,0x10,0x03,0x02,0x02,0x3a,0x02,0x00,0x80,0x04,0xe0,0x10,
24600x02,0x80,0x04,0x3c,0x05,0x00,0x02,0x24,0xc2,0xfe,0xe2,0x14,0xc0,0x02,0x82,0x36,
24610x02,0x80,0x06,0x3c,0x8f,0x7d,0xc2,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
24620xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
24630x2e,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0x98,0x00,0x40,0x14,0x0e,0x00,0xc2,0x34,
24640x01,0x00,0xc2,0x34,0xab,0x03,0x62,0x10,0x2b,0x10,0x43,0x00,0x48,0x01,0x40,0x14,
24650x00,0xff,0x02,0x3c,0x94,0xfe,0x66,0x14,0x00,0xf0,0x02,0x3c,0x5b,0x4e,0x00,0x0c,
24660x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
24670x00,0x00,0x00,0x00,0x4c,0x02,0x62,0x10,0x2b,0x10,0x43,0x00,0xa6,0x00,0x40,0x14,
24680xa1,0x00,0xe2,0x34,0x22,0x00,0xe2,0x34,0xbd,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,
24690x88,0x01,0x40,0x14,0x00,0x20,0x02,0x3c,0x28,0x00,0xe2,0x34,0x82,0xfe,0x62,0x14,
24700x00,0xf0,0x02,0x3c,0x0f,0x00,0x04,0x3c,0xff,0xff,0x85,0x34,0x60,0x00,0x06,0x24,
24710xba,0x44,0x00,0x0c,0x24,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0xe8,0x03,0x04,0x24,
24720x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
24730x0f,0x00,0x06,0x3c,0x24,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0xc5,0x34,
24740x1f,0x00,0x51,0x30,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
24750xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xa3,
24760x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x18,0x02,0xc2,0x10,
24770x2b,0x10,0x46,0x00,0x01,0x01,0x40,0x14,0x00,0xa0,0x02,0x3c,0x00,0x60,0x02,0x3c,
24780x04,0x00,0xc2,0x10,0x80,0x10,0x08,0x00,0x7a,0xfe,0xc5,0x14,0xc0,0x02,0x82,0x36,
24790x80,0x10,0x08,0x00,0x21,0x10,0x48,0x00,0x21,0x10,0x53,0x00,0x21,0x10,0x49,0x00,
24800xc1,0x43,0x44,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
24810x00,0x00,0x00,0x00,0x3f,0x03,0x62,0x10,0x2b,0x10,0x62,0x00,0xb6,0x02,0x40,0x14,
24820xad,0x00,0xe2,0x34,0xc7,0x03,0x62,0x10,0xae,0x00,0xe2,0x34,0x4e,0xfe,0x62,0x14,
24830x00,0xf0,0x02,0x3c,0xff,0x00,0x02,0x3c,0x24,0x20,0x02,0x02,0x00,0xff,0x05,0x32,
24840x02,0x24,0x04,0x00,0x69,0x4f,0x00,0x0c,0x02,0x2a,0x05,0x00,0x00,0x00,0xc2,0xa3,
24850xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
24860x4b,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0x17,0x01,0x40,0x14,0x03,0x00,0xa2,0x34,
24870x82,0x03,0x62,0x10,0x08,0x00,0xa2,0x34,0x3b,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,
24880x00,0xff,0x02,0x32,0x02,0x82,0x02,0x00,0xcc,0x02,0x83,0x36,0x00,0x00,0x70,0xac,
24890x12,0x04,0x00,0x12,0x01,0x00,0x02,0x24,0x9c,0x04,0x02,0x12,0x00,0x00,0x00,0x00,
24900x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
24910x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x4e,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,
24920xe4,0x00,0x40,0x14,0x00,0xff,0x02,0x32,0x13,0x00,0x82,0x34,0x4c,0x03,0x62,0x10,
24930x14,0x00,0x82,0x34,0x24,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,0xd3,0x0a,0x00,0x0c,
24940xfd,0x00,0x04,0x24,0x10,0x10,0x03,0x3c,0xa0,0x00,0x82,0x36,0x10,0x10,0x63,0x34,
24950x00,0xc0,0x07,0x3c,0x25,0xb0,0x06,0x3c,0x00,0x00,0x43,0xac,0xa4,0x00,0x84,0x36,
24960x00,0xa1,0xe7,0x34,0xa8,0x00,0xc6,0x34,0xc0,0x02,0x82,0x36,0x00,0x00,0x80,0xac,
24970x00,0x00,0xc7,0xac,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
24980x60,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xf6,0x00,0x40,0x14,0x03,0x00,0xa2,0x34,
24990x4b,0x03,0x62,0x10,0x04,0x00,0xa2,0x34,0x0b,0xfe,0x62,0x14,0x00,0xf0,0x02,0x3c,
25000xf4,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
25010x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x61,0x02,0x62,0x10,
25020x2b,0x10,0x62,0x00,0xfe,0x00,0x40,0x14,0x01,0x00,0x02,0x24,0x0f,0x00,0xc2,0x34,
25030x63,0x03,0x62,0x10,0x10,0x00,0xc2,0x34,0xfb,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,
25040x00,0xff,0x03,0x32,0x00,0xff,0x02,0x34,0x9d,0x03,0x62,0x10,0xc0,0x02,0x82,0x36,
25050x8c,0x65,0x60,0xae,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25060x47,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0x02,0x01,0x40,0x14,0x03,0x00,0xe2,0x34,
25070x8d,0x03,0x62,0x10,0x04,0x00,0xe2,0x34,0xeb,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,
25080x1e,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
25090x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x9b,0x01,0x62,0x10,0x2b,0x10,0x43,0x00,
25100xcf,0x00,0x40,0x14,0xa2,0x00,0xe2,0x34,0xa0,0x00,0xe2,0x34,0xde,0xfd,0x62,0x14,
25110x00,0xf0,0x02,0x3c,0x00,0x0f,0x02,0x32,0x02,0x22,0x02,0x00,0x01,0x00,0x03,0x24,
25120x3c,0x04,0x83,0x10,0x02,0x00,0x02,0x24,0x34,0x04,0x82,0x10,0x03,0x00,0x02,0x24,
25130x46,0x03,0x82,0x10,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,0x21,0x20,0x00,0x00,
25140xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25150x46,0x02,0x62,0x10,0x2b,0x10,0x62,0x00,0xe6,0xfd,0x40,0x14,0xc0,0x02,0x82,0x36,
25160x18,0x00,0xe2,0x34,0x45,0x03,0x62,0x10,0x19,0x00,0xe2,0x34,0xc6,0xfd,0x62,0x14,
25170x00,0xf0,0x02,0x3c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x94,0x0e,0x83,0x36,
25180x9c,0x0e,0x82,0x36,0xa4,0x0e,0x84,0x36,0xac,0x0e,0x87,0x36,0x00,0x00,0x65,0x8c,
25190x00,0x00,0x48,0x8c,0x00,0x00,0x8a,0x8c,0x00,0x00,0xe6,0x8c,0x02,0x80,0x07,0x3c,
25200x68,0x15,0xed,0x24,0xb4,0x0e,0x82,0x36,0x00,0x00,0x47,0x8c,0x0c,0x40,0xa3,0x8d,
25210xff,0x03,0x02,0x3c,0x10,0x40,0xa4,0x8d,0x24,0x28,0xa2,0x00,0x24,0x30,0xc2,0x00,
25220xbc,0x0e,0x82,0x36,0x00,0x00,0x4b,0x8c,0x00,0xfc,0x02,0x24,0x02,0x2c,0x05,0x00,
25230x24,0x18,0x62,0x00,0x02,0x34,0x06,0x00,0x24,0x20,0x82,0x00,0xc4,0x0e,0x82,0x36,
25240x25,0x18,0x65,0x00,0x25,0x20,0x86,0x00,0x00,0x00,0x45,0x8c,0xff,0x03,0x06,0x3c,
25250xf0,0xff,0x02,0x3c,0xff,0x03,0x42,0x34,0x24,0x38,0xe6,0x00,0x82,0x39,0x07,0x00,
25260x24,0x20,0x82,0x00,0x24,0x40,0x06,0x01,0x08,0x40,0xa9,0x8d,0x25,0x20,0x87,0x00,
25270xcc,0x0e,0x8c,0x36,0xff,0x03,0x07,0x3c,0x00,0x00,0x86,0x8d,0x24,0x18,0x62,0x00,
25280x24,0x50,0x47,0x01,0x24,0x58,0x67,0x01,0x82,0x41,0x08,0x00,0xff,0x9f,0x02,0x3c,
25290x0f,0xc0,0x07,0x3c,0xff,0xff,0xe7,0x34,0xff,0xff,0x42,0x34,0x25,0x18,0x68,0x00,
25300x24,0x48,0x22,0x01,0x24,0x18,0x67,0x00,0xff,0x03,0x02,0x3c,0x24,0x20,0x87,0x00,
25310xff,0x00,0x07,0x3c,0x24,0x28,0xa2,0x00,0x24,0x30,0xc2,0x00,0x00,0x51,0x0a,0x00,
25320x00,0x20,0x02,0x3c,0x00,0x59,0x0b,0x00,0x00,0xff,0xe7,0x34,0x25,0x48,0x22,0x01,
25330x25,0x18,0x6a,0x00,0x25,0x20,0x8b,0x00,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00,
25340x24,0x10,0x07,0x02,0x08,0x40,0xa9,0xad,0x0c,0x40,0xa3,0xad,0x10,0x40,0xa4,0xad,
25350x14,0x40,0xa5,0xa5,0x4e,0x03,0x40,0x10,0x16,0x40,0xa6,0xa5,0xff,0x00,0x02,0x3c,
25360x24,0x10,0x02,0x02,0x02,0x14,0x02,0x00,0x02,0x1a,0x10,0x00,0xc7,0x42,0xa2,0xa1,
25370xc3,0x42,0xa3,0xa1,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,0x61,0x0c,0x63,0x34,
25380x10,0x00,0xa4,0x27,0x00,0x00,0x62,0xa0,0x7a,0x54,0x00,0x0c,0x00,0x00,0x00,0x00,
25390xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25400x95,0x00,0xc2,0x10,0x00,0x40,0x02,0x3c,0x09,0xff,0xc2,0x10,0xc0,0x02,0x82,0x36,
25410x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7b,0x02,0xc2,0x10,
25420x2b,0x10,0x46,0x00,0x83,0x00,0x40,0x14,0x00,0xb0,0x02,0x3c,0x00,0x90,0x02,0x3c,
25430x78,0xfd,0xc2,0x14,0xc0,0x02,0x82,0x36,0x21,0x10,0x13,0x01,0x73,0x44,0x44,0xa0,
25440xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25450x55,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0x6a,0x56,0x00,0x0c,0x21,0x20,0x00,0x02,
25460xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25470x07,0x00,0x42,0x34,0x4c,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0x5b,0x4e,0x00,0x0c,
25480x07,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25490x00,0x00,0x00,0x00,0x02,0x1a,0x02,0x00,0x21,0x88,0x00,0x00,0xaf,0x4a,0x00,0x08,
25500x27,0xb0,0x06,0x3c,0x01,0x00,0x31,0x26,0x00,0x01,0x22,0x2e,0x08,0x00,0x40,0x10,
25510xff,0x00,0x22,0x2e,0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0xff,0x00,0x42,0x30,
25520xf8,0xff,0x43,0x14,0x08,0x00,0xc6,0x24,0x00,0x00,0xd1,0xa7,0xff,0x00,0x22,0x2e,
25530x50,0xfd,0x40,0x14,0xc0,0x02,0x82,0x36,0x12,0x87,0x02,0x3c,0x00,0x00,0xc2,0xaf,
25540xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25550x2d,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
25560x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,0x00,0xff,0x63,0x34,
25570x24,0x10,0x03,0x02,0x02,0x82,0x02,0x00,0xcc,0x02,0x83,0x36,0x00,0x00,0x70,0xac,
25580x00,0x00,0xd1,0x8f,0x21,0x10,0x14,0x02,0x00,0x00,0x51,0xac,0x00,0x00,0x51,0x8c,
25590xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25600x00,0x00,0x00,0x00,0x00,0x64,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
25610xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25620xf4,0x02,0x62,0x10,0xa3,0x00,0xe2,0x34,0x0f,0xfd,0x62,0x14,0x00,0xf0,0x02,0x3c,
25630xc0,0x02,0x82,0x36,0x8c,0x65,0x60,0xae,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25640x00,0x00,0x00,0x00,0xec,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
25650xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25660xe6,0x63,0x62,0xa6,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25670x00,0x00,0x00,0x00,0x08,0x40,0x63,0x8e,0xff,0x9f,0x07,0x3c,0xff,0xff,0xe7,0x34,
25680x02,0x2c,0x10,0x00,0x00,0x1f,0x04,0x32,0x24,0x18,0x67,0x00,0x25,0x18,0x62,0x00,
25690x02,0x8a,0x04,0x00,0x3f,0x00,0xa5,0x30,0xc0,0x02,0x82,0x36,0x08,0x40,0x63,0xae,
25700xbc,0x42,0x71,0xa2,0xc1,0x42,0x65,0xa2,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25710x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xfa,0x00,0x42,0x30,
25720x00,0x00,0xe2,0xa2,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25730x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xfd,0x00,0x42,0x30,
25740x00,0x00,0xe2,0xa2,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25750x00,0x00,0x00,0x00,0xf7,0xfc,0xc2,0x14,0xc0,0x02,0x82,0x36,0x80,0x10,0x08,0x00,
25760x21,0x10,0x53,0x00,0x60,0x45,0x43,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
25770x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x80,0x10,0x08,0x00,0x21,0x10,0x48,0x00,
25780x21,0x10,0x53,0x00,0x21,0x10,0x49,0x00,0x34,0x43,0x44,0xa0,0xc0,0x02,0x82,0x36,
25790x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x77,0x56,0x00,0x0c,
25800x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25810x00,0x00,0x00,0x00,0xff,0xff,0x02,0x34,0x8c,0x65,0x62,0xae,0xc0,0x02,0x82,0x36,
25820x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x07,0x0b,0x00,0x0c,
25830x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25840x00,0x00,0x00,0x00,0xf0,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
25850xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
25860x08,0x40,0x62,0x8e,0xff,0x9f,0x03,0x3c,0xff,0xff,0x63,0x34,0x24,0x10,0x43,0x00,
25870x08,0x40,0x62,0xae,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25880x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
25890x00,0x60,0x81,0x40,0x22,0x51,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x40,
25900x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
25910x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x07,0x3c,0x00,0xff,0xe7,0x34,
25920x24,0x10,0x07,0x02,0x02,0x82,0x02,0x00,0xcc,0x02,0x43,0x36,0x00,0x00,0x70,0xac,
25930x21,0x10,0x12,0x02,0x00,0x00,0x51,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0xaf,
25940x00,0x00,0x51,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
25950x00,0x00,0x00,0x00,0xb7,0x4f,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,
25960x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x21,0x88,0x00,0x00,
25970x6c,0x4b,0x00,0x08,0x27,0xb0,0x04,0x3c,0x01,0x00,0x31,0x26,0x00,0x01,0x22,0x2e,
25980x0a,0x00,0x40,0x10,0xff,0x00,0x22,0x2e,0x00,0x00,0x83,0x94,0x00,0x00,0x00,0x00,
25990xff,0xff,0x67,0x30,0xff,0x00,0xe2,0x30,0xf0,0x00,0x42,0x28,0xf6,0xff,0x40,0x14,
26000x08,0x00,0x84,0x24,0x00,0x00,0xc7,0xa7,0xff,0x00,0x22,0x2e,0x91,0xfc,0x40,0x14,
26010xc0,0x02,0x82,0x36,0x12,0x87,0x02,0x3c,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
26020x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xe4,0x63,0x62,0x96,
26030x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xa7,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
26040x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x04,0x64,0x62,0x92,0x00,0x00,0x00,0x00,
26050x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
26060x00,0x00,0x00,0x00,0x00,0xff,0x02,0x32,0x02,0x12,0x02,0x00,0x03,0x00,0x43,0x2c,
26070x02,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x02,0x40,0x62,0xa2,0x02,0x40,0x63,0x92,
26080x90,0x0c,0x42,0x36,0x00,0x00,0x43,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
26090x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xd7,0x56,0x00,0x0c,0x00,0x00,0x00,0x00,
26100xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
26110x21,0x10,0x13,0x01,0x56,0x44,0x44,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
26120x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,0x24,0x20,0x03,0x02,
26130x73,0x0e,0x00,0x0c,0x02,0x24,0x04,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
26140x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x1c,0x10,0x00,0x00,0x1f,0x02,0x32,
26150x02,0x8a,0x02,0x00,0x3f,0x00,0x65,0x30,0xc1,0x42,0x65,0xa2,0xbc,0x42,0x71,0xa2,
26160x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
26170x1f,0x12,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0x00,0x60,0x01,0x40,
26180x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0x03,0x40,0x62,0x92,0x0e,0x0c,0x44,0x36,
26190x01,0x00,0x42,0x24,0xff,0x00,0x43,0x30,0x00,0x00,0x83,0xa0,0x03,0x40,0x62,0xa2,
26200xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
26210x00,0xff,0x02,0x32,0x02,0x3a,0x02,0x00,0x1a,0x01,0xe0,0x10,0x4f,0x00,0x82,0x36,
26220x94,0x00,0x42,0x36,0x00,0x00,0x43,0x94,0xff,0xff,0xe2,0x24,0xb0,0x03,0x45,0x36,
26230xff,0xff,0x71,0x30,0x1b,0x00,0x27,0x02,0x02,0x00,0xe0,0x14,0x00,0x00,0x00,0x00,
26240x0d,0x00,0x07,0x00,0xff,0xff,0x47,0x30,0x00,0x00,0xb1,0xac,0x80,0xff,0x02,0x24,
26250x00,0x19,0x07,0x00,0x25,0x18,0x62,0x00,0x4f,0x00,0x44,0x36,0x9e,0x00,0x46,0x36,
26260x00,0x00,0xa7,0xac,0x00,0x00,0x83,0xa0,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,
26270x12,0x88,0x00,0x00,0x80,0x12,0x11,0x00,0x00,0xfc,0x42,0x24,0x00,0x00,0xb1,0xac,
26280x00,0x00,0xd1,0xa4,0x42,0x89,0x02,0x00,0x26,0xb0,0x02,0x3c,0x7c,0x00,0x42,0x34,
26290x00,0x00,0xb1,0xac,0x00,0x00,0x51,0xa4,0x25,0xb0,0x02,0x3c,0x44,0x00,0x42,0x34,
26300x00,0x00,0x43,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x00,0x83,0xa4,
26310x00,0x00,0x82,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,0x00,0x00,0x82,0xa4,
26320xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
26330x24,0x10,0x08,0x02,0xcc,0x02,0x43,0x36,0x00,0xff,0x04,0x32,0x02,0x3c,0x02,0x00,
26340x00,0x00,0x70,0xac,0x04,0x00,0xe0,0x10,0x02,0x82,0x04,0x00,0x01,0x00,0x02,0x24,
26350x02,0x00,0xe2,0x10,0x01,0x00,0x04,0x24,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x0c,
26360x00,0x00,0x00,0x00,0x0f,0x00,0x06,0x3c,0x21,0x20,0x00,0x02,0xdd,0x44,0x00,0x0c,
26370xff,0xff,0xc5,0x34,0x0f,0x00,0x07,0x3c,0xff,0xff,0xe7,0x34,0x24,0x88,0x47,0x00,
26380xc0,0x02,0x82,0x36,0x00,0x00,0xd1,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
26390x00,0x00,0x00,0x00,0x28,0xb0,0x02,0x3c,0x00,0x00,0x43,0x90,0xff,0x00,0x02,0x24,
26400xff,0x00,0x70,0x30,0xf3,0xfb,0x02,0x12,0xc0,0x02,0x82,0x36,0x28,0xb0,0x05,0x3c,
26410xff,0x00,0x04,0x24,0xc0,0x10,0x10,0x00,0x21,0x10,0x45,0x00,0x00,0x00,0x43,0x90,
26420x00,0x00,0x00,0x00,0xff,0x00,0x70,0x30,0xfb,0xff,0x04,0x16,0xc0,0x10,0x10,0x00,
26430xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
26440x00,0x1f,0x02,0x32,0x02,0x1c,0x10,0x00,0x02,0x8a,0x02,0x00,0x3f,0x00,0x65,0x30,
26450xc0,0x02,0x82,0x36,0xbc,0x42,0x71,0xa2,0xc1,0x42,0x65,0xa2,0x00,0x00,0x40,0xac,
26460x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x07,0x3c,0x24,0x20,0x07,0x02,
26470x15,0x51,0x00,0x0c,0x02,0x24,0x04,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
26480x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xe8,0x63,0x62,0x92,0x00,0x00,0x00,0x00,
26490x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
26500x00,0x00,0x00,0x00,0xfc,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,
26510xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
26520x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,0xff,0x00,0x51,0x30,0x05,0x00,0x23,0x36,
26530xc0,0x02,0x82,0x36,0x00,0x00,0xe3,0xa2,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
26540x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0xe6,0x63,0x60,0xa6,0x00,0x00,0x40,0xac,
26550x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xbd,0x56,0x00,0x0c,0x21,0x20,0x00,0x02,
26560xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
26570x41,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
26580x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe2,0x92,0x00,0x00,0x00,0x00,
26590xff,0x00,0x51,0x30,0x02,0x00,0x23,0x36,0xc0,0x02,0x82,0x36,0x00,0x00,0xe3,0xa2,
26600x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
26610xec,0x91,0x42,0x24,0x00,0x00,0x47,0x8c,0xc0,0x02,0x43,0x36,0x25,0xb0,0x0c,0x3c,
26620x08,0x40,0xe4,0x8c,0x00,0x00,0x60,0xac,0x42,0x17,0x04,0x00,0x03,0x00,0x42,0x30,
26630x60,0x00,0x40,0x14,0x03,0x0d,0x42,0x36,0x00,0x00,0x45,0x90,0x10,0x40,0xe6,0x8c,
26640xff,0x9f,0x03,0x3c,0xff,0xff,0x63,0x34,0xff,0x3f,0x02,0x3c,0x24,0x20,0x83,0x00,
26650xff,0xff,0x42,0x34,0x00,0x20,0x03,0x3c,0x24,0x58,0xc2,0x00,0x25,0x20,0x83,0x00,
26660x00,0x40,0x02,0x3c,0x70,0x00,0xa5,0x30,0x25,0x58,0x62,0x01,0x08,0x01,0xa0,0x10,
26670x08,0x40,0xe4,0xac,0x94,0x0e,0x82,0x35,0x9c,0x0e,0x83,0x35,0xa4,0x0e,0x86,0x35,
26680x00,0x00,0x45,0x8c,0xac,0x0e,0x87,0x35,0x00,0x00,0x68,0x8c,0x00,0x00,0xca,0x8c,
26690x02,0x80,0x06,0x3c,0x00,0x00,0xe4,0x8c,0x68,0x15,0xc6,0x24,0x0c,0x40,0xc3,0x8c,
26700xb4,0x0e,0x82,0x35,0x00,0x00,0x47,0x8c,0xff,0x03,0x02,0x3c,0x00,0xfc,0x06,0x24,
26710x24,0x28,0xa2,0x00,0x24,0x20,0x82,0x00,0xbc,0x0e,0x82,0x35,0x00,0x00,0x49,0x8c,
26720x02,0x2c,0x05,0x00,0x24,0x10,0x66,0x01,0x24,0x18,0x66,0x00,0x02,0x24,0x04,0x00,
26730xc4,0x0e,0x86,0x35,0x25,0x18,0x65,0x00,0x25,0x10,0x44,0x00,0x00,0x00,0xc5,0x8c,
26740xff,0x03,0x04,0x3c,0xf0,0xff,0x06,0x3c,0xff,0x03,0xc6,0x34,0x24,0x38,0xe4,0x00,
26750xcc,0x0e,0x8b,0x35,0x24,0x40,0x04,0x01,0x82,0x39,0x07,0x00,0x00,0x00,0x64,0x8d,
26760x24,0x10,0x46,0x00,0x24,0x18,0x66,0x00,0x25,0x10,0x47,0x00,0x82,0x41,0x08,0x00,
26770xff,0x03,0x07,0x3c,0x0f,0xc0,0x06,0x3c,0x24,0x50,0x47,0x01,0x24,0x48,0x27,0x01,
26780xff,0xff,0xc6,0x34,0x25,0x18,0x68,0x00,0x24,0x28,0xa7,0x00,0x24,0x20,0x87,0x00,
26790x00,0x51,0x0a,0x00,0x24,0x18,0x66,0x00,0x00,0x49,0x09,0x00,0x24,0x10,0x46,0x00,
26800x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24,0x25,0x18,0x6a,0x00,0x25,0x10,0x49,0x00,
26810x02,0x2c,0x05,0x00,0x02,0x24,0x04,0x00,0x0c,0x40,0xe3,0xac,0x10,0x40,0xe2,0xac,
26820x14,0x40,0xe5,0xa4,0x16,0x40,0xe4,0xa4,0x02,0x80,0x02,0x3c,0x68,0x15,0x43,0x24,
26830x0c,0x40,0x62,0x8c,0x00,0x00,0x00,0x00,0xbd,0x00,0x40,0x04,0x00,0x00,0x00,0x00,
26840x00,0xff,0x02,0x32,0xc6,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,
26850xc3,0x42,0x62,0xa0,0x7a,0x54,0x00,0x0c,0x10,0x00,0xa4,0x27,0xc2,0x53,0x00,0x0c,
26860x00,0x00,0x00,0x00,0x0c,0x40,0x62,0x8e,0x00,0x80,0x03,0x3c,0x25,0x10,0x43,0x00,
26870x0c,0x40,0x62,0xae,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,0x61,0x0c,0x63,0x34,
26880x00,0x00,0x62,0xa0,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
26890x00,0x00,0x00,0x00,0xcf,0x4e,0x00,0x0c,0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36,
26900x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x17,0x51,0x00,0x0c,
26910x00,0x00,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
26920x00,0x00,0x00,0x00,0x9e,0x00,0x83,0x36,0x00,0x00,0x40,0xa0,0x00,0x00,0x60,0xa4,
26930x94,0x00,0x82,0x36,0x00,0x00,0x43,0x94,0x25,0xb0,0x06,0x3c,0x44,0x00,0xc6,0x34,
26940xff,0xff,0x71,0x30,0x80,0x12,0x11,0x00,0x00,0xf8,0x42,0x24,0x42,0x89,0x02,0x00,
26950x26,0xb0,0x02,0x3c,0xb0,0x03,0x83,0x36,0x7c,0x00,0x42,0x34,0x00,0x00,0x71,0xac,
26960x00,0x00,0x51,0xa4,0x00,0x00,0xc3,0x94,0xff,0xfd,0x02,0x24,0x24,0x18,0x62,0x00,
26970x00,0x00,0xc3,0xa4,0x00,0x00,0xc2,0x94,0x00,0x00,0x00,0x00,0x00,0x02,0x42,0x34,
26980x00,0x00,0xc2,0xa4,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
26990x00,0x00,0x00,0x00,0x5b,0x4e,0x00,0x0c,0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,
27000x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x80,0x10,0x08,0x00,
27010x21,0x10,0x53,0x00,0xec,0x44,0x43,0xac,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
27020x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xa7,0x0b,0x00,0x0c,0x00,0x00,0x00,0x00,
27030xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
27040x28,0xb0,0x11,0x3c,0x00,0x00,0x22,0x96,0xff,0x00,0x04,0x3c,0x24,0x18,0x04,0x02,
27050x02,0x24,0x03,0x00,0xff,0x00,0x42,0x30,0x0a,0x00,0x82,0x10,0xff,0x7f,0x02,0x3c,
27060x08,0x00,0x31,0x26,0x00,0x00,0x22,0x96,0xff,0xff,0x23,0x32,0xff,0x00,0x42,0x30,
27070x03,0x00,0x82,0x10,0x00,0x08,0x63,0x2c,0xf9,0xff,0x60,0x14,0x00,0x00,0x00,0x00,
27080xff,0x7f,0x02,0x3c,0xff,0xff,0x42,0x34,0x24,0x10,0x22,0x02,0x00,0x00,0xc2,0xaf,
27090xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
27100xf8,0x63,0x62,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
27110x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xff,0x00,0x03,0x3c,
27120x24,0x10,0x03,0x02,0x00,0xff,0x04,0x32,0xcc,0x02,0x83,0x36,0x02,0x3c,0x02,0x00,
27130x00,0x00,0x70,0xac,0x04,0x00,0xe0,0x10,0x02,0x82,0x04,0x00,0x01,0x00,0x02,0x24,
27140x02,0x00,0xe2,0x10,0x01,0x00,0x04,0x24,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x0c,
27150x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x8f,0x0f,0x00,0x06,0x3c,0xff,0xff,0xc5,0x34,
27160x21,0x20,0x00,0x02,0xba,0x44,0x00,0x0c,0x21,0x30,0x20,0x02,0x0f,0x00,0x07,0x3c,
27170x21,0x20,0x00,0x02,0xdd,0x44,0x00,0x0c,0xff,0xff,0xe5,0x34,0x00,0x00,0xc2,0xaf,
27180x21,0x88,0x40,0x00,0x25,0xb0,0x02,0x3c,0xc8,0x02,0x42,0x34,0x00,0x00,0x51,0xac,
27190xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
27200x25,0xb0,0x06,0x3c,0xff,0x00,0x02,0x24,0x56,0x01,0xc6,0x34,0x00,0x00,0xc2,0xa4,
27210x01,0x00,0x03,0x24,0x02,0x80,0x07,0x3c,0xc0,0x02,0x82,0x36,0xb8,0x7d,0xe3,0xa0,
27220x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,
27230x03,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27240x00,0x00,0x00,0x00,0xde,0x4e,0x00,0x0c,0x21,0x20,0x00,0x02,0xc0,0x02,0x82,0x36,
27250x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x40,0x62,0x8e,
27260xff,0x9f,0x04,0x3c,0xff,0xff,0x84,0x34,0x24,0x10,0x44,0x00,0x08,0x40,0x62,0xae,
27270xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
27280xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
27290x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,0x70,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,
27300x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
27310x7a,0x54,0x00,0x0c,0x10,0x00,0xa4,0x27,0xc3,0x42,0x62,0x92,0x25,0xb0,0x03,0x3c,
27320x61,0x0c,0x63,0x34,0x00,0x00,0x62,0xa0,0xd4,0x4c,0x00,0x08,0xc0,0x02,0x82,0x36,
27330x22,0x51,0x00,0x0c,0x10,0x40,0xeb,0xac,0xbd,0x4c,0x00,0x08,0x02,0x80,0x02,0x3c,
27340xc6,0x4c,0x00,0x08,0x12,0x00,0x02,0x24,0x1a,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,
27350xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
27360xff,0xff,0x02,0x34,0x8c,0x65,0x62,0xae,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,
27370x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,
27380x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,
27390x74,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac,
27400x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,
27410x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x53,0x00,
27420xd4,0x51,0x43,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc3,0xaf,0x00,0x00,0x40,0xac,
27430x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,
27440x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,0x80,0x10,0x02,0x00,
27450xe0,0x66,0xc3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,
27460x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,
27470x12,0x00,0x02,0x24,0xc7,0x42,0xa2,0xa1,0x77,0x4a,0x00,0x08,0xc3,0x42,0xa2,0xa1,
27480x88,0x7d,0x82,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0xaf,0xc0,0x02,0x82,0x36,
27490x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c,
27500x21,0x20,0x00,0x00,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27510x00,0x00,0x00,0x00,0xff,0x00,0x06,0x3c,0x00,0xff,0xc6,0x34,0x00,0x00,0xc5,0x8f,
27520x24,0x20,0x06,0x02,0xe1,0x50,0x00,0x0c,0x02,0x22,0x04,0x00,0xc0,0x02,0x82,0x36,
27530x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
27540x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,
27550x80,0x10,0x02,0x00,0xf0,0x66,0xe3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
27560xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27570x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
27580x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,0x80,0x10,0x02,0x00,0xec,0x66,0xc3,0x24,
27590x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
27600x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
27610x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c,
27620xe8,0x66,0x83,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
27630xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27640x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
27650x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,0x80,0x10,0x02,0x00,0xe4,0x66,0xe3,0x24,
27660x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
27670x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
27680x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c,
27690x00,0x67,0x83,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
27700xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27710x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
27720x21,0x10,0x43,0x00,0x02,0x80,0x07,0x3c,0x80,0x10,0x02,0x00,0xfc,0x66,0xe3,0x24,
27730x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
27740x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,
27750x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,0x02,0x80,0x06,0x3c,
27760x80,0x10,0x02,0x00,0xf8,0x66,0xc3,0x24,0x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,
27770xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27780x00,0x00,0x00,0x00,0xc0,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x80,0x10,0x02,0x00,
27790x21,0x10,0x43,0x00,0x02,0x80,0x04,0x3c,0xf4,0x66,0x83,0x24,0x80,0x10,0x02,0x00,
27800x21,0x10,0x43,0x00,0x00,0x00,0x44,0x8c,0xc0,0x02,0x82,0x36,0x00,0x00,0xc4,0xaf,
27810x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,
27820x02,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27830x00,0x00,0x00,0x00,0xde,0x4f,0x00,0x0c,0x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,
27840x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c,
27850x01,0x00,0x04,0x24,0xc0,0x02,0x82,0x36,0x00,0x00,0x40,0xac,0x08,0x48,0x00,0x08,
27860x00,0x00,0x00,0x00,0x25,0xb0,0x05,0x3c,0x01,0x00,0x06,0x24,0x01,0x80,0x02,0x3c,
27870x04,0x30,0x86,0x00,0xf1,0x02,0xa7,0x34,0xed,0x02,0xa4,0x34,0x6c,0x39,0x42,0x24,
27880x18,0x03,0xa5,0x34,0x08,0x00,0x03,0x24,0x00,0x00,0xa2,0xac,0x00,0x00,0xe3,0xa0,
27890x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,
27900x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,0x00,0x00,0x80,0xa0,0x00,0x00,0x86,0xa0,
27910x00,0x00,0x80,0xa0,0x00,0x00,0xe0,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
27920x01,0x80,0x02,0x3c,0x25,0xb0,0x03,0x3c,0xc8,0x39,0x42,0x24,0x18,0x03,0x63,0x34,
27930x00,0x00,0x62,0xac,0x00,0x00,0x83,0x90,0x30,0x00,0x02,0x24,0x05,0x00,0x62,0x10,
27940x21,0x20,0x00,0x00,0x31,0x00,0x02,0x24,0x02,0x00,0x62,0x10,0x01,0x00,0x04,0x24,
27950x07,0x00,0x04,0x24,0x5b,0x4e,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x80,0x02,0x3c,
27960x25,0xb0,0x03,0x3c,0x04,0x3a,0x42,0x24,0x18,0x03,0x63,0x34,0x02,0x80,0x04,0x3c,
27970x00,0x00,0x62,0xac,0x08,0x00,0xe0,0x03,0xc4,0x7d,0x80,0xac,0x02,0x80,0x02,0x3c,
27980x08,0x7b,0x42,0x24,0xc0,0x20,0x04,0x00,0x21,0x20,0x82,0x00,0x21,0x28,0x00,0x00,
27990x00,0x60,0x06,0x40,0x01,0x00,0xc1,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,
28000x00,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x09,0x00,0x44,0x10,0x00,0x00,0x00,0x00,
28010x04,0x00,0x43,0x8c,0x21,0x28,0x40,0x00,0x00,0x00,0x42,0x8c,0x00,0x00,0x00,0x00,
28020x00,0x00,0x62,0xac,0x04,0x00,0x43,0xac,0x00,0x00,0xa5,0xac,0x04,0x00,0xa5,0xac,
28030x00,0x60,0x86,0x40,0x08,0x00,0xe0,0x03,0x21,0x10,0xa0,0x00,0x21,0x18,0x80,0x00,
28040xe8,0xff,0xbd,0x27,0x01,0x01,0x62,0x2c,0x10,0x00,0xbf,0xaf,0x01,0x00,0x04,0x24,
28050x01,0x02,0x65,0x2c,0x0a,0x00,0x40,0x14,0x21,0x30,0x00,0x00,0x02,0x00,0x04,0x24,
28060x07,0x00,0xa0,0x14,0x01,0x08,0x62,0x2c,0x05,0x00,0x40,0x14,0x03,0x00,0x04,0x24,
28070x10,0x00,0xbf,0x8f,0x21,0x10,0xc0,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,
28080x89,0x4e,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f,0x21,0x30,0x40,0x00,
28090x21,0x10,0xc0,0x00,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x02,0x80,0x03,0x3c,
28100x20,0x7b,0x62,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x00,0x60,0x06,0x40,
28110x01,0x00,0xc1,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x10,0x00,0x83,0x8c,
28120x02,0x80,0x02,0x3c,0x08,0x7b,0x42,0x24,0xc0,0x18,0x03,0x00,0x21,0x18,0x62,0x00,
28130x00,0x00,0x65,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x85,0xac,0x04,0x00,0xa4,0xac,
28140x00,0x00,0x64,0xac,0x04,0x00,0x83,0xac,0x00,0x60,0x86,0x40,0x08,0x00,0xe0,0x03,
28150x00,0x00,0x00,0x00,0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x18,0x04,0x00,
28160x21,0x18,0x64,0x00,0x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,
28170x68,0x15,0x42,0x24,0x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x78,0x51,0x64,0x8c,
28180xff,0xf1,0x02,0x24,0x24,0x20,0x82,0x00,0x08,0x00,0xe0,0x03,0x78,0x51,0x64,0xac,
28190x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x18,0x04,0x00,0x21,0x18,0x64,0x00,
28200x80,0x18,0x03,0x00,0x21,0x18,0x64,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,
28210x80,0x18,0x03,0x00,0x21,0x18,0x62,0x00,0x78,0x51,0x64,0x8c,0xff,0xf1,0x02,0x24,
28220x24,0x20,0x82,0x00,0x00,0x02,0x84,0x34,0x08,0x00,0xe0,0x03,0x78,0x51,0x64,0xac,
28230xe0,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0xc0,0x80,0x04,0x00,0x21,0x80,0x04,0x02,
28240x80,0x80,0x10,0x00,0x21,0x80,0x04,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,
28250x80,0x80,0x10,0x00,0x21,0x80,0x02,0x02,0x1c,0x00,0xbf,0xaf,0x18,0x00,0xb2,0xaf,
28260x14,0x00,0xb1,0xaf,0x78,0x51,0x05,0x8e,0xff,0x1f,0x02,0x3c,0x25,0xb0,0x12,0x3c,
28270xff,0xff,0x42,0x34,0x70,0x51,0x02,0xae,0x84,0x01,0x43,0x36,0xf8,0xff,0x02,0x24,
28280x00,0x00,0x66,0x8c,0x24,0x28,0xa2,0x00,0xff,0xfe,0x02,0x24,0x24,0x28,0xa2,0x00,
28290xff,0xef,0x03,0x24,0x24,0x28,0xa3,0x00,0x74,0x51,0x06,0xae,0x78,0x51,0x05,0xae,
28300xce,0x0d,0x00,0x0c,0x21,0x88,0x80,0x00,0x7a,0x51,0x02,0x92,0x21,0x88,0x32,0x02,
28310x1c,0x00,0xbf,0x8f,0x60,0x01,0x22,0xa2,0x18,0x00,0xb2,0x8f,0x64,0x51,0x00,0xae,
28320x48,0x51,0x00,0xae,0x4c,0x51,0x00,0xae,0x50,0x51,0x00,0xae,0x54,0x51,0x00,0xae,
28330x58,0x51,0x00,0xae,0x5c,0x51,0x00,0xae,0x60,0x51,0x00,0xae,0x14,0x00,0xb1,0x8f,
28340x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xff,0x00,0xa5,0x30,
28350xc0,0x10,0x05,0x00,0x21,0x10,0x45,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x45,0x00,
28360x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
28370x78,0x51,0x43,0x8c,0x25,0xb0,0x05,0x3c,0xff,0x00,0xc6,0x30,0x21,0x30,0xc5,0x00,
28380xaf,0x01,0xc2,0x90,0x07,0x00,0x63,0x30,0x80,0x18,0x03,0x00,0x21,0x18,0x65,0x00,
28390xff,0x00,0x88,0x30,0xff,0x00,0x49,0x30,0x84,0x01,0x66,0x8c,0x21,0x50,0x00,0x00,
28400x21,0x58,0x00,0x00,0x2b,0x00,0x20,0x11,0x21,0x20,0x00,0x01,0x2b,0x00,0xc0,0x10,
28410x2b,0x10,0x09,0x01,0x21,0x28,0x00,0x00,0x3e,0x4f,0x00,0x08,0x01,0x00,0x07,0x24,
28420xff,0x00,0x65,0x30,0x1d,0x00,0xa2,0x2c,0x07,0x00,0x40,0x10,0xff,0xff,0x02,0x25,
28430x04,0x10,0xa7,0x00,0x24,0x10,0x46,0x00,0xf9,0xff,0x40,0x10,0x01,0x00,0xa3,0x24,
28440x21,0x58,0xa0,0x00,0xff,0xff,0x02,0x25,0xff,0x00,0x45,0x30,0x2b,0x18,0xab,0x00,
28450x0f,0x00,0x60,0x14,0x2b,0x10,0x49,0x01,0x01,0x00,0x04,0x24,0x04,0x10,0xa4,0x00,
28460x24,0x10,0x46,0x00,0xff,0xff,0xa7,0x24,0x04,0x00,0x40,0x10,0x01,0x00,0x43,0x25,
28470x17,0x00,0x49,0x11,0xff,0x00,0x6a,0x30,0x21,0x40,0xa0,0x00,0xff,0x00,0xe5,0x30,
28480x2b,0x10,0xab,0x00,0xf6,0xff,0x40,0x10,0x04,0x10,0xa4,0x00,0x2b,0x10,0x49,0x01,
28490x08,0x00,0x40,0x10,0x21,0x20,0x00,0x01,0x23,0x10,0x2a,0x01,0x2a,0x10,0x62,0x01,
28500x04,0x00,0x40,0x14,0x21,0x20,0x00,0x00,0x23,0x10,0x69,0x01,0x21,0x10,0x4a,0x00,
28510xff,0x00,0x44,0x30,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0xfd,0xff,0x40,0x14,
28520x21,0x20,0x00,0x00,0x23,0x10,0x09,0x01,0x5f,0x4f,0x00,0x08,0xff,0x00,0x44,0x30,
28530x21,0x20,0x00,0x01,0x08,0x00,0xe0,0x03,0x21,0x10,0x80,0x00,0xff,0x00,0x84,0x30,
28540xc0,0x10,0x04,0x00,0x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,
28550x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0x80,0x10,0x02,0x00,0x21,0x10,0x43,0x00,
28560x25,0xb0,0x06,0x3c,0x78,0x51,0x43,0x8c,0xff,0x00,0xa5,0x30,0x21,0x20,0x86,0x00,
28570x21,0x28,0xa6,0x00,0x60,0x01,0x82,0x90,0xaf,0x01,0xa4,0x90,0x07,0x00,0x63,0x30,
28580x80,0x18,0x03,0x00,0x21,0x18,0x66,0x00,0xff,0x00,0x48,0x30,0xff,0x00,0x89,0x30,
28590x84,0x01,0x66,0x8c,0x21,0x50,0x00,0x00,0x21,0x58,0x00,0x00,0x2b,0x00,0x20,0x11,
28600x21,0x20,0x00,0x01,0x2b,0x00,0xc0,0x10,0x2b,0x10,0x09,0x01,0x21,0x28,0x00,0x00,
28610x8c,0x4f,0x00,0x08,0x01,0x00,0x07,0x24,0xff,0x00,0x65,0x30,0x1d,0x00,0xa2,0x2c,
28620x07,0x00,0x40,0x10,0xff,0xff,0x02,0x25,0x04,0x10,0xa7,0x00,0x24,0x10,0x46,0x00,
28630xf9,0xff,0x40,0x10,0x01,0x00,0xa3,0x24,0x21,0x58,0xa0,0x00,0xff,0xff,0x02,0x25,
28640xff,0x00,0x45,0x30,0x2b,0x18,0xab,0x00,0x0f,0x00,0x60,0x14,0x2b,0x10,0x49,0x01,
28650x01,0x00,0x04,0x24,0x04,0x10,0xa4,0x00,0x24,0x10,0x46,0x00,0xff,0xff,0xa7,0x24,
28660x04,0x00,0x40,0x10,0x01,0x00,0x43,0x25,0x17,0x00,0x49,0x11,0xff,0x00,0x6a,0x30,
28670x21,0x40,0xa0,0x00,0xff,0x00,0xe5,0x30,0x2b,0x10,0xab,0x00,0xf6,0xff,0x40,0x10,
28680x04,0x10,0xa4,0x00,0x2b,0x10,0x49,0x01,0x08,0x00,0x40,0x10,0x21,0x20,0x00,0x01,
28690x23,0x10,0x2a,0x01,0x2a,0x10,0x62,0x01,0x04,0x00,0x40,0x14,0x21,0x20,0x00,0x00,
28700x23,0x10,0x69,0x01,0x21,0x10,0x4a,0x00,0xff,0x00,0x44,0x30,0x08,0x00,0xe0,0x03,
28710x21,0x10,0x80,0x00,0xfd,0xff,0x40,0x14,0x21,0x20,0x00,0x00,0x23,0x10,0x09,0x01,
28720xad,0x4f,0x00,0x08,0xff,0x00,0x44,0x30,0x21,0x20,0x00,0x01,0x08,0x00,0xe0,0x03,
28730x21,0x10,0x80,0x00,0xe0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x10,0x00,0xb0,0xaf,
28740x68,0x15,0x50,0x24,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x1c,0x00,0xbf,0xaf,
28750x21,0x88,0x00,0x00,0x21,0x90,0x00,0x02,0xee,0x4e,0x00,0x0c,0x21,0x20,0x20,0x02,
28760x7a,0x51,0x02,0x92,0x21,0x28,0x00,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x52,0x00,
28770xec,0x44,0x44,0x8c,0x60,0x45,0x43,0x8c,0x00,0x00,0x00,0x00,0x21,0x18,0x64,0x00,
28780x42,0x18,0x03,0x00,0x44,0x51,0x03,0xae,0x21,0x10,0x05,0x02,0x01,0x00,0xa5,0x24,
28790x1d,0x00,0xa3,0x28,0xb6,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14,
28800x99,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x00,0xae,
28810xe9,0xff,0x40,0x14,0x94,0x00,0x10,0x26,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,
28820x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
28830xc8,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x30,0x00,0xbe,0xaf,0x28,0x00,0xb6,0xaf,
28840x68,0x15,0x46,0x24,0x34,0x00,0xbf,0xaf,0x2c,0x00,0xb7,0xaf,0x24,0x00,0xb5,0xaf,
28850x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,0x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,
28860x10,0x00,0xb0,0xaf,0x8c,0x65,0xc2,0x8c,0xff,0x00,0x8d,0x30,0xff,0x00,0x03,0x24,
28870xff,0xff,0x42,0x38,0x21,0xf0,0x00,0x00,0xff,0xff,0x04,0x34,0x0a,0xf0,0x62,0x00,
28880x8c,0x65,0xc4,0xac,0xb0,0x00,0xa0,0x11,0x08,0x00,0x16,0x24,0x02,0x80,0x02,0x3c,
28890xb8,0x90,0x45,0x24,0x90,0x44,0xc4,0x24,0xff,0x4f,0x00,0x08,0x21,0x88,0x00,0x00,
28900x01,0x00,0x31,0x26,0x00,0x00,0x82,0xa0,0x1d,0x00,0x22,0x2a,0x0b,0x00,0x40,0x10,
28910x01,0x00,0x84,0x24,0x21,0x10,0x25,0x02,0x00,0x00,0x42,0x90,0x00,0x00,0x00,0x00,
28920xf7,0xff,0x40,0x10,0xfd,0xff,0x43,0x24,0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,
28930x00,0x00,0x83,0xa0,0xf7,0xff,0x40,0x14,0x01,0x00,0x84,0x24,0x02,0x80,0x02,0x3c,
28940x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x50,0x8e,0x6c,0x24,
28950xd8,0x8d,0x4b,0x24,0x21,0x88,0x00,0x00,0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00,
28960x21,0x40,0x2a,0x01,0x21,0x38,0x2c,0x01,0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90,
28970x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28,
28980xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,0x34,0x43,0x65,0xa0,0x21,0x10,0x2b,0x02,
28990x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26,
29000x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14,
29010x05,0x00,0x29,0x25,0xa6,0x00,0xa0,0x11,0x02,0x80,0x02,0x3c,0x68,0x15,0x48,0x24,
29020x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x4c,0x91,0x69,0x24,0xd8,0x90,0x47,0x24,
29030x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x10,0x69,0x00,0x21,0x20,0x67,0x00,
29040x00,0x00,0x46,0x8c,0x00,0x00,0x85,0x8c,0x01,0x00,0x31,0x26,0x21,0x18,0x68,0x00,
29050x04,0x00,0x22,0x2a,0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,0x60,0x45,0x66,0xac,
29060x02,0x80,0x02,0x3c,0x68,0x15,0x49,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,
29070x4c,0x91,0x68,0x24,0xd8,0x90,0x47,0x24,0x04,0x00,0x11,0x24,0x80,0x20,0x11,0x00,
29080x21,0x10,0x88,0x00,0x21,0x30,0x87,0x00,0x00,0x00,0x45,0x8c,0x00,0x00,0xc3,0x8c,
29090x01,0x00,0x31,0x26,0x21,0x20,0x89,0x00,0x82,0x28,0x05,0x00,0x82,0x18,0x03,0x00,
29100x1d,0x00,0x22,0x2a,0xec,0x44,0x83,0xac,0xf4,0xff,0x40,0x14,0x60,0x45,0x85,0xac,
29110x02,0x80,0x02,0x3c,0x68,0x15,0x55,0x24,0x21,0x88,0x00,0x00,0x21,0xb8,0xa0,0x02,
29120x21,0xa0,0x00,0x00,0x5a,0x50,0x00,0x08,0x21,0x90,0xa0,0x02,0x01,0x00,0x31,0x26,
29130x20,0x00,0x22,0x2a,0x94,0x00,0x52,0x26,0x38,0x00,0x40,0x10,0x94,0x00,0x94,0x26,
29140x78,0x51,0x44,0x8e,0x01,0x00,0x03,0x24,0x02,0x13,0x04,0x00,0x01,0x00,0x53,0x30,
29150xf6,0xff,0x63,0x16,0x07,0x00,0x82,0x30,0x25,0xb0,0x03,0x3c,0x80,0x10,0x02,0x00,
29160x21,0x10,0x43,0x00,0x84,0x01,0x45,0x8c,0x70,0x51,0x43,0x8e,0x21,0x20,0x20,0x02,
29170x24,0x28,0xa3,0x00,0xce,0x0d,0x00,0x0c,0x74,0x51,0x45,0xae,0x7a,0x51,0x44,0x92,
29180x5c,0x0d,0x00,0x0c,0xff,0x00,0x25,0x32,0x7a,0x51,0x50,0x92,0x00,0x00,0x00,0x00,
29190x21,0x20,0x00,0x02,0x63,0x0d,0x00,0x0c,0x80,0x80,0x10,0x00,0x21,0x80,0x17,0x02,
29200x48,0x51,0x40,0xae,0x4c,0x51,0x40,0xae,0x50,0x51,0x40,0xae,0x54,0x51,0x40,0xae,
29210x58,0x51,0x40,0xae,0x5c,0x51,0x40,0xae,0x60,0x51,0x40,0xae,0x64,0x51,0x40,0xae,
29220xec,0x44,0x04,0x8e,0x60,0x45,0x03,0x8e,0x26,0x10,0x53,0x00,0x21,0x30,0x00,0x00,
29230x21,0x18,0x64,0x00,0x42,0x18,0x03,0x00,0x04,0x00,0x04,0x24,0x0a,0xb0,0x82,0x00,
29240x44,0x51,0x43,0xae,0x21,0x20,0x95,0x02,0x21,0x10,0x86,0x00,0x01,0x00,0xc6,0x24,
29250x1d,0x00,0xc3,0x28,0xb6,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14,
29260x99,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x80,0xac,
29270x94,0x00,0x52,0x26,0xca,0xff,0x40,0x14,0x94,0x00,0x94,0x26,0x25,0xb0,0x02,0x3c,
29280x80,0x01,0x42,0x34,0x00,0x00,0x56,0xa0,0x03,0x00,0xc0,0x17,0x02,0x80,0x03,0x3c,
29290x68,0x15,0x62,0x24,0x8c,0x65,0x40,0xac,0x34,0x00,0xbf,0x8f,0x30,0x00,0xbe,0x8f,
29300x2c,0x00,0xb7,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,
29310x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
29320x08,0x00,0xe0,0x03,0x38,0x00,0xbd,0x27,0x02,0x80,0x02,0x3c,0xb8,0x90,0x45,0x24,
29330x90,0x44,0xc4,0x24,0x21,0x88,0x00,0x00,0x21,0x10,0x25,0x02,0x00,0x00,0x43,0x90,
29340x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,0x00,0x00,0x83,0xa0,0xfa,0xff,0x40,0x14,
29350x01,0x00,0x84,0x24,0x02,0x80,0x02,0x3c,0x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,
29360x02,0x80,0x02,0x3c,0x74,0x8f,0x6c,0x24,0x14,0x8e,0x4b,0x24,0x21,0x88,0x00,0x00,
29370x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00,0x21,0x40,0x2a,0x01,0x21,0x38,0x2c,0x01,
29380x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,
29390x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28,0xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,
29400x34,0x43,0x65,0xa0,0x21,0x10,0x2b,0x02,0x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,
29410x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26,0x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,
29420x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14,0x05,0x00,0x29,0x25,0x02,0x80,0x02,0x3c,
29430x68,0x15,0x49,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x4c,0x91,0x68,0x24,
29440xd8,0x90,0x47,0x24,0x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x10,0x68,0x00,
29450x21,0x20,0x67,0x00,0x00,0x00,0x46,0x8c,0x00,0x00,0x85,0x8c,0x01,0x00,0x31,0x26,
29460x21,0x18,0x69,0x00,0x1d,0x00,0x22,0x2a,0xec,0x44,0x65,0xac,0xf6,0xff,0x40,0x14,
29470x60,0x45,0x66,0xac,0x4f,0x50,0x00,0x08,0x02,0x80,0x02,0x3c,0xd8,0xff,0xbd,0x27,
29480xff,0xff,0x84,0x30,0x18,0x00,0xb2,0xaf,0xf0,0x01,0x92,0x30,0x02,0x91,0x12,0x00,
29490x14,0x00,0xb1,0xaf,0xc0,0x88,0x12,0x00,0x21,0x88,0x32,0x02,0x80,0x88,0x11,0x00,
29500x21,0x88,0x32,0x02,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x80,0x88,0x11,0x00,
29510x21,0x88,0x22,0x02,0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb3,0xaf,0x10,0x00,0xb0,0xaf,
29520x78,0x51,0x30,0x8e,0x00,0x02,0x82,0x30,0xff,0xfe,0x03,0x24,0x2b,0x10,0x02,0x00,
29530x00,0x10,0x10,0x36,0x24,0x80,0x03,0x02,0x00,0x12,0x02,0x00,0x25,0x80,0x02,0x02,
29540x70,0x51,0x25,0xae,0x78,0x51,0x30,0xae,0xa0,0x0e,0x00,0x0c,0x21,0x98,0xa0,0x00,
29550xf8,0xff,0x03,0x24,0x24,0x80,0x03,0x02,0x07,0x00,0x42,0x30,0x25,0x80,0x02,0x02,
29560x07,0x00,0x03,0x32,0x25,0xb0,0x02,0x3c,0x80,0x18,0x03,0x00,0x78,0x51,0x30,0xae,
29570x21,0x18,0x62,0x00,0x84,0x01,0x62,0x8c,0x21,0x20,0x40,0x02,0x24,0x10,0x53,0x00,
29580xce,0x0d,0x00,0x0c,0x74,0x51,0x22,0xae,0x7a,0x51,0x24,0x92,0x21,0x28,0x40,0x02,
29590x20,0x00,0xbf,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
29600x10,0x00,0xb0,0x8f,0x5c,0x0d,0x00,0x08,0x28,0x00,0xbd,0x27,0xee,0x4e,0x00,0x08,
29610xff,0x00,0x84,0x30,0x02,0x80,0x02,0x3c,0x68,0x15,0x43,0x24,0x1f,0x00,0x04,0x24,
29620x78,0x51,0x62,0x8c,0xff,0xff,0x84,0x24,0x00,0x10,0x42,0x34,0x78,0x51,0x62,0xac,
29630xfb,0xff,0x81,0x04,0x94,0x00,0x63,0x24,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
29640x78,0xff,0xbd,0x27,0x60,0x00,0xb0,0xaf,0x25,0xb0,0x10,0x3c,0x70,0x00,0xb4,0xaf,
29650xc4,0x02,0x14,0x36,0x00,0x00,0x80,0xae,0x74,0x00,0xb5,0xaf,0x6c,0x00,0xb3,0xaf,
29660x68,0x00,0xb2,0xaf,0x64,0x00,0xb1,0xaf,0x84,0x00,0xbf,0xaf,0x80,0x00,0xbe,0xaf,
29670x7c,0x00,0xb7,0xaf,0x78,0x00,0xb6,0xaf,0x04,0x00,0x02,0x36,0x04,0x0c,0x13,0x36,
29680x00,0x00,0x43,0x8c,0x00,0x00,0x62,0x8e,0x0f,0x00,0x11,0x3c,0x24,0x18,0x71,0x00,
29690x08,0x0c,0x12,0x36,0x4c,0x00,0xa2,0xaf,0x02,0xac,0x03,0x00,0x00,0x00,0x43,0x8e,
29700x00,0x00,0x00,0x00,0x50,0x00,0xa3,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
29710x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c,
29720xff,0xff,0x25,0x36,0x10,0x00,0xa2,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
29730x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,
29740x01,0x00,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
29750x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,
29760x14,0x00,0xa2,0xaf,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
29770xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,
29780xe0,0x0e,0x05,0x36,0x00,0x00,0xad,0x8c,0xdc,0x0e,0x06,0x36,0x70,0x0e,0x07,0x36,
29790x18,0x00,0xad,0xaf,0x00,0x00,0xc2,0x8c,0x74,0x0e,0x08,0x36,0x78,0x0e,0x09,0x36,
29800x1c,0x00,0xa2,0xaf,0x00,0x00,0xe3,0x8c,0x7c,0x0e,0x0a,0x36,0x80,0x0e,0x0b,0x36,
29810x20,0x00,0xa3,0xaf,0x00,0x00,0x0d,0x8d,0x84,0x0e,0x0c,0x36,0x88,0x0e,0x17,0x36,
29820x24,0x00,0xad,0xaf,0x00,0x00,0x22,0x8d,0x8c,0x0e,0x0e,0x36,0xd0,0x0e,0x18,0x36,
29830x28,0x00,0xa2,0xaf,0x00,0x00,0x43,0x8d,0xd8,0x0e,0x11,0x36,0xd4,0x0e,0x10,0x36,
29840x2c,0x00,0xa3,0xaf,0x00,0x00,0x6d,0x8d,0xed,0x3f,0x04,0x3c,0xfb,0x92,0x84,0x34,
29850x30,0x00,0xad,0xaf,0x00,0x00,0x82,0x8d,0x25,0xb0,0x1e,0x3c,0x21,0xb0,0x00,0x00,
29860x34,0x00,0xa2,0xaf,0x00,0x00,0xe3,0x8e,0xff,0x03,0x0f,0x3c,0x38,0x00,0xa3,0xaf,
29870x00,0x00,0xcd,0x8d,0x00,0x00,0x00,0x00,0x3c,0x00,0xad,0xaf,0x00,0x00,0x02,0x8f,
29880x00,0x00,0x00,0x00,0x40,0x00,0xa2,0xaf,0x00,0x00,0x03,0x8e,0x00,0x00,0x00,0x00,
29890x44,0x00,0xa3,0xaf,0x00,0x00,0x2d,0x8e,0x00,0x00,0x00,0x00,0x48,0x00,0xad,0xaf,
29900x00,0x00,0xa4,0xac,0x00,0x00,0xc4,0xac,0x00,0x00,0xe4,0xac,0x00,0x00,0x04,0xad,
29910x00,0x00,0x24,0xad,0x00,0x00,0x44,0xad,0x00,0x00,0x64,0xad,0x00,0x00,0x84,0xad,
29920x00,0x00,0xe4,0xae,0x00,0x00,0xc4,0xad,0x00,0x00,0x04,0xaf,0x00,0x00,0x04,0xae,
29930x00,0x00,0x24,0xae,0xd0,0x51,0x00,0x08,0x00,0x00,0x00,0x00,0x7a,0x00,0xa2,0x12,
29940x00,0x10,0x03,0x3c,0xac,0x0e,0xc2,0x37,0x94,0x0e,0xc3,0x37,0x25,0xb0,0x09,0x3c,
29950x00,0x00,0x4a,0x8c,0xbc,0x0e,0x29,0x35,0x00,0x00,0x64,0x8c,0xb4,0x0e,0xc2,0x37,
29960x9c,0x0e,0xc3,0x37,0x00,0x00,0x45,0x8c,0x00,0x00,0x66,0x8c,0x00,0x00,0x27,0x8d,
29970x24,0x20,0x8f,0x00,0x00,0xd8,0x02,0x3c,0x24,0x10,0x42,0x01,0x24,0x28,0xaf,0x00,
29980x24,0x30,0xcf,0x00,0x24,0x38,0xef,0x00,0x02,0x24,0x04,0x00,0x20,0x01,0x03,0x24,
29990x01,0x00,0x42,0x2c,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00,0xf2,0x00,0x83,0x10,
30000x02,0x3c,0x07,0x00,0xf0,0x00,0xa3,0x10,0x20,0x00,0x03,0x24,0xee,0x00,0xc3,0x10,
30010x00,0x00,0x00,0x00,0xec,0x00,0xe3,0x10,0x01,0x00,0x08,0x24,0x80,0x00,0x03,0x24,
30020x08,0x00,0x83,0x10,0x21,0x20,0x00,0x00,0x06,0x00,0xa3,0x10,0x21,0x20,0x00,0x00,
30030xe0,0x03,0x03,0x24,0x03,0x00,0xc3,0x10,0x00,0x00,0x00,0x00,0xe5,0x00,0xe3,0x10,
30040x01,0x00,0x04,0x24,0x06,0x00,0x40,0x10,0x09,0x00,0x02,0x24,0x04,0x00,0x00,0x11,
30050x00,0x00,0x00,0x00,0x6d,0x01,0x80,0x14,0x25,0xb0,0x12,0x3c,0x09,0x00,0x02,0x24,
30060xde,0x00,0xc2,0x12,0x25,0xb0,0x04,0x3c,0x01,0x00,0xd6,0x26,0x0a,0x00,0xc2,0x2e,
30070x1d,0x01,0x40,0x10,0x00,0x00,0x00,0x00,0xc8,0xff,0xa0,0x16,0x01,0x00,0x02,0x24,
30080xa0,0x00,0x03,0x3c,0x25,0xb0,0x09,0x3c,0x30,0x54,0x62,0x34,0x04,0x0c,0x29,0x35,
30090x00,0x00,0x22,0xad,0x25,0xb0,0x0d,0x3c,0x08,0x00,0x02,0x3c,0xe4,0x00,0x42,0x34,
30100x08,0x0c,0xad,0x35,0x25,0xb0,0x09,0x3c,0x00,0x00,0xa2,0xad,0x28,0x0e,0x29,0x35,
30110x80,0x80,0x02,0x3c,0x00,0x00,0x22,0xad,0x14,0x02,0x04,0x3c,0x16,0x68,0x02,0x3c,
30120x48,0x01,0x83,0x34,0x40,0x0e,0xc5,0x37,0x44,0x0e,0xc6,0x37,0xa2,0x04,0x42,0x34,
30130x25,0xb0,0x0d,0x3c,0x00,0x00,0xa3,0xac,0x4c,0x0e,0xad,0x35,0x00,0x00,0xc2,0xac,
30140xd1,0x28,0x02,0x24,0x00,0x00,0xa2,0xad,0x14,0x02,0x03,0x3c,0x16,0x28,0x02,0x3c,
30150x4d,0x01,0x63,0x34,0x60,0x0e,0xc7,0x37,0x64,0x0e,0xc8,0x37,0xba,0x08,0x42,0x34,
30160x00,0x00,0xe3,0xac,0x25,0xb0,0x06,0x3c,0x00,0x00,0x02,0xad,0x00,0xfb,0x0d,0x3c,
30170x25,0xb0,0x09,0x3c,0x00,0xf8,0x02,0x3c,0xd1,0x28,0x07,0x24,0x6c,0x0e,0xc6,0x34,
30180x48,0x0e,0x29,0x35,0x01,0x00,0x42,0x34,0x01,0x00,0xad,0x35,0x00,0x00,0xc7,0xac,
30190x03,0x00,0x04,0x24,0x00,0x00,0x2d,0xad,0x00,0x00,0x22,0xad,0x84,0x0a,0x00,0x0c,
30200x58,0x00,0xaf,0xaf,0xa0,0x00,0x04,0x3c,0x25,0xb0,0x03,0x3c,0x25,0xb0,0x06,0x3c,
30210x25,0xb0,0x07,0x3c,0xe4,0x00,0x02,0x24,0x33,0x54,0x84,0x34,0x04,0x0c,0x63,0x34,
30220x08,0x0c,0xc6,0x34,0x28,0x0e,0xe7,0x34,0x00,0x00,0x64,0xac,0x00,0x00,0xc2,0xac,
30230x00,0x00,0xe0,0xac,0x01,0x00,0x02,0x24,0x58,0x00,0xaf,0x8f,0x8a,0xff,0xa2,0x16,
30240xac,0x0e,0xc2,0x37,0x00,0x10,0x03,0x3c,0x1f,0xdc,0x79,0x34,0x1f,0x8c,0x7f,0x34,
30250x23,0x8c,0x6d,0x34,0xa0,0x00,0x03,0x3c,0x30,0x54,0x65,0x34,0x00,0x01,0x17,0x3c,
30260x25,0xb0,0x09,0x3c,0x25,0xb0,0x03,0x3c,0x00,0x01,0xe2,0x36,0x20,0x08,0x29,0x35,
30270x20,0x08,0x63,0x34,0x00,0x00,0x30,0x8d,0x00,0x00,0x62,0xac,0x25,0xb0,0x03,0x3c,
30280x28,0x08,0x63,0x34,0x00,0x00,0x62,0xac,0x25,0xb0,0x02,0x3c,0x04,0x0c,0x42,0x34,
30290x00,0x00,0x45,0xac,0x25,0xb0,0x03,0x3c,0x08,0x00,0x02,0x3c,0xe4,0x00,0x42,0x34,
30300x08,0x0c,0x63,0x34,0x00,0x00,0x62,0xac,0x25,0xb0,0x03,0x3c,0x00,0x7c,0xf3,0x36,
30310x00,0x48,0xf4,0x36,0x30,0x0e,0xc6,0x37,0x34,0x0e,0xc7,0x37,0x80,0x80,0x02,0x3c,
30320x28,0x0e,0x63,0x34,0x00,0x00,0x62,0xac,0x00,0x00,0xd3,0xac,0x00,0x00,0xf4,0xac,
30330x14,0x02,0x06,0x3c,0x16,0x68,0x07,0x3c,0x38,0x0e,0xc8,0x37,0x40,0x0e,0xca,0x37,
30340x44,0x0e,0xcb,0x37,0x3c,0x0e,0xc9,0x37,0x02,0x01,0xc6,0x34,0xc7,0x04,0xe7,0x34,
30350x00,0x00,0x19,0xad,0x25,0xb0,0x03,0x3c,0x00,0x00,0x3f,0xad,0x00,0x00,0x46,0xad,
30360x25,0xb0,0x09,0x3c,0x00,0x00,0x67,0xad,0x25,0xb0,0x06,0x3c,0x00,0x10,0x07,0x3c,
30370x50,0x0e,0xcc,0x37,0x58,0x0e,0xce,0x37,0x5c,0x0e,0xd8,0x37,0xd1,0x28,0x02,0x24,
30380x23,0xdc,0xe7,0x34,0x4c,0x0e,0x29,0x35,0x6c,0x0e,0x63,0x34,0x54,0x0e,0xc6,0x34,
30390x00,0x00,0x22,0xad,0x00,0x00,0x62,0xac,0x14,0x02,0x09,0x3c,0x00,0x00,0x93,0xad,
30400x25,0xb0,0x02,0x3c,0x00,0x00,0xd4,0xac,0x00,0x00,0xc7,0xad,0x00,0x00,0x0d,0xaf,
30410x16,0x28,0x0d,0x3c,0x48,0x0e,0x42,0x34,0x00,0xf8,0x06,0x3c,0x02,0x01,0x29,0x35,
30420x07,0x0d,0xad,0x35,0x00,0xfb,0x03,0x3c,0x60,0x0e,0xd1,0x37,0x64,0x0e,0xd2,0x37,
30430x00,0x00,0x29,0xae,0x03,0x00,0x04,0x24,0x00,0x00,0x4d,0xae,0x00,0x00,0x43,0xac,
30440x00,0x00,0x46,0xac,0x84,0x0a,0x00,0x0c,0x58,0x00,0xaf,0xaf,0x00,0x02,0x02,0x3c,
30450x25,0xb0,0x07,0x3c,0x25,0xb0,0x09,0x3c,0xd1,0x28,0x42,0x34,0x4c,0x0e,0xe7,0x34,
30460x6c,0x0e,0x29,0x35,0x25,0xb0,0x0d,0x3c,0x00,0x00,0xe2,0xac,0x48,0x0e,0xad,0x35,
30470x00,0x00,0x22,0xad,0x00,0xf8,0x03,0x3c,0x00,0xfb,0x02,0x3c,0x00,0x00,0xa2,0xad,
30480x03,0x00,0x04,0x24,0x00,0x00,0xa3,0xad,0x84,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,
30490x4c,0x00,0xa6,0x8f,0x25,0xb0,0x04,0x3c,0x04,0x0c,0x84,0x34,0x00,0x00,0x86,0xac,
30500x50,0x00,0xa9,0x8f,0x25,0xb0,0x07,0x3c,0x25,0xb0,0x0d,0x3c,0x00,0x01,0x10,0x32,
30510x08,0x0c,0xe7,0x34,0x28,0x0e,0xad,0x35,0x00,0x00,0xe9,0xac,0x2b,0x80,0x10,0x00,
30520x00,0x00,0xa0,0xad,0x58,0x00,0xaf,0x8f,0x17,0xff,0x00,0x16,0xac,0x0e,0xc2,0x37,
30530x25,0xb0,0x02,0x3c,0x25,0xb0,0x03,0x3c,0x20,0x08,0x42,0x34,0x28,0x08,0x63,0x34,
30540x00,0x00,0x57,0xac,0x25,0xb0,0x09,0x3c,0x00,0x00,0x77,0xac,0xac,0x0e,0xc2,0x37,
30550x94,0x0e,0xc3,0x37,0x00,0x00,0x4a,0x8c,0xbc,0x0e,0x29,0x35,0x00,0x00,0x64,0x8c,
30560xb4,0x0e,0xc2,0x37,0x9c,0x0e,0xc3,0x37,0x00,0x00,0x45,0x8c,0x00,0x00,0x66,0x8c,
30570x00,0x00,0x27,0x8d,0x24,0x20,0x8f,0x00,0x00,0xd8,0x02,0x3c,0x24,0x10,0x42,0x01,
30580x24,0x28,0xaf,0x00,0x24,0x30,0xcf,0x00,0x24,0x38,0xef,0x00,0x02,0x24,0x04,0x00,
30590x20,0x01,0x03,0x24,0x01,0x00,0x42,0x2c,0x02,0x2c,0x05,0x00,0x02,0x34,0x06,0x00,
30600x10,0xff,0x83,0x14,0x02,0x3c,0x07,0x00,0x80,0x00,0x03,0x24,0x16,0xff,0x83,0x14,
30610x21,0x40,0x00,0x00,0xc3,0x51,0x00,0x08,0x21,0x20,0x00,0x00,0xff,0xff,0x02,0x34,
30620xc4,0x02,0x84,0x34,0x00,0x00,0x82,0xac,0x94,0x0e,0xc3,0x37,0x9c,0x0e,0xc2,0x37,
30630xa4,0x0e,0xc4,0x37,0xac,0x0e,0xc7,0x37,0x00,0x00,0x66,0x8c,0x00,0x00,0x49,0x8c,
30640x00,0x00,0x8b,0x8c,0x00,0x00,0xe5,0x8c,0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24,
30650x0c,0x40,0xe3,0x8c,0x10,0x40,0xe4,0x8c,0xb4,0x0e,0xc2,0x37,0x00,0x00,0x47,0x8c,
30660x25,0xb0,0x0d,0x3c,0x00,0xfc,0x02,0x24,0x24,0x30,0xcf,0x00,0x24,0x28,0xaf,0x00,
30670xbc,0x0e,0xad,0x35,0x00,0x00,0xa8,0x8d,0x24,0x20,0x82,0x00,0x02,0x34,0x06,0x00,
30680x24,0x18,0x62,0x00,0x02,0x2c,0x05,0x00,0xc4,0x0e,0xca,0x37,0xcc,0x0e,0xcc,0x37,
30690xf0,0xff,0x02,0x3c,0xff,0x03,0x42,0x34,0x25,0x18,0x66,0x00,0x25,0x20,0x85,0x00,
30700x00,0x00,0x46,0x8d,0x24,0x48,0x2f,0x01,0x00,0x00,0x85,0x8d,0x24,0x38,0xef,0x00,
30710x24,0x20,0x82,0x00,0x24,0x18,0x62,0x00,0x82,0x49,0x09,0x00,0x82,0x39,0x07,0x00,
30720x0f,0xc0,0x02,0x3c,0xff,0xff,0x42,0x34,0x25,0x18,0x69,0x00,0x25,0x20,0x87,0x00,
30730x24,0x58,0x6f,0x01,0x24,0x40,0x0f,0x01,0x24,0x20,0x82,0x00,0x24,0x18,0x62,0x00,
30740x00,0x59,0x0b,0x00,0x00,0x41,0x08,0x00,0x24,0x30,0xcf,0x00,0x24,0x28,0xaf,0x00,
30750x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,0x25,0x18,0x6b,0x00,0x25,0x20,0x88,0x00,
30760x02,0x34,0x06,0x00,0x02,0x2c,0x05,0x00,0x01,0x00,0xd6,0x26,0x0c,0x40,0x43,0xac,
30770x10,0x40,0x44,0xac,0x14,0x40,0x46,0xa4,0x16,0x40,0x45,0xa4,0x0a,0x00,0xc2,0x2e,
30780xe5,0xfe,0x40,0x14,0x00,0x00,0x00,0x00,0x18,0x00,0xad,0x8f,0x25,0xb0,0x02,0x3c,
30790xe0,0x0e,0x43,0x34,0x10,0x00,0xa6,0x8f,0x00,0x00,0x6d,0xac,0x1c,0x00,0xa3,0x8f,
30800xdc,0x0e,0x47,0x34,0x70,0x0e,0x48,0x34,0x00,0x00,0xe3,0xac,0x20,0x00,0xa7,0x8f,
30810x74,0x0e,0x49,0x34,0x78,0x0e,0x4a,0x34,0x00,0x00,0x07,0xad,0x24,0x00,0xad,0x8f,
30820x7c,0x0e,0x4b,0x34,0x80,0x0e,0x4c,0x34,0x00,0x00,0x2d,0xad,0x28,0x00,0xa3,0x8f,
30830x25,0xb0,0x0d,0x3c,0x84,0x0e,0xad,0x35,0x00,0x00,0x43,0xad,0x2c,0x00,0xa7,0x8f,
30840x88,0x0e,0x52,0x34,0x8c,0x0e,0x4e,0x34,0x00,0x00,0x67,0xad,0x30,0x00,0xa9,0x8f,
30850xd4,0x0e,0x51,0x34,0xd0,0x0e,0x42,0x34,0x00,0x00,0x89,0xad,0x34,0x00,0xa3,0x8f,
30860x0f,0x00,0x10,0x3c,0xff,0xff,0x05,0x36,0x00,0x00,0xa3,0xad,0x38,0x00,0xa7,0x8f,
30870x21,0x20,0x00,0x00,0x00,0x00,0x47,0xae,0x3c,0x00,0xa9,0x8f,0x00,0x00,0x00,0x00,
30880x00,0x00,0xc9,0xad,0x40,0x00,0xad,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0xac,
30890x44,0x00,0xa2,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0xae,0x48,0x00,0xa3,0x8f,
30900x00,0x00,0x00,0x00,0x00,0x00,0x43,0xae,0xba,0x44,0x00,0x0c,0x00,0x00,0x00,0x00,
30910xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,
30920x14,0x00,0xa6,0x8f,0xff,0xff,0x05,0x36,0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,
30930xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x84,0x00,0xbf,0x8f,0x80,0x00,0xbe,0x8f,
30940x7c,0x00,0xb7,0x8f,0x78,0x00,0xb6,0x8f,0x74,0x00,0xb5,0x8f,0x70,0x00,0xb4,0x8f,
30950x6c,0x00,0xb3,0x8f,0x68,0x00,0xb2,0x8f,0x64,0x00,0xb1,0x8f,0x60,0x00,0xb0,0x8f,
30960x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x08,0x88,0x00,0xbd,0x27,0x94,0x0e,0x42,0x36,
30970x9c,0x0e,0x43,0x36,0xa4,0x0e,0x44,0x36,0xac,0x0e,0x45,0x36,0x02,0x80,0x0d,0x3c,
30980x00,0x00,0x47,0x8c,0x68,0x15,0xad,0x25,0x00,0x00,0x6a,0x8c,0x00,0x00,0x8c,0x8c,
30990x00,0x00,0xa3,0x8c,0x10,0x40,0xa4,0x8d,0xb4,0x0e,0x42,0x36,0x00,0x00,0x48,0x8c,
31000x0c,0x40,0xa5,0x8d,0x25,0xb0,0x02,0x3c,0x00,0xfc,0x13,0x24,0xbc,0x0e,0x42,0x34,
31010x24,0x18,0x6f,0x00,0x00,0x00,0x49,0x8c,0x02,0x1c,0x03,0x00,0x24,0x38,0xef,0x00,
31020x24,0x20,0x93,0x00,0xf0,0xff,0x06,0x3c,0x25,0x20,0x83,0x00,0xff,0x03,0xc6,0x34,
31030x02,0x3c,0x07,0x00,0xc4,0x0e,0x42,0x36,0x24,0x28,0xb3,0x00,0x24,0x40,0x0f,0x01,
31040xcc,0x0e,0x4b,0x36,0x25,0x28,0xa7,0x00,0x24,0x20,0x86,0x00,0x00,0x00,0x47,0x8c,
31050x24,0x50,0x4f,0x01,0x00,0x00,0x63,0x8d,0x82,0x41,0x08,0x00,0x0f,0xc0,0x02,0x3c,
31060xff,0xff,0x42,0x34,0x25,0x20,0x88,0x00,0x82,0x51,0x0a,0x00,0x24,0x28,0xa6,0x00,
31070x24,0x48,0x2f,0x01,0x24,0x88,0x82,0x00,0x25,0x28,0xaa,0x00,0x24,0x60,0x8f,0x01,
31080x00,0x49,0x09,0x00,0x25,0x88,0x29,0x02,0x24,0x28,0xa2,0x00,0x24,0x18,0x6f,0x00,
31090x00,0x61,0x0c,0x00,0x24,0x38,0xef,0x00,0x25,0x28,0xac,0x00,0x02,0x3c,0x07,0x00,
31100x02,0x1c,0x03,0x00,0x82,0x27,0x11,0x00,0x01,0x00,0x02,0x24,0x16,0x40,0xa3,0xa5,
31110x14,0x40,0xa7,0xa5,0x0c,0x40,0xa5,0xad,0x4a,0x00,0x82,0x10,0x10,0x40,0xb1,0xad,
31120x80,0x0c,0x4c,0x36,0x00,0x00,0x8a,0x8d,0x82,0x72,0x05,0x00,0xff,0x03,0xce,0x31,
31130x00,0x02,0xc3,0x31,0x25,0x10,0xd3,0x01,0x0b,0x70,0x43,0x00,0x82,0x85,0x0a,0x00,
31140x18,0x00,0xd0,0x01,0xff,0x03,0xaf,0x30,0x00,0x02,0xa3,0x30,0x25,0x10,0xf3,0x01,
31150x0b,0x78,0x43,0x00,0x02,0x75,0x11,0x00,0xff,0x03,0xce,0x31,0xc0,0xff,0x08,0x3c,
31160x25,0x18,0xd3,0x01,0x00,0x02,0xc2,0x31,0x00,0xfc,0x06,0x35,0x0b,0x70,0x62,0x00,
31170x24,0x38,0x46,0x01,0x94,0x0c,0x4a,0x36,0xff,0x0f,0x09,0x3c,0xff,0xff,0x29,0x35,
31180x88,0x0c,0x54,0x36,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30,
31190x18,0x00,0xf0,0x01,0x82,0x7a,0x11,0x00,0xff,0x03,0xef,0x31,0x00,0x14,0x02,0x00,
31200x25,0x38,0xe2,0x00,0x00,0x02,0xe3,0x31,0x25,0x10,0xf3,0x01,0x0b,0x78,0x43,0x00,
31210xc0,0x03,0x84,0x30,0x80,0x25,0x04,0x00,0x9c,0x0c,0x4b,0x36,0x12,0x28,0x00,0x00,
31220x02,0x2a,0x05,0x00,0xff,0x03,0xa2,0x30,0x25,0x10,0xe2,0x00,0x00,0x00,0x82,0xad,
31230x00,0x00,0x42,0x8d,0x00,0x00,0x00,0x00,0x24,0x10,0x49,0x00,0x25,0x10,0x44,0x00,
31240x00,0x00,0x42,0xad,0x00,0x00,0x8a,0x8e,0x00,0x00,0x00,0x00,0x24,0x40,0x48,0x01,
31250x82,0x85,0x08,0x00,0x18,0x00,0xd0,0x01,0x24,0x30,0x46,0x01,0x12,0x18,0x00,0x00,
31260x02,0x1a,0x03,0x00,0x3f,0x00,0x62,0x30,0x18,0x00,0xf0,0x01,0x00,0x14,0x02,0x00,
31270x25,0x30,0xc2,0x00,0xc0,0x03,0x63,0x30,0x80,0x1d,0x03,0x00,0x12,0x20,0x00,0x00,
31280x02,0x22,0x04,0x00,0xff,0x03,0x82,0x30,0x25,0x10,0xc2,0x00,0x00,0x00,0x82,0xae,
31290x00,0x00,0x62,0x8d,0x00,0x00,0x00,0x00,0x24,0x10,0x49,0x00,0x25,0x10,0x43,0x00,
31300x00,0x00,0x62,0xad,0x00,0x17,0x16,0x00,0x25,0xb0,0x03,0x3c,0xdd,0xdd,0x42,0x34,
31310xc4,0x02,0x63,0x34,0x00,0x00,0x62,0xac,0xec,0x52,0x00,0x08,0x00,0x00,0x00,0x00,
31320xe0,0xff,0xbd,0x27,0x44,0x00,0x02,0x24,0x10,0x00,0xa2,0xa3,0x49,0x00,0x03,0x24,
31330x47,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x8c,0x97,0xe7,0x24,0x11,0x00,0xa3,0xa3,
31340x12,0x00,0xa2,0xa3,0x10,0x27,0x03,0x24,0x01,0x00,0x02,0x24,0x01,0x80,0x06,0x3c,
31350x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xe8,0x51,0xc6,0x24,0x0c,0x00,0xe3,0xac,
31360x14,0x00,0xe2,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,
31370x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,
31380xd0,0xff,0xbd,0x27,0x25,0xb0,0x02,0x3c,0x20,0x00,0xb4,0xaf,0x1c,0x00,0xb3,0xaf,
31390x03,0x0d,0x44,0x34,0x2c,0x00,0xbf,0xaf,0x28,0x00,0xb6,0xaf,0x24,0x00,0xb5,0xaf,
31400x18,0x00,0xb2,0xaf,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x83,0x90,
31410x42,0x00,0x45,0x34,0xff,0x00,0x73,0x30,0x70,0x00,0x74,0x32,0x29,0x00,0x80,0x16,
31420x8f,0x00,0x62,0x32,0xff,0xff,0x02,0x24,0x00,0x00,0xa2,0xa0,0x00,0x60,0x01,0x40,
31430x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,
31440x18,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0x80,0x40,0x00,
31450x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,
31460x64,0x00,0x04,0x24,0x00,0x80,0x06,0x36,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c,
31470x18,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,0x03,0x00,0x04,0x24,0x21,0x30,0xa0,0x02,
31480xff,0xff,0x25,0x36,0x5c,0x00,0x80,0x16,0x21,0x20,0x00,0x00,0x2c,0x00,0xbf,0x8f,
31490x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,0x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,
31500x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,0x25,0xb0,0x02,0x3c,
31510x42,0x00,0x42,0x34,0x30,0x00,0xbd,0x27,0x00,0x00,0x40,0xa0,0x08,0x00,0xe0,0x03,
31520x00,0x00,0x00,0x00,0x00,0x00,0x82,0xa0,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
31530x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,0x21,0x20,0x00,0x00,
31540xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0xa8,0x40,0x00,0x00,0x60,0x01,0x40,
31550x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
31560x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
31570x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x21,0x20,0x00,0x00,0xdd,0x44,0x00,0x0c,
31580xff,0xff,0x25,0x36,0x21,0xb0,0x40,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
31590x00,0x60,0x81,0x40,0x64,0x00,0x04,0x24,0xb3,0x0a,0x00,0x0c,0x08,0x00,0x10,0x3c,
31600xff,0xff,0x10,0x36,0x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0x01,0x00,0x12,0x3c,
31610x24,0x30,0xb0,0x02,0x25,0x30,0xd2,0x00,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c,
31620x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0x24,0x80,0xd0,0x02,
31630x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0x25,0x30,0x12,0x02,0xff,0xff,0x25,0x36,
31640xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
31650x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x00,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,
31660x01,0x00,0x21,0x38,0x00,0x60,0x81,0x40,0x0f,0x00,0x11,0x3c,0x18,0x00,0x04,0x24,
31670xdd,0x44,0x00,0x0c,0xff,0xff,0x25,0x36,0x21,0x80,0x40,0x00,0x00,0x60,0x01,0x40,
31680x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,0xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,
31690x00,0x80,0x06,0x36,0xff,0xff,0x25,0x36,0xba,0x44,0x00,0x0c,0x18,0x00,0x04,0x24,
31700x84,0x0a,0x00,0x0c,0x03,0x00,0x04,0x24,0x21,0x30,0xa0,0x02,0xff,0xff,0x25,0x36,
31710xa6,0xff,0x80,0x12,0x21,0x20,0x00,0x00,0x25,0xb0,0x02,0x3c,0x03,0x0d,0x42,0x34,
31720x00,0x00,0x53,0xa0,0xba,0x44,0x00,0x0c,0x00,0x00,0x00,0x00,0xb3,0x0a,0x00,0x0c,
31730x64,0x00,0x04,0x24,0x7a,0x42,0x00,0x0c,0x01,0x00,0x04,0x24,0xff,0xff,0x25,0x36,
31740x21,0x30,0xc0,0x02,0xba,0x44,0x00,0x0c,0x21,0x20,0x00,0x00,0xb3,0x0a,0x00,0x0c,
31750x64,0x00,0x04,0x24,0x2c,0x00,0xbf,0x8f,0x28,0x00,0xb6,0x8f,0x24,0x00,0xb5,0x8f,
31760x20,0x00,0xb4,0x8f,0x1c,0x00,0xb3,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
31770x10,0x00,0xb0,0x8f,0x21,0x20,0x00,0x00,0x7a,0x42,0x00,0x08,0x30,0x00,0xbd,0x27,
31780xd0,0xff,0xbd,0x27,0x28,0x00,0xb4,0xaf,0x02,0x80,0x14,0x3c,0x2c,0x00,0xbf,0xaf,
31790x24,0x00,0xb3,0xaf,0x20,0x00,0xb2,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,
31800x68,0x15,0x86,0x26,0x0c,0x40,0xc2,0x8c,0x00,0x00,0x00,0x00,0x82,0x17,0x02,0x00,
31810x01,0x00,0x42,0x30,0x07,0x00,0x40,0x14,0x68,0x15,0x85,0x26,0x08,0x40,0xc2,0x8c,
31820x01,0x00,0x03,0x24,0x42,0x17,0x02,0x00,0x03,0x00,0x42,0x30,0xf0,0x00,0x43,0x10,
31830x25,0xb0,0x02,0x3c,0x0c,0x40,0xa2,0x8c,0x01,0x00,0x03,0x24,0x82,0x17,0x02,0x00,
31840x01,0x00,0x44,0x30,0x0a,0x00,0x83,0x10,0x00,0x00,0x00,0x00,0x2c,0x00,0xbf,0x8f,
31850x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
31860x18,0x00,0xb0,0x8f,0x21,0x10,0x00,0x00,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,
31870x08,0x40,0xa2,0x8c,0x00,0x00,0x00,0x00,0x42,0x17,0x02,0x00,0x03,0x00,0x42,0x30,
31880xf2,0xff,0x44,0x14,0x25,0xb0,0x02,0x3c,0x0e,0x0c,0x44,0x34,0x00,0x00,0x83,0x90,
31890x00,0x01,0x02,0x24,0xff,0x00,0x63,0x30,0x01,0x00,0x63,0x24,0x8b,0x01,0x62,0x10,
31900x00,0x00,0x00,0x00,0x00,0x00,0x83,0xa0,0x68,0x15,0x84,0x26,0x10,0x40,0x82,0x8c,
31910x01,0x00,0x03,0x24,0x82,0x17,0x02,0x00,0xa4,0x01,0x43,0x10,0x0f,0x00,0x10,0x3c,
31920xc7,0x42,0x92,0x90,0x68,0x15,0x90,0x26,0xc6,0x42,0x03,0x92,0x25,0xb0,0x11,0x3c,
31930x62,0x0c,0x22,0x36,0x00,0x00,0x52,0xa0,0x17,0x01,0x60,0x10,0x01,0x00,0x02,0x24,
31940x03,0x0d,0x23,0x36,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x70,0x00,0x42,0x30,
31950x3e,0x01,0x40,0x14,0x63,0x0c,0x23,0x36,0xc4,0x42,0x02,0x96,0x00,0x00,0x00,0x00,
31960x23,0x20,0x52,0x00,0x2b,0x18,0x52,0x00,0x23,0x10,0x42,0x02,0x0a,0x10,0x83,0x00,
31970x03,0x00,0x42,0x2c,0x0b,0x01,0x40,0x10,0x00,0x00,0x00,0x00,0xc4,0x42,0x03,0x96,
31980x63,0x0c,0x22,0x36,0x00,0x00,0x43,0xa0,0x68,0x15,0x83,0x26,0xc3,0x42,0x62,0x90,
31990x08,0x40,0x66,0x8c,0xc2,0x42,0x72,0xa0,0x23,0x20,0x52,0x00,0x2b,0x38,0x42,0x02,
32000x23,0x50,0x42,0x02,0x02,0x2c,0x06,0x00,0x0b,0x50,0x87,0x00,0x3f,0x00,0xa5,0x30,
32010x3f,0x00,0xc4,0x30,0x24,0x00,0x02,0x24,0x20,0x00,0x03,0x24,0x23,0x10,0x44,0x00,
32020x2d,0x01,0x40,0x15,0x23,0x18,0x65,0x00,0x21,0x30,0x80,0x00,0x21,0x48,0xa0,0x00,
32030x02,0x80,0x0b,0x3c,0x68,0x15,0x83,0x26,0x80,0x10,0x06,0x00,0x21,0x10,0x43,0x00,
32040x0c,0x40,0x63,0x8c,0x18,0x40,0x44,0x8c,0xff,0x03,0x67,0x30,0x1b,0x01,0xe0,0x10,
32050x82,0x2d,0x04,0x00,0x00,0x02,0x62,0x30,0x04,0x00,0x40,0x10,0x18,0x00,0xe5,0x00,
32060x00,0xfc,0x02,0x24,0x25,0x38,0xe2,0x00,0x18,0x00,0xe5,0x00,0x82,0x22,0x03,0x00,
32070xff,0x03,0x84,0x30,0x00,0x02,0x83,0x30,0x12,0x10,0x00,0x00,0x02,0x12,0x02,0x00,
32080x03,0x00,0x60,0x10,0xff,0x03,0x48,0x30,0x00,0xfc,0x02,0x24,0x25,0x20,0x82,0x00,
32090x18,0x00,0x85,0x00,0x80,0x2d,0x05,0x00,0x25,0xb0,0x06,0x3c,0x80,0x0c,0xc7,0x34,
32100x94,0x0c,0xc6,0x34,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30,
32110x00,0x14,0x02,0x00,0x25,0x28,0xa2,0x00,0x25,0x28,0xa8,0x00,0x10,0x00,0xa5,0xaf,
32120x00,0x00,0xe5,0xac,0x00,0x00,0xc3,0x8c,0xff,0x0f,0x02,0x3c,0xc0,0x03,0x84,0x30,
32130xff,0xff,0x42,0x34,0x80,0x25,0x04,0x00,0x24,0x18,0x62,0x00,0x25,0x18,0x64,0x00,
32140x10,0x00,0xa3,0xaf,0x00,0x00,0xc3,0xac,0x68,0x15,0x83,0x26,0x08,0x40,0x62,0x8c,
32150x00,0x00,0x00,0x00,0x08,0x01,0x40,0x04,0xc0,0x28,0x09,0x00,0x21,0x28,0xa3,0x00,
32160xac,0x40,0xa3,0x90,0x25,0xb0,0x04,0x3c,0x22,0x0a,0x82,0x34,0x00,0x00,0x43,0xa0,
32170xad,0x40,0xa6,0x90,0x23,0x0a,0x82,0x34,0x24,0x0a,0x87,0x34,0x00,0x00,0x46,0xa0,
32180xae,0x40,0xa3,0x90,0x25,0x0a,0x86,0x34,0x26,0x0a,0x88,0x34,0x00,0x00,0xe3,0xa0,
32190xaf,0x40,0xa2,0x90,0x27,0x0a,0x87,0x34,0x28,0x0a,0x89,0x34,0x00,0x00,0xc2,0xa0,
32200xb0,0x40,0xa3,0x90,0x29,0x0a,0x84,0x34,0x00,0x00,0x03,0xa1,0xb1,0x40,0xa2,0x90,
32210x00,0x00,0x00,0x00,0x00,0x00,0xe2,0xa0,0xb2,0x40,0xa3,0x90,0x00,0x00,0x00,0x00,
32220x00,0x00,0x23,0xa1,0xb3,0x40,0xa2,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xa0,
32230x8e,0x7d,0x63,0x91,0x22,0x00,0x02,0x24,0x03,0x00,0x62,0x10,0x92,0x00,0x02,0x24,
32240x62,0xff,0x62,0x14,0x00,0x00,0x00,0x00,0x68,0x15,0x82,0x26,0x08,0x40,0x43,0x8c,
32250x01,0x00,0x44,0x39,0x24,0x00,0x02,0x24,0x02,0x1a,0x03,0x00,0x3f,0x00,0x63,0x30,
32260x01,0x00,0x84,0x30,0x04,0x01,0x80,0x10,0x23,0x28,0x43,0x00,0x42,0x18,0x0a,0x00,
32270x40,0x10,0x03,0x00,0x21,0x50,0x43,0x00,0x68,0x15,0x83,0x26,0xc3,0x42,0x62,0x90,
32280x00,0x00,0x00,0x00,0x2b,0x10,0x42,0x02,0x08,0x01,0x40,0x10,0x21,0x20,0x00,0x00,
32290x2b,0x10,0x45,0x01,0x07,0x00,0x40,0x10,0x24,0x00,0x04,0x24,0x08,0x40,0x62,0x8c,
32300x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x3f,0x00,0x42,0x30,0x21,0x20,0x4a,0x00,
32310x68,0x15,0x83,0x26,0x80,0x10,0x04,0x00,0x10,0x40,0x66,0x8c,0x21,0x10,0x43,0x00,
32320x18,0x40,0x44,0x8c,0x82,0x3a,0x06,0x00,0xff,0x03,0xe7,0x30,0xf0,0x00,0xe0,0x10,
32330x82,0x2d,0x04,0x00,0x00,0x02,0xe2,0x30,0x04,0x00,0x40,0x10,0x18,0x00,0xe5,0x00,
32340x00,0xfc,0x02,0x24,0x25,0x38,0xe2,0x00,0x18,0x00,0xe5,0x00,0x02,0x25,0x06,0x00,
32350xff,0x03,0x84,0x30,0x00,0x02,0x83,0x30,0x12,0x10,0x00,0x00,0x02,0x12,0x02,0x00,
32360x03,0x00,0x60,0x10,0xff,0x03,0x48,0x30,0x00,0xfc,0x02,0x24,0x25,0x20,0x82,0x00,
32370x18,0x00,0x85,0x00,0x80,0x2d,0x05,0x00,0x25,0xb0,0x06,0x3c,0x88,0x0c,0xc7,0x34,
32380x9c,0x0c,0xc6,0x34,0x12,0x20,0x00,0x00,0x02,0x22,0x04,0x00,0x3f,0x00,0x82,0x30,
32390x00,0x14,0x02,0x00,0x25,0x28,0xa2,0x00,0x25,0x28,0xa8,0x00,0x10,0x00,0xa5,0xaf,
32400x00,0x00,0xe5,0xac,0x00,0x00,0xc3,0x8c,0xff,0x0f,0x02,0x3c,0xc0,0x03,0x84,0x30,
32410xff,0xff,0x42,0x34,0x80,0x25,0x04,0x00,0x24,0x18,0x62,0x00,0x25,0x18,0x64,0x00,
32420x10,0x00,0xa3,0xaf,0x00,0x00,0xc3,0xac,0x95,0x54,0x00,0x08,0x00,0x00,0x00,0x00,
32430x80,0x0c,0x42,0x34,0x00,0x00,0x43,0x8c,0xc0,0xff,0x02,0x3c,0x21,0x88,0x00,0x00,
32440x24,0x28,0x62,0x00,0xc0,0xff,0x04,0x3c,0x8a,0x55,0x00,0x08,0x18,0x40,0xc3,0x24,
32450x01,0x00,0x31,0x26,0x25,0x00,0x22,0x2e,0x0d,0x00,0x40,0x10,0x02,0x80,0x0b,0x3c,
32460x00,0x00,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x44,0x00,0xf8,0xff,0x45,0x14,
32470x04,0x00,0x63,0x24,0x08,0x40,0xc2,0x8c,0xc0,0xff,0x03,0x24,0x3f,0x00,0x24,0x32,
32480x24,0x10,0x43,0x00,0x25,0x10,0x44,0x00,0x08,0x40,0xc2,0xac,0x02,0x80,0x0b,0x3c,
32490x8e,0x7d,0x63,0x91,0x22,0x00,0x02,0x24,0x3e,0x00,0x62,0x10,0x92,0x00,0x02,0x24,
32500x3d,0x00,0x62,0x10,0x25,0xb0,0x02,0x3c,0x25,0xb0,0x02,0x3c,0x24,0x0a,0x42,0x34,
32510x00,0x00,0x44,0x8c,0x3f,0x3f,0x03,0x3c,0x3f,0x3f,0x63,0x34,0x24,0x20,0x83,0x00,
32520x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,0x16,0x56,0x53,0x24,0x1e,0x57,0x72,0x24,
32530x21,0x88,0x00,0x00,0xb1,0x55,0x00,0x08,0x10,0x00,0xa4,0xaf,0xd4,0x45,0x00,0x0c,
32540x00,0x00,0x00,0x00,0x47,0x00,0x40,0x10,0x68,0x15,0x85,0x26,0x01,0x00,0x31,0x26,
32550x21,0x00,0x22,0x2e,0x17,0x00,0x40,0x10,0x68,0x15,0x84,0x26,0xc0,0x80,0x11,0x00,
32560x10,0x00,0xa4,0x27,0x21,0x28,0x13,0x02,0xd4,0x45,0x00,0x0c,0x04,0x00,0x06,0x24,
32570x21,0x28,0x12,0x02,0x10,0x00,0xa4,0x27,0xf0,0xff,0x40,0x14,0x04,0x00,0x06,0x24,
32580x68,0x15,0x85,0x26,0x08,0x40,0xa3,0x8c,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34,
32590x3f,0x00,0x24,0x32,0x24,0x18,0x62,0x00,0x00,0x24,0x04,0x00,0xff,0x7f,0x02,0x3c,
32600x25,0x18,0x64,0x00,0xff,0xff,0x42,0x34,0x24,0x18,0x62,0x00,0x08,0x40,0xa3,0xac,
32610x68,0x15,0x84,0x26,0x0c,0x40,0x83,0x8c,0x00,0x40,0x02,0x3c,0x25,0x18,0x62,0x00,
32620x25,0xb0,0x02,0x3c,0x0e,0x0c,0x42,0x34,0x0c,0x40,0x83,0xac,0x00,0x00,0x40,0xa0,
32630x8f,0x54,0x00,0x08,0x68,0x15,0x85,0x26,0xc6,0x42,0x02,0xa2,0xba,0x54,0x00,0x08,
32640xc4,0x42,0x12,0xa6,0xda,0x53,0x00,0x0c,0x00,0x00,0x00,0x00,0xc9,0x54,0x00,0x08,
32650xc4,0x42,0x12,0xa6,0x25,0xb0,0x02,0x3c,0x88,0x0c,0x42,0x34,0x00,0x00,0x44,0x8c,
32660x02,0x80,0x03,0x3c,0x68,0x15,0x66,0x24,0xc0,0xff,0x02,0x3c,0x24,0x28,0x82,0x00,
32670x21,0x88,0x00,0x00,0xc0,0xff,0x04,0x3c,0xe6,0x55,0x00,0x08,0x18,0x40,0xc3,0x24,
32680x01,0x00,0x31,0x26,0x25,0x00,0x22,0x2e,0xb8,0xff,0x40,0x10,0x25,0xb0,0x02,0x3c,
32690x00,0x00,0x62,0x8c,0x00,0x00,0x00,0x00,0x24,0x10,0x44,0x00,0xf8,0xff,0x45,0x14,
32700x04,0x00,0x63,0x24,0x08,0x40,0xc2,0x8c,0x3f,0x00,0x23,0x32,0xff,0xc0,0x04,0x24,
32710x24,0x10,0x44,0x00,0x00,0x1a,0x03,0x00,0x25,0x10,0x43,0x00,0x9c,0x55,0x00,0x08,
32720x08,0x40,0xc2,0xac,0x08,0x40,0xa3,0x8c,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34,
32730x3f,0x00,0x24,0x32,0x24,0x18,0x62,0x00,0x00,0x24,0x04,0x00,0x25,0x18,0x64,0x00,
32740x00,0x80,0x02,0x3c,0xc5,0x55,0x00,0x08,0x25,0x18,0x62,0x00,0xcc,0xff,0x02,0x24,
32750x00,0x00,0x62,0xa0,0xcd,0x54,0x00,0x08,0x68,0x15,0x83,0x26,0x25,0xb0,0x02,0x3c,
32760x94,0x0c,0x43,0x34,0x80,0x0c,0x42,0x34,0x00,0x00,0x44,0xac,0x00,0x00,0x60,0xac,
32770x0d,0x55,0x00,0x08,0x68,0x15,0x83,0x26,0x2f,0x00,0xe0,0x10,0x21,0x30,0x00,0x00,
32780x2b,0x10,0x42,0x01,0x21,0x20,0x8a,0x00,0x00,0x00,0x42,0x38,0x24,0x00,0x06,0x24,
32790x2b,0x18,0x43,0x01,0x0b,0x30,0x82,0x00,0xcd,0xfe,0x60,0x10,0x20,0x00,0x09,0x24,
32800x68,0x15,0x83,0x26,0x0a,0x40,0x62,0x94,0x02,0x80,0x0b,0x3c,0x3f,0x00,0x42,0x30,
32810xe0,0x54,0x00,0x08,0x21,0x48,0x4a,0x00,0x21,0x28,0xa3,0x00,0xb4,0x41,0xa3,0x90,
32820x25,0xb0,0x04,0x3c,0x22,0x0a,0x82,0x34,0x00,0x00,0x43,0xa0,0xb5,0x41,0xa6,0x90,
32830x23,0x0a,0x82,0x34,0x24,0x0a,0x87,0x34,0x00,0x00,0x46,0xa0,0xb6,0x41,0xa3,0x90,
32840x25,0x0a,0x86,0x34,0x26,0x0a,0x88,0x34,0x00,0x00,0xe3,0xa0,0xb7,0x41,0xa2,0x90,
32850x27,0x0a,0x87,0x34,0x28,0x0a,0x89,0x34,0x00,0x00,0xc2,0xa0,0xb8,0x41,0xa3,0x90,
32860x29,0x0a,0x84,0x34,0x00,0x00,0x03,0xa1,0xb9,0x41,0xa2,0x90,0x00,0x00,0x00,0x00,
32870x00,0x00,0xe2,0xa0,0xba,0x41,0xa3,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0xa1,
32880xbb,0x41,0xa2,0x90,0x2d,0x55,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xa0,
32890xad,0x54,0x00,0x08,0x68,0x15,0x84,0x26,0x23,0x10,0x8a,0x00,0x2b,0x18,0x44,0x01,
32900x2b,0x20,0x45,0x01,0x0b,0x30,0x43,0x00,0xa1,0xfe,0x80,0x14,0x23,0x48,0xaa,0x00,
32910xde,0x54,0x00,0x08,0x21,0x48,0x00,0x00,0xff,0xff,0x43,0x25,0x42,0x18,0x03,0x00,
32920x40,0x10,0x03,0x00,0x21,0x10,0x43,0x00,0x40,0x55,0x00,0x08,0x01,0x00,0x4a,0x24,
32930x25,0xb0,0x02,0x3c,0x9c,0x0c,0x43,0x34,0x88,0x0c,0x42,0x34,0x00,0x00,0x44,0xac,
32940x00,0x00,0x60,0xac,0x95,0x54,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x40,0x62,0x8c,
32950x00,0x00,0x00,0x00,0x02,0x12,0x02,0x00,0x3f,0x00,0x42,0x30,0x23,0x18,0x4a,0x00,
32960x2b,0x10,0x42,0x01,0x4e,0x55,0x00,0x08,0x0b,0x20,0x62,0x00,0xff,0xff,0x05,0x36,
32970x60,0x00,0x06,0x24,0xba,0x44,0x00,0x0c,0x24,0x00,0x04,0x24,0x84,0x0a,0x00,0x0c,
32980xe8,0x03,0x04,0x24,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x01,0x00,0x21,0x38,
32990x00,0x60,0x81,0x40,0x24,0x00,0x04,0x24,0xdd,0x44,0x00,0x0c,0xff,0xff,0x05,0x36,
33000x1f,0x00,0x52,0x30,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
33010xb3,0x0a,0x00,0x0c,0x64,0x00,0x04,0x24,0xb4,0x54,0x00,0x08,0x68,0x15,0x90,0x26,
33020x00,0xff,0x84,0x30,0x02,0x22,0x04,0x00,0x08,0x00,0x80,0x10,0x02,0x80,0x02,0x3c,
33030xff,0x00,0x02,0x24,0x04,0x00,0x82,0x10,0xcc,0xff,0x03,0x24,0x02,0x80,0x02,0x3c,
33040x08,0x00,0xe0,0x03,0x4e,0x58,0x43,0xa0,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,
33050x4e,0x58,0x44,0xa0,0x02,0x24,0x04,0x00,0xff,0x00,0x84,0x30,0xc0,0x10,0x04,0x00,
33060x21,0x10,0x44,0x00,0x80,0x10,0x02,0x00,0x21,0x10,0x44,0x00,0x02,0x80,0x03,0x3c,
33070x80,0x10,0x02,0x00,0x68,0x15,0x63,0x24,0x20,0x00,0x84,0x2c,0x09,0x00,0x80,0x10,
33080x21,0x10,0x43,0x00,0x68,0x51,0x43,0x8c,0x25,0xb0,0x02,0x3c,0xc4,0x02,0x42,0x34,
33090x02,0x19,0x03,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x43,0xac,0x08,0x00,0xe0,0x03,
33100x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x44,0x79,0x43,0x8c,0x25,0xb0,0x02,0x3c,
33110xc4,0x02,0x42,0x34,0x02,0x19,0x03,0x00,0x7f,0x00,0x63,0x30,0x00,0x00,0x43,0xac,
33120x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xff,0x00,0x85,0x30,0xd2,0xff,0xa3,0x24,
33130xfe,0xff,0xa2,0x24,0xda,0xff,0xa4,0x24,0x04,0x00,0x63,0x2c,0x08,0x00,0x84,0x2c,
33140x06,0x00,0x60,0x14,0xff,0x00,0x42,0x30,0xf0,0xff,0xa2,0x24,0xfc,0xff,0xa3,0x24,
33150x16,0x00,0x46,0x2c,0x03,0x00,0x80,0x10,0xff,0x00,0x62,0x30,0x08,0x00,0xe0,0x03,
33160x00,0x00,0x00,0x00,0xfa,0xff,0xa3,0x24,0xfc,0xff,0xc0,0x10,0x21,0x10,0xa0,0x00,
33170x08,0x00,0xe0,0x03,0xff,0x00,0x62,0x30,0x25,0xb0,0x04,0x3c,0x03,0x0d,0x85,0x34,
33180x00,0x00,0xa3,0x90,0x2d,0x0a,0x84,0x34,0xff,0x00,0x63,0x30,0x08,0x00,0x63,0x34,
33190x00,0x00,0xa3,0xa0,0x00,0x00,0xa2,0x90,0x00,0x00,0x00,0x00,0xf7,0x00,0x42,0x30,
33200x00,0x00,0xa2,0xa0,0x00,0x00,0x83,0x90,0x00,0x00,0x00,0x00,0x3f,0x00,0x63,0x30,
33210x00,0x00,0x83,0xa0,0x00,0x00,0x82,0x90,0x80,0xff,0x03,0x24,0x25,0x10,0x43,0x00,
33220x00,0x00,0x82,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x25,0xb0,0x02,0x3c,
33230xff,0x00,0x03,0x3c,0x82,0x01,0x49,0x34,0x81,0x01,0x48,0x34,0x24,0x10,0x83,0x00,
33240x02,0x3c,0x02,0x00,0x00,0xff,0x63,0x34,0x02,0x80,0x02,0x3c,0x68,0x15,0x45,0x24,
33250x02,0x32,0x04,0x00,0x01,0x00,0x02,0x24,0x24,0x20,0x83,0x00,0xc2,0x4c,0xa2,0xa0,
33260xb0,0x4c,0xa0,0xac,0xb4,0x4c,0xa0,0xac,0xb8,0x4c,0xa0,0xac,0x06,0x00,0x80,0x14,
33270xbc,0x4c,0xa0,0xac,0x00,0x00,0x02,0x91,0x00,0x00,0x23,0x91,0xc0,0x4c,0xa2,0xa0,
33280x08,0x00,0xe0,0x03,0xc1,0x4c,0xa3,0xa0,0xc1,0x4c,0xa7,0xa0,0x08,0x00,0xe0,0x03,
33290xc0,0x4c,0xa6,0xa0,0x02,0x80,0x03,0x3c,0x68,0x15,0x63,0x24,0xc1,0x4c,0x66,0x90,
33300xc0,0x4c,0x65,0x90,0x25,0xb0,0x02,0x3c,0x82,0x01,0x44,0x34,0x81,0x01,0x42,0x34,
33310x00,0x00,0x45,0xa0,0x00,0x00,0x86,0xa0,0x08,0x00,0xe0,0x03,0xc2,0x4c,0x60,0xa0,
33320x02,0x80,0x08,0x3c,0x68,0x15,0x04,0x25,0xc2,0x4c,0x82,0x90,0x00,0x00,0x00,0x00,
33330x15,0x00,0x40,0x10,0x21,0x18,0x00,0x00,0xb4,0x4c,0x82,0x8c,0xb0,0x4c,0x85,0x8c,
33340x25,0xb0,0x03,0x3c,0x40,0x11,0x02,0x00,0x2b,0x10,0xa2,0x00,0x82,0x01,0x67,0x34,
33350x0f,0x00,0x40,0x10,0x81,0x01,0x66,0x34,0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,
33360xf0,0x00,0x63,0x30,0x1f,0x00,0x42,0x30,0x00,0x00,0xc2,0xa0,0x00,0x00,0xe3,0xa0,
33370x68,0x15,0x02,0x25,0x01,0x00,0x03,0x24,0xbc,0x4c,0x40,0xac,0xb0,0x4c,0x40,0xac,
33380xb4,0x4c,0x40,0xac,0xb8,0x4c,0x40,0xac,0x08,0x00,0xe0,0x03,0x21,0x10,0x60,0x00,
33390xb8,0x4c,0x82,0x8c,0x25,0xb0,0x03,0x3c,0x82,0x01,0x69,0x34,0x40,0x11,0x02,0x00,
33400x2b,0x10,0xa2,0x00,0x0e,0x00,0x40,0x14,0x81,0x01,0x66,0x34,0xbc,0x4c,0x82,0x8c,
33410x00,0x00,0x00,0x00,0x40,0x11,0x02,0x00,0x2b,0x10,0xa2,0x00,0x08,0x00,0x40,0x14,
33420x00,0x00,0x00,0x00,0xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,0x00,0x00,0x00,0x00,
33430x00,0x00,0xc2,0xa0,0x00,0x00,0x23,0xa1,0xf7,0x56,0x00,0x08,0x68,0x15,0x02,0x25,
33440xc1,0x4c,0x83,0x90,0xc0,0x4c,0x82,0x90,0xf0,0x00,0x63,0x30,0x7f,0x00,0x42,0x30,
33450x00,0x00,0xc2,0xa0,0x00,0x00,0x23,0xa1,0xf7,0x56,0x00,0x08,0x68,0x15,0x02,0x25,
33460x02,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,0x3d,0x58,0x43,0xa0,
33470xcc,0xff,0x03,0x24,0x02,0x80,0x02,0x3c,0x08,0x00,0xe0,0x03,0x3d,0x58,0x43,0xa0,
33480x25,0xb0,0x03,0x3c,0x33,0x02,0x65,0x34,0x00,0x11,0x04,0x00,0x00,0x00,0xa2,0xa0,
33490x30,0x02,0x63,0x34,0x00,0x00,0x65,0x8c,0x0f,0x00,0x02,0x3c,0xff,0xff,0x42,0x34,
33500x24,0x28,0xa2,0x00,0x01,0x00,0x03,0x24,0x04,0x18,0x83,0x00,0x02,0x00,0xa0,0x10,
33510x21,0x10,0x00,0x00,0xff,0xff,0x62,0x30,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
33520xe0,0xff,0xbd,0x27,0x14,0x00,0xb1,0xaf,0x25,0xb0,0x11,0x3c,0x18,0x00,0xb2,0xaf,
33530x4c,0x00,0x22,0x36,0x1c,0x00,0xbf,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x44,0x90,
33540x02,0x80,0x03,0x3c,0x02,0x00,0x02,0x24,0xff,0x00,0x84,0x30,0x07,0x00,0x82,0x10,
33550x68,0x15,0x72,0x24,0x1c,0x00,0xbf,0x8f,0x18,0x00,0xb2,0x8f,0x14,0x00,0xb1,0x8f,
33560x10,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xe6,0x63,0x43,0x96,
33570x01,0x00,0x02,0x24,0xf7,0xff,0x62,0x14,0x21,0x20,0x00,0x00,0x22,0x57,0x00,0x0c,
33580x00,0x00,0x00,0x00,0x04,0x00,0x04,0x24,0x22,0x57,0x00,0x0c,0x21,0x80,0x40,0x00,
33590x25,0x80,0x02,0x02,0x33,0x02,0x23,0x36,0x08,0x00,0x02,0x24,0xff,0xff,0x10,0x32,
33600x40,0x00,0x25,0x36,0x00,0x00,0x62,0xa0,0xea,0xff,0x00,0x16,0x00,0x00,0x00,0x00,
33610x00,0x00,0xa2,0x94,0xe4,0x63,0x43,0x96,0xff,0xdf,0x42,0x30,0x00,0x20,0x44,0x34,
33620x01,0x00,0x63,0x24,0xe4,0x63,0x43,0xa6,0x00,0x00,0xa2,0xa4,0x00,0x00,0xa4,0xa4,
33630x3f,0x57,0x00,0x08,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,0x25,0xb0,0x02,0x3c,
33640x18,0x03,0x42,0x34,0x80,0x5d,0x63,0x24,0x00,0x00,0x43,0xac,0x63,0x00,0x02,0x24,
33650xff,0xff,0x42,0x24,0xff,0xff,0x41,0x04,0xff,0xff,0x42,0x24,0x02,0x80,0x02,0x3c,
33660x88,0x7d,0x45,0x94,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x8b,0x7d,0x66,0x90,
33670x98,0x7d,0x47,0x90,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xa3,0x7d,0x69,0x90,
33680xa5,0x7d,0x4a,0x90,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xa8,0x7d,0x6b,0x90,
33690xaa,0x7d,0x4c,0x90,0x07,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0x25,0xb0,0x04,0x3c,
33700x95,0x7d,0x43,0xa0,0xb0,0x03,0x84,0x34,0x02,0x80,0x02,0x3c,0x02,0x80,0x18,0x3c,
33710x8a,0x7d,0x08,0x93,0x00,0x00,0x85,0xac,0x96,0x7d,0x40,0xa0,0x02,0x80,0x02,0x3c,
33720x00,0x00,0x86,0xac,0x02,0x80,0x0f,0x3c,0x97,0x7d,0x40,0xa0,0x02,0x80,0x02,0x3c,
33730x00,0x00,0x87,0xac,0x68,0x15,0xee,0x25,0xb8,0x7d,0x40,0xa0,0xfd,0xff,0x02,0x24,
33740xd5,0x4a,0xc2,0xa1,0x01,0x00,0x03,0x24,0x00,0x78,0x02,0x24,0xd4,0x4a,0xc3,0xa1,
33750xd8,0x4a,0xc2,0xa5,0xff,0x07,0x03,0x24,0x0f,0x00,0x0d,0x31,0x02,0x00,0x02,0x24,
33760xda,0x4a,0xc3,0xa5,0x00,0x00,0x88,0xac,0x00,0x00,0x89,0xac,0x00,0x00,0x8a,0xac,
33770x00,0x00,0x8b,0xac,0x00,0x00,0x8c,0xac,0x17,0x00,0xa2,0x11,0x02,0x80,0x02,0x3c,
33780x8a,0x7d,0x02,0x93,0x01,0x00,0x03,0x24,0x0f,0x00,0x42,0x30,0x05,0x00,0x43,0x10,
33790x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0xca,0x7d,0x40,0xa4,0x08,0x00,0xe0,0x03,
33800x00,0x00,0x00,0x00,0x00,0x80,0x02,0x3c,0x68,0x15,0xe4,0x25,0x02,0xbc,0x42,0x34,
33810x68,0x4b,0x82,0xac,0x15,0x15,0x03,0x3c,0x02,0x02,0x02,0x3c,0x07,0x07,0x63,0x34,
33820x64,0x4b,0x82,0xac,0x02,0x80,0x02,0x3c,0x60,0x4b,0x83,0xac,0xca,0x7d,0x40,0xa4,
33830x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x8f,0x7d,0x44,0x90,0x06,0x00,0x03,0x24,
33840x15,0x00,0x83,0x10,0x0b,0x00,0x02,0x24,0x0a,0x00,0x82,0x10,0x00,0xe0,0x02,0x3c,
33850x68,0x15,0xe4,0x25,0x00,0xb2,0x42,0x34,0x00,0x1c,0x03,0x3c,0x68,0x4b,0x82,0xac,
33860x00,0x1c,0x63,0x34,0x00,0x04,0x02,0x24,0x60,0x4b,0x83,0xac,0x9a,0x57,0x00,0x08,
33870x64,0x4b,0x82,0xac,0x00,0x80,0x02,0x3c,0x00,0xbc,0x42,0x34,0x15,0x15,0x03,0x3c,
33880x68,0x4b,0xc2,0xad,0x07,0x07,0x63,0x34,0x03,0x03,0x02,0x3c,0x60,0x4b,0xc3,0xad,
33890x9a,0x57,0x00,0x08,0x64,0x4b,0xc2,0xad,0x00,0xc0,0x02,0x3c,0x00,0xb2,0x42,0x34,
33900x1c,0x1c,0x03,0x3c,0x68,0x4b,0xc2,0xad,0x07,0x07,0x63,0x34,0x00,0x04,0x02,0x24,
33910x60,0x4b,0xc3,0xad,0x9a,0x57,0x00,0x08,0x64,0x4b,0xc2,0xad,0x25,0xb0,0x02,0x3c,
33920x4d,0x00,0x44,0x34,0xff,0x00,0x03,0x3c,0xec,0x02,0x42,0x34,0x00,0x00,0x43,0xac,
33930x00,0x00,0x80,0xa0,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x3c,
33940x25,0xb0,0x02,0x3c,0x64,0x5f,0x63,0x24,0x18,0x03,0x42,0x34,0x00,0x00,0x43,0xac,
33950x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x7f,0x00,0x02,0x3c,0xfd,0xbf,0x45,0x34,
33960x80,0x04,0x03,0x3c,0x25,0x28,0xa3,0x00,0x00,0x08,0x04,0x3c,0x02,0x80,0x02,0x3c,
33970x68,0x15,0x42,0x24,0x25,0x28,0xa4,0x00,0x41,0xb0,0x03,0x3c,0x00,0x00,0x65,0xac,
33980x04,0x4b,0x45,0xac,0xfc,0x4a,0x45,0xac,0x08,0x00,0x63,0x34,0x86,0x00,0x05,0x24,
33990x00,0x00,0x65,0xa4,0x08,0x4b,0x45,0xa4,0x00,0x4b,0x40,0xac,0x0a,0x4b,0x40,0xa4,
34000x0c,0x4b,0x45,0xa4,0x00,0x60,0x01,0x40,0x01,0x00,0x21,0x34,0x00,0x60,0x81,0x40,
34010x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xf8,0x57,0x00,0x08,0x00,0x00,0x00,0x00,
34020x42,0xb0,0x02,0x3c,0xa0,0xff,0x03,0x24,0x01,0x00,0x42,0x34,0xe8,0xff,0xbd,0x27,
34030x21,0x20,0x00,0x00,0x01,0x00,0x05,0x24,0x00,0x01,0x06,0x24,0x00,0x00,0x43,0xa0,
34040x10,0x00,0xbf,0xaf,0xc4,0x0c,0x00,0x0c,0x00,0x00,0x00,0x00,0x10,0x00,0xbf,0x8f,
34050x03,0x00,0x04,0x24,0x01,0x00,0x05,0x24,0x40,0x1f,0x06,0x24,0xc4,0x0c,0x00,0x08,
34060x18,0x00,0xbd,0x27,0xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x14,0x00,0xbf,0xaf,
34070x21,0x5b,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,0x68,0x15,0x42,0x24,
34080x48,0x01,0x03,0x24,0xe0,0x63,0x43,0xac,0xdc,0x63,0x43,0xac,0x21,0x80,0x40,0x00,
34090x1f,0x00,0x03,0x24,0xff,0xff,0x63,0x24,0xc4,0x4c,0x40,0xa4,0xc6,0x4c,0x40,0xa4,
34100xc8,0x4c,0x40,0xa4,0xca,0x4c,0x40,0xa4,0xcc,0x4c,0x40,0xa4,0xce,0x4c,0x40,0xa4,
34110xd0,0x4c,0x40,0xa4,0xd2,0x4c,0x40,0xa4,0xd4,0x4c,0x40,0xa4,0xf5,0xff,0x61,0x04,
34120x24,0x00,0x42,0x24,0x25,0xb0,0x02,0x3c,0x10,0x00,0x03,0x24,0xb0,0x03,0x42,0x34,
34130x02,0x80,0x04,0x3c,0x8c,0x58,0x84,0x24,0x00,0x00,0x43,0xac,0x21,0x28,0x00,0x00,
34140x97,0x45,0x00,0x0c,0x04,0x00,0x06,0x24,0xef,0x5b,0x00,0x0c,0x00,0x00,0x00,0x00,
34150x71,0x5c,0x00,0x0c,0x8c,0x65,0x00,0xae,0xa7,0x5d,0x00,0x0c,0x00,0x00,0x00,0x00,
34160x4b,0x5e,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x03,0x3c,0x8e,0x7d,0x64,0x90,
34170x92,0x00,0x02,0x24,0x03,0x00,0x82,0x10,0x00,0x00,0x00,0x00,0xf7,0x5d,0x00,0x0c,
34180x00,0x00,0x00,0x00,0xdd,0x5d,0x00,0x0c,0x00,0x00,0x00,0x00,0x8b,0x5c,0x00,0x0c,
34190x00,0x00,0x00,0x00,0xe4,0x63,0x00,0xa6,0x67,0x5e,0x00,0x0c,0xe6,0x63,0x00,0xa6,
34200x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x02,0x80,0x04,0x3c,0x02,0x80,0x05,0x3c,
34210xf8,0x7a,0x82,0x24,0x00,0x7b,0xa3,0x24,0x18,0x00,0xbd,0x27,0x04,0x00,0x42,0xac,
34220xf8,0x7a,0x82,0xac,0x00,0x7b,0xa3,0xac,0x08,0x00,0xe0,0x03,0x04,0x00,0x63,0xac,
34230xe8,0xff,0xbd,0x27,0x10,0x00,0xb0,0xaf,0x01,0x80,0x02,0x3c,0x25,0xb0,0x10,0x3c,
34240x18,0x03,0x03,0x36,0x38,0x61,0x42,0x24,0x00,0x00,0x62,0xac,0x14,0x00,0xbf,0xaf,
34250x60,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xd5,0x58,0x00,0x0c,0x00,0x00,0x00,0x00,
34260x01,0x00,0x03,0x24,0x02,0x80,0x02,0x3c,0xfd,0x5a,0x00,0x0c,0xdb,0x60,0x43,0xa0,
34270xd1,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x32,0x41,0x00,0x0c,0x00,0x00,0x00,0x00,
34280x0b,0x58,0x00,0x0c,0x00,0x00,0x00,0x00,0x44,0x00,0x03,0x36,0x00,0x00,0x62,0x94,
34290x00,0x00,0x00,0x00,0x40,0x00,0x42,0x34,0x00,0x00,0x62,0xa4,0xd9,0x57,0x00,0x0c,
34300x00,0x00,0x00,0x00,0xfa,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0xc9,0x5a,0x00,0x0c,
34310x00,0x00,0x00,0x00,0x8e,0x5a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x80,0x04,0x3c,
34320xb4,0x24,0x84,0x24,0xe6,0x5a,0x00,0x0c,0x01,0x00,0x05,0x24,0x01,0x80,0x04,0x3c,
34330x08,0x1e,0x84,0x24,0xe6,0x5a,0x00,0x0c,0x02,0x00,0x05,0x24,0x81,0x4e,0x00,0x0c,
34340x00,0x00,0x00,0x00,0x00,0x80,0x04,0x3c,0x54,0x34,0x84,0x24,0xe6,0x5a,0x00,0x0c,
34350x03,0x00,0x05,0x24,0x02,0x80,0x02,0x3c,0x98,0x7d,0x43,0x90,0x43,0x00,0x04,0x36,
34360x29,0x00,0x60,0x10,0xd8,0x00,0x10,0x36,0x07,0x00,0x02,0x24,0x2b,0x00,0x62,0x10,
34370x25,0xb0,0x04,0x3c,0x10,0x02,0x86,0x34,0x43,0x00,0x85,0x34,0x03,0x00,0x02,0x24,
34380x10,0x00,0x03,0x24,0x00,0x00,0xa2,0xa0,0xd8,0x00,0x84,0x34,0x00,0x00,0xc3,0xa0,
34390x00,0x00,0x82,0x90,0x80,0xff,0x03,0x24,0x42,0xb0,0x05,0x3c,0x25,0x10,0x43,0x00,
34400x00,0x00,0x82,0xa0,0x25,0xb0,0x04,0x3c,0x44,0x00,0x84,0x34,0x00,0x00,0x82,0x94,
34410x00,0x00,0x00,0x00,0xc0,0x00,0x42,0x34,0x00,0x00,0x82,0xa4,0x00,0x00,0xa3,0x90,
34420x00,0x00,0x00,0x00,0x01,0x00,0x63,0x34,0x00,0x00,0xa3,0xa0,0xe0,0x57,0x00,0x0c,
34430x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,0x08,0x00,0x84,0x24,0x21,0x28,0x00,0x00,
34440x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,0x21,0x38,0x00,0x00,0xf8,0x57,0x00,0x0c,
34450x00,0x00,0x00,0x00,0x14,0x00,0xbf,0x8f,0x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,
34460x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,0x00,0x00,0x80,0xa0,0x00,0x00,0x03,0x92,
34470x80,0xff,0x02,0x24,0x25,0x18,0x62,0x00,0x00,0x00,0x03,0xa2,0x25,0xb0,0x04,0x3c,
34480x44,0x00,0x84,0x34,0x00,0x00,0x82,0x94,0x42,0xb0,0x05,0x3c,0xc0,0x00,0x42,0x34,
34490x00,0x00,0x82,0xa4,0x00,0x00,0xa3,0x90,0x00,0x00,0x00,0x00,0x01,0x00,0x63,0x34,
34500x00,0x00,0xa3,0xa0,0xe0,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x02,0x80,0x04,0x3c,
34510x08,0x00,0x84,0x24,0x21,0x28,0x00,0x00,0x21,0x30,0x00,0x00,0x31,0x1c,0x00,0x0c,
34520x21,0x38,0x00,0x00,0xf8,0x57,0x00,0x0c,0x00,0x00,0x00,0x00,0x14,0x00,0xbf,0x8f,
34530x10,0x00,0xb0,0x8f,0x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x18,0x00,0xbd,0x27,
34540x21,0x20,0x00,0x00,0x20,0xb0,0x06,0x3c,0xff,0xff,0x05,0x34,0x21,0x18,0x86,0x00,
34550x04,0x00,0x84,0x24,0x2a,0x10,0xa4,0x00,0x00,0x00,0x60,0xac,0xfb,0xff,0x40,0x10,
34560x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0xb8,0xff,0xbd,0x27,
34570x25,0xb0,0x04,0x3c,0x44,0x00,0xbf,0xaf,0x40,0x00,0xbe,0xaf,0x3c,0x00,0xb7,0xaf,
34580x38,0x00,0xb6,0xaf,0x34,0x00,0xb5,0xaf,0x30,0x00,0xb4,0xaf,0x2c,0x00,0xb3,0xaf,
34590x28,0x00,0xb2,0xaf,0x24,0x00,0xb1,0xaf,0x20,0x00,0xb0,0xaf,0x0a,0x00,0x83,0x34,
34600x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x20,0x00,0x42,0x30,0x0c,0x00,0x40,0x10,
34610x4c,0x87,0x02,0x3c,0x00,0x00,0x62,0x90,0x00,0x00,0x00,0x00,0x10,0x00,0x42,0x30,
34620x66,0x01,0x40,0x10,0x4c,0x87,0x02,0x3c,0x54,0x00,0x83,0x34,0x50,0x00,0x82,0x34,
34630x00,0x00,0x45,0xac,0x00,0x00,0x65,0xa4,0xf9,0x58,0x00,0x08,0x02,0x80,0x03,0x3c,
34640x54,0x00,0x85,0x34,0x00,0xe0,0x42,0x34,0x50,0x00,0x84,0x34,0x12,0x01,0x03,0x24,
34650x00,0x00,0x82,0xac,0x00,0x00,0xa3,0xac,0x02,0x80,0x03,0x3c,0x68,0x15,0x62,0x24,
34660xd5,0x4a,0x43,0x90,0xda,0x4a,0x45,0x94,0x25,0xb0,0x1e,0x3c,0x1c,0x00,0xa3,0xa3,
34670x60,0x4b,0x43,0x8c,0x58,0x00,0xc6,0x37,0xff,0xff,0x04,0x24,0x10,0x00,0xa3,0xaf,
34680x64,0x4b,0x43,0x8c,0x5c,0x00,0xc7,0x37,0x60,0x00,0xc8,0x37,0x14,0x00,0xa3,0xaf,
34690x68,0x4b,0x42,0x8c,0x64,0x00,0xc9,0x37,0x8a,0x00,0xca,0x37,0x18,0x00,0xa2,0xaf,
34700x24,0x10,0x02,0x3c,0x21,0x28,0xa2,0x00,0x4c,0x81,0x02,0x3c,0x00,0xe0,0x42,0x34,
34710x00,0x00,0xc2,0xac,0x96,0x01,0x03,0x24,0x28,0x28,0x02,0x24,0x00,0x00,0xe3,0xac,
34720x89,0x00,0xcb,0x37,0x00,0x00,0x04,0xad,0x8c,0x00,0xcc,0x37,0x00,0x00,0x24,0xad,
34730x09,0x00,0x03,0x24,0x00,0x00,0x42,0xa5,0x10,0x10,0x02,0x24,0x00,0x00,0x63,0xa1,
34740x8e,0x00,0xcd,0x37,0x00,0x00,0x82,0xa5,0x0a,0x0a,0x03,0x24,0x13,0x00,0x02,0x24,
34750x90,0x00,0xce,0x37,0x00,0x00,0xa3,0xa5,0x00,0x00,0xc2,0xa1,0x25,0xb0,0x02,0x3c,
34760x40,0x00,0x03,0x24,0x91,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0x25,0xb0,0x03,0x3c,
34770x3a,0x01,0x02,0x24,0x92,0x00,0x63,0x34,0x00,0x00,0x62,0xa4,0xb5,0x00,0xd1,0x37,
34780x21,0x00,0x03,0x24,0x00,0x00,0x23,0xa2,0x10,0x00,0xa2,0x8f,0xa0,0x00,0xd2,0x37,
34790xa4,0x00,0xd3,0x37,0x00,0x00,0x42,0xae,0x14,0x00,0xa3,0x8f,0xa8,0x00,0xd4,0x37,
34800xac,0x00,0xd5,0x37,0x00,0x00,0x63,0xae,0x18,0x00,0xa2,0x8f,0x25,0xb0,0x03,0x3c,
34810xb0,0x00,0x63,0x34,0x00,0x00,0x82,0xae,0x21,0x10,0x02,0x3c,0xff,0x77,0x42,0x34,
34820x00,0x00,0xa2,0xae,0x25,0xb0,0x02,0x3c,0xd8,0x00,0x42,0x34,0x00,0x00,0x65,0xac,
34830x00,0x00,0x40,0xa0,0x1c,0x00,0xa2,0x93,0x25,0xb0,0x03,0x3c,0xb4,0x00,0x63,0x34,
34840x00,0x00,0x62,0xa0,0x25,0xb0,0x03,0x3c,0x04,0x00,0x02,0x24,0xb6,0x00,0x63,0x34,
34850x00,0x00,0x62,0xa0,0x25,0xb0,0x03,0x3c,0x0f,0x00,0x02,0x24,0xba,0x00,0x63,0x34,
34860xb9,0x00,0xdf,0x37,0x00,0x00,0xe4,0xa3,0x00,0x00,0x62,0xa4,0x25,0xb0,0x02,0x3c,
34870x1a,0x01,0x42,0x34,0x16,0x01,0xd0,0x37,0x18,0x01,0xcf,0x37,0x00,0x00,0x00,0xa6,
34880x25,0xb0,0x03,0x3c,0x00,0x00,0xe0,0xa5,0x00,0x00,0x40,0xa4,0xff,0xff,0x02,0x3c,
34890xff,0x0f,0x42,0x34,0xdc,0x00,0x63,0x34,0x00,0x00,0x62,0xac,0x2f,0x00,0x03,0x3c,
34900x25,0xb0,0x02,0x3c,0x32,0x32,0x63,0x34,0xd0,0x01,0x42,0x34,0x00,0x00,0x43,0xac,
34910x5e,0x00,0x02,0x3c,0x25,0xb0,0x03,0x3c,0x32,0x43,0x42,0x34,0xd4,0x01,0x63,0x34,
34920x00,0x00,0x62,0xac,0x08,0x00,0x03,0x3c,0x25,0xb0,0x02,0x3c,0x30,0xa5,0x63,0x34,
34930xd8,0x01,0x42,0x34,0x00,0x00,0x43,0xac,0xdc,0x01,0xc4,0x37,0x02,0x80,0x03,0x3c,
34940x49,0xa5,0x02,0x34,0x8e,0x7d,0x6d,0x90,0x00,0x00,0x82,0xac,0xc2,0x00,0x02,0x3c,
34950x1a,0x06,0x03,0x24,0x51,0x10,0x42,0x34,0xe0,0x01,0xc5,0x37,0xf4,0x01,0xc6,0x37,
34960xf8,0x01,0xc7,0x37,0x07,0x07,0x04,0x24,0x00,0x00,0xa3,0xa4,0x00,0x02,0xc8,0x37,
34970x00,0x00,0xc4,0xa4,0x26,0x00,0x03,0x24,0x00,0x00,0xe2,0xac,0x03,0x02,0xc9,0x37,
34980x04,0x00,0x02,0x24,0x00,0x00,0x03,0xa5,0x36,0x02,0xca,0x37,0x00,0x00,0x22,0xa1,
34990xc0,0x01,0x03,0x24,0x0c,0x00,0x02,0x24,0x34,0x02,0xcb,0x37,0x00,0x00,0x42,0xa1,
35000x37,0x02,0xcc,0x37,0x00,0x00,0x63,0xa5,0x03,0x00,0x02,0x24,0x22,0x00,0x03,0x24,
35010x00,0x00,0x82,0xa1,0xd6,0x00,0xa3,0x11,0x1b,0x1b,0x02,0x3c,0x13,0x13,0x02,0x3c,
35020x13,0x13,0x42,0x34,0x60,0x01,0xc3,0x37,0x64,0x01,0xc4,0x37,0x68,0x01,0xc5,0x37,
35030x7c,0x01,0xca,0x37,0x6c,0x01,0xc6,0x37,0x70,0x01,0xc7,0x37,0x74,0x01,0xc8,0x37,
35040x78,0x01,0xc9,0x37,0x00,0x00,0x62,0xac,0x00,0x00,0x82,0xac,0x02,0x80,0x03,0x3c,
35050x00,0x00,0xa2,0xac,0x00,0x00,0xc2,0xac,0x00,0x00,0xe2,0xac,0x00,0x00,0x02,0xad,
35060x00,0x00,0x22,0xad,0x00,0x00,0x42,0xad,0x8e,0x7d,0x65,0x90,0x25,0xb0,0x0c,0x3c,
35070x01,0x70,0x03,0x3c,0x80,0x01,0x82,0x35,0x08,0x5f,0x63,0x34,0x22,0x00,0x04,0x24,
35080x00,0x00,0x43,0xac,0xb5,0x00,0xa4,0x10,0x0f,0x1f,0x02,0x3c,0x92,0x00,0x02,0x24,
35090xb2,0x00,0xa2,0x10,0x0f,0x1f,0x02,0x3c,0x0f,0x10,0x02,0x3c,0x00,0xf0,0x51,0x34,
35100xf7,0x01,0x92,0x35,0x15,0xf0,0x4d,0x34,0x77,0x00,0x0e,0x24,0x84,0x01,0x87,0x35,
35110x88,0x01,0x88,0x35,0x10,0xf0,0x44,0x34,0x8c,0x01,0x85,0x35,0x05,0xf0,0x42,0x34,
35120x00,0x00,0xed,0xac,0x90,0x01,0x83,0x35,0x00,0x00,0x04,0xad,0x94,0x01,0x86,0x35,
35130x00,0x00,0xa2,0xac,0xf5,0x0f,0x02,0x24,0x00,0x00,0x71,0xac,0x25,0xb0,0x05,0x3c,
35140x00,0x00,0xc2,0xac,0x98,0x01,0x89,0x35,0x9c,0x01,0x8a,0x35,0xf0,0x0f,0x03,0x24,
35150x0d,0x00,0x02,0x24,0x00,0x00,0x23,0xad,0xa0,0x01,0x8b,0x35,0x00,0x00,0x42,0xad,
35160xa7,0x01,0xb7,0x34,0xf6,0x01,0x8c,0x35,0xff,0xff,0x02,0x24,0x00,0x00,0x6d,0xad,
35170x00,0x00,0x8e,0xa1,0x00,0x00,0x4e,0xa2,0x00,0x00,0xe2,0xa2,0x25,0xb0,0x02,0x3c,
35180xa8,0x01,0xb6,0x34,0xff,0xff,0x09,0x24,0xac,0x01,0x42,0x34,0x00,0x00,0xc9,0xae,
35190x03,0x04,0x04,0x3c,0x00,0x00,0x49,0xac,0x07,0x08,0x03,0x3c,0x25,0xb0,0x02,0x3c,
35200x01,0x02,0x84,0x34,0x05,0x06,0x63,0x34,0xb4,0x01,0xb1,0x34,0xb8,0x01,0xb2,0x34,
35210xbc,0x01,0xb3,0x34,0xb0,0x01,0x42,0x34,0x00,0x00,0x44,0xac,0x00,0x00,0x23,0xae,
35220x25,0xb0,0x02,0x3c,0x00,0x00,0x44,0xae,0x00,0x00,0x63,0xae,0x25,0xb0,0x03,0x3c,
35230x0c,0x00,0x06,0x24,0xc0,0x01,0xb4,0x34,0xc1,0x01,0xb5,0x34,0x0d,0x00,0x08,0x24,
35240xc2,0x01,0x63,0x34,0xc3,0x01,0x42,0x34,0x00,0x00,0x86,0xa2,0xc4,0x01,0xab,0x34,
35250x00,0x00,0xa6,0xa2,0xc5,0x01,0xac,0x34,0x00,0x00,0x66,0xa0,0x0e,0x00,0x07,0x24,
35260x00,0x00,0x48,0xa0,0xc6,0x01,0xaa,0x34,0xc7,0x01,0xad,0x34,0x0f,0x00,0x02,0x24,
35270x00,0x00,0x68,0xa1,0x00,0x00,0x87,0xa1,0x00,0x00,0x47,0xa1,0x00,0x00,0xa2,0xa1,
35280x57,0x01,0x02,0x3c,0x48,0x00,0xbf,0x34,0x46,0x00,0xae,0x34,0x0e,0xe2,0x42,0x34,
35290x00,0x00,0xc0,0xa5,0x4c,0x00,0xbe,0x34,0x00,0x00,0xe2,0xaf,0x4d,0x00,0xb9,0x34,
35300x80,0xff,0x02,0x24,0x00,0x00,0xc0,0xa3,0x00,0x00,0x22,0xa3,0x25,0xb0,0x02,0x3c,
35310xbc,0x00,0x03,0x24,0x40,0x00,0x42,0x34,0x00,0x00,0x43,0xa4,0x25,0xb0,0x03,0x3c,
35320x64,0x03,0xb8,0x34,0xfc,0x37,0x02,0x24,0x40,0x00,0x63,0x34,0x00,0x00,0x00,0xa3,
35330xd8,0x00,0xa7,0x34,0x00,0x00,0x62,0xa4,0x00,0x00,0xe3,0x90,0x2a,0xb0,0x04,0x3c,
35340x80,0xff,0x02,0x24,0x26,0xb0,0x06,0x3c,0x25,0x18,0x62,0x00,0x30,0x00,0x89,0x34,
35350x20,0x20,0x02,0x24,0x38,0x00,0x84,0x34,0x00,0x00,0xe3,0xa0,0x79,0x00,0xc8,0x34,
35360x00,0x00,0x82,0xa4,0x40,0x00,0x03,0x24,0x16,0x00,0x02,0x24,0x00,0x00,0x23,0xa1,
35370x94,0x00,0xaa,0x34,0x00,0x00,0x02,0xa1,0x98,0x00,0xab,0x34,0x64,0x00,0x03,0x24,
35380x22,0x00,0x02,0x24,0x00,0x00,0x43,0xa5,0x7c,0x00,0xd1,0x34,0x00,0x00,0x62,0xa5,
35390x04,0x00,0x12,0x24,0x9c,0x00,0xac,0x34,0x7a,0x00,0xc6,0x34,0x20,0x0c,0x02,0x24,
35400x0a,0x00,0x03,0x24,0x00,0x00,0xd2,0xa0,0x9a,0x00,0xad,0x34,0x00,0x00,0x22,0xa6,
35410x96,0x00,0xae,0x34,0x00,0x00,0x83,0xa1,0xff,0x03,0x02,0x24,0x02,0x00,0x03,0x24,
35420x00,0x00,0xa2,0xa5,0x00,0x00,0xc3,0xa5,0x25,0xb0,0x03,0x3c,0x20,0x00,0x02,0x24,
35430xb7,0x00,0x63,0x34,0x00,0x00,0x62,0xa0,0x25,0xb0,0x02,0x3c,0x09,0x00,0x03,0x24,
35440x89,0x00,0x42,0x34,0x00,0x00,0x43,0xa0,0x44,0x00,0xa5,0x34,0x00,0x00,0xa2,0x94,
35450x02,0x80,0x03,0x3c,0x68,0x15,0x66,0x24,0xff,0xfd,0x03,0x24,0x24,0x10,0x43,0x00,
35460x00,0x00,0xa2,0xa4,0x00,0x00,0xa3,0x94,0xd5,0x4a,0xc4,0x90,0x29,0xb0,0x02,0x3c,
35470x40,0x00,0x42,0x34,0x00,0x02,0x63,0x34,0x00,0x00,0xa3,0xa4,0x00,0x00,0x52,0xa0,
35480xd3,0x0a,0x00,0x0c,0x00,0x00,0x00,0x00,0x44,0x00,0xbf,0x8f,0x40,0x00,0xbe,0x8f,
35490x3c,0x00,0xb7,0x8f,0x38,0x00,0xb6,0x8f,0x34,0x00,0xb5,0x8f,0x30,0x00,0xb4,0x8f,
35500x2c,0x00,0xb3,0x8f,0x28,0x00,0xb2,0x8f,0x24,0x00,0xb1,0x8f,0x20,0x00,0xb0,0x8f,
35510x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x48,0x00,0xbd,0x27,0x54,0x00,0x85,0x34,
35520x00,0xe0,0x42,0x34,0x50,0x00,0x84,0x34,0x12,0x01,0x03,0x24,0x00,0x00,0x82,0xac,
35530x00,0x00,0xa3,0xa4,0xf9,0x58,0x00,0x08,0x02,0x80,0x03,0x3c,0x00,0xf0,0x51,0x34,
35540xf7,0x01,0x92,0x35,0x15,0xf0,0x4d,0x34,0xad,0x59,0x00,0x08,0xff,0xff,0x0e,0x24,
35550x8b,0x59,0x00,0x08,0x1b,0x1b,0x42,0x34,0x25,0xb0,0x03,0x3c,0x25,0xb0,0x08,0x3c,
35560xfc,0x37,0x02,0x24,0x40,0x00,0x63,0x34,0x02,0x80,0x04,0x3c,0x00,0x00,0x62,0xa4,
35570x14,0x80,0x84,0x24,0xff,0x00,0x07,0x24,0xb0,0x03,0x06,0x35,0x00,0x00,0x83,0x94,
35580x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,0x21,0x18,0x68,0x00,0x0a,0x00,0x47,0x10,
35590xff,0x00,0x65,0x30,0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xac,
35600x00,0x00,0xc3,0xac,0x04,0x00,0x82,0x8c,0x08,0x00,0x84,0x24,0x00,0x00,0xc2,0xac,
35610xf2,0xff,0xa7,0x14,0x00,0x00,0x00,0x00,0x25,0xb0,0x08,0x3c,0x01,0x80,0x02,0x3c,
35620x0c,0x7a,0x44,0x24,0xff,0x00,0x07,0x24,0xb0,0x03,0x06,0x35,0x00,0x00,0x83,0x94,
35630x00,0x00,0x00,0x00,0xff,0x00,0x62,0x30,0x21,0x18,0x68,0x00,0x0a,0x00,0x47,0x10,
35640xff,0x00,0x65,0x30,0x04,0x00,0x82,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xac,
35650x00,0x00,0xc3,0xac,0x04,0x00,0x82,0x8c,0x08,0x00,0x84,0x24,0x00,0x00,0xc2,0xac,
35660xf2,0xff,0xa7,0x14,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,
35670x01,0x80,0x02,0x3c,0x02,0x80,0x05,0x3c,0x10,0x6b,0x42,0x24,0x02,0x80,0x03,0x3c,
35680xcc,0x7d,0xa2,0xac,0x00,0x80,0x02,0x3c,0x6c,0x7e,0x60,0xac,0xcc,0x7d,0xa4,0x24,
35690x02,0x80,0x03,0x3c,0xc8,0x06,0x42,0x24,0x70,0x7e,0x60,0xa4,0x08,0x00,0x82,0xac,
35700x02,0x80,0x03,0x3c,0x00,0x80,0x02,0x3c,0x72,0x7e,0x60,0xa4,0x02,0x80,0x06,0x3c,
35710x08,0x0a,0x42,0x24,0x00,0x80,0x03,0x3c,0x74,0x7e,0xc7,0x24,0x14,0x00,0x82,0xac,
35720x38,0x08,0x63,0x24,0x02,0x80,0x02,0x3c,0x74,0x7e,0xc0,0xac,0x10,0x00,0x83,0xac,
35730x04,0x00,0xe0,0xac,0x7c,0x7e,0x40,0xa0,0x00,0x80,0x02,0x3c,0x88,0x19,0x42,0x24,
35740x3c,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,0x00,0x80,0x02,0x3c,0x24,0x0c,0x63,0x24,
35750x78,0x0f,0x42,0x24,0x1c,0x00,0x83,0xac,0x20,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,
35760x00,0x80,0x02,0x3c,0xc8,0x12,0x63,0x24,0x28,0x16,0x42,0x24,0x24,0x00,0x83,0xac,
35770x28,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,0x01,0x80,0x02,0x3c,0x4c,0x1f,0x63,0x24,
35780xd0,0x04,0x42,0x24,0x2c,0x00,0x83,0xac,0x30,0x00,0x82,0xac,0x00,0x80,0x03,0x3c,
35790x00,0x80,0x02,0x3c,0xe4,0x19,0x63,0x24,0x00,0x03,0x42,0x24,0x38,0x00,0x83,0xac,
35800x08,0x00,0xe0,0x03,0x4c,0x00,0x82,0xac,0x25,0xb0,0x02,0x3c,0x08,0x00,0x42,0x34,
35810x00,0x00,0x43,0x8c,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x0e,0x3c,
35820x02,0x80,0x08,0x3c,0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,0xf8,0x03,0x4d,0x24,
35830x00,0x14,0x6c,0x24,0x01,0x00,0x07,0x24,0x00,0x00,0xcb,0x25,0xff,0xff,0x0a,0x24,
35840x00,0x04,0x09,0x25,0x80,0x1a,0x07,0x00,0x21,0x10,0x6b,0x00,0x00,0x00,0x42,0xac,
35850x90,0x00,0x4a,0xac,0x00,0x04,0x04,0x8d,0x01,0x00,0xe7,0x24,0x08,0x00,0x45,0x24,
35860x21,0x18,0x6d,0x00,0x05,0x00,0xe6,0x28,0x04,0x00,0x82,0xac,0x00,0x00,0x44,0xac,
35870x04,0x00,0x49,0xac,0x00,0x04,0x02,0xad,0x8c,0x00,0x40,0xac,0x6c,0x00,0xa3,0xac,
35880xf0,0xff,0xc0,0x14,0x68,0x00,0xac,0xac,0x08,0x00,0xe0,0x03,0x00,0x00,0xc9,0xad,
35890x05,0x00,0xa2,0x2c,0x13,0x00,0x40,0x10,0xff,0xff,0x07,0x24,0x02,0x80,0x02,0x3c,
35900x80,0x1a,0x05,0x00,0x00,0x00,0x42,0x24,0x0e,0x00,0xa0,0x10,0x21,0x30,0x62,0x00,
35910x90,0x00,0xc3,0x8c,0xff,0xff,0x02,0x24,0x0a,0x00,0x62,0x14,0x00,0x00,0x00,0x00,
35920x8c,0x00,0xc2,0x8c,0x00,0x00,0x00,0x00,0x06,0x00,0x40,0x14,0x00,0x00,0x00,0x00,
35930x01,0x00,0x02,0x24,0x88,0x00,0xc4,0xac,0x8c,0x00,0xc2,0xac,0x90,0x00,0xc5,0xac,
35940x21,0x38,0xa0,0x00,0x08,0x00,0xe0,0x03,0x21,0x10,0xe0,0x00,0x25,0xb0,0x04,0x3c,
35950x01,0x80,0x02,0x3c,0x18,0x03,0x85,0x34,0xf4,0x6b,0x42,0x24,0xe0,0xff,0xbd,0x27,
35960x00,0x00,0xa2,0xac,0x1b,0x00,0x86,0x34,0xdb,0xff,0x03,0x24,0x27,0x00,0x84,0x34,
35970x07,0x00,0x02,0x24,0x14,0x00,0xb1,0xaf,0x10,0x00,0xb0,0xaf,0x00,0x00,0x83,0xa0,
35980x18,0x00,0xbf,0xaf,0x00,0x00,0xc2,0xa0,0x01,0x00,0x11,0x24,0x21,0x80,0x00,0x00,
35990x7a,0x42,0x00,0x0c,0x21,0x20,0x00,0x02,0x01,0x00,0x02,0x26,0xff,0x00,0x50,0x30,
36000x2b,0x18,0x30,0x02,0xfa,0xff,0x60,0x10,0x00,0x00,0x00,0x00,0x7a,0x42,0x00,0x0c,
36010x21,0x20,0x00,0x00,0x18,0x00,0xbf,0x8f,0x14,0x00,0xb1,0x8f,0x10,0x00,0xb0,0x8f,
36020x01,0x00,0x02,0x24,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x08,0x00,0xe0,0x03,
36030x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x00,0x00,0x00,0x00,0x02,0x80,0x02,0x3c,
36040x68,0x15,0x42,0x24,0x40,0x10,0x03,0x3c,0xff,0xff,0x44,0x30,0x25,0xc0,0x83,0x00,
36050x94,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0xa0,0x64,0x58,0xac,0x40,0x00,0x18,0x27,
36060xac,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0xb8,0x64,0x58,0xac,0x40,0x00,0x18,0x27,
36070xe0,0xff,0xbd,0x27,0xc4,0x64,0x58,0xac,0x40,0x00,0x18,0x27,0x1c,0x00,0xb7,0xaf,
36080x18,0x00,0xb6,0xaf,0x14,0x00,0xb5,0xaf,0x10,0x00,0xb4,0xaf,0x0c,0x00,0xb3,0xaf,
36090x08,0x00,0xb2,0xaf,0x04,0x00,0xb1,0xaf,0x00,0x00,0xb0,0xaf,0xd0,0x64,0x58,0xac,
36100xa0,0x64,0x45,0x8c,0xac,0x64,0x46,0x8c,0xb8,0x64,0x47,0x8c,0xc4,0x64,0x48,0x8c,
36110xd0,0x64,0x49,0x8c,0x40,0x00,0x18,0x27,0xdc,0x64,0x58,0xac,0x21,0x50,0x00,0x03,
36120x25,0x20,0x83,0x00,0x40,0x00,0x18,0x27,0x20,0x10,0x03,0x3c,0x90,0x64,0x44,0xac,
36130x9c,0x64,0x45,0xac,0xa8,0x64,0x46,0xac,0xb4,0x64,0x47,0xac,0xc0,0x64,0x48,0xac,
36140xcc,0x64,0x49,0xac,0x25,0xb0,0x06,0x3c,0x28,0x64,0x43,0xac,0x24,0x64,0x43,0xac,
36150x34,0x64,0x43,0xac,0x30,0x64,0x43,0xac,0x40,0x64,0x43,0xac,0x3c,0x64,0x43,0xac,
36160x4c,0x64,0x43,0xac,0x48,0x64,0x43,0xac,0xe8,0x64,0x58,0xac,0x00,0x02,0x18,0x27,
36170xd8,0x64,0x4a,0xac,0x00,0x65,0x58,0xac,0x58,0x64,0x43,0xac,0x54,0x64,0x43,0xac,
36180x64,0x64,0x43,0xac,0x60,0x64,0x43,0xac,0x70,0x64,0x43,0xac,0x6c,0x64,0x43,0xac,
36190xac,0x00,0xc4,0x34,0xb0,0x00,0xc5,0x34,0x00,0x00,0x92,0x8c,0xe8,0x64,0x50,0x8c,
36200x00,0x00,0xb3,0x8c,0x21,0x10,0x04,0x3c,0x23,0x10,0x09,0x3c,0x22,0x10,0x0c,0x3c,
36210x02,0x80,0x14,0x3c,0x02,0x80,0x15,0x3c,0x02,0x80,0x16,0x3c,0x02,0x80,0x17,0x3c,
36220x24,0x10,0x05,0x3c,0x21,0x88,0x00,0x03,0x08,0x7b,0x87,0x26,0x00,0x04,0x18,0x27,
36230x10,0x7b,0xa8,0x26,0x18,0x7b,0xca,0x26,0x20,0x7b,0xeb,0x26,0x00,0x04,0x2d,0x35,
36240x00,0x40,0x8e,0x34,0x00,0x80,0x8f,0x35,0x00,0x01,0xc6,0x34,0xe4,0x64,0x50,0xac,
36250xfc,0x64,0x51,0xac,0x64,0x65,0x4d,0xac,0x28,0x65,0x52,0xac,0x34,0x65,0x4e,0xac,
36260x58,0x65,0x4f,0xac,0x4c,0x65,0x53,0xac,0x00,0x00,0xc5,0xac,0x48,0x65,0x45,0xac,
36270x68,0x65,0x43,0xac,0x74,0x65,0x58,0xac,0x7c,0x64,0x43,0xac,0x78,0x64,0x43,0xac,
36280x06,0x65,0x40,0xa4,0x05,0x65,0x40,0xa0,0x04,0x65,0x40,0xa0,0x5c,0x65,0x49,0xac,
36290x60,0x65,0x49,0xac,0x20,0x65,0x44,0xac,0x24,0x65,0x44,0xac,0x2c,0x65,0x44,0xac,
36300x30,0x65,0x44,0xac,0x50,0x65,0x4c,0xac,0x54,0x65,0x4c,0xac,0x44,0x65,0x45,0xac,
36310x6c,0x65,0x43,0xac,0x78,0x65,0x58,0xac,0x04,0x00,0x08,0xad,0x08,0x7b,0x87,0xae,
36320x04,0x00,0x4a,0xad,0x10,0x7b,0xa8,0xae,0x04,0x00,0x6b,0xad,0x18,0x7b,0xca,0xae,
36330x20,0x7b,0xeb,0xae,0x04,0x00,0xe7,0xac,0x02,0x80,0x02,0x3c,0x00,0x14,0x43,0x24,
36340x21,0x20,0xe0,0x00,0x03,0x00,0x06,0x24,0x21,0x10,0x80,0x00,0xff,0xff,0xc6,0x24,
36350x08,0x00,0x78,0xac,0x00,0x00,0x63,0xac,0x10,0x00,0x60,0xac,0x00,0x00,0x67,0xac,
36360x21,0x20,0x60,0x00,0x04,0x00,0x62,0xac,0x00,0x00,0x43,0xac,0x00,0x01,0x18,0x27,
36370xf5,0xff,0xc1,0x04,0x18,0x00,0x63,0x24,0x02,0x80,0x02,0x3c,0x10,0x7b,0x49,0x24,
36380x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x04,0x00,0x28,0x8d,0x60,0x14,0x4b,0x24,
36390x04,0x00,0xe4,0xac,0x00,0x14,0x6a,0x24,0x01,0x00,0x07,0x24,0x21,0x28,0x00,0x00,
36400x07,0x00,0x06,0x24,0x21,0x20,0xab,0x00,0x21,0x10,0xaa,0x00,0xff,0xff,0xc6,0x24,
36410x68,0x00,0x58,0xac,0x70,0x00,0x47,0xac,0x18,0x00,0xa5,0x24,0x00,0x00,0x89,0xac,
36420x04,0x00,0x88,0xac,0x00,0x00,0x04,0xad,0x00,0x01,0x18,0x27,0xf5,0xff,0xc1,0x04,
36430x21,0x40,0x80,0x00,0x02,0x80,0x02,0x3c,0x18,0x7b,0x4a,0x24,0x02,0x80,0x03,0x3c,
36440x02,0x80,0x02,0x3c,0x04,0x00,0x45,0x8d,0x20,0x15,0x4b,0x24,0x04,0x00,0x24,0xad,
36450x02,0x00,0x07,0x24,0x00,0x14,0x69,0x24,0x21,0x20,0x00,0x00,0x01,0x00,0x06,0x24,
36460x21,0x40,0x8b,0x00,0x21,0x10,0x89,0x00,0xff,0xff,0xc6,0x24,0x28,0x01,0x58,0xac,
36470x30,0x01,0x47,0xac,0x18,0x00,0x84,0x24,0x00,0x00,0x0a,0xad,0x04,0x00,0x05,0xad,
36480x00,0x00,0xa8,0xac,0x00,0x02,0x18,0x27,0xf5,0xff,0xc1,0x04,0x21,0x28,0x00,0x01,
36490x02,0x80,0x05,0x3c,0x20,0x7b,0xa5,0x24,0x04,0x00,0xa6,0x8c,0x1c,0x00,0xb7,0x8f,
36500x18,0x00,0xb6,0x8f,0x14,0x00,0xb5,0x8f,0x10,0x00,0xb4,0x8f,0x0c,0x00,0xb3,0x8f,
36510x08,0x00,0xb2,0x8f,0x04,0x00,0xb1,0x8f,0x00,0x00,0xb0,0x8f,0x02,0x80,0x07,0x3c,
36520x02,0x80,0x03,0x3c,0x50,0x15,0xe4,0x24,0x00,0x14,0x63,0x24,0x03,0x00,0x02,0x24,
36530x20,0x00,0xbd,0x27,0x58,0x01,0x78,0xac,0x04,0x00,0x48,0xad,0x04,0x00,0xa4,0xac,
36540x60,0x01,0x62,0xac,0x50,0x15,0xe5,0xac,0x04,0x00,0x86,0xac,0x08,0x00,0xe0,0x03,
36550x00,0x00,0xc4,0xac,0xd0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x20,0x00,0xb2,0xaf,
36560x02,0x80,0x03,0x3c,0x4c,0x91,0x52,0x24,0x02,0x80,0x02,0x3c,0x28,0x00,0xb4,0xaf,
36570x24,0x00,0xb3,0xaf,0x1c,0x00,0xb1,0xaf,0x18,0x00,0xb0,0xaf,0x2c,0x00,0xbf,0xaf,
36580xd8,0x90,0x73,0x24,0x68,0x15,0x50,0x24,0x21,0x88,0x00,0x00,0x02,0x80,0x14,0x3c,
36590xee,0x4e,0x00,0x0c,0x21,0x20,0x20,0x02,0x78,0x51,0x05,0x8e,0x6c,0x00,0x66,0x8e,
36600xb8,0x90,0x82,0x26,0x6c,0x00,0x43,0x8e,0x1b,0x00,0x44,0x90,0xff,0xf1,0x02,0x24,
36610x21,0x18,0x66,0x00,0x24,0x28,0xa2,0x00,0x00,0x21,0x04,0x00,0x42,0x18,0x03,0x00,
36620x00,0x02,0xa5,0x34,0x44,0x51,0x03,0xae,0x68,0x51,0x04,0xae,0x78,0x51,0x05,0xae,
36630x6c,0x51,0x04,0xae,0x21,0x30,0x00,0x00,0x21,0x10,0x06,0x02,0x01,0x00,0xc6,0x24,
36640x1d,0x00,0xc3,0x28,0x99,0x51,0x40,0xa0,0x7c,0x51,0x40,0xa0,0xfa,0xff,0x60,0x14,
36650xb6,0x51,0x40,0xa0,0x01,0x00,0x31,0x26,0x20,0x00,0x22,0x2a,0xd4,0x51,0x00,0xae,
36660xe3,0xff,0x40,0x14,0x94,0x00,0x10,0x26,0x02,0x80,0x02,0x3c,0x02,0x80,0x03,0x3c,
36670x68,0x15,0x4b,0x24,0x02,0x80,0x02,0x3c,0x4c,0x91,0x6f,0x24,0xd8,0x90,0x4d,0x24,
36680x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0xb8,0x90,0x6e,0x24,0x98,0x90,0x4c,0x24,
36690x21,0x88,0x00,0x00,0x80,0x18,0x11,0x00,0x21,0x20,0x6d,0x00,0x21,0x10,0x6f,0x00,
36700x21,0x28,0x2e,0x02,0x21,0x30,0x2c,0x02,0x00,0x00,0x88,0x8c,0x00,0x00,0xa9,0x90,
36710x00,0x00,0xc7,0x90,0x00,0x00,0x4a,0x8c,0x21,0x10,0x2b,0x02,0x01,0x00,0x31,0x26,
36720x21,0x18,0x6b,0x00,0x1d,0x00,0x24,0x2a,0xec,0x44,0x68,0xac,0xca,0x44,0x47,0xa0,
36730x60,0x45,0x6a,0xac,0xef,0xff,0x80,0x14,0x90,0x44,0x49,0xa0,0x02,0x80,0x02,0x3c,
36740x68,0x15,0x4a,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x02,0x3c,0x74,0x8f,0x6b,0x24,
36750x14,0x8e,0x4c,0x24,0x21,0x88,0x00,0x00,0x21,0x48,0x00,0x00,0x21,0x30,0x00,0x00,
36760x21,0x40,0x2a,0x01,0x21,0x38,0x2b,0x01,0x21,0x10,0xe6,0x00,0x91,0x00,0x44,0x90,
36770x00,0x00,0x45,0x90,0x21,0x18,0x06,0x01,0x01,0x00,0xc6,0x24,0x05,0x00,0xc2,0x28,
36780xc5,0x43,0x64,0xa0,0xf8,0xff,0x40,0x14,0x34,0x43,0x65,0xa0,0x21,0x10,0x2c,0x02,
36790x1d,0x00,0x44,0x90,0x00,0x00,0x45,0x90,0x21,0x18,0x2a,0x02,0x01,0x00,0x31,0x26,
36800x1d,0x00,0x22,0x2a,0x73,0x44,0x64,0xa0,0x56,0x44,0x65,0xa0,0xeb,0xff,0x40,0x14,
36810x05,0x00,0x29,0x25,0x52,0x00,0x02,0x24,0x10,0x00,0xa2,0xa3,0x41,0x00,0x03,0x24,
36820x4d,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x1c,0x97,0xe7,0x24,0x11,0x00,0xa3,0xa3,
36830x12,0x00,0xa2,0xa3,0xe8,0x03,0x03,0x24,0x01,0x00,0x02,0x24,0x00,0x80,0x06,0x3c,
36840x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xf0,0x37,0xc6,0x24,0x0c,0x00,0xe3,0xac,
36850x14,0x00,0xe2,0xa0,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x2c,0x00,0xbf,0x8f,
36860x28,0x00,0xb4,0x8f,0x24,0x00,0xb3,0x8f,0x20,0x00,0xb2,0x8f,0x1c,0x00,0xb1,0x8f,
36870x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x30,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
36880x02,0x80,0x02,0x3c,0x42,0x00,0x03,0x24,0x10,0x00,0xa3,0xa3,0x55,0x60,0x40,0xa0,
36890x4e,0x00,0x03,0x24,0x43,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0x54,0x97,0xe7,0x24,
36900x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24,
36910x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0xdc,0x44,0xc6,0x24,
36920x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
36930x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
36940x20,0x00,0xbd,0x27,0x48,0xfd,0xbd,0x27,0xb4,0x02,0xb3,0xaf,0x02,0x80,0x02,0x3c,
36950x02,0x80,0x13,0x3c,0x24,0x92,0x46,0x24,0x68,0x15,0x63,0x26,0xb0,0x02,0xb2,0xaf,
36960xac,0x02,0xb1,0xaf,0xa8,0x02,0xb0,0xaf,0x03,0x40,0x60,0xa0,0x21,0x38,0xa0,0x03,
36970x90,0x00,0xc8,0x24,0x00,0x00,0xc2,0x8c,0x04,0x00,0xc3,0x8c,0x08,0x00,0xc4,0x8c,
36980x0c,0x00,0xc5,0x8c,0x10,0x00,0xc6,0x24,0x00,0x00,0xe2,0xac,0x04,0x00,0xe3,0xac,
36990x08,0x00,0xe4,0xac,0x0c,0x00,0xe5,0xac,0xf6,0xff,0xc8,0x14,0x10,0x00,0xe7,0x24,
37000x00,0x00,0xc3,0x8c,0x02,0x80,0x02,0x3c,0xb8,0x92,0x58,0x24,0x00,0x00,0xe3,0xac,
37010x98,0x00,0xb9,0x27,0x00,0x01,0x12,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93,
37020x09,0x00,0x04,0x93,0x0d,0x00,0x05,0x93,0x00,0x00,0x11,0x93,0x02,0x00,0x0d,0x93,
37030x04,0x00,0x10,0x93,0x06,0x00,0x0c,0x93,0x08,0x00,0x0f,0x93,0x0a,0x00,0x07,0x93,
37040x0c,0x00,0x0e,0x93,0x0e,0x00,0x06,0x93,0x03,0x00,0x08,0x93,0x07,0x00,0x09,0x93,
37050x0b,0x00,0x0a,0x93,0x0f,0x00,0x0b,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00,
37060x00,0x22,0x04,0x00,0x00,0x2a,0x05,0x00,0x25,0x10,0x51,0x00,0x25,0x18,0x70,0x00,
37070x25,0x20,0x8f,0x00,0x25,0x28,0xae,0x00,0x00,0x6c,0x0d,0x00,0x00,0x64,0x0c,0x00,
37080x00,0x3c,0x07,0x00,0x00,0x34,0x06,0x00,0x25,0x68,0xa2,0x01,0x25,0x60,0x83,0x01,
37090x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0x00,0x46,0x08,0x00,0x00,0x4e,0x09,0x00,
37100x00,0x56,0x0a,0x00,0x00,0x5e,0x0b,0x00,0x25,0x40,0x0d,0x01,0x25,0x48,0x2c,0x01,
37110x25,0x50,0x47,0x01,0x25,0x58,0x66,0x01,0x10,0x00,0x18,0x27,0x00,0x00,0x28,0xaf,
37120x04,0x00,0x29,0xaf,0x08,0x00,0x2a,0xaf,0x0c,0x00,0x2b,0xaf,0xd2,0xff,0x12,0x17,
37130x10,0x00,0x39,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93,0x00,0x00,0x09,0x93,
37140x02,0x00,0x04,0x93,0x04,0x00,0x08,0x93,0x06,0x00,0x05,0x93,0x07,0x00,0x06,0x93,
37150x03,0x00,0x07,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00,0x25,0x10,0x49,0x00,
37160x25,0x18,0x68,0x00,0x00,0x24,0x04,0x00,0x00,0x2c,0x05,0x00,0x25,0x20,0x82,0x00,
37170x25,0x28,0xa3,0x00,0x00,0x3e,0x07,0x00,0x00,0x36,0x06,0x00,0x02,0x80,0x02,0x3c,
37180x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0xc0,0x93,0x58,0x24,0x04,0x00,0x26,0xaf,
37190x00,0x00,0x27,0xaf,0x00,0x01,0x12,0x27,0xa0,0x01,0xb9,0x27,0x01,0x00,0x02,0x93,
37200x05,0x00,0x03,0x93,0x09,0x00,0x04,0x93,0x0d,0x00,0x05,0x93,0x00,0x00,0x11,0x93,
37210x02,0x00,0x0d,0x93,0x04,0x00,0x10,0x93,0x06,0x00,0x0c,0x93,0x08,0x00,0x0f,0x93,
37220x0a,0x00,0x07,0x93,0x0c,0x00,0x0e,0x93,0x0e,0x00,0x06,0x93,0x03,0x00,0x08,0x93,
37230x07,0x00,0x09,0x93,0x0b,0x00,0x0a,0x93,0x0f,0x00,0x0b,0x93,0x00,0x12,0x02,0x00,
37240x00,0x1a,0x03,0x00,0x00,0x22,0x04,0x00,0x00,0x2a,0x05,0x00,0x25,0x10,0x51,0x00,
37250x25,0x18,0x70,0x00,0x25,0x20,0x8f,0x00,0x25,0x28,0xae,0x00,0x00,0x6c,0x0d,0x00,
37260x00,0x64,0x0c,0x00,0x00,0x3c,0x07,0x00,0x00,0x34,0x06,0x00,0x25,0x68,0xa2,0x01,
37270x25,0x60,0x83,0x01,0x25,0x38,0xe4,0x00,0x25,0x30,0xc5,0x00,0x00,0x46,0x08,0x00,
37280x00,0x4e,0x09,0x00,0x00,0x56,0x0a,0x00,0x00,0x5e,0x0b,0x00,0x25,0x40,0x0d,0x01,
37290x25,0x48,0x2c,0x01,0x25,0x50,0x47,0x01,0x25,0x58,0x66,0x01,0x10,0x00,0x18,0x27,
37300x00,0x00,0x28,0xaf,0x04,0x00,0x29,0xaf,0x08,0x00,0x2a,0xaf,0x0c,0x00,0x2b,0xaf,
37310xd2,0xff,0x12,0x17,0x10,0x00,0x39,0x27,0x01,0x00,0x02,0x93,0x05,0x00,0x03,0x93,
37320x00,0x00,0x09,0x93,0x02,0x00,0x04,0x93,0x04,0x00,0x08,0x93,0x06,0x00,0x05,0x93,
37330x07,0x00,0x06,0x93,0x03,0x00,0x07,0x93,0x00,0x12,0x02,0x00,0x00,0x1a,0x03,0x00,
37340x25,0x10,0x49,0x00,0x25,0x18,0x68,0x00,0x00,0x24,0x04,0x00,0x00,0x2c,0x05,0x00,
37350x25,0x20,0x82,0x00,0x25,0x28,0xa3,0x00,0x00,0x3e,0x07,0x00,0x00,0x36,0x06,0x00,
37360x25,0x30,0xc5,0x00,0x25,0x38,0xe4,0x00,0x02,0x80,0x02,0x3c,0x04,0x00,0x26,0xaf,
37370x00,0x00,0x27,0xaf,0x68,0x15,0x46,0x24,0x21,0x50,0x00,0x00,0x80,0x20,0x0a,0x00,
37380x21,0x10,0x9d,0x00,0x00,0x00,0x45,0x8c,0x01,0x00,0x43,0x25,0xff,0x00,0x6a,0x30,
37390x21,0x20,0x86,0x00,0x25,0x00,0x42,0x2d,0xf8,0xff,0x40,0x14,0x18,0x40,0x85,0xac,
37400x02,0x80,0x02,0x3c,0x68,0x15,0x4b,0x24,0x21,0x50,0x00,0x00,0xc0,0x10,0x0a,0x00,
37410x21,0x48,0x5d,0x00,0x21,0x38,0x00,0x00,0x21,0x40,0x4b,0x00,0x21,0x10,0x27,0x01,
37420xa0,0x01,0x46,0x90,0x98,0x00,0x45,0x90,0x01,0x00,0xe4,0x24,0x21,0x18,0x07,0x01,
37430xff,0x00,0x87,0x30,0x08,0x00,0xe2,0x2c,0xb4,0x41,0x66,0xa0,0xf7,0xff,0x40,0x14,
37440xac,0x40,0x65,0xa0,0x01,0x00,0x42,0x25,0xff,0x00,0x4a,0x30,0x21,0x00,0x43,0x2d,
37450xef,0xff,0x60,0x14,0xc0,0x10,0x0a,0x00,0x25,0xb0,0x02,0x3c,0x0a,0x00,0x42,0x34,
37460x00,0x00,0x43,0x90,0x00,0x00,0x00,0x00,0x20,0x00,0x63,0x30,0x42,0x00,0x60,0x10,
37470x68,0x15,0x64,0x26,0x33,0x00,0x02,0x24,0xc1,0x42,0x62,0xa1,0x1c,0x00,0x03,0x24,
37480x0f,0x00,0x02,0x24,0xbc,0x42,0x63,0xa1,0xbd,0x42,0x62,0xa1,0x68,0x15,0x65,0x26,
37490x08,0x40,0xa4,0x8c,0xff,0x7f,0x08,0x3c,0xff,0xff,0x08,0x35,0xc0,0xff,0x02,0x24,
37500x24,0x20,0x88,0x00,0x24,0x20,0x82,0x00,0x0c,0x00,0x84,0x34,0xff,0xc0,0x02,0x24,
37510x24,0x20,0x82,0x00,0xc0,0xff,0x02,0x3c,0xff,0xff,0x42,0x34,0x00,0x18,0x84,0x34,
37520xbf,0xff,0x03,0x3c,0x24,0x20,0x82,0x00,0xff,0xff,0x63,0x34,0x7f,0xff,0x02,0x3c,
37530x24,0x20,0x83,0x00,0xff,0xff,0x42,0x34,0x24,0x20,0x82,0x00,0x0c,0x40,0xa6,0x8c,
37540x7f,0xff,0x03,0x24,0x40,0x40,0x84,0x34,0xff,0xff,0x02,0x3c,0x24,0x20,0x83,0x00,
37550xff,0x7f,0x42,0x34,0xff,0xbf,0x03,0x3c,0x10,0x40,0xa7,0x8c,0x24,0x20,0x82,0x00,
37560xff,0xff,0x63,0x34,0xff,0x9f,0x02,0x3c,0x24,0x30,0xc3,0x00,0xff,0xff,0x42,0x34,
37570xff,0x3f,0x03,0x3c,0x24,0x20,0x82,0x00,0xff,0xff,0x63,0x34,0x12,0x00,0x02,0x24,
37580xb4,0x02,0xb3,0x8f,0xb0,0x02,0xb2,0x8f,0xac,0x02,0xb1,0x8f,0xa8,0x02,0xb0,0x8f,
37590x24,0x38,0xe3,0x00,0xc7,0x42,0xa2,0xa0,0x1f,0x00,0x03,0x24,0x01,0x00,0x02,0x24,
37600x24,0x30,0xc8,0x00,0xbe,0x42,0xa3,0xa0,0xc0,0x42,0xa2,0xa0,0xff,0x00,0x03,0x24,
37610xff,0xff,0x02,0x24,0xb8,0x02,0xbd,0x27,0x08,0x40,0xa4,0xac,0x10,0x40,0xa7,0xac,
37620x0c,0x40,0xa6,0xac,0xc2,0x42,0xa2,0xa0,0xc4,0x42,0xa3,0xa4,0xbf,0x42,0xa0,0xa0,
37630x08,0x00,0xe0,0x03,0xc6,0x42,0xa0,0xa0,0x33,0x00,0x02,0x24,0xc1,0x42,0x82,0xa0,
37640x0d,0x00,0x03,0x24,0x03,0x00,0x02,0x24,0xbc,0x42,0x83,0xa0,0x65,0x5d,0x00,0x08,
37650xbd,0x42,0x82,0xa0,0xe0,0xff,0xbd,0x27,0x02,0x80,0x07,0x3c,0x68,0x15,0xe7,0x24,
37660x18,0x00,0xbf,0xaf,0x00,0x40,0xe3,0x8c,0xf0,0xff,0x02,0x24,0x02,0x80,0x08,0x3c,
37670x24,0x18,0x62,0x00,0xff,0xf0,0x02,0x24,0x24,0x18,0x62,0x00,0x00,0x40,0xe3,0xac,
37680x1c,0x00,0x03,0x24,0x36,0x00,0x02,0x24,0xcf,0x42,0xe3,0xa0,0x20,0x00,0x03,0x24,
37690xce,0x42,0xe2,0xa0,0xd1,0x42,0xe3,0xa0,0x32,0x00,0x02,0x24,0x20,0x00,0x03,0x24,
37700xd0,0x42,0xe2,0xa0,0xc8,0x42,0xe3,0xa4,0x0a,0x00,0x02,0x24,0x00,0x02,0x03,0x24,
37710xd2,0x42,0xe2,0xa0,0xcc,0x42,0xe3,0xa4,0x00,0x01,0x02,0x24,0x49,0x00,0x03,0x24,
37720x38,0x97,0x08,0x25,0xff,0xff,0x0a,0x34,0x01,0x00,0x09,0x24,0x11,0x00,0xa3,0xa3,
37730xca,0x42,0xe2,0xa4,0xd0,0x07,0x03,0x24,0x44,0x00,0x02,0x24,0x00,0x80,0x06,0x3c,
37740x10,0x00,0xa2,0xa3,0x10,0x00,0xa5,0x27,0x47,0x00,0x02,0x24,0x21,0x20,0x00,0x01,
37750x54,0x45,0xc6,0x24,0x04,0x40,0xea,0xac,0x02,0x40,0xe9,0xa0,0x0c,0x00,0x03,0xad,
37760x14,0x00,0x09,0xa1,0xe6,0x42,0xe0,0xa0,0xdc,0x63,0xea,0xac,0xd7,0x42,0xe0,0xa0,
37770x12,0x00,0xa2,0xa3,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,
37780x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
37790x02,0x80,0x02,0x3c,0x50,0x00,0x03,0x24,0x10,0x00,0xa3,0xa3,0x2a,0x62,0x40,0xa0,
37800x41,0x00,0x03,0x24,0x52,0x00,0x02,0x24,0x02,0x80,0x07,0x3c,0xc4,0x97,0xe7,0x24,
37810x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24,
37820x01,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0x88,0x5b,0xc6,0x24,
37830x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
37840x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
37850x20,0x00,0xbd,0x27,0xd8,0xff,0xbd,0x27,0x18,0x00,0xb0,0xaf,0x02,0x80,0x10,0x3c,
37860x68,0x15,0x10,0x26,0x20,0x00,0xbf,0xaf,0x1c,0x00,0xb1,0xaf,0x00,0x40,0x09,0x8e,
37870xff,0xff,0x02,0x24,0xff,0x00,0x4b,0x30,0x0f,0xff,0x02,0x24,0x24,0x48,0x22,0x01,
37880xff,0xff,0x02,0x3c,0xff,0x0f,0x42,0x34,0x24,0x48,0x22,0x01,0x01,0x00,0x07,0x3c,
37890x47,0x00,0x02,0x24,0x3b,0x00,0x03,0x24,0x02,0x80,0x08,0x3c,0x10,0x00,0xa2,0xa3,
37900x11,0x00,0xa3,0xa3,0xe0,0x97,0x08,0x25,0x56,0x30,0xea,0x34,0xd0,0x07,0x02,0x24,
37910x01,0x00,0x03,0x24,0xf4,0x98,0xe7,0x34,0x00,0x80,0x06,0x3c,0x04,0x43,0x0b,0xae,
37920x00,0x40,0x09,0xae,0x43,0x00,0x11,0x24,0x10,0x00,0xa5,0x27,0x0c,0x43,0x07,0xae,
37930x10,0x43,0x0a,0xae,0x0c,0x00,0x02,0xad,0x14,0x00,0x03,0xa1,0x08,0x43,0x00,0xae,
37940x14,0x43,0x00,0xae,0x18,0x43,0x00,0xae,0x21,0x20,0x00,0x01,0xe4,0x4e,0xc6,0x24,
37950x12,0x00,0xb1,0xa3,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x1e,0x00,0x02,0x24,
37960x21,0x43,0x02,0xa2,0x4a,0x00,0x03,0x24,0x45,0x00,0x02,0x24,0x1c,0x43,0x03,0xa2,
37970x1d,0x43,0x02,0xa2,0x23,0x00,0x03,0x24,0x3e,0x00,0x02,0x24,0x1e,0x43,0x11,0xa2,
37980x1f,0x43,0x02,0xa2,0x20,0x43,0x03,0xa2,0x20,0x00,0xbf,0x8f,0x1c,0x00,0xb1,0x8f,
37990x18,0x00,0xb0,0x8f,0x08,0x00,0xe0,0x03,0x28,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,
38000x3b,0x00,0x02,0x24,0x43,0x00,0x03,0x24,0x10,0x00,0xa2,0xa3,0x11,0x00,0xa3,0xa3,
38010x36,0x00,0x02,0x24,0x02,0x80,0x03,0x3c,0x02,0x80,0x07,0x3c,0xfc,0x97,0xe7,0x24,
38020x12,0x00,0xa2,0xa3,0x3b,0x58,0x60,0xa0,0xd0,0x07,0x02,0x24,0x01,0x00,0x03,0x24,
38030x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0xe0,0x00,0x20,0x53,0xc6,0x24,
38040x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
38050x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
38060x20,0x00,0xbd,0x27,0xff,0xff,0x07,0x24,0x02,0x80,0x02,0x3c,0xe0,0xff,0xbd,0x27,
38070x3d,0x58,0x47,0xa0,0x3b,0x00,0x03,0x24,0x43,0x00,0x02,0x24,0x10,0x00,0xa3,0xa3,
38080x11,0x00,0xa2,0xa3,0x36,0x00,0x03,0x24,0x16,0x00,0x02,0x24,0x02,0x80,0x08,0x3c,
38090x18,0x98,0x08,0x25,0x12,0x00,0xa3,0xa3,0x13,0x00,0xa2,0xa3,0xd0,0x07,0x03,0x24,
38100x01,0x00,0x02,0x24,0x00,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,0x21,0x20,0x00,0x01,
38110x0c,0x00,0x03,0xad,0x14,0x00,0x02,0xa1,0x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,
38120xb8,0x54,0xc6,0x24,0x18,0x00,0xbf,0x8f,0x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,
38130x20,0x00,0xbd,0x27,0xe0,0xff,0xbd,0x27,0x02,0x80,0x02,0x3c,0x52,0x00,0x03,0x24,
38140x10,0x00,0xa3,0xa3,0x4c,0x79,0x40,0xa4,0x54,0x00,0x03,0x24,0x53,0x00,0x02,0x24,
38150x02,0x80,0x07,0x3c,0x34,0x98,0xe7,0x24,0x11,0x00,0xa2,0xa3,0x12,0x00,0xa3,0xa3,
38160xf4,0x01,0x02,0x24,0x01,0x00,0x03,0x24,0x01,0x80,0x06,0x3c,0x10,0x00,0xa5,0x27,
38170x21,0x20,0xe0,0x00,0xc8,0x5c,0xc6,0x24,0x0c,0x00,0xe2,0xac,0x14,0x00,0xe3,0xa0,
38180x18,0x00,0xbf,0xaf,0xfb,0x0c,0x00,0x0c,0x13,0x00,0xa0,0xa3,0x18,0x00,0xbf,0x8f,
38190x00,0x00,0x00,0x00,0x08,0x00,0xe0,0x03,0x20,0x00,0xbd,0x27,0x00,0x00,0x00,0x00,
38200x00,0x00,0x00,0x00,0x78,0x0c,0x00,0x00,0x01,0x00,0x00,0x5e,0x78,0x0c,0x00,0x00,
38210x01,0x00,0x01,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x02,0x5e,0x78,0x0c,0x00,0x00,
38220x01,0x00,0x03,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x04,0x5d,0x78,0x0c,0x00,0x00,
38230x01,0x00,0x05,0x5b,0x78,0x0c,0x00,0x00,0x01,0x00,0x06,0x59,0x78,0x0c,0x00,0x00,
38240x01,0x00,0x07,0x57,0x78,0x0c,0x00,0x00,0x01,0x00,0x08,0x55,0x78,0x0c,0x00,0x00,
38250x01,0x00,0x09,0x53,0x78,0x0c,0x00,0x00,0x01,0x00,0x0a,0x51,0x78,0x0c,0x00,0x00,
38260x01,0x00,0x0b,0x4f,0x78,0x0c,0x00,0x00,0x01,0x00,0x0c,0x4d,0x78,0x0c,0x00,0x00,
38270x01,0x00,0x0d,0x4b,0x78,0x0c,0x00,0x00,0x01,0x00,0x0e,0x49,0x78,0x0c,0x00,0x00,
38280x01,0x00,0x0f,0x47,0x78,0x0c,0x00,0x00,0x01,0x00,0x10,0x45,0x78,0x0c,0x00,0x00,
38290x01,0x00,0x11,0x43,0x78,0x0c,0x00,0x00,0x01,0x00,0x12,0x41,0x78,0x0c,0x00,0x00,
38300x01,0x00,0x13,0x3f,0x78,0x0c,0x00,0x00,0x01,0x00,0x14,0x3d,0x78,0x0c,0x00,0x00,
38310x01,0x00,0x15,0x3b,0x78,0x0c,0x00,0x00,0x01,0x00,0x16,0x39,0x78,0x0c,0x00,0x00,
38320x01,0x00,0x17,0x37,0x78,0x0c,0x00,0x00,0x01,0x00,0x18,0x35,0x78,0x0c,0x00,0x00,
38330x01,0x00,0x19,0x33,0x78,0x0c,0x00,0x00,0x01,0x00,0x1a,0x31,0x78,0x0c,0x00,0x00,
38340x01,0x00,0x1b,0x2f,0x78,0x0c,0x00,0x00,0x01,0x00,0x1c,0x2d,0x78,0x0c,0x00,0x00,
38350x01,0x00,0x1d,0x2b,0x78,0x0c,0x00,0x00,0x01,0x00,0x1e,0x29,0x78,0x0c,0x00,0x00,
38360x01,0x00,0x1f,0x27,0x78,0x0c,0x00,0x00,0x01,0x00,0x20,0x25,0x78,0x0c,0x00,0x00,
38370x01,0x00,0x21,0x23,0x78,0x0c,0x00,0x00,0x01,0x00,0x22,0x21,0x78,0x0c,0x00,0x00,
38380x01,0x00,0x23,0x1f,0x78,0x0c,0x00,0x00,0x01,0x00,0x24,0x1d,0x78,0x0c,0x00,0x00,
38390x01,0x00,0x25,0x1b,0x78,0x0c,0x00,0x00,0x01,0x00,0x26,0x19,0x78,0x0c,0x00,0x00,
38400x01,0x00,0x27,0x17,0x78,0x0c,0x00,0x00,0x01,0x00,0x28,0x15,0x78,0x0c,0x00,0x00,
38410x01,0x00,0x29,0x13,0x78,0x0c,0x00,0x00,0x01,0x00,0x2a,0x11,0x78,0x0c,0x00,0x00,
38420x01,0x00,0x2b,0x0f,0x78,0x0c,0x00,0x00,0x01,0x00,0x2c,0x0d,0x78,0x0c,0x00,0x00,
38430x01,0x00,0x2d,0x0b,0x78,0x0c,0x00,0x00,0x01,0x00,0x2e,0x09,0x78,0x0c,0x00,0x00,
38440x01,0x00,0x2f,0x07,0x78,0x0c,0x00,0x00,0x01,0x00,0x30,0x05,0x78,0x0c,0x00,0x00,
38450x01,0x00,0x31,0x03,0x78,0x0c,0x00,0x00,0x01,0x00,0x32,0x01,0x78,0x0c,0x00,0x00,
38460x01,0x00,0x33,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x34,0x01,0x78,0x0c,0x00,0x00,
38470x01,0x00,0x35,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x36,0x01,0x78,0x0c,0x00,0x00,
38480x01,0x00,0x37,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x38,0x01,0x78,0x0c,0x00,0x00,
38490x01,0x00,0x39,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3a,0x01,0x78,0x0c,0x00,0x00,
38500x01,0x00,0x3b,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3c,0x01,0x78,0x0c,0x00,0x00,
38510x01,0x00,0x3d,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x3e,0x01,0x78,0x0c,0x00,0x00,
38520x01,0x00,0x3f,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x40,0x5e,0x78,0x0c,0x00,0x00,
38530x01,0x00,0x41,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x42,0x5e,0x78,0x0c,0x00,0x00,
38540x01,0x00,0x43,0x5e,0x78,0x0c,0x00,0x00,0x01,0x00,0x44,0x5d,0x78,0x0c,0x00,0x00,
38550x01,0x00,0x45,0x5b,0x78,0x0c,0x00,0x00,0x01,0x00,0x46,0x59,0x78,0x0c,0x00,0x00,
38560x01,0x00,0x47,0x57,0x78,0x0c,0x00,0x00,0x01,0x00,0x48,0x55,0x78,0x0c,0x00,0x00,
38570x01,0x00,0x49,0x53,0x78,0x0c,0x00,0x00,0x01,0x00,0x4a,0x51,0x78,0x0c,0x00,0x00,
38580x01,0x00,0x4b,0x4f,0x78,0x0c,0x00,0x00,0x01,0x00,0x4c,0x4d,0x78,0x0c,0x00,0x00,
38590x01,0x00,0x4d,0x4b,0x78,0x0c,0x00,0x00,0x01,0x00,0x4e,0x49,0x78,0x0c,0x00,0x00,
38600x01,0x00,0x4f,0x47,0x78,0x0c,0x00,0x00,0x01,0x00,0x50,0x45,0x78,0x0c,0x00,0x00,
38610x01,0x00,0x51,0x43,0x78,0x0c,0x00,0x00,0x01,0x00,0x52,0x41,0x78,0x0c,0x00,0x00,
38620x01,0x00,0x53,0x3f,0x78,0x0c,0x00,0x00,0x01,0x00,0x54,0x3d,0x78,0x0c,0x00,0x00,
38630x01,0x00,0x55,0x3b,0x78,0x0c,0x00,0x00,0x01,0x00,0x56,0x39,0x78,0x0c,0x00,0x00,
38640x01,0x00,0x57,0x37,0x78,0x0c,0x00,0x00,0x01,0x00,0x58,0x35,0x78,0x0c,0x00,0x00,
38650x01,0x00,0x59,0x33,0x78,0x0c,0x00,0x00,0x01,0x00,0x5a,0x31,0x78,0x0c,0x00,0x00,
38660x01,0x00,0x5b,0x2f,0x78,0x0c,0x00,0x00,0x01,0x00,0x5c,0x2d,0x78,0x0c,0x00,0x00,
38670x01,0x00,0x5d,0x2b,0x78,0x0c,0x00,0x00,0x01,0x00,0x5e,0x29,0x78,0x0c,0x00,0x00,
38680x01,0x00,0x5f,0x27,0x78,0x0c,0x00,0x00,0x01,0x00,0x60,0x25,0x78,0x0c,0x00,0x00,
38690x01,0x00,0x61,0x23,0x78,0x0c,0x00,0x00,0x01,0x00,0x62,0x21,0x78,0x0c,0x00,0x00,
38700x01,0x00,0x63,0x1f,0x78,0x0c,0x00,0x00,0x01,0x00,0x64,0x1d,0x78,0x0c,0x00,0x00,
38710x01,0x00,0x65,0x1b,0x78,0x0c,0x00,0x00,0x01,0x00,0x66,0x19,0x78,0x0c,0x00,0x00,
38720x01,0x00,0x67,0x17,0x78,0x0c,0x00,0x00,0x01,0x00,0x68,0x15,0x78,0x0c,0x00,0x00,
38730x01,0x00,0x69,0x13,0x78,0x0c,0x00,0x00,0x01,0x00,0x6a,0x11,0x78,0x0c,0x00,0x00,
38740x01,0x00,0x6b,0x0f,0x78,0x0c,0x00,0x00,0x01,0x00,0x6c,0x0d,0x78,0x0c,0x00,0x00,
38750x01,0x00,0x6d,0x0b,0x78,0x0c,0x00,0x00,0x01,0x00,0x6e,0x09,0x78,0x0c,0x00,0x00,
38760x01,0x00,0x6f,0x07,0x78,0x0c,0x00,0x00,0x01,0x00,0x70,0x05,0x78,0x0c,0x00,0x00,
38770x01,0x00,0x71,0x03,0x78,0x0c,0x00,0x00,0x01,0x00,0x72,0x01,0x78,0x0c,0x00,0x00,
38780x01,0x00,0x73,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x74,0x01,0x78,0x0c,0x00,0x00,
38790x01,0x00,0x75,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x76,0x01,0x78,0x0c,0x00,0x00,
38800x01,0x00,0x77,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x78,0x01,0x78,0x0c,0x00,0x00,
38810x01,0x00,0x79,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7a,0x01,0x78,0x0c,0x00,0x00,
38820x01,0x00,0x7b,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7c,0x01,0x78,0x0c,0x00,0x00,
38830x01,0x00,0x7d,0x01,0x78,0x0c,0x00,0x00,0x01,0x00,0x7e,0x01,0x78,0x0c,0x00,0x00,
38840x01,0x00,0x7f,0x01,0x78,0x0c,0x00,0x00,0x1e,0x00,0x00,0x30,0x78,0x0c,0x00,0x00,
38850x1e,0x00,0x01,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x02,0x30,0x78,0x0c,0x00,0x00,
38860x1e,0x00,0x03,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x04,0x30,0x78,0x0c,0x00,0x00,
38870x1e,0x00,0x05,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x06,0x30,0x78,0x0c,0x00,0x00,
38880x1e,0x00,0x07,0x30,0x78,0x0c,0x00,0x00,0x1e,0x00,0x08,0x3e,0x78,0x0c,0x00,0x00,
38890x1e,0x00,0x09,0x40,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0a,0x42,0x78,0x0c,0x00,0x00,
38900x1e,0x00,0x0b,0x44,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0c,0x46,0x78,0x0c,0x00,0x00,
38910x1e,0x00,0x0d,0x48,0x78,0x0c,0x00,0x00,0x1e,0x00,0x0e,0x48,0x78,0x0c,0x00,0x00,
38920x1e,0x00,0x0f,0x4a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x10,0x4a,0x78,0x0c,0x00,0x00,
38930x1e,0x00,0x11,0x4c,0x78,0x0c,0x00,0x00,0x1e,0x00,0x12,0x4c,0x78,0x0c,0x00,0x00,
38940x1e,0x00,0x13,0x4e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x14,0x50,0x78,0x0c,0x00,0x00,
38950x1e,0x00,0x15,0x50,0x78,0x0c,0x00,0x00,0x1e,0x00,0x16,0x50,0x78,0x0c,0x00,0x00,
38960x1e,0x00,0x17,0x52,0x78,0x0c,0x00,0x00,0x1e,0x00,0x18,0x52,0x78,0x0c,0x00,0x00,
38970x1e,0x00,0x19,0x52,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1a,0x54,0x78,0x0c,0x00,0x00,
38980x1e,0x00,0x1b,0x54,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1c,0x54,0x78,0x0c,0x00,0x00,
38990x1e,0x00,0x1d,0x56,0x78,0x0c,0x00,0x00,0x1e,0x00,0x1e,0x56,0x78,0x0c,0x00,0x00,
39000x1e,0x00,0x1f,0x56,0x78,0x0c,0x00,0x00,0x1e,0x00,0x20,0x56,0x78,0x0c,0x00,0x00,
39010x1e,0x00,0x21,0x58,0x78,0x0c,0x00,0x00,0x1e,0x00,0x22,0x58,0x78,0x0c,0x00,0x00,
39020x1e,0x00,0x23,0x58,0x78,0x0c,0x00,0x00,0x1e,0x00,0x24,0x58,0x78,0x0c,0x00,0x00,
39030x1e,0x00,0x25,0x5a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x26,0x5a,0x78,0x0c,0x00,0x00,
39040x1e,0x00,0x27,0x5a,0x78,0x0c,0x00,0x00,0x1e,0x00,0x28,0x5c,0x78,0x0c,0x00,0x00,
39050x1e,0x00,0x29,0x5c,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2a,0x5e,0x78,0x0c,0x00,0x00,
39060x1e,0x00,0x2b,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2c,0x5e,0x78,0x0c,0x00,0x00,
39070x1e,0x00,0x2d,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x2e,0x5e,0x78,0x0c,0x00,0x00,
39080x1e,0x00,0x2f,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x30,0x5e,0x78,0x0c,0x00,0x00,
39090x1e,0x00,0x31,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x32,0x5e,0x78,0x0c,0x00,0x00,
39100x1e,0x00,0x33,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x34,0x5e,0x78,0x0c,0x00,0x00,
39110x1e,0x00,0x35,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x36,0x5e,0x78,0x0c,0x00,0x00,
39120x1e,0x00,0x37,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x38,0x5e,0x78,0x0c,0x00,0x00,
39130x1e,0x00,0x39,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3a,0x5e,0x78,0x0c,0x00,0x00,
39140x1e,0x00,0x3b,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3c,0x5e,0x78,0x0c,0x00,0x00,
39150x1e,0x00,0x3d,0x5e,0x78,0x0c,0x00,0x00,0x1e,0x00,0x3e,0x5e,0x78,0x0c,0x00,0x00,
39160x1e,0x00,0x3f,0x5e,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x08,0x00,0x00,
39170x00,0x00,0x04,0x03,0x04,0x08,0x00,0x00,0x03,0x00,0x00,0x00,0x08,0x08,0x00,0x00,
39180x00,0xfc,0x00,0x00,0x0c,0x08,0x00,0x00,0x0a,0x00,0x00,0x04,0x10,0x08,0x00,0x00,
39190xff,0x10,0x10,0x80,0x14,0x08,0x00,0x00,0x10,0x3d,0x0c,0x02,0x18,0x08,0x00,0x00,
39200xc5,0x03,0x00,0x00,0x1c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x00,
39210x04,0x00,0x00,0x00,0x24,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x28,0x08,0x00,0x00,
39220x04,0x00,0x00,0x00,0x2c,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x30,0x08,0x00,0x00,
39230x04,0x00,0x00,0x00,0x34,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x38,0x08,0x00,0x00,
39240x04,0x00,0x00,0x00,0x3c,0x08,0x00,0x00,0x00,0x02,0x69,0x00,0x40,0x08,0x00,0x00,
39250x00,0x00,0x00,0x00,0x44,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x08,0x00,0x00,
39260x00,0x00,0x00,0x00,0x4c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x08,0x00,0x00,
39270x00,0x00,0x00,0x00,0x54,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x08,0x00,0x00,
39280x65,0xa9,0x65,0xa9,0x5c,0x08,0x00,0x00,0x65,0xa9,0x65,0xa9,0x60,0x08,0x00,0x00,
39290x30,0x01,0x7f,0x0f,0x64,0x08,0x00,0x00,0x30,0x01,0x7f,0x0f,0x68,0x08,0x00,0x00,
39300x30,0x01,0x7f,0x0f,0x6c,0x08,0x00,0x00,0x30,0x01,0x7f,0x0f,0x70,0x08,0x00,0x00,
39310x00,0x03,0x00,0x03,0x74,0x08,0x00,0x00,0x00,0x03,0x00,0x03,0x78,0x08,0x00,0x00,
39320x00,0x00,0x00,0x00,0x7c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x08,0x00,0x00,
39330x00,0x00,0x00,0x00,0x94,0x08,0x00,0x00,0xfe,0xff,0xff,0xff,0x98,0x08,0x00,0x00,
39340x10,0x20,0x30,0x40,0x9c,0x08,0x00,0x00,0x50,0x60,0x70,0x00,0xb0,0x08,0x00,0x00,
39350x00,0x00,0x00,0x00,0xe0,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x08,0x00,0x00,
39360x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x04,0x0e,0x00,0x00,
39370x03,0x03,0x03,0x03,0x08,0x0e,0x00,0x00,0x03,0x03,0x00,0x00,0x0c,0x0e,0x00,0x00,
39380x00,0x00,0x00,0x00,0x10,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x14,0x0e,0x00,0x00,
39390x03,0x03,0x03,0x03,0x18,0x0e,0x00,0x00,0x03,0x03,0x03,0x03,0x1c,0x0e,0x00,0x00,
39400x03,0x03,0x03,0x03,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x09,0x00,0x00,
39410x23,0x00,0x00,0x00,0x08,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x09,0x00,0x00,
39420x33,0x13,0x32,0x03,0x08,0x0a,0x00,0x00,0x00,0x86,0x88,0x8f,0x2c,0x0a,0x00,0x00,
39430x00,0x00,0x92,0x00,0x00,0x0c,0x00,0x00,0x80,0x00,0x00,0x00,0x04,0x0c,0x00,0x00,
39440x33,0x54,0x00,0x00,0x08,0x0c,0x00,0x00,0xe4,0x00,0x00,0x00,0x0c,0x0c,0x00,0x00,
39450x6c,0x6c,0x6c,0x6c,0x10,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x0c,0x00,0x00,
39460x00,0x01,0x00,0x40,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x0c,0x00,0x00,
39470x00,0x01,0x00,0x40,0x20,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x24,0x0c,0x00,0x00,
39480x00,0x01,0x00,0x40,0x28,0x0c,0x00,0x00,0x00,0x00,0x00,0x08,0x2c,0x0c,0x00,0x00,
39490x00,0x01,0x00,0x40,0x30,0x0c,0x00,0x00,0x44,0x6a,0xe9,0x8d,0x34,0x0c,0x00,0x00,
39500xcd,0x52,0x96,0x46,0x38,0x0c,0x00,0x00,0x90,0x5a,0x01,0x48,0x3c,0x0c,0x00,0x00,
39510x64,0x97,0x97,0x1a,0x40,0x0c,0x00,0x00,0x3f,0x42,0x7c,0x1f,0x44,0x0c,0x00,0x00,
39520xb7,0x00,0x01,0x00,0x48,0x0c,0x00,0x00,0x00,0x00,0x02,0xec,0x4c,0x0c,0x00,0x00,
39530x03,0x03,0xfc,0x00,0x50,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x54,0x0c,0x00,0x00,
39540x94,0x00,0x3c,0x43,0x58,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x5c,0x0c,0x00,0x00,
39550x94,0x00,0x3c,0x43,0x60,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x64,0x0c,0x00,0x00,
39560x94,0x00,0x3c,0x43,0x68,0x0c,0x00,0x00,0x1c,0x34,0x54,0x69,0x6c,0x0c,0x00,0x00,
39570x94,0x00,0x3c,0x43,0x70,0x0c,0x00,0x00,0x0d,0x00,0x5a,0x2c,0x74,0x0c,0x00,0x00,
39580x1b,0x15,0x86,0x01,0x78,0x0c,0x00,0x00,0x1f,0x00,0x00,0x00,0x7c,0x0c,0x00,0x00,
39590x12,0x16,0xb9,0x00,0x80,0x0c,0x00,0x00,0x80,0x00,0x00,0x20,0x84,0x0c,0x00,0x00,
39600x00,0x00,0x00,0x00,0x88,0x0c,0x00,0x00,0x80,0x00,0x00,0x20,0x8c,0x0c,0x00,0x00,
39610x00,0x00,0x20,0x08,0x90,0x0c,0x00,0x00,0x00,0x01,0x00,0x40,0x94,0x0c,0x00,0x00,
39620x00,0x00,0x00,0x00,0x98,0x0c,0x00,0x00,0x00,0x01,0x00,0x40,0x9c,0x0c,0x00,0x00,
39630x00,0x00,0x00,0x00,0xa0,0x0c,0x00,0x00,0x92,0x24,0x49,0x00,0xa4,0x0c,0x00,0x00,
39640x00,0x00,0x00,0x00,0xa8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x0c,0x00,0x00,
39650x00,0x00,0x00,0x00,0xb0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xb4,0x0c,0x00,0x00,
39660x00,0x00,0x00,0x00,0xb8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0x0c,0x00,0x00,
39670x92,0x24,0x49,0x00,0xc0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x0c,0x00,0x00,
39680x00,0x00,0x00,0x00,0xc8,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xcc,0x0c,0x00,0x00,
39690x00,0x00,0x00,0x00,0xd0,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0xd4,0x0c,0x00,0x00,
39700x00,0x00,0x00,0x00,0xd8,0x0c,0x00,0x00,0x27,0x24,0xb2,0x64,0xdc,0x0c,0x00,0x00,
39710x32,0x69,0x76,0x00,0xe0,0x0c,0x00,0x00,0x22,0x22,0x22,0x00,0xe4,0x0c,0x00,0x00,
39720x00,0x00,0x00,0x00,0xe8,0x0c,0x00,0x00,0x02,0x43,0x64,0x07,0x00,0x0d,0x00,0x00,
39730x80,0x07,0x00,0x00,0x04,0x0d,0x00,0x00,0x03,0x04,0x00,0x00,0x08,0x0d,0x00,0x00,
39740x7f,0x90,0x00,0x00,0x0c,0x0d,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x0d,0x00,0x00,
39750x99,0x99,0x69,0xa0,0x14,0x0d,0x00,0x00,0x67,0x3c,0x99,0x99,0x18,0x0d,0x00,0x00,
39760x6b,0x5b,0x8f,0x6a,0x1c,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x0d,0x00,0x00,
39770x00,0x00,0x00,0x00,0x24,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x0d,0x00,0x00,
39780x00,0x00,0x00,0x00,0x2c,0x0d,0x00,0x00,0x75,0x19,0x97,0xcc,0x30,0x0d,0x00,0x00,
39790x00,0x00,0x00,0x00,0x34,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x0d,0x00,0x00,
39800x00,0x00,0x00,0x00,0x3c,0x0d,0x00,0x00,0x93,0x72,0x02,0x00,0x40,0x0d,0x00,0x00,
39810x00,0x00,0x00,0x00,0x44,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x0d,0x00,0x00,
39820x00,0x00,0x00,0x00,0x50,0x0d,0x00,0x00,0x0a,0x14,0x37,0x64,0x54,0x0d,0x00,0x00,
39830x02,0xbd,0x4d,0x02,0x58,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x0d,0x00,0x00,
39840x64,0x20,0x03,0x30,0x60,0x0d,0x00,0x00,0x68,0xde,0x53,0x46,0x64,0x0d,0x00,0x00,
39850x3c,0x8a,0x51,0x00,0x68,0x0d,0x00,0x00,0x06,0x01,0x00,0x00,0xff,0x00,0x00,0x00,
39860xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
39870x44,0x05,0x01,0x80,0x10,0x00,0x00,0x00,0x74,0x05,0x01,0x80,0x10,0x00,0x00,0x00,
39880xe0,0x2e,0x00,0x80,0x10,0x00,0x00,0x00,0xec,0x2e,0x00,0x80,0x10,0x00,0x00,0x00,
39890xa0,0x08,0x01,0x80,0x08,0x00,0x00,0x00,0x38,0x06,0x01,0x80,0x00,0xb7,0x00,0x00,
39900x01,0xe0,0x0e,0x00,0x02,0x4d,0x04,0x00,0x03,0x41,0x04,0x00,0x04,0xc3,0x08,0x00,
39910x05,0x72,0x0c,0x00,0x06,0xe6,0x00,0x00,0x07,0x2a,0x08,0x00,0x08,0x3f,0x00,0x00,
39920x09,0x35,0x03,0x00,0x0a,0xd4,0x09,0x00,0x0b,0xbb,0x07,0x00,0x0c,0x50,0x08,0x00,
39930x0d,0xdf,0x0c,0x00,0x0e,0x2b,0x00,0x00,0x0f,0x14,0x01,0x00,0x00,0xb7,0x01,0x00,
39940x01,0x01,0x00,0x00,0x02,0x00,0x04,0x00,0x01,0x02,0x00,0x00,0x02,0x01,0x04,0x00,
39950x01,0x03,0x00,0x00,0x02,0x02,0x04,0x00,0x01,0x04,0x00,0x00,0x02,0x03,0x04,0x00,
39960x01,0x05,0x00,0x00,0x02,0x04,0x04,0x00,0x01,0x06,0x00,0x00,0x02,0x05,0x04,0x00,
39970x01,0x07,0x00,0x00,0x02,0x08,0x04,0x00,0x01,0x08,0x00,0x00,0x02,0x09,0x04,0x00,
39980x01,0x09,0x00,0x00,0x02,0x0a,0x04,0x00,0x01,0x0a,0x00,0x00,0x02,0x0b,0x04,0x00,
39990x01,0x0b,0x00,0x00,0x02,0x02,0x05,0x00,0x01,0x0c,0x00,0x00,0x02,0x03,0x05,0x00,
40000x01,0x0d,0x00,0x00,0x02,0x04,0x05,0x00,0x01,0x0e,0x00,0x00,0x02,0x05,0x05,0x00,
40010x01,0x0f,0x00,0x00,0x02,0x40,0x05,0x00,0x01,0x10,0x00,0x00,0x02,0x41,0x05,0x00,
40020x01,0x11,0x00,0x00,0x02,0x42,0x05,0x00,0x01,0x12,0x00,0x00,0x02,0x43,0x05,0x00,
40030x01,0x13,0x00,0x00,0x02,0x44,0x05,0x00,0x01,0x14,0x00,0x00,0x02,0x45,0x05,0x00,
40040x01,0x15,0x00,0x00,0x02,0x80,0x05,0x00,0x01,0x16,0x00,0x00,0x02,0x81,0x05,0x00,
40050x01,0x17,0x00,0x00,0x02,0x82,0x05,0x00,0x01,0x18,0x00,0x00,0x02,0x83,0x05,0x00,
40060x01,0x19,0x00,0x00,0x02,0x84,0x05,0x00,0x01,0x1a,0x00,0x00,0x02,0x85,0x05,0x00,
40070x01,0x1b,0x00,0x00,0x02,0x88,0x05,0x00,0x01,0x1c,0x00,0x00,0x02,0x89,0x05,0x00,
40080x01,0x1d,0x00,0x00,0x02,0x8a,0x05,0x00,0x01,0x1e,0x00,0x00,0x02,0x8b,0x05,0x00,
40090x01,0x1f,0x00,0x00,0x02,0x43,0x06,0x00,0x01,0x20,0x00,0x00,0x02,0x44,0x06,0x00,
40100x01,0x21,0x00,0x00,0x02,0x45,0x06,0x00,0x01,0x22,0x00,0x00,0x02,0x80,0x06,0x00,
40110x01,0x23,0x00,0x00,0x02,0x81,0x06,0x00,0x01,0x24,0x00,0x00,0x02,0x82,0x06,0x00,
40120x01,0x25,0x00,0x00,0x02,0x83,0x06,0x00,0x01,0x26,0x00,0x00,0x02,0x84,0x06,0x00,
40130x01,0x27,0x00,0x00,0x02,0x85,0x06,0x00,0x01,0x28,0x00,0x00,0x02,0x88,0x06,0x00,
40140x01,0x29,0x00,0x00,0x02,0x89,0x06,0x00,0x01,0x2a,0x00,0x00,0x02,0x8a,0x06,0x00,
40150x01,0x2b,0x00,0x00,0x02,0x8b,0x06,0x00,0x01,0x2c,0x00,0x00,0x02,0x8c,0x06,0x00,
40160x01,0x2d,0x00,0x00,0x02,0x42,0x07,0x00,0x01,0x2e,0x00,0x00,0x02,0x43,0x07,0x00,
40170x01,0x2f,0x00,0x00,0x02,0x44,0x07,0x00,0x01,0x30,0x00,0x00,0x02,0x45,0x07,0x00,
40180x01,0x31,0x00,0x00,0x02,0x80,0x07,0x00,0x01,0x32,0x00,0x00,0x02,0x81,0x07,0x00,
40190x01,0x33,0x00,0x00,0x02,0x82,0x07,0x00,0x01,0x34,0x00,0x00,0x02,0x83,0x07,0x00,
40200x01,0x35,0x00,0x00,0x02,0x84,0x07,0x00,0x01,0x36,0x00,0x00,0x02,0x85,0x07,0x00,
40210x01,0x37,0x00,0x00,0x02,0x88,0x07,0x00,0x01,0x38,0x00,0x00,0x02,0x89,0x07,0x00,
40220x01,0x39,0x00,0x00,0x02,0x8a,0x07,0x00,0x01,0x3a,0x00,0x00,0x02,0x8b,0x07,0x00,
40230x01,0x3b,0x00,0x00,0x02,0x8c,0x07,0x00,0x01,0x3c,0x00,0x00,0x02,0x8d,0x07,0x00,
40240x01,0x3d,0x00,0x00,0x02,0x90,0x07,0x00,0x01,0x3e,0x00,0x00,0x02,0x91,0x07,0x00,
40250x01,0x3f,0x00,0x00,0x02,0x92,0x07,0x00,0x01,0x40,0x00,0x00,0x02,0x93,0x07,0x00,
40260x01,0x41,0x00,0x00,0x02,0x94,0x07,0x00,0x01,0x42,0x00,0x00,0x02,0x95,0x07,0x00,
40270x01,0x43,0x00,0x00,0x02,0x98,0x07,0x00,0x01,0x44,0x00,0x00,0x02,0x99,0x07,0x00,
40280x01,0x45,0x00,0x00,0x02,0x9a,0x07,0x00,0x01,0x46,0x00,0x00,0x02,0x9b,0x07,0x00,
40290x01,0x47,0x00,0x00,0x02,0x9c,0x07,0x00,0x01,0x48,0x00,0x00,0x02,0x9d,0x07,0x00,
40300x01,0x49,0x00,0x00,0x02,0xa0,0x07,0x00,0x01,0x4a,0x00,0x00,0x02,0xa1,0x07,0x00,
40310x01,0x4b,0x00,0x00,0x02,0xa2,0x07,0x00,0x01,0x4c,0x00,0x00,0x02,0xa3,0x07,0x00,
40320x01,0x4d,0x00,0x00,0x02,0xa4,0x07,0x00,0x01,0x4e,0x00,0x00,0x02,0xa5,0x07,0x00,
40330x01,0x4f,0x00,0x00,0x02,0xa8,0x07,0x00,0x01,0x50,0x00,0x00,0x02,0xa9,0x07,0x00,
40340x01,0x51,0x00,0x00,0x02,0xaa,0x03,0x00,0x01,0x52,0x00,0x00,0x02,0xab,0x03,0x00,
40350x01,0x53,0x00,0x00,0x02,0xac,0x03,0x00,0x01,0x54,0x00,0x00,0x02,0xad,0x03,0x00,
40360x01,0x55,0x00,0x00,0x02,0xb0,0x03,0x00,0x01,0x56,0x00,0x00,0x02,0xb1,0x03,0x00,
40370x01,0x57,0x00,0x00,0x02,0xb2,0x03,0x00,0x01,0x58,0x00,0x00,0x02,0xb3,0x03,0x00,
40380x01,0x59,0x00,0x00,0x02,0xb4,0x03,0x00,0x01,0x5a,0x00,0x00,0x02,0xb5,0x03,0x00,
40390x01,0x5b,0x00,0x00,0x02,0xb8,0x03,0x00,0x01,0x5c,0x00,0x00,0x02,0xb9,0x03,0x00,
40400x01,0x5d,0x00,0x00,0x02,0xba,0x03,0x00,0x01,0x5e,0x00,0x00,0x02,0xbb,0x03,0x00,
40410x01,0x5f,0x00,0x00,0x02,0xbb,0x03,0x00,0x03,0x80,0x00,0x00,0x05,0x04,0x00,0x00,
40420x00,0xb7,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,
40430x02,0x4d,0x0c,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x02,0x4d,0x04,0x00,
40440x00,0xbf,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0xb7,0x00,0x00,
40450x01,0xe0,0x0e,0x00,0x02,0x4d,0x04,0x00,0x03,0x41,0x04,0x00,0x04,0xc3,0x08,0x00,
40460x05,0x72,0x0c,0x00,0x06,0xe6,0x00,0x00,0x07,0x2a,0x08,0x00,0x08,0x3f,0x00,0x00,
40470x09,0x35,0x03,0x00,0x0a,0xd4,0x09,0x00,0x0b,0xbb,0x07,0x00,0x0c,0x50,0x08,0x00,
40480x0d,0xdf,0x0c,0x00,0x0e,0x2b,0x00,0x00,0x0f,0x14,0x01,0x00,0x00,0xb7,0x01,0x00,
40490x01,0x01,0x00,0x00,0x02,0x00,0x04,0x00,0x01,0x02,0x00,0x00,0x02,0x01,0x04,0x00,
40500x01,0x03,0x00,0x00,0x02,0x02,0x04,0x00,0x01,0x04,0x00,0x00,0x02,0x03,0x04,0x00,
40510x01,0x05,0x00,0x00,0x02,0x04,0x04,0x00,0x01,0x06,0x00,0x00,0x02,0x05,0x04,0x00,
40520x01,0x07,0x00,0x00,0x02,0x08,0x04,0x00,0x01,0x08,0x00,0x00,0x02,0x09,0x04,0x00,
40530x01,0x09,0x00,0x00,0x02,0x0a,0x04,0x00,0x01,0x0a,0x00,0x00,0x02,0x0b,0x04,0x00,
40540x01,0x0b,0x00,0x00,0x02,0x02,0x05,0x00,0x01,0x0c,0x00,0x00,0x02,0x03,0x05,0x00,
40550x01,0x0d,0x00,0x00,0x02,0x04,0x05,0x00,0x01,0x0e,0x00,0x00,0x02,0x05,0x05,0x00,
40560x01,0x0f,0x00,0x00,0x02,0x40,0x05,0x00,0x01,0x10,0x00,0x00,0x02,0x41,0x05,0x00,
40570x01,0x11,0x00,0x00,0x02,0x42,0x05,0x00,0x01,0x12,0x00,0x00,0x02,0x43,0x05,0x00,
40580x01,0x13,0x00,0x00,0x02,0x44,0x05,0x00,0x01,0x14,0x00,0x00,0x02,0x45,0x05,0x00,
40590x01,0x15,0x00,0x00,0x02,0x80,0x05,0x00,0x01,0x16,0x00,0x00,0x02,0x81,0x05,0x00,
40600x01,0x17,0x00,0x00,0x02,0x82,0x05,0x00,0x01,0x18,0x00,0x00,0x02,0x83,0x05,0x00,
40610x01,0x19,0x00,0x00,0x02,0x84,0x05,0x00,0x01,0x1a,0x00,0x00,0x02,0x85,0x05,0x00,
40620x01,0x1b,0x00,0x00,0x02,0x88,0x05,0x00,0x01,0x1c,0x00,0x00,0x02,0x89,0x05,0x00,
40630x01,0x1d,0x00,0x00,0x02,0x8a,0x05,0x00,0x01,0x1e,0x00,0x00,0x02,0x8b,0x05,0x00,
40640x01,0x1f,0x00,0x00,0x02,0x43,0x06,0x00,0x01,0x20,0x00,0x00,0x02,0x44,0x06,0x00,
40650x01,0x21,0x00,0x00,0x02,0x45,0x06,0x00,0x01,0x22,0x00,0x00,0x02,0x80,0x06,0x00,
40660x01,0x23,0x00,0x00,0x02,0x81,0x06,0x00,0x01,0x24,0x00,0x00,0x02,0x82,0x06,0x00,
40670x01,0x25,0x00,0x00,0x02,0x83,0x06,0x00,0x01,0x26,0x00,0x00,0x02,0x84,0x06,0x00,
40680x01,0x27,0x00,0x00,0x02,0x85,0x06,0x00,0x01,0x28,0x00,0x00,0x02,0x88,0x06,0x00,
40690x01,0x29,0x00,0x00,0x02,0x89,0x06,0x00,0x01,0x2a,0x00,0x00,0x02,0x8a,0x06,0x00,
40700x01,0x2b,0x00,0x00,0x02,0x8b,0x06,0x00,0x01,0x2c,0x00,0x00,0x02,0x8c,0x06,0x00,
40710x01,0x2d,0x00,0x00,0x02,0x42,0x07,0x00,0x01,0x2e,0x00,0x00,0x02,0x43,0x07,0x00,
40720x01,0x2f,0x00,0x00,0x02,0x44,0x07,0x00,0x01,0x30,0x00,0x00,0x02,0x45,0x07,0x00,
40730x01,0x31,0x00,0x00,0x02,0x80,0x07,0x00,0x01,0x32,0x00,0x00,0x02,0x81,0x07,0x00,
40740x01,0x33,0x00,0x00,0x02,0x82,0x07,0x00,0x01,0x34,0x00,0x00,0x02,0x83,0x07,0x00,
40750x01,0x35,0x00,0x00,0x02,0x84,0x07,0x00,0x01,0x36,0x00,0x00,0x02,0x85,0x07,0x00,
40760x01,0x37,0x00,0x00,0x02,0x88,0x07,0x00,0x01,0x38,0x00,0x00,0x02,0x89,0x07,0x00,
40770x01,0x39,0x00,0x00,0x02,0x8a,0x07,0x00,0x01,0x3a,0x00,0x00,0x02,0x8b,0x07,0x00,
40780x01,0x3b,0x00,0x00,0x02,0x8c,0x07,0x00,0x01,0x3c,0x00,0x00,0x02,0x8d,0x07,0x00,
40790x01,0x3d,0x00,0x00,0x02,0x90,0x07,0x00,0x01,0x3e,0x00,0x00,0x02,0x91,0x07,0x00,
40800x01,0x3f,0x00,0x00,0x02,0x92,0x07,0x00,0x01,0x40,0x00,0x00,0x02,0x93,0x07,0x00,
40810x01,0x41,0x00,0x00,0x02,0x94,0x07,0x00,0x01,0x42,0x00,0x00,0x02,0x95,0x07,0x00,
40820x01,0x43,0x00,0x00,0x02,0x98,0x07,0x00,0x01,0x44,0x00,0x00,0x02,0x99,0x07,0x00,
40830x01,0x45,0x00,0x00,0x02,0x9a,0x07,0x00,0x01,0x46,0x00,0x00,0x02,0x9b,0x07,0x00,
40840x01,0x47,0x00,0x00,0x02,0x9c,0x07,0x00,0x01,0x48,0x00,0x00,0x02,0x9d,0x07,0x00,
40850x01,0x49,0x00,0x00,0x02,0xa0,0x07,0x00,0x01,0x4a,0x00,0x00,0x02,0xa1,0x07,0x00,
40860x01,0x4b,0x00,0x00,0x02,0xa2,0x07,0x00,0x01,0x4c,0x00,0x00,0x02,0xa3,0x07,0x00,
40870x01,0x4d,0x00,0x00,0x02,0xa4,0x07,0x00,0x01,0x4e,0x00,0x00,0x02,0xa5,0x07,0x00,
40880x01,0x4f,0x00,0x00,0x02,0xa8,0x07,0x00,0x01,0x50,0x00,0x00,0x02,0xa9,0x07,0x00,
40890x01,0x51,0x00,0x00,0x02,0xaa,0x03,0x00,0x01,0x52,0x00,0x00,0x02,0xab,0x03,0x00,
40900x01,0x53,0x00,0x00,0x02,0xac,0x03,0x00,0x01,0x54,0x00,0x00,0x02,0xad,0x03,0x00,
40910x01,0x55,0x00,0x00,0x02,0xb0,0x03,0x00,0x01,0x56,0x00,0x00,0x02,0xb1,0x03,0x00,
40920x01,0x57,0x00,0x00,0x02,0xb2,0x03,0x00,0x01,0x58,0x00,0x00,0x02,0xb3,0x03,0x00,
40930x01,0x59,0x00,0x00,0x02,0xb4,0x03,0x00,0x01,0x5a,0x00,0x00,0x02,0xb5,0x03,0x00,
40940x01,0x5b,0x00,0x00,0x02,0xb8,0x03,0x00,0x01,0x5c,0x00,0x00,0x02,0xb9,0x03,0x00,
40950x01,0x5d,0x00,0x00,0x02,0xba,0x03,0x00,0x01,0x5e,0x00,0x00,0x02,0xbb,0x03,0x00,
40960x01,0x5f,0x00,0x00,0x02,0xbb,0x03,0x00,0x03,0x80,0x00,0x00,0x05,0x04,0x00,0x00,
40970x00,0xb7,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,
40980x02,0x4d,0x0c,0x00,0xfe,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x02,0x4d,0x04,0x00,
40990x00,0xbf,0x02,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x0a,0x00,0x00,0x00,
41000x4f,0x6e,0x41,0x73,0x73,0x6f,0x63,0x52,0x65,0x71,0x00,0x00,0x4f,0x6e,0x41,0x73,
41010x73,0x6f,0x63,0x52,0x73,0x70,0x00,0x00,0x4f,0x6e,0x52,0x65,0x41,0x73,0x73,0x6f,
41020x63,0x52,0x65,0x71,0x00,0x00,0x00,0x00,0x4f,0x6e,0x52,0x65,0x41,0x73,0x73,0x6f,
41030x63,0x52,0x73,0x70,0x00,0x00,0x00,0x00,0x4f,0x6e,0x50,0x72,0x6f,0x62,0x65,0x52,
41040x65,0x71,0x00,0x00,0x4f,0x6e,0x50,0x72,0x6f,0x62,0x65,0x52,0x73,0x70,0x00,0x00,
41050x44,0x6f,0x52,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x00,0x00,0x44,0x6f,0x52,0x65,
41060x73,0x65,0x72,0x76,0x65,0x64,0x00,0x00,0x4f,0x6e,0x42,0x65,0x61,0x63,0x6f,0x6e,
41070x00,0x00,0x00,0x00,0x4f,0x6e,0x41,0x54,0x49,0x4d,0x00,0x00,0x4f,0x6e,0x44,0x69,
41080x73,0x61,0x73,0x73,0x6f,0x63,0x00,0x00,0x4f,0x6e,0x41,0x75,0x74,0x68,0x00,0x00,
41090x4f,0x6e,0x44,0x65,0x41,0x75,0x74,0x68,0x00,0x00,0x00,0x00,0x4f,0x6e,0x41,0x63,
41100x74,0x69,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x8b,0x01,0x80,
41110x28,0x14,0x01,0x80,0x10,0x00,0x00,0x00,0x94,0x8b,0x01,0x80,0x30,0x14,0x01,0x80,
41120x20,0x00,0x00,0x00,0xa0,0x8b,0x01,0x80,0x28,0x14,0x01,0x80,0x30,0x00,0x00,0x00,
41130xb0,0x8b,0x01,0x80,0x30,0x14,0x01,0x80,0x40,0x00,0x00,0x00,0xc0,0x8b,0x01,0x80,
41140x38,0x14,0x01,0x80,0x50,0x00,0x00,0x00,0xcc,0x8b,0x01,0x80,0x40,0x14,0x01,0x80,
41150x00,0x00,0x00,0x00,0xd8,0x8b,0x01,0x80,0xa8,0x14,0x01,0x80,0x00,0x00,0x00,0x00,
41160xe4,0x8b,0x01,0x80,0xa8,0x14,0x01,0x80,0x80,0x00,0x00,0x00,0xf0,0x8b,0x01,0x80,
41170x48,0x14,0x01,0x80,0x90,0x00,0x00,0x00,0xfc,0x8b,0x01,0x80,0x50,0x14,0x01,0x80,
41180xa0,0x00,0x00,0x00,0x04,0x8c,0x01,0x80,0x58,0x14,0x01,0x80,0xb0,0x00,0x00,0x00,
41190x10,0x8c,0x01,0x80,0x90,0x14,0x01,0x80,0xc0,0x00,0x00,0x00,0x18,0x8c,0x01,0x80,
41200x98,0x14,0x01,0x80,0xd0,0x00,0x00,0x00,0x24,0x8c,0x01,0x80,0xa0,0x14,0x01,0x80,
41210x00,0x00,0x00,0x00,0xdc,0x8c,0x01,0x80,0xdc,0x8c,0x01,0x80,0x31,0x10,0x10,0x00,
41220x00,0x30,0x00,0x00,0x31,0x20,0x10,0x00,0x00,0x30,0x00,0x00,0x31,0x28,0x10,0x00,
41230x00,0x30,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x30,0x00,0x00,0x31,0x2f,0x10,0x10,
41240x00,0x30,0x00,0x00,0x31,0x30,0x18,0x00,0x00,0x30,0x00,0x00,0x31,0x30,0x20,0x10,
41250x00,0x30,0x00,0x00,0x22,0x20,0x18,0x08,0x00,0x20,0x00,0x00,0x22,0x21,0x14,0x08,
41260x00,0x20,0x00,0x00,0x22,0x21,0x1c,0x08,0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x08,
41270x00,0x20,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x20,0x00,0x00,0x22,0x21,0x20,0x18,
41280x00,0x20,0x00,0x00,0x1a,0x19,0x18,0x10,0x00,0x18,0x00,0x00,0x12,0x11,0x10,0x08,
41290x00,0x10,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x02,
41300x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x08,0x00,0x00,0x0a,0x09,0x08,0x06,
41310x00,0x08,0x00,0x00,0x08,0x07,0x06,0x04,0x00,0x06,0x00,0x00,0x06,0x05,0x04,0x02,
41320x00,0x04,0x00,0x00,0x06,0x05,0x04,0x03,0x00,0x04,0x00,0x00,0x05,0x04,0x03,0x02,
41330x00,0x03,0x00,0x00,0x09,0x08,0x07,0x06,0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03,
41340x06,0x05,0x05,0x04,0x04,0x03,0x03,0x03,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x02,
41350x00,0x09,0x08,0x07,0x06,0x07,0x06,0x06,0x05,0x05,0x04,0x04,0x03,0x05,0x04,0x04,
41360x03,0x03,0x02,0x02,0x02,0x04,0x03,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,
41370x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x08,0x08,0x08,0x08,
41380x20,0x20,0x20,0x20,0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,0x30,0x08,0x08,0x08,
41390x08,0x18,0x18,0x18,0x18,0x18,0x20,0x30,0x30,0x10,0x20,0x20,0x20,0x20,0x20,0x30,
41400x30,0x08,0x10,0x20,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x08,0x08,0x08,0x08,
41410x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,
41420x08,0x08,0x08,0x08,0x08,0x20,0x20,0x20,0x20,0x08,0x08,0x08,0x08,0x18,0x18,0x18,
41430x18,0x18,0x20,0x30,0x30,0x10,0x20,0x20,0x20,0x20,0x20,0x30,0x30,0x08,0x10,0x20,
41440x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,
41450x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x00,
41460x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,
41470x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x12,0x11,0x10,0x08,0x00,0x22,
41480x21,0x20,0x18,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,
41490x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,
41500x18,0x00,0x22,0x21,0x1c,0x08,0x00,0x22,0x20,0x18,0x08,0x00,0x0a,0x09,0x08,0x02,
41510x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,
41520x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x22,
41530x21,0x1c,0x08,0x00,0x31,0x30,0x18,0x00,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,
41540x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x1a,0x19,0x18,
41550x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,
41560x00,0x1a,0x19,0x18,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x31,0x2c,0x10,0x10,0x00,
41570x31,0x28,0x10,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x22,
41580x21,0x20,0x18,0x00,0x22,0x21,0x20,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x22,0x20,
41590x18,0x08,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2c,0x10,0x10,0x00,0x0a,0x09,0x08,
41600x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x18,
41610x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,
41620x31,0x10,0x10,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x00,0x00,0x0a,0x09,0x08,0x04,
41630x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,
41640x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,
41650x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x12,0x11,
41660x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,
41670x04,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x00,0x00,0x0a,0x09,0x08,0x00,
41680x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x1c,0x08,0x00,0x22,0x21,0x14,0x08,0x00,
41690x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x02,0x00,0x0a,
41700x09,0x08,0x02,0x00,0x0a,0x09,0x08,0x00,0x00,0x22,0x21,0x20,0x10,0x00,0x22,0x21,
41710x20,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x22,0x21,0x14,0x08,0x00,0x0a,0x09,0x08,
41720x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,0x00,0x0a,0x09,0x08,0x04,
41730x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,
41740x1a,0x19,0x18,0x10,0x00,0x1a,0x19,0x18,0x10,0x00,0x22,0x21,0x20,0x08,0x00,0x31,
41750x2c,0x10,0x10,0x00,0x31,0x28,0x10,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,
41760x20,0x18,0x00,0x22,0x21,0x20,0x18,0x00,0x22,0x21,0x20,0x08,0x00,0x22,0x21,0x14,
41770x08,0x00,0x22,0x20,0x18,0x08,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2c,0x10,0x10,
41780x00,0x0a,0x09,0x08,0x00,0x00,0x12,0x11,0x10,0x08,0x00,0x22,0x21,0x20,0x18,0x00,
41790x22,0x21,0x20,0x18,0x00,0x31,0x30,0x20,0x10,0x00,0x31,0x2f,0x10,0x10,0x00,0x31,
41800x2f,0x10,0x10,0x00,0x31,0x10,0x10,0x00,0x00,0x31,0x2c,0x10,0x10,0x00,0x00,0x00,
41810x01,0x02,0x04,0x08,0x02,0x04,0x08,0x0c,0x10,0x18,0x20,0x30,0x02,0x04,0x08,0x0c,
41820x10,0x18,0x20,0x30,0x06,0x0c,0x10,0x18,0x24,0x30,0x3c,0x48,0x48,0x00,0x00,0x00,
41830x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x27,0x2c,0x19,0x1b,0x1e,0x20,
41840x23,0x29,0x2a,0x2b,0x00,0x00,0x00,0x00,0x25,0x29,0x2b,0x2e,0x2e,0x00,0x00,0x00,
41850x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
41860x18,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,
41870x60,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xd8,0x00,0x00,0x00,
41880x50,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,
41890x40,0x01,0x00,0x00,0x90,0x01,0x00,0x00,0xe0,0x01,0x00,0x00,0x30,0x02,0x00,0x00,
41900x2c,0x01,0x00,0x00,0x40,0x01,0x00,0x00,0xe0,0x01,0x00,0x00,0xd0,0x02,0x00,0x00,
41910x80,0x0c,0x00,0x00,0x80,0x0c,0x00,0x00,0x80,0x0c,0x00,0x00,0xa0,0x0f,0x00,0x00,
41920xa0,0x0f,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
41930x08,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
41940x24,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60,0x00,0x00,0x00,
41950x6c,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x50,0x00,0x00,0x00,
41960x64,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,
41970x18,0x01,0x00,0x00,0x64,0x00,0x00,0x00,0xa0,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,
41980x68,0x01,0x00,0x00,0x40,0x06,0x00,0x00,0x40,0x06,0x00,0x00,0x40,0x06,0x00,0x00,
41990xd0,0x07,0x00,0x00,0xd0,0x07,0x00,0x00,0x2c,0x05,0x00,0x80,0x20,0x05,0x00,0x80,
42000x14,0x05,0x00,0x80,0x08,0x05,0x00,0x80,0xfc,0x04,0x00,0x80,0xf0,0x04,0x00,0x80,
42010xe4,0x04,0x00,0x80,0xd8,0x04,0x00,0x80,0xcc,0x04,0x00,0x80,0xc0,0x04,0x00,0x80,
42020x78,0x04,0x00,0x80,0x68,0x15,0x02,0x80,0xc0,0x3a,0x00,0x80,0xcc,0x3a,0x00,0x80,
42030xd8,0x3a,0x00,0x80,0xe4,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,
42040xc0,0x3a,0x00,0x80,0xc0,0x3a,0x00,0x80,0xf0,0x3a,0x00,0x80,0xfc,0x3a,0x00,0x80,
42050x08,0x3b,0x00,0x80,0x14,0x3b,0x00,0x80,0x68,0x15,0x02,0x80,0xfe,0x01,0x80,0x7f,
42060xe2,0x01,0x80,0x78,0xc7,0x01,0xc0,0x71,0xae,0x01,0x80,0x6b,0x95,0x01,0x40,0x65,
42070x7f,0x01,0xc0,0x5f,0x69,0x01,0x40,0x5a,0x55,0x01,0x40,0x55,0x42,0x01,0x80,0x50,
42080x30,0x01,0x00,0x4c,0x1f,0x01,0xc0,0x47,0x0f,0x01,0xc0,0x43,0x00,0x01,0x00,0x40,
42090xf2,0x00,0x80,0x3c,0xe4,0x00,0x00,0x39,0xd7,0x00,0xc0,0x35,0xcb,0x00,0xc0,0x32,
42100xc0,0x00,0x00,0x30,0xb5,0x00,0x40,0x2d,0xab,0x00,0xc0,0x2a,0xa2,0x00,0x80,0x28,
42110x98,0x00,0x00,0x26,0x90,0x00,0x00,0x24,0x88,0x00,0x00,0x22,0x80,0x00,0x00,0x20,
42120x79,0x00,0x40,0x1e,0x72,0x00,0x80,0x1c,0x6c,0x00,0x00,0x1b,0x66,0x00,0x80,0x19,
42130x60,0x00,0x00,0x18,0x5b,0x00,0xc0,0x16,0x56,0x00,0x80,0x15,0x51,0x00,0x40,0x14,
42140x4c,0x00,0x00,0x13,0x48,0x00,0x00,0x12,0x44,0x00,0x00,0x11,0x40,0x00,0x00,0x10,
42150x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04,0x33,0x32,0x2b,0x23,0x1a,0x11,0x08,0x04,
42160x30,0x2f,0x29,0x21,0x19,0x10,0x08,0x03,0x2d,0x2d,0x27,0x1f,0x18,0x0f,0x08,0x03,
42170x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03,0x28,0x28,0x22,0x1c,0x15,0x0d,0x07,0x03,
42180x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,0x24,0x23,0x1f,0x19,0x13,0x0c,0x06,0x03,
42190x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,0x20,0x20,0x1b,0x16,0x11,0x08,0x05,0x02,
42200x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,0x1d,0x1c,0x18,0x14,0x0f,0x0a,0x05,0x02,
42210x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,0x1a,0x19,0x16,0x12,0x0d,0x09,0x04,0x02,
42220x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,0x17,0x16,0x13,0x10,0x0c,0x08,0x04,0x02,
42230x16,0x15,0x12,0x0f,0x0b,0x07,0x04,0x01,0x14,0x14,0x11,0x0e,0x0b,0x07,0x03,0x02,
42240x13,0x13,0x10,0x0d,0x0a,0x06,0x03,0x01,0x12,0x12,0x0f,0x0c,0x09,0x06,0x03,0x01,
42250x11,0x11,0x0f,0x0c,0x09,0x06,0x03,0x01,0x10,0x10,0x0e,0x0b,0x08,0x05,0x03,0x01,
42260x0f,0x0f,0x0d,0x0b,0x08,0x05,0x03,0x01,0x0e,0x0e,0x0c,0x0a,0x08,0x05,0x02,0x01,
42270x0d,0x0d,0x0c,0x0a,0x07,0x05,0x02,0x01,0x0d,0x0c,0x0b,0x09,0x07,0x04,0x02,0x01,
42280x0c,0x0c,0x0a,0x09,0x06,0x04,0x02,0x01,0x0b,0x0b,0x0a,0x08,0x06,0x04,0x02,0x01,
42290x0b,0x0a,0x09,0x08,0x06,0x04,0x02,0x01,0x0a,0x0a,0x09,0x07,0x05,0x03,0x02,0x01,
42300x0a,0x09,0x08,0x07,0x05,0x03,0x02,0x01,0x09,0x09,0x08,0x06,0x05,0x03,0x01,0x01,
42310x09,0x08,0x07,0x06,0x04,0x03,0x01,0x01,0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00,
42320x33,0x32,0x2b,0x19,0x00,0x00,0x00,0x00,0x30,0x2f,0x29,0x18,0x00,0x00,0x00,0x00,
42330x2d,0x2d,0x17,0x17,0x00,0x00,0x00,0x00,0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00,
42340x28,0x28,0x24,0x14,0x00,0x00,0x00,0x00,0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
42350x24,0x23,0x1f,0x12,0x00,0x00,0x00,0x00,0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
42360x20,0x20,0x1b,0x10,0x00,0x00,0x00,0x00,0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
42370x1d,0x1c,0x18,0x0e,0x00,0x00,0x00,0x00,0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
42380x1a,0x19,0x16,0x0d,0x00,0x00,0x00,0x00,0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
42390x17,0x16,0x13,0x0b,0x00,0x00,0x00,0x00,0x16,0x15,0x12,0x0b,0x00,0x00,0x00,0x00,
42400x14,0x14,0x11,0x0a,0x00,0x00,0x00,0x00,0x13,0x13,0x10,0x0a,0x00,0x00,0x00,0x00,
42410x12,0x12,0x0f,0x09,0x00,0x00,0x00,0x00,0x11,0x11,0x0f,0x09,0x00,0x00,0x00,0x00,
42420x10,0x10,0x0e,0x08,0x00,0x00,0x00,0x00,0x0f,0x0f,0x0d,0x08,0x00,0x00,0x00,0x00,
42430x0e,0x0e,0x0c,0x07,0x00,0x00,0x00,0x00,0x0d,0x0d,0x0c,0x07,0x00,0x00,0x00,0x00,
42440x0d,0x0c,0x0b,0x06,0x00,0x00,0x00,0x00,0x0c,0x0c,0x0a,0x06,0x00,0x00,0x00,0x00,
42450x0b,0x0b,0x0a,0x06,0x00,0x00,0x00,0x00,0x0b,0x0a,0x09,0x05,0x00,0x00,0x00,0x00,
42460x0a,0x0a,0x09,0x05,0x00,0x00,0x00,0x00,0x0a,0x09,0x08,0x05,0x00,0x00,0x00,0x00,
42470x09,0x09,0x08,0x05,0x00,0x00,0x00,0x00,0x09,0x08,0x07,0x04,0x00,0x00,0x00,0x00,
42480x06,0x00,0x2a,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42490x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42500x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42510x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42520x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42530x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42540x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42550x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42560x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42570x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42580x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42590x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
42600x08,0x28,0x28,0x28,0x28,0x28,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
42610x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
42620x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
42630x04,0x04,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x41,0x41,0x41,0x41,0x41,0x41,0x01,
42640x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
42650x01,0x01,0x01,0x10,0x10,0x10,0x10,0x10,0x10,0x42,0x42,0x42,0x42,0x42,0x42,0x02,
42660x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
42670x02,0x02,0x02,0x10,0x10,0x10,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42680x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42690x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
42700x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
42710x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
42720x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,
42730x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
42740x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,
42750x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00,0x19,0x77,0x00,0x00,0x00,0x00,0x00,0x00,
42760x00,0x26,0x72,0xb0,0x00,0x26,0x72,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42770x00,0x00,0x00,0x00,0x00,0x26,0x65,0x60,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x02,
42780x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xf2,0x30,0xb8,0xff,0xff,0xff,0xff,
4279};
4280
4281u8 Rtl8192SUFwMainArray[MainArrayLength] = { 5u8 Rtl8192SUFwMainArray[MainArrayLength] = {
42820x0, }; 60x0, };
4283 7
diff --git a/drivers/staging/rtl8192su/r8192SU_HWImg.h b/drivers/staging/rtl8192su/r8192SU_HWImg.h
index 96b15252ea86..36e84aff6ed6 100644
--- a/drivers/staging/rtl8192su/r8192SU_HWImg.h
+++ b/drivers/staging/rtl8192su/r8192SU_HWImg.h
@@ -5,8 +5,6 @@
5 5
6/*Created on 2009/ 3/ 6, 5:29*/ 6/*Created on 2009/ 3/ 6, 5:29*/
7 7
8#define ImgArrayLength 68368
9extern u8 Rtl8192SUFwImgArray[ImgArrayLength];
10#define MainArrayLength 1 8#define MainArrayLength 1
11extern u8 Rtl8192SUFwMainArray[MainArrayLength]; 9extern u8 Rtl8192SUFwMainArray[MainArrayLength];
12#define DataArrayLength 1 10#define DataArrayLength 1
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c
index 3561adf0468a..752a3f1fb3f5 100644
--- a/drivers/staging/rtl8192su/r8192S_firmware.c
+++ b/drivers/staging/rtl8192su/r8192S_firmware.c
@@ -360,117 +360,58 @@ bool FirmwareDownload92S(struct net_device *dev)
360 360
361 RT_TRACE(COMP_FIRMWARE, " --->FirmwareDownload92S()\n"); 361 RT_TRACE(COMP_FIRMWARE, " --->FirmwareDownload92S()\n");
362 362
363 //3// 363/*
364 //3 //<1> Open Image file, and map file to contineous memory if open file success. 364* Load the firmware from RTL8192SU/rtl8192sfw.bin
365 //3 // or read image file from array. Default load from BIN file 365*/
366 //3// 366 if(pFirmware->szFwTmpBufferLen == 0)
367 priv->firmware_source = FW_SOURCE_IMG_FILE;// We should decided by Reg.
368
369 switch( priv->firmware_source )
370 { 367 {
371 case FW_SOURCE_IMG_FILE: 368 rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev);
372 if(pFirmware->szFwTmpBufferLen == 0) 369 if(rc < 0 ) {
373 { 370 RT_TRACE(COMP_ERR, "request firmware fail!\n");
374 371 goto DownloadFirmware_Fail;
375 rc = request_firmware(&fw_entry, pFwImageFileName[ulInitStep],&priv->udev->dev);//===>1 372 }
376 if(rc < 0 ) {
377 RT_TRACE(COMP_ERR, "request firmware fail!\n");
378 goto DownloadFirmware_Fail;
379 }
380
381 if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer))
382 {
383 RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
384 release_firmware(fw_entry);
385 goto DownloadFirmware_Fail;
386 }
387 373
388 memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size); 374 if(fw_entry->size > sizeof(pFirmware->szFwTmpBuffer)) {
389 pFirmware->szFwTmpBufferLen = fw_entry->size; 375 RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
390 release_firmware(fw_entry); 376 release_firmware(fw_entry);
391 377 goto DownloadFirmware_Fail;
392 pucMappedFile = pFirmware->szFwTmpBuffer;
393 file_length = pFirmware->szFwTmpBufferLen;
394
395 //Retrieve FW header.
396 pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
397 pFwHdr = pFirmware->pFwHeader;
398 RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
399 pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
400 pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
401 pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0);
402 if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM)))
403 {
404 RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\
405 __FUNCTION__);
406 goto DownloadFirmware_Fail;
407 } else {
408 pucMappedFile+=FwHdrSize;
409
410 //Retrieve IMEM image.
411 memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
412 pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
413 }
414
415 if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM))
416 {
417 RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\
418 __FUNCTION__);
419 goto DownloadFirmware_Fail;
420 } else {
421 pucMappedFile += pFirmware->FwIMEMLen;
422
423 /* Retriecve EMEM image */
424 memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6
425 pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
426 }
427
428
429 } 378 }
430 break;
431 379
432 case FW_SOURCE_HEADER_FILE: 380 memcpy(pFirmware->szFwTmpBuffer,fw_entry->data,fw_entry->size);
433#if 1 381 pFirmware->szFwTmpBufferLen = fw_entry->size;
434#define Rtl819XFwImageArray Rtl8192SUFwImgArray 382 release_firmware(fw_entry);
435 //2008.11.10 Add by tynli. 383
436 pucMappedFile = Rtl819XFwImageArray; 384 pucMappedFile = pFirmware->szFwTmpBuffer;
437 ulFileLength = ImgArrayLength; 385 file_length = pFirmware->szFwTmpBufferLen;
438 386
439 RT_TRACE(COMP_INIT,"Fw download from header.\n"); 387 /* Retrieve FW header. */
440 /* Retrieve FW header*/
441 pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile; 388 pFirmware->pFwHeader = (PRT_8192S_FIRMWARE_HDR) pucMappedFile;
442 pFwHdr = pFirmware->pFwHeader; 389 pFwHdr = pFirmware->pFwHeader;
443 RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \ 390 RT_TRACE(COMP_FIRMWARE,"signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", \
444 pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \ 391 pFwHdr->Signature, pFwHdr->Version, pFwHdr->DMEMSize, \
445 pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE); 392 pFwHdr->IMG_IMEM_SIZE, pFwHdr->IMG_SRAM_SIZE);
446 pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0); 393 pFirmware->FirmwareVersion = byte(pFwHdr->Version ,0);
447 394 if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) {
448 if ((pFwHdr->IMG_IMEM_SIZE==0) || (pFwHdr->IMG_IMEM_SIZE > sizeof(pFirmware->FwIMEM))) 395 RT_TRACE(COMP_ERR, "%s: memory for data image is less than IMEM required\n",\
449 { 396 __FUNCTION__);
450 printk("FirmwareDownload92S(): memory for data image is less than IMEM required\n");
451 goto DownloadFirmware_Fail; 397 goto DownloadFirmware_Fail;
452 } else { 398 } else {
453 pucMappedFile+=FwHdrSize; 399 pucMappedFile+=FwHdrSize;
454 //Retrieve IMEM image. 400 /* Retrieve IMEM image. */
455 memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE); 401 memcpy(pFirmware->FwIMEM, pucMappedFile, pFwHdr->IMG_IMEM_SIZE);
456 pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE; 402 pFirmware->FwIMEMLen = pFwHdr->IMG_IMEM_SIZE;
457 } 403 }
458 404
459 if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) 405 if (pFwHdr->IMG_SRAM_SIZE > sizeof(pFirmware->FwEMEM)) {
460 { 406 RT_TRACE(COMP_ERR, "%s: memory for data image is less than EMEM required\n",\
461 printk(" FirmwareDownload92S(): memory for data image is less than EMEM required\n"); 407 __FUNCTION__);
462 goto DownloadFirmware_Fail; 408 goto DownloadFirmware_Fail;
463 } else { 409 } else {
464 pucMappedFile+= pFirmware->FwIMEMLen; 410 pucMappedFile += pFirmware->FwIMEMLen;
465 411 /* Retriecve EMEM image */
466 //Retriecve EMEM image. 412 memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE);//===>6
467 memcpy(pFirmware->FwEMEM, pucMappedFile, pFwHdr->IMG_SRAM_SIZE); 413 pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE;
468 pFirmware->FwEMEMLen = pFwHdr->IMG_SRAM_SIZE; 414 }
469 }
470#endif
471 break;
472 default:
473 break;
474 } 415 }
475 416
476 FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus); 417 FwStatus = FirmwareGetNextStatus(pFirmware->FWStatus);
@@ -538,3 +479,4 @@ bool FirmwareDownload92S(struct net_device *dev)
538 return rtStatus; 479 return rtStatus;
539} 480}
540 481
482MODULE_FIRMWARE("RTL8192SU/rtl8192sfw.bin");
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.h b/drivers/staging/rtl8192su/r8192S_firmware.h
index c525380e6473..2c2cf8032ded 100644
--- a/drivers/staging/rtl8192su/r8192S_firmware.h
+++ b/drivers/staging/rtl8192su/r8192S_firmware.h
@@ -59,12 +59,6 @@ typedef enum _desc_packet_type_e{
59 DESC_PACKET_TYPE_NORMAL = 1, 59 DESC_PACKET_TYPE_NORMAL = 1,
60}desc_packet_type_e; 60}desc_packet_type_e;
61 61
62typedef enum _firmware_source{
63 FW_SOURCE_IMG_FILE = 0,
64 FW_SOURCE_HEADER_FILE = 1,
65}firmware_source_e, *pfirmware_source_e;
66
67
68typedef enum _opt_rst_type{ 62typedef enum _opt_rst_type{
69 OPT_SYSTEM_RESET = 0, 63 OPT_SYSTEM_RESET = 0,
70 OPT_FIRMWARE_RESET = 1, 64 OPT_FIRMWARE_RESET = 1,
@@ -185,7 +179,6 @@ typedef enum _FIRMWARE_8192S_STATUS{
185#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k 179#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k
186 180
187typedef struct _rt_firmware{ 181typedef struct _rt_firmware{
188 firmware_source_e eFWSource;
189 PRT_8192S_FIRMWARE_HDR pFwHeader; 182 PRT_8192S_FIRMWARE_HDR pFwHeader;
190 FIRMWARE_8192S_STATUS FWStatus; 183 FIRMWARE_8192S_STATUS FWStatus;
191 u16 FirmwareVersion; 184 u16 FirmwareVersion;
diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c
index 77ab026288d3..63d4e5fd7b18 100644
--- a/drivers/staging/rtl8192su/r8192S_phy.c
+++ b/drivers/staging/rtl8192su/r8192S_phy.c
@@ -2407,8 +2407,8 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
2407 break; 2407 break;
2408 2408
2409 default: 2409 default:
2410 RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci():\ 2410 RT_TRACE(COMP_DBG, "SetBWModeCallback8190Pci(): unknown Bandwidth: %#X\n",
2411 unknown Bandwidth: %#X\n",priv->CurrentChannelBW); 2411 priv->CurrentChannelBW);
2412 break; 2412 break;
2413 } 2413 }
2414 2414
@@ -3398,8 +3398,8 @@ void SwChnlCallback8192SUsb(struct net_device *dev)
3398 u32 delay; 3398 u32 delay;
3399// bool ret; 3399// bool ret;
3400 3400
3401 RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel\ 3401 RT_TRACE(COMP_SCAN, "==>SwChnlCallback8190Pci(), switch to channel %d\n",
3402 %d\n", priv->chan); 3402 priv->chan);
3403 3403
3404 3404
3405 if(!priv->up) 3405 if(!priv->up)
@@ -3525,8 +3525,8 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
3525 break; 3525 break;
3526 3526
3527 default: 3527 default:
3528 RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci():\ 3528 RT_TRACE(COMP_DBG, "SetChannelBandwidth8190Pci(): unknown Bandwidth: %#X\n",
3529 unknown Bandwidth: %#X\n",priv->CurrentChannelBW); 3529 priv->CurrentChannelBW);
3530 break; 3530 break;
3531 } 3531 }
3532 3532
@@ -3660,8 +3660,8 @@ void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
3660 break; 3660 break;
3661 3661
3662 default: 3662 default:
3663 RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem():\ 3663 RT_TRACE(COMP_DBG, "SetBWModeCallback8192SUsbWorkItem(): unknown Bandwidth: %#X\n",
3664 unknown Bandwidth: %#X\n",priv->CurrentChannelBW); 3664 priv->CurrentChannelBW);
3665 break; 3665 break;
3666 } 3666 }
3667 3667
diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h
index 2a11e0113d3a..ba87623f32ee 100644
--- a/drivers/staging/rtl8192su/r8192U.h
+++ b/drivers/staging/rtl8192su/r8192U.h
@@ -1258,7 +1258,6 @@ typedef struct r8192_priv
1258 u8 Rf_Mode; //add for Firmware RF -R/W switch 1258 u8 Rf_Mode; //add for Firmware RF -R/W switch
1259 prt_firmware pFirmware; 1259 prt_firmware pFirmware;
1260 rtl819xUsb_loopback_e LoopbackMode; 1260 rtl819xUsb_loopback_e LoopbackMode;
1261 firmware_source_e firmware_source;
1262 bool usb_error; 1261 bool usb_error;
1263 1262
1264 u16 EEPROMTxPowerDiff; 1263 u16 EEPROMTxPowerDiff;
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c
index 6f424fe8a237..7d0305cc2106 100644
--- a/drivers/staging/rtl8192su/r8192U_core.c
+++ b/drivers/staging/rtl8192su/r8192U_core.c
@@ -110,7 +110,7 @@ u32 rt_global_debug_component = \
110#define TOTAL_CAM_ENTRY 32 110#define TOTAL_CAM_ENTRY 32
111#define CAM_CONTENT_COUNT 8 111#define CAM_CONTENT_COUNT 8
112 112
113static struct usb_device_id rtl8192_usb_id_tbl[] = { 113static const struct usb_device_id rtl8192_usb_id_tbl[] = {
114 /* Realtek */ 114 /* Realtek */
115 {USB_DEVICE(0x0bda, 0x8192)}, 115 {USB_DEVICE(0x0bda, 0x8192)},
116 {USB_DEVICE(0x0bda, 0x8709)}, 116 {USB_DEVICE(0x0bda, 0x8709)},
@@ -2340,25 +2340,24 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
2340 skb->len, rtl8192_tx_isr, skb); 2340 skb->len, rtl8192_tx_isr, skb);
2341 2341
2342 status = usb_submit_urb(tx_urb, GFP_ATOMIC); 2342 status = usb_submit_urb(tx_urb, GFP_ATOMIC);
2343 if (!status){ 2343 if (!status) {
2344//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27 2344 /*
2345 * we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted.
2346 * Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
2347 */
2345 bool bSend0Byte = false; 2348 bool bSend0Byte = false;
2346 u8 zero = 0; 2349 u8 zero = 0;
2347 if(udev->speed == USB_SPEED_HIGH) 2350 if(udev->speed == USB_SPEED_HIGH) {
2348 {
2349 if (skb->len > 0 && skb->len % 512 == 0) 2351 if (skb->len > 0 && skb->len % 512 == 0)
2350 bSend0Byte = true; 2352 bSend0Byte = true;
2351 } 2353 }
2352 else 2354 else {
2353 {
2354 if (skb->len > 0 && skb->len % 64 == 0) 2355 if (skb->len > 0 && skb->len % 64 == 0)
2355 bSend0Byte = true; 2356 bSend0Byte = true;
2356 } 2357 }
2357 if (bSend0Byte) 2358 if (bSend0Byte) {
2358 {
2359#if 1
2360 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC); 2359 tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
2361 if(!tx_urb_zero){ 2360 if(!tx_urb_zero) {
2362 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n"); 2361 RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
2363 return -ENOMEM; 2362 return -ENOMEM;
2364 } 2363 }
@@ -2366,16 +2365,23 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
2366 usb_sndbulkpipe(udev,idx_pipe), &zero, 2365 usb_sndbulkpipe(udev,idx_pipe), &zero,
2367 0, tx_zero_isr, dev); 2366 0, tx_zero_isr, dev);
2368 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC); 2367 status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
2369 if (status){ 2368 switch (status) {
2370 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status); 2369 case 0:
2371 return -1; 2370 break;
2371 case -ECONNRESET:
2372 case -ENOENT:
2373 case -ESHUTDOWN:
2374 break;
2375 default:
2376 RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d",
2377 atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
2378 return -1;
2372 } 2379 }
2373#endif
2374 } 2380 }
2375 dev->trans_start = jiffies; 2381 dev->trans_start = jiffies;
2376 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]); 2382 atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
2377 return 0; 2383 return 0;
2378 }else{ 2384 } else {
2379 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), 2385 RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
2380 status); 2386 status);
2381 return -1; 2387 return -1;
@@ -2952,7 +2958,7 @@ void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2952 wireless_mode = WIRELESS_MODE_B; 2958 wireless_mode = WIRELESS_MODE_B;
2953 } 2959 }
2954 } 2960 }
2955#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA 2961#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2956 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); 2962 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2957#endif 2963#endif
2958 //LZM 090306 usb crash here, mark it temp 2964 //LZM 090306 usb crash here, mark it temp
@@ -3359,6 +3365,46 @@ u8 rtl8192SU_BoardTypeToRFtype(struct net_device* dev, u8 Boardtype)
3359 return RFtype; 3365 return RFtype;
3360} 3366}
3361 3367
3368void update_hal_variables(struct r8192_priv *priv)
3369{
3370 int rf_path;
3371 int i;
3372 u8 index;
3373
3374 for (rf_path = 0; rf_path < 2; rf_path++) {
3375 for (i = 0; i < 3; i++) {
3376 RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfCckChnlAreaTxPwr[rf_path][i]);
3377 RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
3378 RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
3379 }
3380 /* Assign dedicated channel tx power */
3381 for(i = 0; i < 14; i++) {
3382 /* channel 1-3 use the same Tx Power Level. */
3383 if (i < 3) /* Channel 1-3 */
3384 index = 0;
3385 else if (i < 9) /* Channel 4-9 */
3386 index = 1;
3387 else /* Channel 10-14 */
3388 index = 2;
3389 /* Record A & B CCK /OFDM - 1T/2T Channel area tx power */
3390 priv->RfTxPwrLevelCck[rf_path][i] = priv->RfCckChnlAreaTxPwr[rf_path][index];
3391 priv->RfTxPwrLevelOfdm1T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
3392 priv->RfTxPwrLevelOfdm2T[rf_path][i] = priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
3393 if (rf_path == 0) {
3394 priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
3395 priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
3396 }
3397 }
3398 for(i = 0; i < 14; i++) {
3399 RT_TRACE((COMP_INIT),
3400 "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
3401 rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
3402 priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
3403 priv->RfTxPwrLevelOfdm2T[rf_path][i] );
3404 }
3405 }
3406}
3407
3362// 3408//
3363// Description: 3409// Description:
3364// Config HW adapter information into initial value. 3410// Config HW adapter information into initial value.
@@ -3374,7 +3420,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
3374 struct r8192_priv *priv = ieee80211_priv(dev); 3420 struct r8192_priv *priv = ieee80211_priv(dev);
3375 //u16 i,usValue; 3421 //u16 i,usValue;
3376 //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00}; 3422 //u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
3377 u8 rf_path, index; // For EEPROM/EFUSE After V0.6_1117 3423 u8 rf_path; // For EEPROM/EFUSE After V0.6_1117
3378 int i; 3424 int i;
3379 3425
3380 RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n"); 3426 RT_TRACE(COMP_INIT, "====> ConfigAdapterInfo8192SForAutoLoadFail\n");
@@ -3426,10 +3472,9 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
3426 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]); 3472 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3427 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]); 3473 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3428 3474
3429 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n", 3475 RT_TRACE(COMP_INIT,
3430 dev->dev_addr[0], dev->dev_addr[1], 3476 "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
3431 dev->dev_addr[2], dev->dev_addr[3], 3477 dev->dev_addr);
3432 dev->dev_addr[4], dev->dev_addr[5]);
3433 3478
3434 priv->EEPROMBoardType = EEPROM_Default_BoardType; 3479 priv->EEPROMBoardType = EEPROM_Default_BoardType;
3435 priv->rf_type = RF_1T2R; //RF_2T2R 3480 priv->rf_type = RF_1T2R; //RF_2T2R
@@ -3455,42 +3500,7 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
3455 } 3500 }
3456 } 3501 }
3457 3502
3458 for (i = 0; i < 3; i++) 3503 update_hal_variables(priv);
3459 {
3460 //RT_TRACE((COMP_EFUSE), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3461 //priv->RfCckChnlAreaTxPwr[rf_path][i]);
3462 //RT_TRACE((COMP_EFUSE), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3463 //priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
3464 //RT_TRACE((COMP_EFUSE), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3465 //priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
3466 }
3467
3468 // Assign dedicated channel tx power
3469 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
3470 {
3471 if (i < 3) // Cjanel 1-3
3472 index = 0;
3473 else if (i < 9) // Channel 4-9
3474 index = 1;
3475 else // Channel 10-14
3476 index = 2;
3477
3478 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
3479 priv->RfTxPwrLevelCck[rf_path][i] =
3480 priv->RfCckChnlAreaTxPwr[rf_path][index];
3481 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
3482 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
3483 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
3484 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
3485 }
3486
3487 for(i=0; i<14; i++)
3488 {
3489 //RT_TRACE((COMP_EFUSE), "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
3490 //rf_path, i, priv->RfTxPwrLevelCck[0][i],
3491 //priv->RfTxPwrLevelOfdm1T[0][i] ,
3492 //priv->RfTxPwrLevelOfdm2T[0][i] );
3493 }
3494 3504
3495 // 3505 //
3496 // Update remained HAL variables. 3506 // Update remained HAL variables.
@@ -3767,10 +3777,9 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
3767 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]); 3777 write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
3768 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]); 3778 write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
3769 3779
3770 RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n", 3780 RT_TRACE(COMP_INIT,
3771 dev->dev_addr[0], dev->dev_addr[1], 3781 "ReadAdapterInfo8192SEFuse(), Permanent Address = %pM\n",
3772 dev->dev_addr[2], dev->dev_addr[3], 3782 dev->dev_addr);
3773 dev->dev_addr[4], dev->dev_addr[5]);
3774 3783
3775 // 3784 //
3776 // Get CustomerID(Boad Type) 3785 // Get CustomerID(Boad Type)
@@ -3901,53 +3910,7 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
3901 } 3910 }
3902 3911
3903 } 3912 }
3904// 3913 update_hal_variables(priv);
3905 // Update Tx Power HAL variables.
3906//
3907 for (rf_path = 0; rf_path < 2; rf_path++)
3908 {
3909 for (i = 0; i < 3; i++)
3910 {
3911 RT_TRACE((COMP_INIT), "CCK RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3912 priv->RfCckChnlAreaTxPwr[rf_path][i]);
3913 RT_TRACE((COMP_INIT), "OFDM-1T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i,
3914 priv->RfOfdmChnlAreaTxPwr1T[rf_path][i]);
3915 RT_TRACE((COMP_INIT), "OFDM-2T RF-%d CHan_Area-%d = 0x%x\n", rf_path, i, priv->RfOfdmChnlAreaTxPwr2T[rf_path][i]);
3916 }
3917
3918 // Assign dedicated channel tx power
3919 for(i=0; i<14; i++) // channel 1~3 use the same Tx Power Level.
3920 {
3921 if (i < 3) // Cjanel 1-3
3922 index = 0;
3923 else if (i < 9) // Channel 4-9
3924 index = 1;
3925 else // Channel 10-14
3926 index = 2;
3927
3928 // Record A & B CCK /OFDM - 1T/2T Channel area tx power
3929 priv->RfTxPwrLevelCck[rf_path][i] =
3930 priv->RfCckChnlAreaTxPwr[rf_path][index];
3931 priv->RfTxPwrLevelOfdm1T[rf_path][i] =
3932 priv->RfOfdmChnlAreaTxPwr1T[rf_path][index];
3933 priv->RfTxPwrLevelOfdm2T[rf_path][i] =
3934 priv->RfOfdmChnlAreaTxPwr2T[rf_path][index];
3935 if (rf_path == 0)
3936 {
3937 priv->TxPowerLevelOFDM24G[i] = priv->RfTxPwrLevelOfdm1T[rf_path][i] ;
3938 priv->TxPowerLevelCCK[i] = priv->RfTxPwrLevelCck[rf_path][i];
3939 }
3940 }
3941
3942 for(i=0; i<14; i++)
3943 {
3944 RT_TRACE((COMP_INIT),
3945 "Rf-%d TxPwr CH-%d CCK OFDM_1T OFDM_2T= 0x%x/0x%x/0x%x\n",
3946 rf_path, i, priv->RfTxPwrLevelCck[rf_path][i],
3947 priv->RfTxPwrLevelOfdm1T[rf_path][i] ,
3948 priv->RfTxPwrLevelOfdm2T[rf_path][i] );
3949 }
3950 }
3951 } 3914 }
3952 3915
3953 // 3916 //
@@ -7677,7 +7640,7 @@ void setKey( struct net_device *dev,
7677 if (EntryNo >= TOTAL_CAM_ENTRY) 7640 if (EntryNo >= TOTAL_CAM_ENTRY)
7678 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); 7641 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
7679 7642
7680 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr)); 7643 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
7681 7644
7682 if (DefaultKey) 7645 if (DefaultKey)
7683 usConfig |= BIT15 | (KeyType<<2); 7646 usConfig |= BIT15 | (KeyType<<2);
diff --git a/drivers/staging/rtl8192su/r8192U_dm.c b/drivers/staging/rtl8192su/r8192U_dm.c
index 7891e9640272..fa5e24416dde 100644
--- a/drivers/staging/rtl8192su/r8192U_dm.c
+++ b/drivers/staging/rtl8192su/r8192U_dm.c
@@ -2697,7 +2697,7 @@ static void dm_check_edca_turbo(
2697 u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"}; 2697 u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"};
2698 static int wb_tmp = 0; 2698 static int wb_tmp = 0;
2699 if (wb_tmp == 0){ 2699 if (wb_tmp == 0){
2700 printk("%s():iot peer is %#x:%s, bssid:"MAC_FMT"\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], MAC_ARG(priv->ieee80211->current_network.bssid)); 2700 printk("%s():iot peer is %#x:%s, bssid:%pM\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], priv->ieee80211->current_network.bssid);
2701 wb_tmp = 1; 2701 wb_tmp = 1;
2702 } 2702 }
2703 } 2703 }
diff --git a/drivers/staging/rtl8192u/Kconfig b/drivers/staging/rtl8192u/Kconfig
index 9913ab8fb359..0439c90b4163 100644
--- a/drivers/staging/rtl8192u/Kconfig
+++ b/drivers/staging/rtl8192u/Kconfig
@@ -1,6 +1,7 @@
1config RTL8192U 1config RTL8192U
2 tristate "RealTek RTL8192U Wireless LAN NIC driver" 2 tristate "RealTek RTL8192U Wireless LAN NIC driver"
3 depends on PCI && WLAN && USB 3 depends on PCI && WLAN && USB
4 depends on WIRELESS_EXT 4 select WIRELESS_EXT
5 select WEXT_PRIV
5 default N 6 default N
6 ---help--- 7 ---help---
diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile
index 2d59c4ef6c5b..738f4a80ec67 100644
--- a/drivers/staging/rtl8192u/Makefile
+++ b/drivers/staging/rtl8192u/Makefile
@@ -3,7 +3,7 @@ NIC_SELECT = RTL8192U
3EXTRA_CFLAGS += -std=gnu89 3EXTRA_CFLAGS += -std=gnu89
4EXTRA_CFLAGS += -O2 4EXTRA_CFLAGS += -O2
5 5
6EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y 6EXTRA_CFLAGS += -DCONFIG_FORCE_HARD_FLOAT=y
7EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX 7EXTRA_CFLAGS += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX
8EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO 8EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO
9#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE 9#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE
diff --git a/drivers/staging/rtl8192u/ieee80211.h b/drivers/staging/rtl8192u/ieee80211.h
index 3a47f1213e85..9d05ed6791ee 100644
--- a/drivers/staging/rtl8192u/ieee80211.h
+++ b/drivers/staging/rtl8192u/ieee80211.h
@@ -551,9 +551,6 @@ do { if (ieee80211_debug_level & (level)) \
551 551
552/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ 552/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
553 553
554#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
555#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
556
557/* 554/*
558 * To use the debug system; 555 * To use the debug system;
559 * 556 *
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
index 10908e123b86..39847c81e29c 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h
@@ -30,6 +30,7 @@
30#include <linux/jiffies.h> 30#include <linux/jiffies.h>
31#include <linux/timer.h> 31#include <linux/timer.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/semaphore.h>
33 34
34#include <linux/delay.h> 35#include <linux/delay.h>
35#include <linux/wireless.h> 36#include <linux/wireless.h>
@@ -551,9 +552,6 @@ do { if (ieee80211_debug_level & (level)) \
551 552
552/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ 553/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
553 554
554#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
555#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
556
557/* 555/*
558 * To use the debug system; 556 * To use the debug system;
559 * 557 *
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
index 0b33bf463320..0b57632bcff9 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c
@@ -288,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
288 if (!(keyidx & (1 << 5))) { 288 if (!(keyidx & (1 << 5))) {
289 if (net_ratelimit()) { 289 if (net_ratelimit()) {
290 printk(KERN_DEBUG "CCMP: received packet without ExtIV" 290 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
291 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 291 " flag from %pM\n", hdr->addr2);
292 } 292 }
293 key->dot11RSNAStatsCCMPFormatErrors++; 293 key->dot11RSNAStatsCCMPFormatErrors++;
294 return -2; 294 return -2;
@@ -301,9 +301,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
301 } 301 }
302 if (!key->key_set) { 302 if (!key->key_set) {
303 if (net_ratelimit()) { 303 if (net_ratelimit()) {
304 printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT 304 printk(KERN_DEBUG "CCMP: received packet from %pM"
305 " with keyid=%d that does not have a configured" 305 " with keyid=%d that does not have a configured"
306 " key\n", MAC_ARG(hdr->addr2), keyidx); 306 " key\n", hdr->addr2, keyidx);
307 } 307 }
308 return -3; 308 return -3;
309 } 309 }
@@ -318,11 +318,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
318 318
319 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { 319 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
320 if (net_ratelimit()) { 320 if (net_ratelimit()) {
321 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT 321 printk(KERN_DEBUG "CCMP: replay detected: STA=%pM"
322 " previous PN %02x%02x%02x%02x%02x%02x " 322 " previous PN %pm received PN %pm\n",
323 "received PN %02x%02x%02x%02x%02x%02x\n", 323 hdr->addr2, key->rx_pn, pn);
324 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
325 MAC_ARG(pn));
326 } 324 }
327 key->dot11RSNAStatsCCMPReplays++; 325 key->dot11RSNAStatsCCMPReplays++;
328 return -4; 326 return -4;
@@ -359,7 +357,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
359 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { 357 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
360 if (net_ratelimit()) { 358 if (net_ratelimit()) {
361 printk(KERN_DEBUG "CCMP: decrypt failed: STA=" 359 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
362 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 360 "%pM\n", hdr->addr2);
363 } 361 }
364 key->dot11RSNAStatsCCMPDecryptErrors++; 362 key->dot11RSNAStatsCCMPDecryptErrors++;
365 return -5; 363 return -5;
@@ -435,11 +433,10 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv)
435{ 433{
436 struct ieee80211_ccmp_data *ccmp = priv; 434 struct ieee80211_ccmp_data *ccmp = priv;
437 p += sprintf(p, "key[%d] alg=CCMP key_set=%d " 435 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
438 "tx_pn=%02x%02x%02x%02x%02x%02x " 436 "tx_pn=%pm rx_pn=%pm "
439 "rx_pn=%02x%02x%02x%02x%02x%02x "
440 "format_errors=%d replays=%d decrypt_errors=%d\n", 437 "format_errors=%d replays=%d decrypt_errors=%d\n",
441 ccmp->key_idx, ccmp->key_set, 438 ccmp->key_idx, ccmp->key_set,
442 MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn), 439 ccmp->tx_pn, ccmp->rx_pn,
443 ccmp->dot11RSNAStatsCCMPFormatErrors, 440 ccmp->dot11RSNAStatsCCMPFormatErrors,
444 ccmp->dot11RSNAStatsCCMPReplays, 441 ccmp->dot11RSNAStatsCCMPReplays,
445 ccmp->dot11RSNAStatsCCMPDecryptErrors); 442 ccmp->dot11RSNAStatsCCMPDecryptErrors);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
index 841b99955b79..9510507d8d05 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c
@@ -410,7 +410,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
410 if (!(keyidx & (1 << 5))) { 410 if (!(keyidx & (1 << 5))) {
411 if (net_ratelimit()) { 411 if (net_ratelimit()) {
412 printk(KERN_DEBUG "TKIP: received packet without ExtIV" 412 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
413 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); 413 " flag from %pM\n", hdr->addr2);
414 } 414 }
415 return -2; 415 return -2;
416 } 416 }
@@ -422,9 +422,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
422 } 422 }
423 if (!tkey->key_set) { 423 if (!tkey->key_set) {
424 if (net_ratelimit()) { 424 if (net_ratelimit()) {
425 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT 425 printk(KERN_DEBUG "TKIP: received packet from %pM"
426 " with keyid=%d that does not have a configured" 426 " with keyid=%d that does not have a configured"
427 " key\n", MAC_ARG(hdr->addr2), keyidx); 427 " key\n", hdr->addr2, keyidx);
428 } 428 }
429 return -3; 429 return -3;
430 } 430 }
@@ -437,9 +437,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
437 if (iv32 < tkey->rx_iv32 || 437 if (iv32 < tkey->rx_iv32 ||
438 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { 438 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
439 if (net_ratelimit()) { 439 if (net_ratelimit()) {
440 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT 440 printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
441 " previous TSC %08x%04x received TSC " 441 " previous TSC %08x%04x received TSC "
442 "%08x%04x\n", MAC_ARG(hdr->addr2), 442 "%08x%04x\n", hdr->addr2,
443 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); 443 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
444 } 444 }
445 tkey->dot11RSNAStatsTKIPReplays++; 445 tkey->dot11RSNAStatsTKIPReplays++;
@@ -460,8 +460,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
460 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { 460 if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
461 if (net_ratelimit()) { 461 if (net_ratelimit()) {
462 printk(KERN_DEBUG ": TKIP: failed to decrypt " 462 printk(KERN_DEBUG ": TKIP: failed to decrypt "
463 "received packet from " MAC_FMT "\n", 463 "received packet from %pM\n",
464 MAC_ARG(hdr->addr2)); 464 hdr->addr2);
465 } 465 }
466 return -7; 466 return -7;
467 } 467 }
@@ -480,7 +480,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
480 } 480 }
481 if (net_ratelimit()) { 481 if (net_ratelimit()) {
482 printk(KERN_DEBUG "TKIP: ICV error detected: STA=" 482 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
483 MAC_FMT "\n", MAC_ARG(hdr->addr2)); 483 "%pM\n", hdr->addr2);
484 } 484 }
485 tkey->dot11RSNAStatsTKIPICVErrors++; 485 tkey->dot11RSNAStatsTKIPICVErrors++;
486 return -5; 486 return -5;
@@ -635,8 +635,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
635 struct ieee80211_hdr_4addr *hdr; 635 struct ieee80211_hdr_4addr *hdr;
636 hdr = (struct ieee80211_hdr_4addr *) skb->data; 636 hdr = (struct ieee80211_hdr_4addr *) skb->data;
637 printk(KERN_DEBUG "%s: Michael MIC verification failed for " 637 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
638 "MSDU from " MAC_FMT " keyidx=%d\n", 638 "MSDU from %pM keyidx=%d\n",
639 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), 639 skb->dev ? skb->dev->name : "N/A", hdr->addr2,
640 keyidx); 640 keyidx);
641 if (skb->dev) 641 if (skb->dev)
642 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); 642 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
index 7a8690f449b4..b752017a4d18 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
@@ -260,7 +260,7 @@ static int store_debug_level(struct file *file, const char *buffer,
260 unsigned long count, void *data) 260 unsigned long count, void *data)
261{ 261{
262 char buf[] = "0x00000000"; 262 char buf[] = "0x00000000";
263 unsigned long len = min(sizeof(buf) - 1, count); 263 unsigned long len = min_t(unsigned long, sizeof(buf) - 1, count);
264 char *p = (char *)buf; 264 char *p = (char *)buf;
265 unsigned long val; 265 unsigned long val;
266 266
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index 0e003c5bb000..7e9b367594a0 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -360,8 +360,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
360 strcmp(crypt->ops->name, "TKIP") == 0) { 360 strcmp(crypt->ops->name, "TKIP") == 0) {
361 if (net_ratelimit()) { 361 if (net_ratelimit()) {
362 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 362 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
363 "received packet from " MAC_FMT "\n", 363 "received packet from %pM\n",
364 ieee->dev->name, MAC_ARG(hdr->addr2)); 364 ieee->dev->name, hdr->addr2);
365 } 365 }
366 return -1; 366 return -1;
367 } 367 }
@@ -372,8 +372,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
372 atomic_dec(&crypt->refcnt); 372 atomic_dec(&crypt->refcnt);
373 if (res < 0) { 373 if (res < 0) {
374 IEEE80211_DEBUG_DROP( 374 IEEE80211_DEBUG_DROP(
375 "decryption failed (SA=" MAC_FMT 375 "decryption failed (SA=%pM"
376 ") res=%d\n", MAC_ARG(hdr->addr2), res); 376 ") res=%d\n", hdr->addr2, res);
377 if (res == -2) 377 if (res == -2)
378 IEEE80211_DEBUG_DROP("Decryption failed ICV " 378 IEEE80211_DEBUG_DROP("Decryption failed ICV "
379 "mismatch (key %d)\n", 379 "mismatch (key %d)\n",
@@ -410,8 +410,8 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
410 atomic_dec(&crypt->refcnt); 410 atomic_dec(&crypt->refcnt);
411 if (res < 0) { 411 if (res < 0) {
412 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" 412 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
413 " (SA=" MAC_FMT " keyidx=%d)\n", 413 " (SA=%pM keyidx=%d)\n",
414 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx); 414 ieee->dev->name, hdr->addr2, keyidx);
415 return -1; 415 return -1;
416 } 416 }
417 417
@@ -1016,8 +1016,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1016 * frames silently instead of filling system log with 1016 * frames silently instead of filling system log with
1017 * these reports. */ 1017 * these reports. */
1018 IEEE80211_DEBUG_DROP("Decryption failed (not set)" 1018 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
1019 " (SA=" MAC_FMT ")\n", 1019 " (SA=%pM)\n",
1020 MAC_ARG(hdr->addr2)); 1020 hdr->addr2);
1021 ieee->ieee_stats.rx_discards_undecryptable++; 1021 ieee->ieee_stats.rx_discards_undecryptable++;
1022 goto rx_dropped; 1022 goto rx_dropped;
1023 } 1023 }
@@ -1256,8 +1256,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1256 } else { 1256 } else {
1257 IEEE80211_DEBUG_DROP( 1257 IEEE80211_DEBUG_DROP(
1258 "encryption configured, but RX " 1258 "encryption configured, but RX "
1259 "frame not encrypted (SA=" MAC_FMT ")\n", 1259 "frame not encrypted (SA=%pM)\n",
1260 MAC_ARG(hdr->addr2)); 1260 hdr->addr2);
1261 goto rx_dropped; 1261 goto rx_dropped;
1262 } 1262 }
1263 } 1263 }
@@ -1276,9 +1276,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1276 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { 1276 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
1277 IEEE80211_DEBUG_DROP( 1277 IEEE80211_DEBUG_DROP(
1278 "dropped unencrypted RX data " 1278 "dropped unencrypted RX data "
1279 "frame from " MAC_FMT 1279 "frame from %pM"
1280 " (drop_unencrypted=1)\n", 1280 " (drop_unencrypted=1)\n",
1281 MAC_ARG(hdr->addr2)); 1281 hdr->addr2);
1282 goto rx_dropped; 1282 goto rx_dropped;
1283 } 1283 }
1284/* 1284/*
@@ -2260,11 +2260,11 @@ static inline int ieee80211_network_init(
2260 } 2260 }
2261 2261
2262 if (network->mode == 0) { 2262 if (network->mode == 0) {
2263 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " 2263 IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
2264 "network.\n", 2264 "network.\n",
2265 escape_essid(network->ssid, 2265 escape_essid(network->ssid,
2266 network->ssid_len), 2266 network->ssid_len),
2267 MAC_ARG(network->bssid)); 2267 network->bssid);
2268 return 1; 2268 return 1;
2269 } 2269 }
2270 2270
@@ -2439,9 +2439,9 @@ static inline void ieee80211_process_probe_response(
2439 2439
2440 memset(&network, 0, sizeof(struct ieee80211_network)); 2440 memset(&network, 0, sizeof(struct ieee80211_network));
2441 IEEE80211_DEBUG_SCAN( 2441 IEEE80211_DEBUG_SCAN(
2442 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", 2442 "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
2443 escape_essid(info_element->data, info_element->len), 2443 escape_essid(info_element->data, info_element->len),
2444 MAC_ARG(beacon->header.addr3), 2444 beacon->header.addr3,
2445 (beacon->capability & (1<<0xf)) ? '1' : '0', 2445 (beacon->capability & (1<<0xf)) ? '1' : '0',
2446 (beacon->capability & (1<<0xe)) ? '1' : '0', 2446 (beacon->capability & (1<<0xe)) ? '1' : '0',
2447 (beacon->capability & (1<<0xd)) ? '1' : '0', 2447 (beacon->capability & (1<<0xd)) ? '1' : '0',
@@ -2460,10 +2460,10 @@ static inline void ieee80211_process_probe_response(
2460 (beacon->capability & (1<<0x0)) ? '1' : '0'); 2460 (beacon->capability & (1<<0x0)) ? '1' : '0');
2461 2461
2462 if (ieee80211_network_init(ieee, beacon, &network, stats)) { 2462 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
2463 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n", 2463 IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
2464 escape_essid(info_element->data, 2464 escape_essid(info_element->data,
2465 info_element->len), 2465 info_element->len),
2466 MAC_ARG(beacon->header.addr3), 2466 beacon->header.addr3,
2467 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 2467 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2468 IEEE80211_STYPE_PROBE_RESP ? 2468 IEEE80211_STYPE_PROBE_RESP ?
2469 "PROBE RESPONSE" : "BEACON"); 2469 "PROBE RESPONSE" : "BEACON");
@@ -2574,11 +2574,11 @@ static inline void ieee80211_process_probe_response(
2574 /* If there are no more slots, expire the oldest */ 2574 /* If there are no more slots, expire the oldest */
2575 list_del(&oldest->list); 2575 list_del(&oldest->list);
2576 target = oldest; 2576 target = oldest;
2577 IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from " 2577 IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
2578 "network list.\n", 2578 "network list.\n",
2579 escape_essid(target->ssid, 2579 escape_essid(target->ssid,
2580 target->ssid_len), 2580 target->ssid_len),
2581 MAC_ARG(target->bssid)); 2581 target->bssid);
2582 } else { 2582 } else {
2583 /* Otherwise just pull from the free list */ 2583 /* Otherwise just pull from the free list */
2584 target = list_entry(ieee->network_free_list.next, 2584 target = list_entry(ieee->network_free_list.next,
@@ -2588,10 +2588,10 @@ static inline void ieee80211_process_probe_response(
2588 2588
2589 2589
2590#ifdef CONFIG_IEEE80211_DEBUG 2590#ifdef CONFIG_IEEE80211_DEBUG
2591 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n", 2591 IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
2592 escape_essid(network.ssid, 2592 escape_essid(network.ssid,
2593 network.ssid_len), 2593 network.ssid_len),
2594 MAC_ARG(network.bssid), 2594 network.bssid,
2595 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 2595 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2596 IEEE80211_STYPE_PROBE_RESP ? 2596 IEEE80211_STYPE_PROBE_RESP ?
2597 "PROBE RESPONSE" : "BEACON"); 2597 "PROBE RESPONSE" : "BEACON");
@@ -2601,10 +2601,10 @@ static inline void ieee80211_process_probe_response(
2601 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) 2601 if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
2602 ieee80211_softmac_new_net(ieee,&network); 2602 ieee80211_softmac_new_net(ieee,&network);
2603 } else { 2603 } else {
2604 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", 2604 IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
2605 escape_essid(target->ssid, 2605 escape_essid(target->ssid,
2606 target->ssid_len), 2606 target->ssid_len),
2607 MAC_ARG(target->bssid), 2607 target->bssid,
2608 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == 2608 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
2609 IEEE80211_STYPE_PROBE_RESP ? 2609 IEEE80211_STYPE_PROBE_RESP ?
2610 "PROBE RESPONSE" : "BEACON"); 2610 "PROBE RESPONSE" : "BEACON");
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
index 8a86e93465c8..27d925712cdd 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -1731,7 +1731,7 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1731 ieee80211_resp_to_assoc_rq(ieee, dest); 1731 ieee80211_resp_to_assoc_rq(ieee, dest);
1732 } 1732 }
1733 1733
1734 printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest)); 1734 printk(KERN_INFO"New client associated: %pM\n", dest);
1735 //FIXME 1735 //FIXME
1736} 1736}
1737 1737
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
index b29c36bac377..48537d948945 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
@@ -200,8 +200,8 @@ int ieee80211_encrypt_fragment(
200 header = (struct ieee80211_hdr *) frag->data; 200 header = (struct ieee80211_hdr *) frag->data;
201 if (net_ratelimit()) { 201 if (net_ratelimit()) {
202 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 202 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
203 "TX packet to " MAC_FMT "\n", 203 "TX packet to %pM\n",
204 ieee->dev->name, MAC_ARG(header->addr1)); 204 ieee->dev->name, header->addr1);
205 } 205 }
206 return -1; 206 return -1;
207 } 207 }
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
index 5f12d62658c9..c0b2c02b0ac4 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c
@@ -289,10 +289,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
289 else 289 else
290 IEEE80211_DEBUG_SCAN( 290 IEEE80211_DEBUG_SCAN(
291 "Not showing network '%s (" 291 "Not showing network '%s ("
292 MAC_FMT ")' due to age (%lums).\n", 292 "%pM)' due to age (%lums).\n",
293 escape_essid(network->ssid, 293 escape_essid(network->ssid,
294 network->ssid_len), 294 network->ssid_len),
295 MAC_ARG(network->bssid), 295 network->bssid,
296 (jiffies - network->last_scanned) / (HZ / 100)); 296 (jiffies - network->last_scanned) / (HZ / 100));
297 } 297 }
298 298
@@ -718,7 +718,7 @@ int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
718 } else 718 } else
719 idx = ieee->tx_keyidx; 719 idx = ieee->tx_keyidx;
720 720
721 if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY && 721 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
722 ext->alg != IW_ENCODE_ALG_WEP) 722 ext->alg != IW_ENCODE_ALG_WEP)
723 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) 723 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
724 return -EINVAL; 724 return -EINVAL;
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
index 512a57aebde3..27d083a70eb2 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -113,7 +113,7 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
113 u16 tmp = 0; 113 u16 tmp = 0;
114 u16 len = ieee->tx_headroom + 9; 114 u16 len = ieee->tx_headroom + 9;
115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) 115 //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2))
116 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev); 116 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev);
117 if (pBA == NULL||ieee == NULL) 117 if (pBA == NULL||ieee == NULL)
118 { 118 {
119 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); 119 IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
@@ -201,7 +201,7 @@ static struct sk_buff* ieee80211_DELBA(
201 u16 len = 6 + ieee->tx_headroom; 201 u16 len = 6 + ieee->tx_headroom;
202 202
203 if (net_ratelimit()) 203 if (net_ratelimit())
204 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst)); 204 IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst);
205 205
206 memset(&DelbaParamSet, 0, 2); 206 memset(&DelbaParamSet, 0, 2);
207 207
@@ -355,7 +355,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
355 pBaTimeoutVal = (u16*)(tag + 5); 355 pBaTimeoutVal = (u16*)(tag + 5);
356 pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); 356 pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
357 357
358 printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst)); 358 printk("====================>rx ADDBAREQ from :%pM\n", dst);
359//some other capability is not ready now. 359//some other capability is not ready now.
360 if( (ieee->current_network.qos_data.active == 0) || 360 if( (ieee->current_network.qos_data.active == 0) ||
361 (ieee->pHTInfo->bCurrentHTSupport == false)) //|| 361 (ieee->pHTInfo->bCurrentHTSupport == false)) //||
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
index 2c4eb38c89a8..50f4f5943e75 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
@@ -41,7 +41,7 @@ static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
41//static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; 41//static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
42static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; 42static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
43 43
44// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the 44// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
45// code in other place?? 45// code in other place??
46//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; 46//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
47/******************************************************************************************************************** 47/********************************************************************************************************************
@@ -1342,7 +1342,7 @@ void HTUseDefaultSetting(struct ieee80211_device* ieee)
1342 1342
1343 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; 1343 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
1344 1344
1345 pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; 1345 pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
1346 1346
1347 // Set BWOpMode register 1347 // Set BWOpMode register
1348 1348
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
index 5373d565af24..d1275e887f0c 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
@@ -290,7 +290,7 @@ PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8
290 if(search_dir[dir] ==false ) 290 if(search_dir[dir] ==false )
291 continue; 291 continue;
292 list_for_each_entry(pRet, psearch_list, List){ 292 list_for_each_entry(pRet, psearch_list, List){
293 // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); 293 // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
294 if (memcmp(pRet->Addr, Addr, 6) == 0) 294 if (memcmp(pRet->Addr, Addr, 6) == 0)
295 if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) 295 if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
296 if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) 296 if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
@@ -445,7 +445,7 @@ bool GetTs(
445 ResetRxTsEntry(tmp); 445 ResetRxTsEntry(tmp);
446 } 446 }
447 447
448 IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr)); 448 IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr);
449 // Prepare TS Info releated field 449 // Prepare TS Info releated field
450 pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field 450 pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field
451 pTSInfo->field.ucTSID = UP; // TSID 451 pTSInfo->field.ucTSID = UP; // TSID
@@ -531,7 +531,7 @@ void RemoveTsEntry(
531void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) 531void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
532{ 532{
533 PTS_COMMON_INFO pTS, pTmpTS; 533 PTS_COMMON_INFO pTS, pTmpTS;
534 printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr)); 534 printk("===========>RemovePeerTS,%pM\n", Addr);
535 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) 535 list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
536 { 536 {
537 if (memcmp(pTS->Addr, Addr, 6) == 0) 537 if (memcmp(pTS->Addr, Addr, 6) == 0)
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c
index adade13e1e19..f1e085ba1cf1 100644
--- a/drivers/staging/rtl8192u/r8192U_core.c
+++ b/drivers/staging/rtl8192u/r8192U_core.c
@@ -104,7 +104,7 @@ u32 rt_global_debug_component = \
104#define TOTAL_CAM_ENTRY 32 104#define TOTAL_CAM_ENTRY 32
105#define CAM_CONTENT_COUNT 8 105#define CAM_CONTENT_COUNT 8
106 106
107static struct usb_device_id rtl8192_usb_id_tbl[] = { 107static const struct usb_device_id rtl8192_usb_id_tbl[] = {
108 /* Realtek */ 108 /* Realtek */
109 {USB_DEVICE(0x0bda, 0x8192)}, 109 {USB_DEVICE(0x0bda, 0x8192)},
110 {USB_DEVICE(0x0bda, 0x8709)}, 110 {USB_DEVICE(0x0bda, 0x8709)},
@@ -2719,7 +2719,7 @@ void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2719 wireless_mode = WIRELESS_MODE_B; 2719 wireless_mode = WIRELESS_MODE_B;
2720 } 2720 }
2721 } 2721 }
2722#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA 2722#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2723 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting ); 2723 ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2724#endif 2724#endif
2725 priv->ieee80211->mode = wireless_mode; 2725 priv->ieee80211->mode = wireless_mode;
@@ -2976,7 +2976,7 @@ static void rtl8192_read_eeprom_info(struct net_device* dev)
2976 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); 2976 memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2977 //should I set IDR0 here? 2977 //should I set IDR0 here?
2978 } 2978 }
2979 RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr)); 2979 RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2980 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R 2980 priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2981 priv->rf_chip = RF_8256; 2981 priv->rf_chip = RF_8256;
2982 2982
@@ -6037,7 +6037,7 @@ void setKey( struct net_device *dev,
6037 if (EntryNo >= TOTAL_CAM_ENTRY) 6037 if (EntryNo >= TOTAL_CAM_ENTRY)
6038 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); 6038 RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6039 6039
6040 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr)); 6040 RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6041 6041
6042 if (DefaultKey) 6042 if (DefaultKey)
6043 usConfig |= BIT15 | (KeyType<<2); 6043 usConfig |= BIT15 | (KeyType<<2);
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c
index 4877138a9f96..dd7ea4c075db 100644
--- a/drivers/staging/samsung-laptop/samsung-laptop.c
+++ b/drivers/staging/samsung-laptop/samsung-laptop.c
@@ -99,7 +99,8 @@ static struct rfkill *rfk;
99 99
100static int force; 100static int force;
101module_param(force, bool, 0); 101module_param(force, bool, 0);
102MODULE_PARM_DESC(force, "Disable the DMI check and forces the driver to be loaded"); 102MODULE_PARM_DESC(force,
103 "Disable the DMI check and forces the driver to be loaded");
103 104
104static int debug; 105static int debug;
105module_param(debug, bool, S_IRUGO | S_IWUSR); 106module_param(debug, bool, S_IRUGO | S_IWUSR);
@@ -370,7 +371,8 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
370 { 371 {
371 .ident = "N128", 372 .ident = "N128",
372 .matches = { 373 .matches = {
373 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 374 DMI_MATCH(DMI_SYS_VENDOR,
375 "SAMSUNG ELECTRONICS CO., LTD."),
374 DMI_MATCH(DMI_PRODUCT_NAME, "N128"), 376 DMI_MATCH(DMI_PRODUCT_NAME, "N128"),
375 DMI_MATCH(DMI_BOARD_NAME, "N128"), 377 DMI_MATCH(DMI_BOARD_NAME, "N128"),
376 }, 378 },
@@ -379,7 +381,8 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
379 { 381 {
380 .ident = "N130", 382 .ident = "N130",
381 .matches = { 383 .matches = {
382 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 384 DMI_MATCH(DMI_SYS_VENDOR,
385 "SAMSUNG ELECTRONICS CO., LTD."),
383 DMI_MATCH(DMI_PRODUCT_NAME, "N130"), 386 DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
384 DMI_MATCH(DMI_BOARD_NAME, "N130"), 387 DMI_MATCH(DMI_BOARD_NAME, "N130"),
385 }, 388 },
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index e7bc9ec63a8c..265de7949a78 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -35,6 +35,7 @@
35#include <linux/cdev.h> 35#include <linux/cdev.h>
36#include <linux/kdev_t.h> 36#include <linux/kdev_t.h>
37#include <linux/mutex.h> 37#include <linux/mutex.h>
38#include <linux/sched.h>
38#include <linux/mm.h> 39#include <linux/mm.h>
39#include <linux/poll.h> 40#include <linux/poll.h>
40#include <linux/wait.h> 41#include <linux/wait.h>
@@ -182,8 +183,8 @@ static DECLARE_WAIT_QUEUE_HEAD(sep_event);
182static int sep_load_firmware(struct sep_device *sep) 183static int sep_load_firmware(struct sep_device *sep)
183{ 184{
184 const struct firmware *fw; 185 const struct firmware *fw;
185 char *cache_name = "cache.image.bin"; 186 char *cache_name = "sep/cache.image.bin";
186 char *res_name = "resident.image.bin"; 187 char *res_name = "sep/resident.image.bin";
187 int error; 188 int error;
188 189
189 edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); 190 edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
@@ -222,6 +223,9 @@ static int sep_load_firmware(struct sep_device *sep)
222 return 0; 223 return 0;
223} 224}
224 225
226MODULE_FIRMWARE("sep/cache.image.bin");
227MODULE_FIRMWARE("sep/resident.image.bin");
228
225/** 229/**
226 * sep_map_and_alloc_shared_area - allocate shared block 230 * sep_map_and_alloc_shared_area - allocate shared block
227 * @sep: security processor 231 * @sep: security processor
@@ -273,8 +277,8 @@ static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep,
273 void *virt_address) 277 void *virt_address)
274{ 278{
275 dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr); 279 dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
276 edbg("sep: virt to bus b %08llx v %p\n", 280 edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa,
277 (unsigned long long)pa, virt_address); 281 virt_address);
278 return pa; 282 return pa;
279} 283}
280 284
@@ -380,8 +384,7 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
380 shared area */ 384 shared area */
381 if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { 385 if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
382 edbg("SEP Driver mmap requested size is more than allowed\n"); 386 edbg("SEP Driver mmap requested size is more than allowed\n");
383 printk(KERN_WARNING "SEP Driver mmap requested size is more \ 387 printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n");
384 than allowed\n");
385 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end); 388 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
386 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start); 389 printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
387 return -EAGAIN; 390 return -EAGAIN;
@@ -941,8 +944,9 @@ static int sep_lock_user_pages(struct sep_device *sep,
941 dbg("data_size is %lu\n", data_size); 944 dbg("data_size is %lu\n", data_size);
942 while (1); 945 while (1);
943 } 946 }
944 edbg("lli_array[%lu].physical_address is %08lx, \ 947 edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n",
945 lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); 948 count, lli_array[count].physical_address,
949 count, lli_array[count].block_size);
946 } 950 }
947 951
948 /* set output params */ 952 /* set output params */
@@ -1771,7 +1775,7 @@ static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep,
1771static int sep_create_flow_dma_tables_handler(struct sep_device *sep, 1775static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
1772 unsigned long arg) 1776 unsigned long arg)
1773{ 1777{
1774 int error; 1778 int error = -ENOENT;
1775 struct sep_driver_build_flow_table_t command_args; 1779 struct sep_driver_build_flow_table_t command_args;
1776 /* first table - output */ 1780 /* first table - output */
1777 struct sep_lli_entry_t first_table_data; 1781 struct sep_lli_entry_t first_table_data;
@@ -2232,7 +2236,7 @@ static int sep_set_flow_id_handler(struct sep_device *sep,
2232 return error; 2236 return error;
2233} 2237}
2234 2238
2235static int sep_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 2239static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
2236{ 2240{
2237 int error = 0; 2241 int error = 0;
2238 struct sep_device *sep = filp->private_data; 2242 struct sep_device *sep = filp->private_data;
@@ -2586,7 +2590,7 @@ end_function:
2586 return error; 2590 return error;
2587} 2591}
2588 2592
2589static struct pci_device_id sep_pci_id_tbl[] = { 2593static const struct pci_device_id sep_pci_id_tbl[] = {
2590 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)}, 2594 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
2591 {0} 2595 {0}
2592}; 2596};
@@ -2607,7 +2611,7 @@ static dev_t sep_devno;
2607/* the files operations structure of the driver */ 2611/* the files operations structure of the driver */
2608static struct file_operations sep_file_operations = { 2612static struct file_operations sep_file_operations = {
2609 .owner = THIS_MODULE, 2613 .owner = THIS_MODULE,
2610 .ioctl = sep_ioctl, 2614 .unlocked_ioctl = sep_ioctl,
2611 .poll = sep_poll, 2615 .poll = sep_poll,
2612 .open = sep_open, 2616 .open = sep_open,
2613 .release = sep_release, 2617 .release = sep_release,
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
index 060e9de3b065..44f2d4eaf84b 100644
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c
@@ -126,7 +126,7 @@ static int debug;
126#define MODEM_CTRL 0x40 126#define MODEM_CTRL 0x40
127#define RS232_MODE 0x00 127#define RS232_MODE 0x00
128 128
129static struct usb_device_id serqt_id_table[] = { 129static const struct usb_device_id serqt_id_table[] = {
130 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)}, 130 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU100)},
131 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)}, 131 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU200)},
132 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)}, 132 {USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU100)},
@@ -1277,7 +1277,7 @@ static void qt_set_termios(struct tty_struct *tty,
1277 if (cflag & CSTOPB) 1277 if (cflag & CSTOPB)
1278 new_LCR |= SERIAL_TWO_STOPB; 1278 new_LCR |= SERIAL_TWO_STOPB;
1279 else 1279 else
1280 new_LCR |= SERIAL_TWO_STOPB; 1280 new_LCR |= SERIAL_ONE_STOPB;
1281 1281
1282 dbg("%s - 4\n", __func__); 1282 dbg("%s - 4\n", __func__);
1283 1283
diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h
index ccf7625b8bb3..eb3a619c6a94 100644
--- a/drivers/staging/slicoss/slic.h
+++ b/drivers/staging/slicoss/slic.h
@@ -527,15 +527,6 @@ struct adapter {
527 (largestat) += ((newstat) - (oldstat)); \ 527 (largestat) += ((newstat) - (oldstat)); \
528} 528}
529 529
530#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
531{ \
532 _Result = true; \
533 if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
534 _Result = false; \
535 if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
536 _Result = false; \
537}
538
539#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) 530#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
540#define SLIC_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & \ 531#define SLIC_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & \
541 0x00000000FFFFFFFF) 532 0x00000000FFFFFFFF)
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index f5cc01ba4145..7daeced317c4 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -101,7 +101,7 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev);
101static int slic_entry_open(struct net_device *dev); 101static int slic_entry_open(struct net_device *dev);
102static int slic_entry_halt(struct net_device *dev); 102static int slic_entry_halt(struct net_device *dev);
103static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 103static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
104static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev); 104static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
105static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb, 105static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb,
106 void *cmd, u32 skbtype, u32 status); 106 void *cmd, u32 skbtype, u32 status);
107static void slic_config_pci(struct pci_dev *pcidev); 107static void slic_config_pci(struct pci_dev *pcidev);
@@ -194,14 +194,10 @@ MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting");
194module_param(intagg_delay, int, 0); 194module_param(intagg_delay, int, 0);
195MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay"); 195MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
196 196
197static struct pci_device_id slic_pci_tbl[] __devinitdata = { 197static DEFINE_PCI_DEVICE_TABLE(slic_pci_tbl) = {
198 {PCI_VENDOR_ID_ALACRITECH, 198 { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_1GB_DEVICE_ID) },
199 SLIC_1GB_DEVICE_ID, 199 { PCI_DEVICE(PCI_VENDOR_ID_ALACRITECH, SLIC_2GB_DEVICE_ID) },
200 PCI_ANY_ID, PCI_ANY_ID,}, 200 { 0 }
201 {PCI_VENDOR_ID_ALACRITECH,
202 SLIC_2GB_DEVICE_ID,
203 PCI_ANY_ID, PCI_ANY_ID,},
204 {0,}
205}; 201};
206 202
207MODULE_DEVICE_TABLE(pci, slic_pci_tbl); 203MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
@@ -292,7 +288,7 @@ static void slic_init_adapter(struct net_device *netdev,
292{ 288{
293 ushort index; 289 ushort index;
294 struct slic_handle *pslic_handle; 290 struct slic_handle *pslic_handle;
295 struct adapter *adapter = (struct adapter *)netdev_priv(netdev); 291 struct adapter *adapter = netdev_priv(netdev);
296 292
297/* adapter->pcidev = pcidev;*/ 293/* adapter->pcidev = pcidev;*/
298 adapter->vendid = pci_tbl_entry->vendor; 294 adapter->vendid = pci_tbl_entry->vendor;
@@ -370,6 +366,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
370 ulong mmio_start = 0; 366 ulong mmio_start = 0;
371 ulong mmio_len = 0; 367 ulong mmio_len = 0;
372 struct sliccard *card = NULL; 368 struct sliccard *card = NULL;
369 int pci_using_dac = 0;
373 370
374 slic_global.dynamic_intagg = dynamic_intagg; 371 slic_global.dynamic_intagg = dynamic_intagg;
375 372
@@ -383,16 +380,26 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
383 printk(KERN_DEBUG "%s\n", slic_proc_version); 380 printk(KERN_DEBUG "%s\n", slic_proc_version);
384 } 381 }
385 382
386 err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64)); 383 if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
387 if (err) { 384 pci_using_dac = 1;
388 err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)); 385 if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
389 if (err) 386 dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for "
387 "consistent allocations\n");
390 goto err_out_disable_pci; 388 goto err_out_disable_pci;
389 }
390 } else if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) {
391 pci_using_dac = 0;
392 pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
393 } else {
394 dev_err(&pcidev->dev, "no usable DMA configuration\n");
395 goto err_out_disable_pci;
391 } 396 }
392 397
393 err = pci_request_regions(pcidev, DRV_NAME); 398 err = pci_request_regions(pcidev, DRV_NAME);
394 if (err) 399 if (err) {
400 dev_err(&pcidev->dev, "can't obtain PCI resources\n");
395 goto err_out_disable_pci; 401 goto err_out_disable_pci;
402 }
396 403
397 pci_set_master(pcidev); 404 pci_set_master(pcidev);
398 405
@@ -408,6 +415,8 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
408 adapter = netdev_priv(netdev); 415 adapter = netdev_priv(netdev);
409 adapter->netdev = netdev; 416 adapter->netdev = netdev;
410 adapter->pcidev = pcidev; 417 adapter->pcidev = pcidev;
418 if (pci_using_dac)
419 netdev->features |= NETIF_F_HIGHDMA;
411 420
412 mmio_start = pci_resource_start(pcidev, 0); 421 mmio_start = pci_resource_start(pcidev, 0);
413 mmio_len = pci_resource_len(pcidev, 0); 422 mmio_len = pci_resource_len(pcidev, 0);
@@ -484,7 +493,7 @@ err_out_disable_pci:
484 493
485static int slic_entry_open(struct net_device *dev) 494static int slic_entry_open(struct net_device *dev)
486{ 495{
487 struct adapter *adapter = (struct adapter *) netdev_priv(dev); 496 struct adapter *adapter = netdev_priv(dev);
488 struct sliccard *card = adapter->card; 497 struct sliccard *card = adapter->card;
489 u32 locked = 0; 498 u32 locked = 0;
490 int status; 499 int status;
@@ -534,7 +543,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
534 struct net_device *dev = pci_get_drvdata(pcidev); 543 struct net_device *dev = pci_get_drvdata(pcidev);
535 u32 mmio_start = 0; 544 u32 mmio_start = 0;
536 uint mmio_len = 0; 545 uint mmio_len = 0;
537 struct adapter *adapter = (struct adapter *) netdev_priv(dev); 546 struct adapter *adapter = netdev_priv(dev);
538 struct sliccard *card; 547 struct sliccard *card;
539 struct mcast_address *mcaddr, *mlist; 548 struct mcast_address *mcaddr, *mlist;
540 549
@@ -581,7 +590,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
581 590
582static int slic_entry_halt(struct net_device *dev) 591static int slic_entry_halt(struct net_device *dev)
583{ 592{
584 struct adapter *adapter = (struct adapter *)netdev_priv(dev); 593 struct adapter *adapter = netdev_priv(dev);
585 struct sliccard *card = adapter->card; 594 struct sliccard *card = adapter->card;
586 __iomem struct slic_regs *slic_regs = adapter->slic_regs; 595 __iomem struct slic_regs *slic_regs = adapter->slic_regs;
587 596
@@ -624,7 +633,7 @@ static int slic_entry_halt(struct net_device *dev)
624 633
625static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 634static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
626{ 635{
627 struct adapter *adapter = (struct adapter *)netdev_priv(dev); 636 struct adapter *adapter = netdev_priv(dev);
628 struct ethtool_cmd edata; 637 struct ethtool_cmd edata;
629 struct ethtool_cmd ecmd; 638 struct ethtool_cmd ecmd;
630 u32 data[7]; 639 u32 data[7];
@@ -649,8 +658,7 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
649 658
650 if (copy_from_user(data, rq->ifr_data, 28)) { 659 if (copy_from_user(data, rq->ifr_data, 28)) {
651 PRINT_ERROR 660 PRINT_ERROR
652 ("slic: copy_from_user FAILED getting \ 661 ("slic: copy_from_user FAILED getting initial simba param\n");
653 initial simba param\n");
654 return -EFAULT; 662 return -EFAULT;
655 } 663 }
656 664
@@ -665,8 +673,7 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
665 (tracemon_request == 673 (tracemon_request ==
666 SLIC_DUMP_IN_PROGRESS)) { 674 SLIC_DUMP_IN_PROGRESS)) {
667 PRINT_ERROR 675 PRINT_ERROR
668 ("ATK Diagnostic Trace Dump Requested but \ 676 ("ATK Diagnostic Trace Dump Requested but already in progress... ignore\n");
669 already in progress... ignore\n");
670 } else { 677 } else {
671 PRINT_ERROR 678 PRINT_ERROR
672 ("ATK Diagnostic Trace Dump Requested\n"); 679 ("ATK Diagnostic Trace Dump Requested\n");
@@ -784,10 +791,10 @@ static void slic_xmit_build_request(struct adapter *adapter,
784 791
785#define NORMAL_ETHFRAME 0 792#define NORMAL_ETHFRAME 0
786 793
787static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev) 794static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
788{ 795{
789 struct sliccard *card; 796 struct sliccard *card;
790 struct adapter *adapter = (struct adapter *)netdev_priv(dev); 797 struct adapter *adapter = netdev_priv(dev);
791 struct slic_hostcmd *hcmd = NULL; 798 struct slic_hostcmd *hcmd = NULL;
792 u32 status = 0; 799 u32 status = 0;
793 u32 skbtype = NORMAL_ETHFRAME; 800 u32 skbtype = NORMAL_ETHFRAME;
@@ -1071,7 +1078,7 @@ static void slic_xmit_complete(struct adapter *adapter)
1071static irqreturn_t slic_interrupt(int irq, void *dev_id) 1078static irqreturn_t slic_interrupt(int irq, void *dev_id)
1072{ 1079{
1073 struct net_device *dev = (struct net_device *)dev_id; 1080 struct net_device *dev = (struct net_device *)dev_id;
1074 struct adapter *adapter = (struct adapter *)netdev_priv(dev); 1081 struct adapter *adapter = netdev_priv(dev);
1075 u32 isr; 1082 u32 isr;
1076 1083
1077 if ((adapter->pshmem) && (adapter->pshmem->isr)) { 1084 if ((adapter->pshmem) && (adapter->pshmem->isr)) {
@@ -1229,22 +1236,21 @@ static void slic_init_cleanup(struct adapter *adapter)
1229 1236
1230static struct net_device_stats *slic_get_stats(struct net_device *dev) 1237static struct net_device_stats *slic_get_stats(struct net_device *dev)
1231{ 1238{
1232 struct adapter *adapter = (struct adapter *)netdev_priv(dev); 1239 struct adapter *adapter = netdev_priv(dev);
1233 struct net_device_stats *stats;
1234 1240
1235 ASSERT(adapter); 1241 ASSERT(adapter);
1236 stats = &adapter->stats; 1242 dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions;
1237 stats->collisions = adapter->slic_stats.iface.xmit_collisions; 1243 dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors;
1238 stats->rx_errors = adapter->slic_stats.iface.rcv_errors; 1244 dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors;
1239 stats->tx_errors = adapter->slic_stats.iface.xmt_errors; 1245 dev->stats.rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
1240 stats->rx_missed_errors = adapter->slic_stats.iface.rcv_discards; 1246 dev->stats.tx_heartbeat_errors = 0;
1241 stats->tx_heartbeat_errors = 0; 1247 dev->stats.tx_aborted_errors = 0;
1242 stats->tx_aborted_errors = 0; 1248 dev->stats.tx_window_errors = 0;
1243 stats->tx_window_errors = 0; 1249 dev->stats.tx_fifo_errors = 0;
1244 stats->tx_fifo_errors = 0; 1250 dev->stats.rx_frame_errors = 0;
1245 stats->rx_frame_errors = 0; 1251 dev->stats.rx_length_errors = 0;
1246 stats->rx_length_errors = 0; 1252
1247 return &adapter->stats; 1253 return &dev->stats;
1248} 1254}
1249 1255
1250/* 1256/*
@@ -1254,13 +1260,11 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev)
1254static int slic_mcast_add_list(struct adapter *adapter, char *address) 1260static int slic_mcast_add_list(struct adapter *adapter, char *address)
1255{ 1261{
1256 struct mcast_address *mcaddr, *mlist; 1262 struct mcast_address *mcaddr, *mlist;
1257 bool equaladdr;
1258 1263
1259 /* Check to see if it already exists */ 1264 /* Check to see if it already exists */
1260 mlist = adapter->mcastaddrs; 1265 mlist = adapter->mcastaddrs;
1261 while (mlist) { 1266 while (mlist) {
1262 ETHER_EQ_ADDR(mlist->address, address, equaladdr); 1267 if (!compare_ether_addr(mlist->address, address))
1263 if (equaladdr)
1264 return STATUS_SUCCESS; 1268 return STATUS_SUCCESS;
1265 mlist = mlist->next; 1269 mlist = mlist->next;
1266 } 1270 }
@@ -1360,7 +1364,7 @@ static void slic_mcast_set_bit(struct adapter *adapter, char *address)
1360 1364
1361static void slic_mcast_set_list(struct net_device *dev) 1365static void slic_mcast_set_list(struct net_device *dev)
1362{ 1366{
1363 struct adapter *adapter = (struct adapter *)netdev_priv(dev); 1367 struct adapter *adapter = netdev_priv(dev);
1364 int status = STATUS_SUCCESS; 1368 int status = STATUS_SUCCESS;
1365 char *addresses; 1369 char *addresses;
1366 struct dev_mc_list *mc_list; 1370 struct dev_mc_list *mc_list;
@@ -1852,6 +1856,9 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
1852 return 0; 1856 return 0;
1853} 1857}
1854 1858
1859MODULE_FIRMWARE("slicoss/oasisrcvucode.sys");
1860MODULE_FIRMWARE("slicoss/gbrcvucode.sys");
1861
1855static int slic_card_download(struct adapter *adapter) 1862static int slic_card_download(struct adapter *adapter)
1856{ 1863{
1857 const struct firmware *fw; 1864 const struct firmware *fw;
@@ -1963,6 +1970,9 @@ static int slic_card_download(struct adapter *adapter)
1963 return STATUS_SUCCESS; 1970 return STATUS_SUCCESS;
1964} 1971}
1965 1972
1973MODULE_FIRMWARE("slicoss/oasisdownload.sys");
1974MODULE_FIRMWARE("slicoss/gbdownload.sys");
1975
1966static void slic_adapter_set_hwaddr(struct adapter *adapter) 1976static void slic_adapter_set_hwaddr(struct adapter *adapter)
1967{ 1977{
1968 struct sliccard *card = adapter->card; 1978 struct sliccard *card = adapter->card;
@@ -2466,7 +2476,6 @@ static bool slic_mac_filter(struct adapter *adapter,
2466 u32 opts = adapter->macopts; 2476 u32 opts = adapter->macopts;
2467 u32 *dhost4 = (u32 *)&ether_frame->ether_dhost[0]; 2477 u32 *dhost4 = (u32 *)&ether_frame->ether_dhost[0];
2468 u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4]; 2478 u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
2469 bool equaladdr;
2470 2479
2471 if (opts & MAC_PROMISC) 2480 if (opts & MAC_PROMISC)
2472 return true; 2481 return true;
@@ -2490,10 +2499,8 @@ static bool slic_mac_filter(struct adapter *adapter,
2490 struct mcast_address *mcaddr = adapter->mcastaddrs; 2499 struct mcast_address *mcaddr = adapter->mcastaddrs;
2491 2500
2492 while (mcaddr) { 2501 while (mcaddr) {
2493 ETHER_EQ_ADDR(mcaddr->address, 2502 if (!compare_ether_addr(mcaddr->address,
2494 ether_frame->ether_dhost, 2503 ether_frame->ether_dhost)) {
2495 equaladdr);
2496 if (equaladdr) {
2497 adapter->rcv_multicasts++; 2504 adapter->rcv_multicasts++;
2498 adapter->stats.multicast++; 2505 adapter->stats.multicast++;
2499 return true; 2506 return true;
@@ -2515,7 +2522,7 @@ static bool slic_mac_filter(struct adapter *adapter,
2515 2522
2516static int slic_mac_set_address(struct net_device *dev, void *ptr) 2523static int slic_mac_set_address(struct net_device *dev, void *ptr)
2517{ 2524{
2518 struct adapter *adapter = (struct adapter *)netdev_priv(dev); 2525 struct adapter *adapter = netdev_priv(dev);
2519 struct sockaddr *addr = ptr; 2526 struct sockaddr *addr = ptr;
2520 2527
2521 if (netif_running(dev)) 2528 if (netif_running(dev))
@@ -2523,6 +2530,9 @@ static int slic_mac_set_address(struct net_device *dev, void *ptr)
2523 if (!adapter) 2530 if (!adapter)
2524 return -EBUSY; 2531 return -EBUSY;
2525 2532
2533 if (!is_valid_ether_addr(addr->sa_data))
2534 return -EINVAL;
2535
2526 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 2536 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
2527 memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len); 2537 memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
2528 2538
@@ -3960,10 +3970,8 @@ static void slic_debug_adapter_create(struct adapter *adapter)
3960 3970
3961static void slic_debug_adapter_destroy(struct adapter *adapter) 3971static void slic_debug_adapter_destroy(struct adapter *adapter)
3962{ 3972{
3963 if (adapter->debugfs_entry) { 3973 debugfs_remove(adapter->debugfs_entry);
3964 debugfs_remove(adapter->debugfs_entry); 3974 adapter->debugfs_entry = NULL;
3965 adapter->debugfs_entry = NULL;
3966 }
3967} 3975}
3968 3976
3969static void slic_debug_card_create(struct sliccard *card) 3977static void slic_debug_card_create(struct sliccard *card)
diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig
index 204dbfc3c38b..315102c7fed1 100644
--- a/drivers/staging/sm7xx/Kconfig
+++ b/drivers/staging/sm7xx/Kconfig
@@ -6,10 +6,3 @@ config FB_SM7XX
6 select FB_CFB_IMAGEBLIT 6 select FB_CFB_IMAGEBLIT
7 help 7 help
8 Frame Buffer driver for the Silicon Motion SM7XX serial graphic card. 8 Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
9
10config FB_SM7XX_ACCEL
11 bool "Siliconmotion Acceleration functions (EXPERIMENTAL)"
12 depends on FB_SM7XX && EXPERIMENTAL
13 help
14 This will compile the Trident frame buffer device with
15 acceleration functions.
diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO
index 1f61f5e11cf5..a66d9e406497 100644
--- a/drivers/staging/sm7xx/TODO
+++ b/drivers/staging/sm7xx/TODO
@@ -1,5 +1,6 @@
1TODO: 1TODO:
2- Dual head support 2- Dual head support
3- 2D acceleration support
3- use kernel coding style 4- use kernel coding style
4- checkpatch.pl clean 5- checkpatch.pl clean
5- refine the code and remove unused code 6- refine the code and remove unused code
diff --git a/drivers/staging/sm7xx/smtc2d.c b/drivers/staging/sm7xx/smtc2d.c
deleted file mode 100644
index 2fff0a0052d1..000000000000
--- a/drivers/staging/sm7xx/smtc2d.c
+++ /dev/null
@@ -1,979 +0,0 @@
1/*
2 * Silicon Motion SM7XX 2D drawing engine functions.
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Author: Boyod boyod.yang@siliconmotion.com.cn
6 *
7 * Copyright (C) 2009 Lemote, Inc.
8 * Author: Wu Zhangjin, wuzhangjin@gmail.com
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for
12 * more details.
13 *
14 * Version 0.10.26192.21.01
15 * - Add PowerPC support
16 * - Add 2D support for Lynx -
17 * Verified on 2.6.19.2
18 * Boyod.yang <boyod.yang@siliconmotion.com.cn>
19 */
20
21unsigned char smtc_de_busy;
22
23void SMTC_write2Dreg(unsigned long nOffset, unsigned long nData)
24{
25 writel(nData, smtc_2DBaseAddress + nOffset);
26}
27
28unsigned long SMTC_read2Dreg(unsigned long nOffset)
29{
30 return readl(smtc_2DBaseAddress + nOffset);
31}
32
33void SMTC_write2Ddataport(unsigned long nOffset, unsigned long nData)
34{
35 writel(nData, smtc_2Ddataport + nOffset);
36}
37
38/**********************************************************************
39 *
40 * deInit
41 *
42 * Purpose
43 * Drawing engine initialization.
44 *
45 **********************************************************************/
46
47void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
48 unsigned int bpp)
49{
50 /* Get current power configuration. */
51 unsigned char clock;
52 clock = smtc_seqr(0x21);
53
54 /* initialize global 'mutex lock' variable */
55 smtc_de_busy = 0;
56
57 /* Enable 2D Drawing Engine */
58 smtc_seqw(0x21, clock & 0xF8);
59
60 SMTC_write2Dreg(DE_CLIP_TL,
61 FIELD_VALUE(0, DE_CLIP_TL, TOP, 0) |
62 FIELD_SET(0, DE_CLIP_TL, STATUS, DISABLE) |
63 FIELD_SET(0, DE_CLIP_TL, INHIBIT, OUTSIDE) |
64 FIELD_VALUE(0, DE_CLIP_TL, LEFT, 0));
65
66 if (bpp >= 24) {
67 SMTC_write2Dreg(DE_PITCH,
68 FIELD_VALUE(0, DE_PITCH, DESTINATION,
69 nModeWidth * 3) | FIELD_VALUE(0,
70 DE_PITCH,
71 SOURCE,
72 nModeWidth
73 * 3));
74 } else {
75 SMTC_write2Dreg(DE_PITCH,
76 FIELD_VALUE(0, DE_PITCH, DESTINATION,
77 nModeWidth) | FIELD_VALUE(0,
78 DE_PITCH,
79 SOURCE,
80 nModeWidth));
81 }
82
83 SMTC_write2Dreg(DE_WINDOW_WIDTH,
84 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
85 nModeWidth) | FIELD_VALUE(0,
86 DE_WINDOW_WIDTH,
87 SOURCE,
88 nModeWidth));
89
90 switch (bpp) {
91 case 8:
92 SMTC_write2Dreg(DE_STRETCH_FORMAT,
93 FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
94 NORMAL) | FIELD_VALUE(0,
95 DE_STRETCH_FORMAT,
96 PATTERN_Y,
97 0) |
98 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
99 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
100 PIXEL_FORMAT,
101 8) | FIELD_SET(0,
102 DE_STRETCH_FORMAT,
103 ADDRESSING,
104 XY) |
105 FIELD_VALUE(0, DE_STRETCH_FORMAT,
106 SOURCE_HEIGHT, 3));
107 break;
108 case 24:
109 SMTC_write2Dreg(DE_STRETCH_FORMAT,
110 FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
111 NORMAL) | FIELD_VALUE(0,
112 DE_STRETCH_FORMAT,
113 PATTERN_Y,
114 0) |
115 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
116 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
117 PIXEL_FORMAT,
118 24) | FIELD_SET(0,
119 DE_STRETCH_FORMAT,
120 ADDRESSING,
121 XY) |
122 FIELD_VALUE(0, DE_STRETCH_FORMAT,
123 SOURCE_HEIGHT, 3));
124 break;
125 case 16:
126 default:
127 SMTC_write2Dreg(DE_STRETCH_FORMAT,
128 FIELD_SET(0, DE_STRETCH_FORMAT, PATTERN_XY,
129 NORMAL) | FIELD_VALUE(0,
130 DE_STRETCH_FORMAT,
131 PATTERN_Y,
132 0) |
133 FIELD_VALUE(0, DE_STRETCH_FORMAT, PATTERN_X,
134 0) | FIELD_SET(0, DE_STRETCH_FORMAT,
135 PIXEL_FORMAT,
136 16) | FIELD_SET(0,
137 DE_STRETCH_FORMAT,
138 ADDRESSING,
139 XY) |
140 FIELD_VALUE(0, DE_STRETCH_FORMAT,
141 SOURCE_HEIGHT, 3));
142 break;
143 }
144
145 SMTC_write2Dreg(DE_MASKS,
146 FIELD_VALUE(0, DE_MASKS, BYTE_MASK, 0xFFFF) |
147 FIELD_VALUE(0, DE_MASKS, BIT_MASK, 0xFFFF));
148 SMTC_write2Dreg(DE_COLOR_COMPARE_MASK,
149 FIELD_VALUE(0, DE_COLOR_COMPARE_MASK, MASKS, \
150 0xFFFFFF));
151 SMTC_write2Dreg(DE_COLOR_COMPARE,
152 FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR, 0xFFFFFF));
153}
154
155void deVerticalLine(unsigned long dst_base,
156 unsigned long dst_pitch,
157 unsigned long nX,
158 unsigned long nY,
159 unsigned long dst_height, unsigned long nColor)
160{
161 deWaitForNotBusy();
162
163 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
164 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
165 dst_base));
166
167 SMTC_write2Dreg(DE_PITCH,
168 FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
169 FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
170
171 SMTC_write2Dreg(DE_WINDOW_WIDTH,
172 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
173 dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
174 SOURCE,
175 dst_pitch));
176
177 SMTC_write2Dreg(DE_FOREGROUND,
178 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
179
180 SMTC_write2Dreg(DE_DESTINATION,
181 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
182 FIELD_VALUE(0, DE_DESTINATION, X, nX) |
183 FIELD_VALUE(0, DE_DESTINATION, Y, nY));
184
185 SMTC_write2Dreg(DE_DIMENSION,
186 FIELD_VALUE(0, DE_DIMENSION, X, 1) |
187 FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
188
189 SMTC_write2Dreg(DE_CONTROL,
190 FIELD_SET(0, DE_CONTROL, STATUS, START) |
191 FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
192 FIELD_SET(0, DE_CONTROL, MAJOR, Y) |
193 FIELD_SET(0, DE_CONTROL, STEP_X, NEGATIVE) |
194 FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
195 FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
196 FIELD_SET(0, DE_CONTROL, COMMAND, SHORT_STROKE) |
197 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
198 FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
199
200 smtc_de_busy = 1;
201}
202
203void deHorizontalLine(unsigned long dst_base,
204 unsigned long dst_pitch,
205 unsigned long nX,
206 unsigned long nY,
207 unsigned long dst_width, unsigned long nColor)
208{
209 deWaitForNotBusy();
210
211 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
212 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
213 dst_base));
214
215 SMTC_write2Dreg(DE_PITCH,
216 FIELD_VALUE(0, DE_PITCH, DESTINATION, dst_pitch) |
217 FIELD_VALUE(0, DE_PITCH, SOURCE, dst_pitch));
218
219 SMTC_write2Dreg(DE_WINDOW_WIDTH,
220 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
221 dst_pitch) | FIELD_VALUE(0, DE_WINDOW_WIDTH,
222 SOURCE,
223 dst_pitch));
224 SMTC_write2Dreg(DE_FOREGROUND,
225 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
226 SMTC_write2Dreg(DE_DESTINATION,
227 FIELD_SET(0, DE_DESTINATION, WRAP,
228 DISABLE) | FIELD_VALUE(0, DE_DESTINATION, X,
229 nX) | FIELD_VALUE(0,
230 DE_DESTINATION,
231 Y,
232 nY));
233 SMTC_write2Dreg(DE_DIMENSION,
234 FIELD_VALUE(0, DE_DIMENSION, X,
235 dst_width) | FIELD_VALUE(0, DE_DIMENSION,
236 Y_ET, 1));
237 SMTC_write2Dreg(DE_CONTROL,
238 FIELD_SET(0, DE_CONTROL, STATUS, START) | FIELD_SET(0,
239 DE_CONTROL,
240 DIRECTION,
241 RIGHT_TO_LEFT)
242 | FIELD_SET(0, DE_CONTROL, MAJOR, X) | FIELD_SET(0,
243 DE_CONTROL,
244 STEP_X,
245 POSITIVE)
246 | FIELD_SET(0, DE_CONTROL, STEP_Y,
247 NEGATIVE) | FIELD_SET(0, DE_CONTROL,
248 LAST_PIXEL,
249 OFF) | FIELD_SET(0,
250 DE_CONTROL,
251 COMMAND,
252 SHORT_STROKE)
253 | FIELD_SET(0, DE_CONTROL, ROP_SELECT,
254 ROP2) | FIELD_VALUE(0, DE_CONTROL, ROP,
255 0x0C));
256
257 smtc_de_busy = 1;
258}
259
260void deLine(unsigned long dst_base,
261 unsigned long dst_pitch,
262 unsigned long nX1,
263 unsigned long nY1,
264 unsigned long nX2, unsigned long nY2, unsigned long nColor)
265{
266 unsigned long nCommand =
267 FIELD_SET(0, DE_CONTROL, STATUS, START) |
268 FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
269 FIELD_SET(0, DE_CONTROL, MAJOR, X) |
270 FIELD_SET(0, DE_CONTROL, STEP_X, POSITIVE) |
271 FIELD_SET(0, DE_CONTROL, STEP_Y, POSITIVE) |
272 FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
273 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
274 FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C);
275 unsigned long DeltaX;
276 unsigned long DeltaY;
277
278 /* Calculate delta X */
279 if (nX1 <= nX2)
280 DeltaX = nX2 - nX1;
281 else {
282 DeltaX = nX1 - nX2;
283 nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_X, NEGATIVE);
284 }
285
286 /* Calculate delta Y */
287 if (nY1 <= nY2)
288 DeltaY = nY2 - nY1;
289 else {
290 DeltaY = nY1 - nY2;
291 nCommand = FIELD_SET(nCommand, DE_CONTROL, STEP_Y, NEGATIVE);
292 }
293
294 /* Determine the major axis */
295 if (DeltaX < DeltaY)
296 nCommand = FIELD_SET(nCommand, DE_CONTROL, MAJOR, Y);
297
298 /* Vertical line? */
299 if (nX1 == nX2)
300 deVerticalLine(dst_base, dst_pitch, nX1, nY1, DeltaY, nColor);
301
302 /* Horizontal line? */
303 else if (nY1 == nY2)
304 deHorizontalLine(dst_base, dst_pitch, nX1, nY1, \
305 DeltaX, nColor);
306
307 /* Diagonal line? */
308 else if (DeltaX == DeltaY) {
309 deWaitForNotBusy();
310
311 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
312 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
313 ADDRESS, dst_base));
314
315 SMTC_write2Dreg(DE_PITCH,
316 FIELD_VALUE(0, DE_PITCH, DESTINATION,
317 dst_pitch) | FIELD_VALUE(0,
318 DE_PITCH,
319 SOURCE,
320 dst_pitch));
321
322 SMTC_write2Dreg(DE_WINDOW_WIDTH,
323 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
324 dst_pitch) | FIELD_VALUE(0,
325 DE_WINDOW_WIDTH,
326 SOURCE,
327 dst_pitch));
328
329 SMTC_write2Dreg(DE_FOREGROUND,
330 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
331
332 SMTC_write2Dreg(DE_DESTINATION,
333 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
334 FIELD_VALUE(0, DE_DESTINATION, X, 1) |
335 FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
336
337 SMTC_write2Dreg(DE_DIMENSION,
338 FIELD_VALUE(0, DE_DIMENSION, X, 1) |
339 FIELD_VALUE(0, DE_DIMENSION, Y_ET, DeltaX));
340
341 SMTC_write2Dreg(DE_CONTROL,
342 FIELD_SET(nCommand, DE_CONTROL, COMMAND,
343 SHORT_STROKE));
344 }
345
346 /* Generic line */
347 else {
348 unsigned int k1, k2, et, w;
349 if (DeltaX < DeltaY) {
350 k1 = 2 * DeltaX;
351 et = k1 - DeltaY;
352 k2 = et - DeltaY;
353 w = DeltaY + 1;
354 } else {
355 k1 = 2 * DeltaY;
356 et = k1 - DeltaX;
357 k2 = et - DeltaX;
358 w = DeltaX + 1;
359 }
360
361 deWaitForNotBusy();
362
363 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
364 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE,
365 ADDRESS, dst_base));
366
367 SMTC_write2Dreg(DE_PITCH,
368 FIELD_VALUE(0, DE_PITCH, DESTINATION,
369 dst_pitch) | FIELD_VALUE(0,
370 DE_PITCH,
371 SOURCE,
372 dst_pitch));
373
374 SMTC_write2Dreg(DE_WINDOW_WIDTH,
375 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
376 dst_pitch) | FIELD_VALUE(0,
377 DE_WINDOW_WIDTH,
378 SOURCE,
379 dst_pitch));
380
381 SMTC_write2Dreg(DE_FOREGROUND,
382 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
383
384 SMTC_write2Dreg(DE_SOURCE,
385 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
386 FIELD_VALUE(0, DE_SOURCE, X_K1, k1) |
387 FIELD_VALUE(0, DE_SOURCE, Y_K2, k2));
388
389 SMTC_write2Dreg(DE_DESTINATION,
390 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
391 FIELD_VALUE(0, DE_DESTINATION, X, nX1) |
392 FIELD_VALUE(0, DE_DESTINATION, Y, nY1));
393
394 SMTC_write2Dreg(DE_DIMENSION,
395 FIELD_VALUE(0, DE_DIMENSION, X, w) |
396 FIELD_VALUE(0, DE_DIMENSION, Y_ET, et));
397
398 SMTC_write2Dreg(DE_CONTROL,
399 FIELD_SET(nCommand, DE_CONTROL, COMMAND,
400 LINE_DRAW));
401 }
402
403 smtc_de_busy = 1;
404}
405
406void deFillRect(unsigned long dst_base,
407 unsigned long dst_pitch,
408 unsigned long dst_X,
409 unsigned long dst_Y,
410 unsigned long dst_width,
411 unsigned long dst_height, unsigned long nColor)
412{
413 deWaitForNotBusy();
414
415 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
416 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
417 dst_base));
418
419 if (dst_pitch) {
420 SMTC_write2Dreg(DE_PITCH,
421 FIELD_VALUE(0, DE_PITCH, DESTINATION,
422 dst_pitch) | FIELD_VALUE(0,
423 DE_PITCH,
424 SOURCE,
425 dst_pitch));
426
427 SMTC_write2Dreg(DE_WINDOW_WIDTH,
428 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
429 dst_pitch) | FIELD_VALUE(0,
430 DE_WINDOW_WIDTH,
431 SOURCE,
432 dst_pitch));
433 }
434
435 SMTC_write2Dreg(DE_FOREGROUND,
436 FIELD_VALUE(0, DE_FOREGROUND, COLOR, nColor));
437
438 SMTC_write2Dreg(DE_DESTINATION,
439 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
440 FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
441 FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
442
443 SMTC_write2Dreg(DE_DIMENSION,
444 FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
445 FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
446
447 SMTC_write2Dreg(DE_CONTROL,
448 FIELD_SET(0, DE_CONTROL, STATUS, START) |
449 FIELD_SET(0, DE_CONTROL, DIRECTION, LEFT_TO_RIGHT) |
450 FIELD_SET(0, DE_CONTROL, LAST_PIXEL, OFF) |
451 FIELD_SET(0, DE_CONTROL, COMMAND, RECTANGLE_FILL) |
452 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
453 FIELD_VALUE(0, DE_CONTROL, ROP, 0x0C));
454
455 smtc_de_busy = 1;
456}
457
458/**********************************************************************
459 *
460 * deRotatePattern
461 *
462 * Purpose
463 * Rotate the given pattern if necessary
464 *
465 * Parameters
466 * [in]
467 * pPattern - Pointer to DE_SURFACE structure containing
468 * pattern attributes
469 * patternX - X position (0-7) of pattern origin
470 * patternY - Y position (0-7) of pattern origin
471 *
472 * [out]
473 * pattern_dstaddr - Pointer to pre-allocated buffer containing
474 * rotated pattern
475 *
476 **********************************************************************/
477void deRotatePattern(unsigned char *pattern_dstaddr,
478 unsigned long pattern_src_addr,
479 unsigned long pattern_BPP,
480 unsigned long pattern_stride, int patternX, int patternY)
481{
482 unsigned int i;
483 unsigned long pattern[PATTERN_WIDTH * PATTERN_HEIGHT];
484 unsigned int x, y;
485 unsigned char *pjPatByte;
486
487 if (pattern_dstaddr != NULL) {
488 deWaitForNotBusy();
489
490 if (patternX || patternY) {
491 /* Rotate pattern */
492 pjPatByte = (unsigned char *)pattern;
493
494 switch (pattern_BPP) {
495 case 8:
496 {
497 for (y = 0; y < 8; y++) {
498 unsigned char *pjBuffer =
499 pattern_dstaddr +
500 ((patternY + y) & 7) * 8;
501 for (x = 0; x < 8; x++) {
502 pjBuffer[(patternX +
503 x) & 7] =
504 pjPatByte[x];
505 }
506 pjPatByte += pattern_stride;
507 }
508 break;
509 }
510
511 case 16:
512 {
513 for (y = 0; y < 8; y++) {
514 unsigned short *pjBuffer =
515 (unsigned short *)
516 pattern_dstaddr +
517 ((patternY + y) & 7) * 8;
518 for (x = 0; x < 8; x++) {
519 pjBuffer[(patternX +
520 x) & 7] =
521 ((unsigned short *)
522 pjPatByte)[x];
523 }
524 pjPatByte += pattern_stride;
525 }
526 break;
527 }
528
529 case 32:
530 {
531 for (y = 0; y < 8; y++) {
532 unsigned long *pjBuffer =
533 (unsigned long *)
534 pattern_dstaddr +
535 ((patternY + y) & 7) * 8;
536 for (x = 0; x < 8; x++) {
537 pjBuffer[(patternX +
538 x) & 7] =
539 ((unsigned long *)
540 pjPatByte)[x];
541 }
542 pjPatByte += pattern_stride;
543 }
544 break;
545 }
546 }
547 } else {
548 /*Don't rotate,just copy pattern into pattern_dstaddr*/
549 for (i = 0; i < (pattern_BPP * 2); i++) {
550 ((unsigned long *)pattern_dstaddr)[i] =
551 pattern[i];
552 }
553 }
554
555 }
556}
557
558/**********************************************************************
559 *
560 * deCopy
561 *
562 * Purpose
563 * Copy a rectangular area of the source surface to a destination surface
564 *
565 * Remarks
566 * Source bitmap must have the same color depth (BPP) as the destination
567 * bitmap.
568 *
569**********************************************************************/
570void deCopy(unsigned long dst_base,
571 unsigned long dst_pitch,
572 unsigned long dst_BPP,
573 unsigned long dst_X,
574 unsigned long dst_Y,
575 unsigned long dst_width,
576 unsigned long dst_height,
577 unsigned long src_base,
578 unsigned long src_pitch,
579 unsigned long src_X,
580 unsigned long src_Y, pTransparent pTransp, unsigned char nROP2)
581{
582 unsigned long nDirection = 0;
583 unsigned long nTransparent = 0;
584 /* Direction of ROP2 operation:
585 * 1 = Left to Right,
586 * (-1) = Right to Left
587 */
588 unsigned long opSign = 1;
589 /* xWidth is in pixels */
590 unsigned long xWidth = 192 / (dst_BPP / 8);
591 unsigned long de_ctrl = 0;
592
593 deWaitForNotBusy();
594
595 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE,
596 FIELD_VALUE(0, DE_WINDOW_DESTINATION_BASE, ADDRESS,
597 dst_base));
598
599 SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE,
600 FIELD_VALUE(0, DE_WINDOW_SOURCE_BASE, ADDRESS,
601 src_base));
602
603 if (dst_pitch && src_pitch) {
604 SMTC_write2Dreg(DE_PITCH,
605 FIELD_VALUE(0, DE_PITCH, DESTINATION,
606 dst_pitch) | FIELD_VALUE(0,
607 DE_PITCH,
608 SOURCE,
609 src_pitch));
610
611 SMTC_write2Dreg(DE_WINDOW_WIDTH,
612 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
613 dst_pitch) | FIELD_VALUE(0,
614 DE_WINDOW_WIDTH,
615 SOURCE,
616 src_pitch));
617 }
618
619 /* Set transparent bits if necessary */
620 if (pTransp != NULL) {
621 nTransparent =
622 pTransp->match | pTransp->select | pTransp->control;
623
624 /* Set color compare register */
625 SMTC_write2Dreg(DE_COLOR_COMPARE,
626 FIELD_VALUE(0, DE_COLOR_COMPARE, COLOR,
627 pTransp->color));
628 }
629
630 /* Determine direction of operation */
631 if (src_Y < dst_Y) {
632 /* +----------+
633 |S |
634 | +----------+
635 | | | |
636 | | | |
637 +---|------+ |
638 | D |
639 +----------+ */
640
641 nDirection = BOTTOM_TO_TOP;
642 } else if (src_Y > dst_Y) {
643 /* +----------+
644 |D |
645 | +----------+
646 | | | |
647 | | | |
648 +---|------+ |
649 | S |
650 +----------+ */
651
652 nDirection = TOP_TO_BOTTOM;
653 } else {
654 /* src_Y == dst_Y */
655
656 if (src_X <= dst_X) {
657 /* +------+---+------+
658 |S | | D|
659 | | | |
660 | | | |
661 | | | |
662 +------+---+------+ */
663
664 nDirection = RIGHT_TO_LEFT;
665 } else {
666 /* src_X > dst_X */
667
668 /* +------+---+------+
669 |D | | S|
670 | | | |
671 | | | |
672 | | | |
673 +------+---+------+ */
674
675 nDirection = LEFT_TO_RIGHT;
676 }
677 }
678
679 if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) {
680 src_X += dst_width - 1;
681 src_Y += dst_height - 1;
682 dst_X += dst_width - 1;
683 dst_Y += dst_height - 1;
684 opSign = (-1);
685 }
686
687 if (dst_BPP >= 24) {
688 src_X *= 3;
689 src_Y *= 3;
690 dst_X *= 3;
691 dst_Y *= 3;
692 dst_width *= 3;
693 if ((nDirection == BOTTOM_TO_TOP)
694 || (nDirection == RIGHT_TO_LEFT)) {
695 src_X += 2;
696 dst_X += 2;
697 }
698 }
699
700 /* Workaround for 192 byte hw bug */
701 if ((nROP2 != 0x0C) && ((dst_width * (dst_BPP / 8)) >= 192)) {
702 /*
703 * Perform the ROP2 operation in chunks of (xWidth *
704 * dst_height)
705 */
706 while (1) {
707 deWaitForNotBusy();
708
709 SMTC_write2Dreg(DE_SOURCE,
710 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
711 FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
712 FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
713
714 SMTC_write2Dreg(DE_DESTINATION,
715 FIELD_SET(0, DE_DESTINATION, WRAP,
716 DISABLE) | FIELD_VALUE(0,
717 DE_DESTINATION,
718 X,
719 dst_X)
720 | FIELD_VALUE(0, DE_DESTINATION, Y,
721 dst_Y));
722
723 SMTC_write2Dreg(DE_DIMENSION,
724 FIELD_VALUE(0, DE_DIMENSION, X,
725 xWidth) | FIELD_VALUE(0,
726 DE_DIMENSION,
727 Y_ET,
728 dst_height));
729
730 de_ctrl =
731 FIELD_VALUE(0, DE_CONTROL, ROP,
732 nROP2) | nTransparent | FIELD_SET(0,
733 DE_CONTROL,
734 ROP_SELECT,
735 ROP2)
736 | FIELD_SET(0, DE_CONTROL, COMMAND,
737 BITBLT) | ((nDirection ==
738 1) ? FIELD_SET(0,
739 DE_CONTROL,
740 DIRECTION,
741 RIGHT_TO_LEFT)
742 : FIELD_SET(0, DE_CONTROL,
743 DIRECTION,
744 LEFT_TO_RIGHT)) |
745 FIELD_SET(0, DE_CONTROL, STATUS, START);
746
747 SMTC_write2Dreg(DE_CONTROL, de_ctrl);
748
749 src_X += (opSign * xWidth);
750 dst_X += (opSign * xWidth);
751 dst_width -= xWidth;
752
753 if (dst_width <= 0) {
754 /* ROP2 operation is complete */
755 break;
756 }
757
758 if (xWidth > dst_width)
759 xWidth = dst_width;
760 }
761 } else {
762 deWaitForNotBusy();
763 SMTC_write2Dreg(DE_SOURCE,
764 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
765 FIELD_VALUE(0, DE_SOURCE, X_K1, src_X) |
766 FIELD_VALUE(0, DE_SOURCE, Y_K2, src_Y));
767
768 SMTC_write2Dreg(DE_DESTINATION,
769 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
770 FIELD_VALUE(0, DE_DESTINATION, X, dst_X) |
771 FIELD_VALUE(0, DE_DESTINATION, Y, dst_Y));
772
773 SMTC_write2Dreg(DE_DIMENSION,
774 FIELD_VALUE(0, DE_DIMENSION, X, dst_width) |
775 FIELD_VALUE(0, DE_DIMENSION, Y_ET, dst_height));
776
777 de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, nROP2) |
778 nTransparent |
779 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
780 FIELD_SET(0, DE_CONTROL, COMMAND, BITBLT) |
781 ((nDirection == 1) ? FIELD_SET(0, DE_CONTROL, DIRECTION,
782 RIGHT_TO_LEFT)
783 : FIELD_SET(0, DE_CONTROL, DIRECTION,
784 LEFT_TO_RIGHT)) | FIELD_SET(0, DE_CONTROL,
785 STATUS, START);
786 SMTC_write2Dreg(DE_CONTROL, de_ctrl);
787 }
788
789 smtc_de_busy = 1;
790}
791
792/*
793 * This function sets the pixel format that will apply to the 2D Engine.
794 */
795void deSetPixelFormat(unsigned long bpp)
796{
797 unsigned long de_format;
798
799 de_format = SMTC_read2Dreg(DE_STRETCH_FORMAT);
800
801 switch (bpp) {
802 case 8:
803 de_format =
804 FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 8);
805 break;
806 default:
807 case 16:
808 de_format =
809 FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 16);
810 break;
811 case 32:
812 de_format =
813 FIELD_SET(de_format, DE_STRETCH_FORMAT, PIXEL_FORMAT, 32);
814 break;
815 }
816
817 SMTC_write2Dreg(DE_STRETCH_FORMAT, de_format);
818}
819
820/*
821 * System memory to Video memory monochrome expansion.
822 *
823 * Source is monochrome image in system memory. This function expands the
824 * monochrome data to color image in video memory.
825 */
826
827long deSystemMem2VideoMemMonoBlt(const char *pSrcbuf,
828 long srcDelta,
829 unsigned long startBit,
830 unsigned long dBase,
831 unsigned long dPitch,
832 unsigned long bpp,
833 unsigned long dx, unsigned long dy,
834 unsigned long width, unsigned long height,
835 unsigned long fColor,
836 unsigned long bColor,
837 unsigned long rop2) {
838 unsigned long bytePerPixel;
839 unsigned long ulBytesPerScan;
840 unsigned long ul4BytesPerScan;
841 unsigned long ulBytesRemain;
842 unsigned long de_ctrl = 0;
843 unsigned char ajRemain[4];
844 long i, j;
845
846 bytePerPixel = bpp / 8;
847
848 /* Just make sure the start bit is within legal range */
849 startBit &= 7;
850
851 ulBytesPerScan = (width + startBit + 7) / 8;
852 ul4BytesPerScan = ulBytesPerScan & ~3;
853 ulBytesRemain = ulBytesPerScan & 3;
854
855 if (smtc_de_busy)
856 deWaitForNotBusy();
857
858 /*
859 * 2D Source Base. Use 0 for HOST Blt.
860 */
861
862 SMTC_write2Dreg(DE_WINDOW_SOURCE_BASE, 0);
863
864 /*
865 * 2D Destination Base.
866 *
867 * It is an address offset (128 bit aligned) from the beginning of
868 * frame buffer.
869 */
870
871 SMTC_write2Dreg(DE_WINDOW_DESTINATION_BASE, dBase);
872
873 if (dPitch) {
874
875 /*
876 * Program pitch (distance between the 1st points of two
877 * adjacent lines).
878 *
879 * Note that input pitch is BYTE value, but the 2D Pitch
880 * register uses pixel values. Need Byte to pixel convertion.
881 */
882
883 SMTC_write2Dreg(DE_PITCH,
884 FIELD_VALUE(0, DE_PITCH, DESTINATION,
885 dPitch /
886 bytePerPixel) | FIELD_VALUE(0,
887 DE_PITCH,
888 SOURCE,
889 dPitch /
890 bytePerPixel));
891
892 /* Screen Window width in Pixels.
893 *
894 * 2D engine uses this value to calculate the linear address in
895 * frame buffer for a given point.
896 */
897
898 SMTC_write2Dreg(DE_WINDOW_WIDTH,
899 FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION,
900 (dPitch /
901 bytePerPixel)) | FIELD_VALUE(0,
902 DE_WINDOW_WIDTH,
903 SOURCE,
904 (dPitch
905 /
906 bytePerPixel)));
907 }
908 /* Note: For 2D Source in Host Write, only X_K1 field is needed, and
909 * Y_K2 field is not used. For mono bitmap, use startBit for X_K1.
910 */
911
912 SMTC_write2Dreg(DE_SOURCE,
913 FIELD_SET(0, DE_SOURCE, WRAP, DISABLE) |
914 FIELD_VALUE(0, DE_SOURCE, X_K1, startBit) |
915 FIELD_VALUE(0, DE_SOURCE, Y_K2, 0));
916
917 SMTC_write2Dreg(DE_DESTINATION,
918 FIELD_SET(0, DE_DESTINATION, WRAP, DISABLE) |
919 FIELD_VALUE(0, DE_DESTINATION, X, dx) |
920 FIELD_VALUE(0, DE_DESTINATION, Y, dy));
921
922 SMTC_write2Dreg(DE_DIMENSION,
923 FIELD_VALUE(0, DE_DIMENSION, X, width) |
924 FIELD_VALUE(0, DE_DIMENSION, Y_ET, height));
925
926 SMTC_write2Dreg(DE_FOREGROUND, fColor);
927 SMTC_write2Dreg(DE_BACKGROUND, bColor);
928
929 if (bpp)
930 deSetPixelFormat(bpp);
931 /* Set the pixel format of the destination */
932
933 de_ctrl = FIELD_VALUE(0, DE_CONTROL, ROP, rop2) |
934 FIELD_SET(0, DE_CONTROL, ROP_SELECT, ROP2) |
935 FIELD_SET(0, DE_CONTROL, COMMAND, HOST_WRITE) |
936 FIELD_SET(0, DE_CONTROL, HOST, MONO) |
937 FIELD_SET(0, DE_CONTROL, STATUS, START);
938
939 SMTC_write2Dreg(DE_CONTROL, de_ctrl | deGetTransparency());
940
941 /* Write MONO data (line by line) to 2D Engine data port */
942 for (i = 0; i < height; i++) {
943 /* For each line, send the data in chunks of 4 bytes */
944 for (j = 0; j < (ul4BytesPerScan / 4); j++)
945 SMTC_write2Ddataport(0,
946 *(unsigned long *)(pSrcbuf +
947 (j * 4)));
948
949 if (ulBytesRemain) {
950 memcpy(ajRemain, pSrcbuf + ul4BytesPerScan,
951 ulBytesRemain);
952 SMTC_write2Ddataport(0, *(unsigned long *)ajRemain);
953 }
954
955 pSrcbuf += srcDelta;
956 }
957 smtc_de_busy = 1;
958
959 return 0;
960}
961
962/*
963 * This function gets the transparency status from DE_CONTROL register.
964 * It returns a double word with the transparent fields properly set,
965 * while other fields are 0.
966 */
967unsigned long deGetTransparency(void)
968{
969 unsigned long de_ctrl;
970
971 de_ctrl = SMTC_read2Dreg(DE_CONTROL);
972
973 de_ctrl &=
974 FIELD_MASK(DE_CONTROL_TRANSPARENCY_MATCH) |
975 FIELD_MASK(DE_CONTROL_TRANSPARENCY_SELECT) |
976 FIELD_MASK(DE_CONTROL_TRANSPARENCY);
977
978 return de_ctrl;
979}
diff --git a/drivers/staging/sm7xx/smtc2d.h b/drivers/staging/sm7xx/smtc2d.h
deleted file mode 100644
index 02b4fa29136c..000000000000
--- a/drivers/staging/sm7xx/smtc2d.h
+++ /dev/null
@@ -1,530 +0,0 @@
1/*
2 * Silicon Motion SM712 2D drawing engine functions.
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Author: Ge Wang, gewang@siliconmotion.com
6 *
7 * Copyright (C) 2009 Lemote, Inc.
8 * Author: Wu Zhangjin, wuzhangjin@gmail.com
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for
12 * more details.
13 */
14
15#ifndef NULL
16#define NULL 0
17#endif
18
19/* Internal macros */
20
21#define _F_START(f) (0 ? f)
22#define _F_END(f) (1 ? f)
23#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f))
24#define _F_MASK(f) (((1ULL << _F_SIZE(f)) - 1) << _F_START(f))
25#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f))
26#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f))
27
28/* Global macros */
29
30#define FIELD_GET(x, reg, field) \
31( \
32 _F_NORMALIZE((x), reg ## _ ## field) \
33)
34
35#define FIELD_SET(x, reg, field, value) \
36( \
37 (x & ~_F_MASK(reg ## _ ## field)) \
38 | _F_DENORMALIZE(reg ## _ ## field ## _ ## value, reg ## _ ## field) \
39)
40
41#define FIELD_VALUE(x, reg, field, value) \
42( \
43 (x & ~_F_MASK(reg ## _ ## field)) \
44 | _F_DENORMALIZE(value, reg ## _ ## field) \
45)
46
47#define FIELD_CLEAR(reg, field) \
48( \
49 ~_F_MASK(reg ## _ ## field) \
50)
51
52/* Field Macros */
53
54#define FIELD_START(field) (0 ? field)
55#define FIELD_END(field) (1 ? field)
56#define FIELD_SIZE(field) \
57 (1 + FIELD_END(field) - FIELD_START(field))
58
59#define FIELD_MASK(field) \
60 (((1 << (FIELD_SIZE(field)-1)) \
61 | ((1 << (FIELD_SIZE(field)-1)) - 1)) \
62 << FIELD_START(field))
63
64#define FIELD_NORMALIZE(reg, field) \
65 (((reg) & FIELD_MASK(field)) >> FIELD_START(field))
66
67#define FIELD_DENORMALIZE(field, value) \
68 (((value) << FIELD_START(field)) & FIELD_MASK(field))
69
70#define FIELD_INIT(reg, field, value) \
71 FIELD_DENORMALIZE(reg ## _ ## field, \
72 reg ## _ ## field ## _ ## value)
73
74#define FIELD_INIT_VAL(reg, field, value) \
75 (FIELD_DENORMALIZE(reg ## _ ## field, value))
76
77#define FIELD_VAL_SET(x, r, f, v) ({ \
78 x = (x & ~FIELD_MASK(r ## _ ## f)) \
79 | FIELD_DENORMALIZE(r ## _ ## f, r ## _ ## f ## _ ## v) \
80})
81
82#define RGB(r, g, b) ((unsigned long)(((r) << 16) | ((g) << 8) | (b)))
83
84/* Transparent info definition */
85typedef struct {
86 unsigned long match; /* Matching pixel is OPAQUE/TRANSPARENT */
87 unsigned long select; /* Transparency controlled by SRC/DST */
88 unsigned long control; /* ENABLE/DISABLE transparency */
89 unsigned long color; /* Transparent color */
90} Transparent, *pTransparent;
91
92#define PIXEL_DEPTH_1_BP 0 /* 1 bit per pixel */
93#define PIXEL_DEPTH_8_BPP 1 /* 8 bits per pixel */
94#define PIXEL_DEPTH_16_BPP 2 /* 16 bits per pixel */
95#define PIXEL_DEPTH_32_BPP 3 /* 32 bits per pixel */
96#define PIXEL_DEPTH_YUV422 8 /* 16 bits per pixel YUV422 */
97#define PIXEL_DEPTH_YUV420 9 /* 16 bits per pixel YUV420 */
98
99#define PATTERN_WIDTH 8
100#define PATTERN_HEIGHT 8
101
102#define TOP_TO_BOTTOM 0
103#define BOTTOM_TO_TOP 1
104#define RIGHT_TO_LEFT BOTTOM_TO_TOP
105#define LEFT_TO_RIGHT TOP_TO_BOTTOM
106
107/* Constants used in Transparent structure */
108#define MATCH_OPAQUE 0x00000000
109#define MATCH_TRANSPARENT 0x00000400
110#define SOURCE 0x00000000
111#define DESTINATION 0x00000200
112
113/* 2D registers. */
114
115#define DE_SOURCE 0x000000
116#define DE_SOURCE_WRAP 31 : 31
117#define DE_SOURCE_WRAP_DISABLE 0
118#define DE_SOURCE_WRAP_ENABLE 1
119#define DE_SOURCE_X_K1 29 : 16
120#define DE_SOURCE_Y_K2 15 : 0
121
122#define DE_DESTINATION 0x000004
123#define DE_DESTINATION_WRAP 31 : 31
124#define DE_DESTINATION_WRAP_DISABLE 0
125#define DE_DESTINATION_WRAP_ENABLE 1
126#define DE_DESTINATION_X 28 : 16
127#define DE_DESTINATION_Y 15 : 0
128
129#define DE_DIMENSION 0x000008
130#define DE_DIMENSION_X 28 : 16
131#define DE_DIMENSION_Y_ET 15 : 0
132
133#define DE_CONTROL 0x00000C
134#define DE_CONTROL_STATUS 31 : 31
135#define DE_CONTROL_STATUS_STOP 0
136#define DE_CONTROL_STATUS_START 1
137#define DE_CONTROL_PATTERN 30 : 30
138#define DE_CONTROL_PATTERN_MONO 0
139#define DE_CONTROL_PATTERN_COLOR 1
140#define DE_CONTROL_UPDATE_DESTINATION_X 29 : 29
141#define DE_CONTROL_UPDATE_DESTINATION_X_DISABLE 0
142#define DE_CONTROL_UPDATE_DESTINATION_X_ENABLE 1
143#define DE_CONTROL_QUICK_START 28 : 28
144#define DE_CONTROL_QUICK_START_DISABLE 0
145#define DE_CONTROL_QUICK_START_ENABLE 1
146#define DE_CONTROL_DIRECTION 27 : 27
147#define DE_CONTROL_DIRECTION_LEFT_TO_RIGHT 0
148#define DE_CONTROL_DIRECTION_RIGHT_TO_LEFT 1
149#define DE_CONTROL_MAJOR 26 : 26
150#define DE_CONTROL_MAJOR_X 0
151#define DE_CONTROL_MAJOR_Y 1
152#define DE_CONTROL_STEP_X 25 : 25
153#define DE_CONTROL_STEP_X_POSITIVE 1
154#define DE_CONTROL_STEP_X_NEGATIVE 0
155#define DE_CONTROL_STEP_Y 24 : 24
156#define DE_CONTROL_STEP_Y_POSITIVE 1
157#define DE_CONTROL_STEP_Y_NEGATIVE 0
158#define DE_CONTROL_STRETCH 23 : 23
159#define DE_CONTROL_STRETCH_DISABLE 0
160#define DE_CONTROL_STRETCH_ENABLE 1
161#define DE_CONTROL_HOST 22 : 22
162#define DE_CONTROL_HOST_COLOR 0
163#define DE_CONTROL_HOST_MONO 1
164#define DE_CONTROL_LAST_PIXEL 21 : 21
165#define DE_CONTROL_LAST_PIXEL_OFF 0
166#define DE_CONTROL_LAST_PIXEL_ON 1
167#define DE_CONTROL_COMMAND 20 : 16
168#define DE_CONTROL_COMMAND_BITBLT 0
169#define DE_CONTROL_COMMAND_RECTANGLE_FILL 1
170#define DE_CONTROL_COMMAND_DE_TILE 2
171#define DE_CONTROL_COMMAND_TRAPEZOID_FILL 3
172#define DE_CONTROL_COMMAND_ALPHA_BLEND 4
173#define DE_CONTROL_COMMAND_RLE_STRIP 5
174#define DE_CONTROL_COMMAND_SHORT_STROKE 6
175#define DE_CONTROL_COMMAND_LINE_DRAW 7
176#define DE_CONTROL_COMMAND_HOST_WRITE 8
177#define DE_CONTROL_COMMAND_HOST_READ 9
178#define DE_CONTROL_COMMAND_HOST_WRITE_BOTTOM_UP 10
179#define DE_CONTROL_COMMAND_ROTATE 11
180#define DE_CONTROL_COMMAND_FONT 12
181#define DE_CONTROL_COMMAND_TEXTURE_LOAD 15
182#define DE_CONTROL_ROP_SELECT 15 : 15
183#define DE_CONTROL_ROP_SELECT_ROP3 0
184#define DE_CONTROL_ROP_SELECT_ROP2 1
185#define DE_CONTROL_ROP2_SOURCE 14 : 14
186#define DE_CONTROL_ROP2_SOURCE_BITMAP 0
187#define DE_CONTROL_ROP2_SOURCE_PATTERN 1
188#define DE_CONTROL_MONO_DATA 13 : 12
189#define DE_CONTROL_MONO_DATA_NOT_PACKED 0
190#define DE_CONTROL_MONO_DATA_8_PACKED 1
191#define DE_CONTROL_MONO_DATA_16_PACKED 2
192#define DE_CONTROL_MONO_DATA_32_PACKED 3
193#define DE_CONTROL_REPEAT_ROTATE 11 : 11
194#define DE_CONTROL_REPEAT_ROTATE_DISABLE 0
195#define DE_CONTROL_REPEAT_ROTATE_ENABLE 1
196#define DE_CONTROL_TRANSPARENCY_MATCH 10 : 10
197#define DE_CONTROL_TRANSPARENCY_MATCH_OPAQUE 0
198#define DE_CONTROL_TRANSPARENCY_MATCH_TRANSPARENT 1
199#define DE_CONTROL_TRANSPARENCY_SELECT 9 : 9
200#define DE_CONTROL_TRANSPARENCY_SELECT_SOURCE 0
201#define DE_CONTROL_TRANSPARENCY_SELECT_DESTINATION 1
202#define DE_CONTROL_TRANSPARENCY 8 : 8
203#define DE_CONTROL_TRANSPARENCY_DISABLE 0
204#define DE_CONTROL_TRANSPARENCY_ENABLE 1
205#define DE_CONTROL_ROP 7 : 0
206
207/* Pseudo fields. */
208
209#define DE_CONTROL_SHORT_STROKE_DIR 27 : 24
210#define DE_CONTROL_SHORT_STROKE_DIR_225 0
211#define DE_CONTROL_SHORT_STROKE_DIR_135 1
212#define DE_CONTROL_SHORT_STROKE_DIR_315 2
213#define DE_CONTROL_SHORT_STROKE_DIR_45 3
214#define DE_CONTROL_SHORT_STROKE_DIR_270 4
215#define DE_CONTROL_SHORT_STROKE_DIR_90 5
216#define DE_CONTROL_SHORT_STROKE_DIR_180 8
217#define DE_CONTROL_SHORT_STROKE_DIR_0 10
218#define DE_CONTROL_ROTATION 25 : 24
219#define DE_CONTROL_ROTATION_0 0
220#define DE_CONTROL_ROTATION_270 1
221#define DE_CONTROL_ROTATION_90 2
222#define DE_CONTROL_ROTATION_180 3
223
224#define DE_PITCH 0x000010
225#define DE_PITCH_DESTINATION 28 : 16
226#define DE_PITCH_SOURCE 12 : 0
227
228#define DE_FOREGROUND 0x000014
229#define DE_FOREGROUND_COLOR 31 : 0
230
231#define DE_BACKGROUND 0x000018
232#define DE_BACKGROUND_COLOR 31 : 0
233
234#define DE_STRETCH_FORMAT 0x00001C
235#define DE_STRETCH_FORMAT_PATTERN_XY 30 : 30
236#define DE_STRETCH_FORMAT_PATTERN_XY_NORMAL 0
237#define DE_STRETCH_FORMAT_PATTERN_XY_OVERWRITE 1
238#define DE_STRETCH_FORMAT_PATTERN_Y 29 : 27
239#define DE_STRETCH_FORMAT_PATTERN_X 25 : 23
240#define DE_STRETCH_FORMAT_PIXEL_FORMAT 21 : 20
241#define DE_STRETCH_FORMAT_PIXEL_FORMAT_8 0
242#define DE_STRETCH_FORMAT_PIXEL_FORMAT_16 1
243#define DE_STRETCH_FORMAT_PIXEL_FORMAT_24 3
244#define DE_STRETCH_FORMAT_PIXEL_FORMAT_32 2
245#define DE_STRETCH_FORMAT_ADDRESSING 19 : 16
246#define DE_STRETCH_FORMAT_ADDRESSING_XY 0
247#define DE_STRETCH_FORMAT_ADDRESSING_LINEAR 15
248#define DE_STRETCH_FORMAT_SOURCE_HEIGHT 11 : 0
249
250#define DE_COLOR_COMPARE 0x000020
251#define DE_COLOR_COMPARE_COLOR 23 : 0
252
253#define DE_COLOR_COMPARE_MASK 0x000024
254#define DE_COLOR_COMPARE_MASK_MASKS 23 : 0
255
256#define DE_MASKS 0x000028
257#define DE_MASKS_BYTE_MASK 31 : 16
258#define DE_MASKS_BIT_MASK 15 : 0
259
260#define DE_CLIP_TL 0x00002C
261#define DE_CLIP_TL_TOP 31 : 16
262#define DE_CLIP_TL_STATUS 13 : 13
263#define DE_CLIP_TL_STATUS_DISABLE 0
264#define DE_CLIP_TL_STATUS_ENABLE 1
265#define DE_CLIP_TL_INHIBIT 12 : 12
266#define DE_CLIP_TL_INHIBIT_OUTSIDE 0
267#define DE_CLIP_TL_INHIBIT_INSIDE 1
268#define DE_CLIP_TL_LEFT 11 : 0
269
270#define DE_CLIP_BR 0x000030
271#define DE_CLIP_BR_BOTTOM 31 : 16
272#define DE_CLIP_BR_RIGHT 12 : 0
273
274#define DE_MONO_PATTERN_LOW 0x000034
275#define DE_MONO_PATTERN_LOW_PATTERN 31 : 0
276
277#define DE_MONO_PATTERN_HIGH 0x000038
278#define DE_MONO_PATTERN_HIGH_PATTERN 31 : 0
279
280#define DE_WINDOW_WIDTH 0x00003C
281#define DE_WINDOW_WIDTH_DESTINATION 28 : 16
282#define DE_WINDOW_WIDTH_SOURCE 12 : 0
283
284#define DE_WINDOW_SOURCE_BASE 0x000040
285#define DE_WINDOW_SOURCE_BASE_EXT 27 : 27
286#define DE_WINDOW_SOURCE_BASE_EXT_LOCAL 0
287#define DE_WINDOW_SOURCE_BASE_EXT_EXTERNAL 1
288#define DE_WINDOW_SOURCE_BASE_CS 26 : 26
289#define DE_WINDOW_SOURCE_BASE_CS_0 0
290#define DE_WINDOW_SOURCE_BASE_CS_1 1
291#define DE_WINDOW_SOURCE_BASE_ADDRESS 25 : 0
292
293#define DE_WINDOW_DESTINATION_BASE 0x000044
294#define DE_WINDOW_DESTINATION_BASE_EXT 27 : 27
295#define DE_WINDOW_DESTINATION_BASE_EXT_LOCAL 0
296#define DE_WINDOW_DESTINATION_BASE_EXT_EXTERNAL 1
297#define DE_WINDOW_DESTINATION_BASE_CS 26 : 26
298#define DE_WINDOW_DESTINATION_BASE_CS_0 0
299#define DE_WINDOW_DESTINATION_BASE_CS_1 1
300#define DE_WINDOW_DESTINATION_BASE_ADDRESS 25 : 0
301
302#define DE_ALPHA 0x000048
303#define DE_ALPHA_VALUE 7 : 0
304
305#define DE_WRAP 0x00004C
306#define DE_WRAP_X 31 : 16
307#define DE_WRAP_Y 15 : 0
308
309#define DE_STATUS 0x000050
310#define DE_STATUS_CSC 1 : 1
311#define DE_STATUS_CSC_CLEAR 0
312#define DE_STATUS_CSC_NOT_ACTIVE 0
313#define DE_STATUS_CSC_ACTIVE 1
314#define DE_STATUS_2D 0 : 0
315#define DE_STATUS_2D_CLEAR 0
316#define DE_STATUS_2D_NOT_ACTIVE 0
317#define DE_STATUS_2D_ACTIVE 1
318
319/* Color Space Conversion registers. */
320
321#define CSC_Y_SOURCE_BASE 0x0000C8
322#define CSC_Y_SOURCE_BASE_EXT 27 : 27
323#define CSC_Y_SOURCE_BASE_EXT_LOCAL 0
324#define CSC_Y_SOURCE_BASE_EXT_EXTERNAL 1
325#define CSC_Y_SOURCE_BASE_CS 26 : 26
326#define CSC_Y_SOURCE_BASE_CS_0 0
327#define CSC_Y_SOURCE_BASE_CS_1 1
328#define CSC_Y_SOURCE_BASE_ADDRESS 25 : 0
329
330#define CSC_CONSTANTS 0x0000CC
331#define CSC_CONSTANTS_Y 31 : 24
332#define CSC_CONSTANTS_R 23 : 16
333#define CSC_CONSTANTS_G 15 : 8
334#define CSC_CONSTANTS_B 7 : 0
335
336#define CSC_Y_SOURCE_X 0x0000D0
337#define CSC_Y_SOURCE_X_INTEGER 26 : 16
338#define CSC_Y_SOURCE_X_FRACTION 15 : 3
339
340#define CSC_Y_SOURCE_Y 0x0000D4
341#define CSC_Y_SOURCE_Y_INTEGER 27 : 16
342#define CSC_Y_SOURCE_Y_FRACTION 15 : 3
343
344#define CSC_U_SOURCE_BASE 0x0000D8
345#define CSC_U_SOURCE_BASE_EXT 27 : 27
346#define CSC_U_SOURCE_BASE_EXT_LOCAL 0
347#define CSC_U_SOURCE_BASE_EXT_EXTERNAL 1
348#define CSC_U_SOURCE_BASE_CS 26 : 26
349#define CSC_U_SOURCE_BASE_CS_0 0
350#define CSC_U_SOURCE_BASE_CS_1 1
351#define CSC_U_SOURCE_BASE_ADDRESS 25 : 0
352
353#define CSC_V_SOURCE_BASE 0x0000DC
354#define CSC_V_SOURCE_BASE_EXT 27 : 27
355#define CSC_V_SOURCE_BASE_EXT_LOCAL 0
356#define CSC_V_SOURCE_BASE_EXT_EXTERNAL 1
357#define CSC_V_SOURCE_BASE_CS 26 : 26
358#define CSC_V_SOURCE_BASE_CS_0 0
359#define CSC_V_SOURCE_BASE_CS_1 1
360#define CSC_V_SOURCE_BASE_ADDRESS 25 : 0
361
362#define CSC_SOURCE_DIMENSION 0x0000E0
363#define CSC_SOURCE_DIMENSION_X 31 : 16
364#define CSC_SOURCE_DIMENSION_Y 15 : 0
365
366#define CSC_SOURCE_PITCH 0x0000E4
367#define CSC_SOURCE_PITCH_Y 31 : 16
368#define CSC_SOURCE_PITCH_UV 15 : 0
369
370#define CSC_DESTINATION 0x0000E8
371#define CSC_DESTINATION_WRAP 31 : 31
372#define CSC_DESTINATION_WRAP_DISABLE 0
373#define CSC_DESTINATION_WRAP_ENABLE 1
374#define CSC_DESTINATION_X 27 : 16
375#define CSC_DESTINATION_Y 11 : 0
376
377#define CSC_DESTINATION_DIMENSION 0x0000EC
378#define CSC_DESTINATION_DIMENSION_X 31 : 16
379#define CSC_DESTINATION_DIMENSION_Y 15 : 0
380
381#define CSC_DESTINATION_PITCH 0x0000F0
382#define CSC_DESTINATION_PITCH_X 31 : 16
383#define CSC_DESTINATION_PITCH_Y 15 : 0
384
385#define CSC_SCALE_FACTOR 0x0000F4
386#define CSC_SCALE_FACTOR_HORIZONTAL 31 : 16
387#define CSC_SCALE_FACTOR_VERTICAL 15 : 0
388
389#define CSC_DESTINATION_BASE 0x0000F8
390#define CSC_DESTINATION_BASE_EXT 27 : 27
391#define CSC_DESTINATION_BASE_EXT_LOCAL 0
392#define CSC_DESTINATION_BASE_EXT_EXTERNAL 1
393#define CSC_DESTINATION_BASE_CS 26 : 26
394#define CSC_DESTINATION_BASE_CS_0 0
395#define CSC_DESTINATION_BASE_CS_1 1
396#define CSC_DESTINATION_BASE_ADDRESS 25 : 0
397
398#define CSC_CONTROL 0x0000FC
399#define CSC_CONTROL_STATUS 31 : 31
400#define CSC_CONTROL_STATUS_STOP 0
401#define CSC_CONTROL_STATUS_START 1
402#define CSC_CONTROL_SOURCE_FORMAT 30 : 28
403#define CSC_CONTROL_SOURCE_FORMAT_YUV422 0
404#define CSC_CONTROL_SOURCE_FORMAT_YUV420I 1
405#define CSC_CONTROL_SOURCE_FORMAT_YUV420 2
406#define CSC_CONTROL_SOURCE_FORMAT_YVU9 3
407#define CSC_CONTROL_SOURCE_FORMAT_IYU1 4
408#define CSC_CONTROL_SOURCE_FORMAT_IYU2 5
409#define CSC_CONTROL_SOURCE_FORMAT_RGB565 6
410#define CSC_CONTROL_SOURCE_FORMAT_RGB8888 7
411#define CSC_CONTROL_DESTINATION_FORMAT 27 : 26
412#define CSC_CONTROL_DESTINATION_FORMAT_RGB565 0
413#define CSC_CONTROL_DESTINATION_FORMAT_RGB8888 1
414#define CSC_CONTROL_HORIZONTAL_FILTER 25 : 25
415#define CSC_CONTROL_HORIZONTAL_FILTER_DISABLE 0
416#define CSC_CONTROL_HORIZONTAL_FILTER_ENABLE 1
417#define CSC_CONTROL_VERTICAL_FILTER 24 : 24
418#define CSC_CONTROL_VERTICAL_FILTER_DISABLE 0
419#define CSC_CONTROL_VERTICAL_FILTER_ENABLE 1
420#define CSC_CONTROL_BYTE_ORDER 23 : 23
421#define CSC_CONTROL_BYTE_ORDER_YUYV 0
422#define CSC_CONTROL_BYTE_ORDER_UYVY 1
423
424#define DE_DATA_PORT_501 0x110000
425#define DE_DATA_PORT_712 0x400000
426#define DE_DATA_PORT_722 0x6000
427
428/* point to virtual Memory Map IO starting address */
429extern char *smtc_RegBaseAddress;
430/* point to virtual video memory starting address */
431extern char *smtc_VRAMBaseAddress;
432extern unsigned char smtc_de_busy;
433
434extern unsigned long memRead32(unsigned long nOffset);
435extern void memWrite32(unsigned long nOffset, unsigned long nData);
436extern unsigned long SMTC_read2Dreg(unsigned long nOffset);
437
438/* 2D functions */
439extern void deInit(unsigned int nModeWidth, unsigned int nModeHeight,
440 unsigned int bpp);
441
442extern void deWaitForNotBusy(void);
443
444extern void deVerticalLine(unsigned long dst_base,
445 unsigned long dst_pitch,
446 unsigned long nX,
447 unsigned long nY,
448 unsigned long dst_height,
449 unsigned long nColor);
450
451extern void deHorizontalLine(unsigned long dst_base,
452 unsigned long dst_pitch,
453 unsigned long nX,
454 unsigned long nY,
455 unsigned long dst_width,
456 unsigned long nColor);
457
458extern void deLine(unsigned long dst_base,
459 unsigned long dst_pitch,
460 unsigned long nX1,
461 unsigned long nY1,
462 unsigned long nX2,
463 unsigned long nY2,
464 unsigned long nColor);
465
466extern void deFillRect(unsigned long dst_base,
467 unsigned long dst_pitch,
468 unsigned long dst_X,
469 unsigned long dst_Y,
470 unsigned long dst_width,
471 unsigned long dst_height,
472 unsigned long nColor);
473
474extern void deRotatePattern(unsigned char *pattern_dstaddr,
475 unsigned long pattern_src_addr,
476 unsigned long pattern_BPP,
477 unsigned long pattern_stride,
478 int patternX,
479 int patternY);
480
481extern void deCopy(unsigned long dst_base,
482 unsigned long dst_pitch,
483 unsigned long dst_BPP,
484 unsigned long dst_X,
485 unsigned long dst_Y,
486 unsigned long dst_width,
487 unsigned long dst_height,
488 unsigned long src_base,
489 unsigned long src_pitch,
490 unsigned long src_X,
491 unsigned long src_Y,
492 pTransparent pTransp,
493 unsigned char nROP2);
494
495/*
496 * System memory to Video memory monochrome expansion.
497 *
498 * Source is monochrome image in system memory. This function expands the
499 * monochrome data to color image in video memory.
500 *
501 * @pSrcbuf: pointer to start of source buffer in system memory
502 * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top
503 * down and -ive mean button up
504 * @startBit: Mono data can start at any bit in a byte, this value should
505 * be 0 to 7
506 * @dBase: Address of destination : offset in frame buffer
507 * @dPitch: Pitch value of destination surface in BYTE
508 * @bpp: Color depth of destination surface
509 * @dx, dy: Starting coordinate of destination surface
510 * @width, height: width and height of rectange in pixel value
511 * @fColor,bColor: Foreground, Background color (corresponding to a 1, 0 in
512 * the monochrome data)
513 * @rop2: ROP value
514 */
515
516extern long deSystemMem2VideoMemMonoBlt(
517 const char *pSrcbuf,
518 long srcDelta,
519 unsigned long startBit,
520 unsigned long dBase,
521 unsigned long dPitch,
522 unsigned long bpp,
523 unsigned long dx, unsigned long dy,
524 unsigned long width, unsigned long height,
525 unsigned long fColor,
526 unsigned long bColor,
527 unsigned long rop2);
528
529extern unsigned long deGetTransparency(void);
530extern void deSetPixelFormat(unsigned long bpp);
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
index a4f6f49aef48..9c82a1a81ccc 100644
--- a/drivers/staging/sm7xx/smtcfb.c
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -45,7 +45,6 @@
45struct screen_info smtc_screen_info; 45struct screen_info smtc_screen_info;
46 46
47#include "smtcfb.h" 47#include "smtcfb.h"
48#include "smtc2d.h"
49 48
50#ifdef DEBUG 49#ifdef DEBUG
51#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) 50#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
@@ -120,10 +119,6 @@ static struct vesa_mode_table vesa_mode[] = {
120char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ 119char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
121char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ 120char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
122 121
123char *smtc_2DBaseAddress; /* 2D engine starting address */
124char *smtc_2Ddataport; /* 2D data port offset */
125short smtc_2Dacceleration;
126
127static u32 colreg[17]; 122static u32 colreg[17];
128static struct par_info hw; /* hardware information */ 123static struct par_info hw; /* hardware information */
129 124
@@ -135,16 +130,6 @@ u16 smtc_ChipIDs[] = {
135 130
136#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16)) 131#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
137 132
138void deWaitForNotBusy(void)
139{
140 unsigned long i = 0x1000000;
141 while (i--) {
142 if ((smtc_seqr(0x16) & 0x18) == 0x10)
143 break;
144 }
145 smtc_de_busy = 0;
146}
147
148static void sm712_set_timing(struct smtcfb_info *sfb, 133static void sm712_set_timing(struct smtcfb_info *sfb,
149 struct par_info *ppar_info) 134 struct par_info *ppar_info)
150{ 135{
@@ -324,7 +309,7 @@ static inline unsigned int chan_to_field(unsigned int chan,
324 return chan << bf->offset; 309 return chan << bf->offset;
325} 310}
326 311
327static int smtcfb_blank(int blank_mode, struct fb_info *info) 312static int cfb_blank(int blank_mode, struct fb_info *info)
328{ 313{
329 /* clear DPMS setting */ 314 /* clear DPMS setting */
330 switch (blank_mode) { 315 switch (blank_mode) {
@@ -622,93 +607,13 @@ smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
622} 607}
623#endif /* ! __BIG_ENDIAN */ 608#endif /* ! __BIG_ENDIAN */
624 609
625#include "smtc2d.c"
626
627void smtcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
628{
629 struct par_info *p = (struct par_info *)info->par;
630
631 if (smtc_2Dacceleration) {
632 if (!area->width || !area->height)
633 return;
634
635 deCopy(p->BaseAddressInVRAM, 0, info->var.bits_per_pixel,
636 area->dx, area->dy, area->width, area->height,
637 p->BaseAddressInVRAM, 0, area->sx, area->sy, 0, 0xC);
638
639 } else
640 cfb_copyarea(info, area);
641}
642
643void smtcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
644{
645 struct par_info *p = (struct par_info *)info->par;
646
647 if (smtc_2Dacceleration) {
648 if (!rect->width || !rect->height)
649 return;
650 if (info->var.bits_per_pixel >= 24)
651 deFillRect(p->BaseAddressInVRAM, 0, rect->dx * 3,
652 rect->dy * 3, rect->width * 3, rect->height,
653 rect->color);
654 else
655 deFillRect(p->BaseAddressInVRAM, 0, rect->dx, rect->dy,
656 rect->width, rect->height, rect->color);
657 } else
658 cfb_fillrect(info, rect);
659}
660
661void smtcfb_imageblit(struct fb_info *info, const struct fb_image *image)
662{
663 struct par_info *p = (struct par_info *)info->par;
664 u32 bg_col = 0, fg_col = 0;
665
666 if ((smtc_2Dacceleration) && (image->depth == 1)) {
667 if (smtc_de_busy)
668 deWaitForNotBusy();
669
670 switch (info->var.bits_per_pixel) {
671 case 8:
672 bg_col = image->bg_color;
673 fg_col = image->fg_color;
674 break;
675 case 16:
676 bg_col =
677 ((u32 *) (info->pseudo_palette))[image->bg_color];
678 fg_col =
679 ((u32 *) (info->pseudo_palette))[image->fg_color];
680 break;
681 case 32:
682 bg_col =
683 ((u32 *) (info->pseudo_palette))[image->bg_color];
684 fg_col =
685 ((u32 *) (info->pseudo_palette))[image->fg_color];
686 break;
687 }
688
689 deSystemMem2VideoMemMonoBlt(
690 image->data,
691 image->width / 8,
692 0,
693 p->BaseAddressInVRAM,
694 0,
695 0,
696 image->dx, image->dy,
697 image->width, image->height,
698 fg_col, bg_col,
699 0x0C);
700
701 } else
702 cfb_imageblit(info, image);
703}
704
705static struct fb_ops smtcfb_ops = { 610static struct fb_ops smtcfb_ops = {
706 .owner = THIS_MODULE, 611 .owner = THIS_MODULE,
707 .fb_setcolreg = smtc_setcolreg, 612 .fb_setcolreg = smtc_setcolreg,
708 .fb_blank = smtcfb_blank, 613 .fb_blank = cfb_blank,
709 .fb_fillrect = smtcfb_fillrect, 614 .fb_fillrect = cfb_fillrect,
710 .fb_imageblit = smtcfb_imageblit, 615 .fb_imageblit = cfb_imageblit,
711 .fb_copyarea = smtcfb_copyarea, 616 .fb_copyarea = cfb_copyarea,
712#ifdef __BIG_ENDIAN 617#ifdef __BIG_ENDIAN
713 .fb_read = smtcfb_read, 618 .fb_read = smtcfb_read,
714 .fb_write = smtcfb_write, 619 .fb_write = smtcfb_write,
@@ -772,12 +677,6 @@ void smtcfb_setmode(struct smtcfb_info *sfb)
772 hw.height = sfb->fb.var.yres; 677 hw.height = sfb->fb.var.yres;
773 hw.hz = 60; 678 hw.hz = 60;
774 smtc_set_timing(sfb, &hw); 679 smtc_set_timing(sfb, &hw);
775 if (smtc_2Dacceleration) {
776 printk("2D acceleration enabled!\n");
777 /* Init smtc drawing engine */
778 deInit(sfb->fb.var.xres, sfb->fb.var.yres,
779 sfb->fb.var.bits_per_pixel);
780 }
781} 680}
782 681
783/* 682/*
@@ -1004,9 +903,7 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev,
1004#endif 903#endif
1005 hw.m_pMMIO = (smtc_RegBaseAddress = 904 hw.m_pMMIO = (smtc_RegBaseAddress =
1006 smtc_VRAMBaseAddress + 0x00700000); 905 smtc_VRAMBaseAddress + 0x00700000);
1007 smtc_2DBaseAddress = (hw.m_pDPR = 906 hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000;
1008 smtc_VRAMBaseAddress + 0x00408000);
1009 smtc_2Ddataport = smtc_VRAMBaseAddress + DE_DATA_PORT_712;
1010 hw.m_pVPR = hw.m_pLFB + 0x0040c000; 907 hw.m_pVPR = hw.m_pLFB + 0x0040c000;
1011#ifdef __BIG_ENDIAN 908#ifdef __BIG_ENDIAN
1012 if (sfb->fb.var.bits_per_pixel == 32) { 909 if (sfb->fb.var.bits_per_pixel == 32) {
@@ -1035,27 +932,21 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev,
1035 if (sfb->fb.var.bits_per_pixel == 32) 932 if (sfb->fb.var.bits_per_pixel == 32)
1036 smtc_seqw(0x17, 0x30); 933 smtc_seqw(0x17, 0x30);
1037#endif 934#endif
1038#ifdef CONFIG_FB_SM7XX_ACCEL
1039 smtc_2Dacceleration = 1;
1040#endif
1041 break; 935 break;
1042 case 0x720: 936 case 0x720:
1043 sfb->fb.fix.mmio_start = pFramebufferPhysical; 937 sfb->fb.fix.mmio_start = pFramebufferPhysical;
1044 sfb->fb.fix.mmio_len = 0x00200000; 938 sfb->fb.fix.mmio_len = 0x00200000;
1045 smem_size = SM722_VIDEOMEMORYSIZE; 939 smem_size = SM722_VIDEOMEMORYSIZE;
1046 smtc_2DBaseAddress = (hw.m_pDPR = 940 hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000);
1047 ioremap(pFramebufferPhysical, 0x00a00000));
1048 hw.m_pLFB = (smtc_VRAMBaseAddress = 941 hw.m_pLFB = (smtc_VRAMBaseAddress =
1049 smtc_2DBaseAddress + 0x00200000); 942 hw.m_pDPR + 0x00200000);
1050 hw.m_pMMIO = (smtc_RegBaseAddress = 943 hw.m_pMMIO = (smtc_RegBaseAddress =
1051 smtc_2DBaseAddress + 0x000c0000); 944 hw.m_pDPR + 0x000c0000);
1052 smtc_2Ddataport = smtc_2DBaseAddress + DE_DATA_PORT_722; 945 hw.m_pVPR = hw.m_pDPR + 0x800;
1053 hw.m_pVPR = smtc_2DBaseAddress + 0x800;
1054 946
1055 smtc_seqw(0x62, 0xff); 947 smtc_seqw(0x62, 0xff);
1056 smtc_seqw(0x6a, 0x0d); 948 smtc_seqw(0x6a, 0x0d);
1057 smtc_seqw(0x6b, 0x02); 949 smtc_seqw(0x6b, 0x02);
1058 smtc_2Dacceleration = 0;
1059 break; 950 break;
1060 default: 951 default:
1061 printk(KERN_INFO 952 printk(KERN_INFO
@@ -1103,7 +994,7 @@ static int __init smtcfb_pci_probe(struct pci_dev *pdev,
1103 994
1104 995
1105/* Jason (08/11/2009) PCI_DRV wrapper essential structs */ 996/* Jason (08/11/2009) PCI_DRV wrapper essential structs */
1106static struct pci_device_id smtcfb_pci_table[] = { 997static const struct pci_device_id smtcfb_pci_table[] = {
1107 {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 998 {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1108 {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 999 {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1109 {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 1000 {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff --git a/drivers/staging/udlfb/Kconfig b/drivers/staging/udlfb/Kconfig
index 641692da0e4f..65bd5db4ca56 100644
--- a/drivers/staging/udlfb/Kconfig
+++ b/drivers/staging/udlfb/Kconfig
@@ -1,8 +1,14 @@
1config FB_UDL 1config FB_UDL
2 tristate "Displaylink USB Framebuffer support" 2 tristate "Displaylink USB Framebuffer support"
3 depends on FB && USB 3 depends on FB && USB
4 select FB_MODE_HELPERS
5 select FB_SYS_FILLRECT
6 select FB_SYS_COPYAREA
7 select FB_SYS_IMAGEBLIT
8 select FB_SYS_FOPS
9 select FB_DEFERRED_IO
4 ---help--- 10 ---help---
5 This is an experimental driver for DisplayLink USB devices 11 This is a kernel framebuffer driver for DisplayLink USB devices.
6 that provides a framebuffer device. A normal framebuffer can 12 Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
7 be used with this driver, or xorg can be run on the device 13 mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
8 using it. 14 To compile as a module, choose M here: the module name is udlfb.
diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c
index f5416af1e902..8f6223c8303a 100644
--- a/drivers/staging/udlfb/udlfb.c
+++ b/drivers/staging/udlfb/udlfb.c
@@ -1,17 +1,20 @@
1/***************************************************************************** 1/*
2 * DLFB Kernel Driver * 2 * udlfb.c -- Framebuffer driver for DisplayLink USB controller
3 * Version 0.2 (udlfb) * 3 *
4 * (C) 2009 Roberto De Ioris <roberto@unbit.it> * 4 * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it>
5 * * 5 * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com>
6 * This file is licensed under the GPLv2. See COPYING in the package. * 6 * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
7 * Based on the amazing work of Florian Echtler and libdlo 0.1 * 7 *
8 * * 8 * This file is subject to the terms and conditions of the GNU General Public
9 * * 9 * License v2. See the file COPYING in the main directory of this archive for
10 * 10.06.09 release 0.2.3 (edid ioctl, fallback for unsupported modes) * 10 * more details.
11 * 05.06.09 release 0.2.2 (real screen blanking, rle compression, double buffer) * 11 *
12 * 31.05.09 release 0.2 * 12 * Layout is based on skeletonfb by James Simmons and Geert Uytterhoeven,
13 * 22.05.09 First public (ugly) release * 13 * usb-skeleton by GregKH.
14 *****************************************************************************/ 14 *
15 * Device-specific portions based on information from Displaylink, with work
16 * from Florian Echtler, Henrik Bjerregaard Pedersen, and others.
17 */
15 18
16#include <linux/module.h> 19#include <linux/module.h>
17#include <linux/kernel.h> 20#include <linux/kernel.h>
@@ -20,606 +23,672 @@
20#include <linux/uaccess.h> 23#include <linux/uaccess.h>
21#include <linux/mm.h> 24#include <linux/mm.h>
22#include <linux/fb.h> 25#include <linux/fb.h>
23#include <linux/mutex.h>
24#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
25 27
26#include "udlfb.h" 28#include "udlfb.h"
27 29
28#define DRIVER_VERSION "DLFB 0.2" 30static struct fb_fix_screeninfo dlfb_fix = {
31 .id = "udlfb",
32 .type = FB_TYPE_PACKED_PIXELS,
33 .visual = FB_VISUAL_TRUECOLOR,
34 .xpanstep = 0,
35 .ypanstep = 0,
36 .ywrapstep = 0,
37 .accel = FB_ACCEL_NONE,
38};
29 39
30/* memory functions taken from vfb */ 40static const u32 udlfb_info_flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
41#ifdef FBINFO_VIRTFB
42 FBINFO_VIRTFB |
43#endif
44 FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT |
45 FBINFO_HWACCEL_COPYAREA | FBINFO_MISC_ALWAYS_SETPAR;
31 46
32static void *rvmalloc(unsigned long size) 47/*
33{ 48 * There are many DisplayLink-based products, all with unique PIDs. We are able
34 void *mem; 49 * to support all volume ones (circa 2009) with a single driver, so we match
35 unsigned long adr; 50 * globally on VID. TODO: Probe() needs to detect when we might be running
51 * "future" chips, and bail on those, so a compatible driver can match.
52 */
53static struct usb_device_id id_table[] = {
54 {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,},
55 {},
56};
57MODULE_DEVICE_TABLE(usb, id_table);
36 58
37 size = PAGE_ALIGN(size); 59#ifndef CONFIG_FB_DEFERRED_IO
38 mem = vmalloc_32(size); 60#warning message "kernel FB_DEFFERRED_IO option to support generic fbdev apps"
39 if (!mem) 61#endif
40 return NULL;
41 62
42 memset(mem, 0, size); /* Clear the ram out, no junk to the user */ 63#ifndef CONFIG_FB_SYS_IMAGEBLIT
43 adr = (unsigned long)mem; 64#ifndef CONFIG_FB_SYS_IMAGEBLIT_MODULE
44 while (size > 0) { 65#warning message "FB_SYS_* in kernel or module option to support fb console"
45 SetPageReserved(vmalloc_to_page((void *)adr)); 66#endif
46 adr += PAGE_SIZE; 67#endif
47 size -= PAGE_SIZE;
48 }
49 68
50 return mem; 69#ifndef CONFIG_FB_MODE_HELPERS
51} 70#warning message "kernel FB_MODE_HELPERS required. Expect build break"
71#endif
52 72
53static void rvfree(void *mem, unsigned long size) 73/* dlfb keeps a list of urbs for efficient bulk transfers */
54{ 74static void dlfb_urb_completion(struct urb *urb);
55 unsigned long adr; 75static struct urb *dlfb_get_urb(struct dlfb_data *dev);
76static int dlfb_submit_urb(struct dlfb_data *dev, struct urb * urb, size_t len);
77static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size);
78static void dlfb_free_urb_list(struct dlfb_data *dev);
56 79
57 if (!mem) 80/* other symbols with dependents */
58 return; 81#ifdef CONFIG_FB_DEFERRED_IO
82static struct fb_deferred_io dlfb_defio;
83#endif
59 84
60 adr = (unsigned long)mem; 85/*
61 while ((long)size > 0) { 86 * All DisplayLink bulk operations start with 0xAF, followed by specific code
62 ClearPageReserved(vmalloc_to_page((void *)adr)); 87 * All operations are written to buffers which then later get sent to device
63 adr += PAGE_SIZE; 88 */
64 size -= PAGE_SIZE; 89static char *dlfb_set_register(char *buf, u8 reg, u8 val)
65 } 90{
66 vfree(mem); 91 *buf++ = 0xAF;
92 *buf++ = 0x20;
93 *buf++ = reg;
94 *buf++ = val;
95 return buf;
67} 96}
68 97
69static int dlfb_mmap(struct fb_info *info, struct vm_area_struct *vma) 98static char *dlfb_vidreg_lock(char *buf)
70{ 99{
71 unsigned long start = vma->vm_start; 100 return dlfb_set_register(buf, 0xFF, 0x00);
72 unsigned long size = vma->vm_end - vma->vm_start;
73 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
74 unsigned long page, pos;
75
76 printk("MMAP: %lu %u\n", offset + size, info->fix.smem_len);
77
78 if (offset + size > info->fix.smem_len)
79 return -EINVAL;
80
81 pos = (unsigned long)info->fix.smem_start + offset;
82
83 while (size > 0) {
84 page = vmalloc_to_pfn((void *)pos);
85 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
86 return -EAGAIN;
87
88 start += PAGE_SIZE;
89 pos += PAGE_SIZE;
90 if (size > PAGE_SIZE)
91 size -= PAGE_SIZE;
92 else
93 size = 0;
94 }
95
96 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
97 return 0;
98
99} 101}
100 102
101/* ioctl structure */ 103static char *dlfb_vidreg_unlock(char *buf)
102struct dloarea { 104{
103 int x, y; 105 return dlfb_set_register(buf, 0xFF, 0xFF);
104 int w, h; 106}
105 int x2, y2;
106};
107 107
108/* 108/*
109static struct usb_device_id id_table [] = { 109 * On/Off for driving the DisplayLink framebuffer to the display
110 { USB_DEVICE(0x17e9, 0x023d) }, 110 */
111 { } 111static char *dlfb_enable_hvsync(char *buf, bool enable)
112}; 112{
113*/ 113 if (enable)
114 return dlfb_set_register(buf, 0x1F, 0x00);
115 else
116 return dlfb_set_register(buf, 0x1F, 0x01);
117}
114 118
115static struct usb_device_id id_table[] = { 119static char *dlfb_set_color_depth(char *buf, u8 selection)
116 {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, 120{
117 {}, 121 return dlfb_set_register(buf, 0x00, selection);
118}; 122}
119MODULE_DEVICE_TABLE(usb, id_table);
120 123
121static struct usb_driver dlfb_driver; 124static char *dlfb_set_base16bpp(char *wrptr, u32 base)
125{
126 /* the base pointer is 16 bits wide, 0x20 is hi byte. */
127 wrptr = dlfb_set_register(wrptr, 0x20, base >> 16);
128 wrptr = dlfb_set_register(wrptr, 0x21, base >> 8);
129 return dlfb_set_register(wrptr, 0x22, base);
130}
122 131
123// thanks to Henrik Bjerregaard Pedersen for this function 132/*
124static char *rle_compress16(uint16_t * src, char *dst, int rem) 133 * DisplayLink HW has separate 16bpp and 8bpp framebuffers.
134 * In 24bpp modes, the low 323 RGB bits go in the 8bpp framebuffer
135 */
136static char *dlfb_set_base8bpp(char *wrptr, u32 base)
125{ 137{
138 wrptr = dlfb_set_register(wrptr, 0x26, base >> 16);
139 wrptr = dlfb_set_register(wrptr, 0x27, base >> 8);
140 return dlfb_set_register(wrptr, 0x28, base);
141}
126 142
127 int rl; 143static char *dlfb_set_register_16(char *wrptr, u8 reg, u16 value)
128 uint16_t pix0; 144{
129 char *end_if_raw = dst + 6 + 2 * rem; 145 wrptr = dlfb_set_register(wrptr, reg, value >> 8);
146 return dlfb_set_register(wrptr, reg+1, value);
147}
130 148
131 dst += 6; // header will be filled in if RLE is worth it 149/*
150 * This is kind of weird because the controller takes some
151 * register values in a different byte order than other registers.
152 */
153static char *dlfb_set_register_16be(char *wrptr, u8 reg, u16 value)
154{
155 wrptr = dlfb_set_register(wrptr, reg, value);
156 return dlfb_set_register(wrptr, reg+1, value >> 8);
157}
132 158
133 while (rem && dst < end_if_raw) { 159/*
134 char *start = (char *)src; 160 * LFSR is linear feedback shift register. The reason we have this is
161 * because the display controller needs to minimize the clock depth of
162 * various counters used in the display path. So this code reverses the
163 * provided value into the lfsr16 value by counting backwards to get
164 * the value that needs to be set in the hardware comparator to get the
165 * same actual count. This makes sense once you read above a couple of
166 * times and think about it from a hardware perspective.
167 */
168static u16 dlfb_lfsr16(u16 actual_count)
169{
170 u32 lv = 0xFFFF; /* This is the lfsr value that the hw starts with */
135 171
136 pix0 = *src++; 172 while (actual_count--) {
137 rl = 1; 173 lv = ((lv << 1) |
138 rem--; 174 (((lv >> 15) ^ (lv >> 4) ^ (lv >> 2) ^ (lv >> 1)) & 1))
139 while (rem && *src == pix0) 175 & 0xFFFF;
140 rem--, rl++, src++;
141 *dst++ = rl;
142 *dst++ = start[1];
143 *dst++ = start[0];
144 } 176 }
145 177
146 return dst; 178 return (u16) lv;
147} 179}
148 180
149/* 181/*
150Thanks to Henrik Bjerregaard Pedersen for rle implementation and code refactoring. 182 * This does LFSR conversion on the value that is to be written.
151Next step is huffman compression. 183 * See LFSR explanation above for more detail.
152*/ 184 */
153 185static char *dlfb_set_register_lfsr16(char *wrptr, u8 reg, u16 value)
154static int
155image_blit(struct dlfb_data *dev_info, int x, int y, int width, int height,
156 char *data)
157{ 186{
187 return dlfb_set_register_16(wrptr, reg, dlfb_lfsr16(value));
188}
158 189
159 int i, j, base; 190/*
160 int rem = width; 191 * This takes a standard fbdev screeninfo struct and all of its monitor mode
161 int ret; 192 * details and converts them into the DisplayLink equivalent register commands.
162 193 */
163 int firstdiff, thistime; 194static char *dlfb_set_vid_cmds(char *wrptr, struct fb_var_screeninfo *var)
164 195{
165 char *bufptr; 196 u16 xds, yds;
166 197 u16 xde, yde;
167 if (x + width > dev_info->info->var.xres) 198 u16 yec;
168 return -EINVAL;
169
170 if (y + height > dev_info->info->var.yres)
171 return -EINVAL;
172 199
173 mutex_lock(&dev_info->bulk_mutex); 200 /* x display start */
201 xds = var->left_margin + var->hsync_len;
202 wrptr = dlfb_set_register_lfsr16(wrptr, 0x01, xds);
203 /* x display end */
204 xde = xds + var->xres;
205 wrptr = dlfb_set_register_lfsr16(wrptr, 0x03, xde);
174 206
175 base = 207 /* y display start */
176 dev_info->base16 + ((dev_info->info->var.xres * 2 * y) + (x * 2)); 208 yds = var->upper_margin + var->vsync_len;
209 wrptr = dlfb_set_register_lfsr16(wrptr, 0x05, yds);
210 /* y display end */
211 yde = yds + var->yres;
212 wrptr = dlfb_set_register_lfsr16(wrptr, 0x07, yde);
177 213
178 data += (dev_info->info->var.xres * 2 * y) + (x * 2); 214 /* x end count is active + blanking - 1 */
215 wrptr = dlfb_set_register_lfsr16(wrptr, 0x09,
216 xde + var->right_margin - 1);
179 217
180 /* printk("IMAGE_BLIT\n"); */ 218 /* libdlo hardcodes hsync start to 1 */
219 wrptr = dlfb_set_register_lfsr16(wrptr, 0x0B, 1);
181 220
182 bufptr = dev_info->buf; 221 /* hsync end is width of sync pulse + 1 */
222 wrptr = dlfb_set_register_lfsr16(wrptr, 0x0D, var->hsync_len + 1);
183 223
184 for (i = y; i < y + height; i++) { 224 /* hpixels is active pixels */
225 wrptr = dlfb_set_register_16(wrptr, 0x0F, var->xres);
185 226
186 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 227 /* yendcount is vertical active + vertical blanking */
187 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 228 yec = var->yres + var->upper_margin + var->lower_margin +
188 bufptr = dev_info->buf; 229 var->vsync_len;
189 } 230 wrptr = dlfb_set_register_lfsr16(wrptr, 0x11, yec);
190 231
191 rem = width; 232 /* libdlo hardcodes vsync start to 0 */
233 wrptr = dlfb_set_register_lfsr16(wrptr, 0x13, 0);
192 234
193 /* printk("WRITING LINE %d\n", i); */ 235 /* vsync end is width of vsync pulse */
236 wrptr = dlfb_set_register_lfsr16(wrptr, 0x15, var->vsync_len);
194 237
195 while (rem) { 238 /* vpixels is active pixels */
239 wrptr = dlfb_set_register_16(wrptr, 0x17, var->yres);
196 240
197 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 241 /* convert picoseconds to 5kHz multiple for pclk5k = x * 1E12/5k */
198 ret = 242 wrptr = dlfb_set_register_16be(wrptr, 0x1B,
199 dlfb_bulk_msg(dev_info, 243 200*1000*1000/var->pixclock);
200 bufptr - dev_info->buf);
201 bufptr = dev_info->buf;
202 }
203 // number of pixels to consider this time
204 thistime = rem;
205 if (thistime > 255)
206 thistime = 255;
207
208 // find position of first pixel that has changed
209 firstdiff = -1;
210 for (j = 0; j < thistime * 2; j++) {
211 if (dev_info->backing_buffer
212 [base - dev_info->base16 + j] != data[j]) {
213 firstdiff = j / 2;
214 break;
215 }
216 }
217 244
218 if (firstdiff >= 0) { 245 return wrptr;
219 char *end_of_rle; 246}
220
221 end_of_rle =
222 rle_compress16((uint16_t *) (data +
223 firstdiff * 2),
224 bufptr,
225 thistime - firstdiff);
226
227 if (end_of_rle <
228 bufptr + 6 + 2 * (thistime - firstdiff)) {
229 bufptr[0] = 0xAF;
230 bufptr[1] = 0x69;
231
232 bufptr[2] =
233 (char)((base +
234 firstdiff * 2) >> 16);
235 bufptr[3] =
236 (char)((base + firstdiff * 2) >> 8);
237 bufptr[4] =
238 (char)(base + firstdiff * 2);
239 bufptr[5] = thistime - firstdiff;
240
241 bufptr = end_of_rle;
242
243 } else {
244 // fallback to raw (or some other encoding?)
245 *bufptr++ = 0xAF;
246 *bufptr++ = 0x68;
247
248 *bufptr++ =
249 (char)((base +
250 firstdiff * 2) >> 16);
251 *bufptr++ =
252 (char)((base + firstdiff * 2) >> 8);
253 *bufptr++ =
254 (char)(base + firstdiff * 2);
255 *bufptr++ = thistime - firstdiff;
256 // PUT COMPRESSION HERE
257 for (j = firstdiff * 2;
258 j < thistime * 2; j += 2) {
259 *bufptr++ = data[j + 1];
260 *bufptr++ = data[j];
261 }
262 }
263 }
264 247
265 base += thistime * 2; 248/*
266 data += thistime * 2; 249 * This takes a standard fbdev screeninfo struct that was fetched or prepared
267 rem -= thistime; 250 * and then generates the appropriate command sequence that then drives the
268 } 251 * display controller.
252 */
253static int dlfb_set_video_mode(struct dlfb_data *dev,
254 struct fb_var_screeninfo *var)
255{
256 char *buf;
257 char *wrptr;
258 int retval = 0;
259 int writesize;
260 struct urb *urb;
269 261
270 memcpy(dev_info->backing_buffer + (base - dev_info->base16) - 262 if (!atomic_read(&dev->usb_active))
271 (width * 2), data - (width * 2), width * 2); 263 return -EPERM;
272 264
273 base += (dev_info->info->var.xres * 2) - (width * 2); 265 urb = dlfb_get_urb(dev);
274 data += (dev_info->info->var.xres * 2) - (width * 2); 266 if (!urb)
267 return -ENOMEM;
268 buf = (char *) urb->transfer_buffer;
275 269
276 } 270 /*
271 * This first section has to do with setting the base address on the
272 * controller * associated with the display. There are 2 base
273 * pointers, currently, we only * use the 16 bpp segment.
274 */
275 wrptr = dlfb_vidreg_lock(buf);
276 wrptr = dlfb_set_color_depth(wrptr, 0x00);
277 /* set base for 16bpp segment to 0 */
278 wrptr = dlfb_set_base16bpp(wrptr, 0);
279 /* set base for 8bpp segment to end of fb */
280 wrptr = dlfb_set_base8bpp(wrptr, dev->info->fix.smem_len);
277 281
278 if (bufptr > dev_info->buf) { 282 wrptr = dlfb_set_vid_cmds(wrptr, var);
279 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 283 wrptr = dlfb_enable_hvsync(wrptr, true);
280 } 284 wrptr = dlfb_vidreg_unlock(wrptr);
281 285
282 mutex_unlock(&dev_info->bulk_mutex); 286 writesize = wrptr - buf;
283 287
284 return base; 288 retval = dlfb_submit_urb(dev, urb, writesize);
285 289
290 return retval;
286} 291}
287 292
288static int 293static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
289draw_rect(struct dlfb_data *dev_info, int x, int y, int width, int height,
290 unsigned char red, unsigned char green, unsigned char blue)
291{ 294{
295 unsigned long start = vma->vm_start;
296 unsigned long size = vma->vm_end - vma->vm_start;
297 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
298 unsigned long page, pos;
299 struct dlfb_data *dev = info->par;
292 300
293 int i, j, base; 301 dl_notice("MMAP: %lu %u\n", offset + size, info->fix.smem_len);
294 int ret;
295 unsigned short col =
296 (((((red) & 0xF8) | ((green) >> 5)) & 0xFF) << 8) +
297 (((((green) & 0x1C) << 3) | ((blue) >> 3)) & 0xFF);
298 int rem = width;
299
300 char *bufptr;
301 302
302 if (x + width > dev_info->info->var.xres) 303 if (offset + size > info->fix.smem_len)
303 return -EINVAL; 304 return -EINVAL;
304 305
305 if (y + height > dev_info->info->var.yres) 306 pos = (unsigned long)info->fix.smem_start + offset;
306 return -EINVAL;
307 307
308 mutex_lock(&dev_info->bulk_mutex); 308 while (size > 0) {
309 page = vmalloc_to_pfn((void *)pos);
310 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
311 return -EAGAIN;
309 312
310 base = dev_info->base16 + (dev_info->info->var.xres * 2 * y) + (x * 2); 313 start += PAGE_SIZE;
314 pos += PAGE_SIZE;
315 if (size > PAGE_SIZE)
316 size -= PAGE_SIZE;
317 else
318 size = 0;
319 }
311 320
312 bufptr = dev_info->buf; 321 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
322 return 0;
313 323
314 for (i = y; i < y + height; i++) { 324}
315 325
316 for (j = 0; j < width * 2; j += 2) { 326/*
317 dev_info->backing_buffer[base - dev_info->base16 + j] = 327 * Trims identical data from front and back of line
318 (char)(col >> 8); 328 * Sets new front buffer address and width
319 dev_info->backing_buffer[base - dev_info->base16 + j + 329 * And returns byte count of identical pixels
320 1] = (char)(col); 330 * Assumes CPU natural alignment (unsigned long)
321 } 331 * for back and front buffer ptrs and width
322 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 332 */
323 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 333static int dlfb_trim_hline(const u8 *bback, const u8 **bfront, int *width_bytes)
324 bufptr = dev_info->buf; 334{
335 int j, k;
336 const unsigned long *back = (const unsigned long *) bback;
337 const unsigned long *front = (const unsigned long *) *bfront;
338 const int width = *width_bytes / sizeof(unsigned long);
339 int identical = width;
340 int start = width;
341 int end = width;
342
343 prefetch((void *) front);
344 prefetch((void *) back);
345
346 for (j = 0; j < width; j++) {
347 if (back[j] != front[j]) {
348 start = j;
349 break;
325 } 350 }
351 }
326 352
327 rem = width; 353 for (k = width - 1; k > j; k--) {
328 354 if (back[k] != front[k]) {
329 while (rem) { 355 end = k+1;
330 356 break;
331 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) {
332 ret =
333 dlfb_bulk_msg(dev_info,
334 bufptr - dev_info->buf);
335 bufptr = dev_info->buf;
336 }
337
338 *bufptr++ = 0xAF;
339 *bufptr++ = 0x69;
340
341 *bufptr++ = (char)(base >> 16);
342 *bufptr++ = (char)(base >> 8);
343 *bufptr++ = (char)(base);
344
345 if (rem > 255) {
346 *bufptr++ = 255;
347 *bufptr++ = 255;
348 rem -= 255;
349 base += 255 * 2;
350 } else {
351 *bufptr++ = rem;
352 *bufptr++ = rem;
353 base += rem * 2;
354 rem = 0;
355 }
356
357 *bufptr++ = (char)(col >> 8);
358 *bufptr++ = (char)(col);
359
360 } 357 }
361
362 base += (dev_info->info->var.xres * 2) - (width * 2);
363
364 } 358 }
365 359
366 if (bufptr > dev_info->buf) 360 identical = start + (width - end);
367 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 361 *bfront = (u8 *) &front[start];
362 *width_bytes = (end - start) * sizeof(unsigned long);
368 363
369 mutex_unlock(&dev_info->bulk_mutex); 364 return identical * sizeof(unsigned long);
370
371 return 1;
372} 365}
373 366
374static void swapfb(struct dlfb_data *dev_info) 367/*
368Render a command stream for an encoded horizontal line segment of pixels.
369
370A command buffer holds several commands.
371It always begins with a fresh command header
372(the protocol doesn't require this, but we enforce it to allow
373multiple buffers to be potentially encoded and sent in parallel).
374A single command encodes one contiguous horizontal line of pixels
375
376The function relies on the client to do all allocation, so that
377rendering can be done directly to output buffers (e.g. USB URBs).
378The function fills the supplied command buffer, providing information
379on where it left off, so the client may call in again with additional
380buffers if the line will take several buffers to complete.
381
382A single command can transmit a maximum of 256 pixels,
383regardless of the compression ratio (protocol design limit).
384To the hardware, 0 for a size byte means 256
385
386Rather than 256 pixel commands which are either rl or raw encoded,
387the rlx command simply assumes alternating raw and rl spans within one cmd.
388This has a slightly larger header overhead, but produces more even results.
389It also processes all data (read and write) in a single pass.
390Performance benchmarks of common cases show it having just slightly better
391compression than 256 pixel raw -or- rle commands, with similar CPU consumpion.
392But for very rl friendly data, will compress not quite as well.
393*/
394static void dlfb_compress_hline(
395 const uint16_t **pixel_start_ptr,
396 const uint16_t *const pixel_end,
397 uint32_t *device_address_ptr,
398 uint8_t **command_buffer_ptr,
399 const uint8_t *const cmd_buffer_end)
375{ 400{
401 const uint16_t *pixel = *pixel_start_ptr;
402 uint32_t dev_addr = *device_address_ptr;
403 uint8_t *cmd = *command_buffer_ptr;
404 const int bpp = 2;
405
406 while ((pixel_end > pixel) &&
407 (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) {
408 uint8_t *raw_pixels_count_byte = 0;
409 uint8_t *cmd_pixels_count_byte = 0;
410 const uint16_t *raw_pixel_start = 0;
411 const uint16_t *cmd_pixel_start, *cmd_pixel_end = 0;
412 const uint32_t be_dev_addr = cpu_to_be32(dev_addr);
413
414 prefetchw((void *) cmd); /* pull in one cache line at least */
415
416 *cmd++ = 0xAF;
417 *cmd++ = 0x6B;
418 *cmd++ = (uint8_t) ((be_dev_addr >> 8) & 0xFF);
419 *cmd++ = (uint8_t) ((be_dev_addr >> 16) & 0xFF);
420 *cmd++ = (uint8_t) ((be_dev_addr >> 24) & 0xFF);
421
422 cmd_pixels_count_byte = cmd++; /* we'll know this later */
423 cmd_pixel_start = pixel;
424
425 raw_pixels_count_byte = cmd++; /* we'll know this later */
426 raw_pixel_start = pixel;
427
428 cmd_pixel_end = pixel + min(MAX_CMD_PIXELS + 1,
429 min((int)(pixel_end - pixel),
430 (int)(cmd_buffer_end - cmd) / bpp));
431
432 prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
433
434 while (pixel < cmd_pixel_end) {
435 const uint16_t * const repeating_pixel = pixel;
436
437 *(uint16_t *)cmd = cpu_to_be16p(pixel);
438 cmd += 2;
439 pixel++;
440
441 if (unlikely((pixel < cmd_pixel_end) &&
442 (*pixel == *repeating_pixel))) {
443 /* go back and fill in raw pixel count */
444 *raw_pixels_count_byte = ((repeating_pixel -
445 raw_pixel_start) + 1) & 0xFF;
446
447 while ((pixel < cmd_pixel_end)
448 && (*pixel == *repeating_pixel)) {
449 pixel++;
450 }
376 451
377 int tmpbase; 452 /* immediately after raw data is repeat byte */
378 char *bufptr; 453 *cmd++ = ((pixel - repeating_pixel) - 1) & 0xFF;
379
380 mutex_lock(&dev_info->bulk_mutex);
381
382 tmpbase = dev_info->base16;
383
384 dev_info->base16 = dev_info->base16d;
385 dev_info->base16d = tmpbase;
386 454
387 bufptr = dev_info->buf; 455 /* Then start another raw pixel span */
456 raw_pixel_start = pixel;
457 raw_pixels_count_byte = cmd++;
458 }
459 }
388 460
389 bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); 461 if (pixel > raw_pixel_start) {
462 /* finalize last RAW span */
463 *raw_pixels_count_byte = (pixel-raw_pixel_start) & 0xFF;
464 }
390 465
391 // set addresses 466 *cmd_pixels_count_byte = (pixel - cmd_pixel_start) & 0xFF;
392 bufptr = 467 dev_addr += (pixel - cmd_pixel_start) * bpp;
393 dlfb_set_register(bufptr, 0x20, (char)(dev_info->base16 >> 16)); 468 }
394 bufptr = dlfb_set_register(bufptr, 0x21, (char)(dev_info->base16 >> 8));
395 bufptr = dlfb_set_register(bufptr, 0x22, (char)(dev_info->base16));
396 469
397 bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); 470 if (cmd_buffer_end <= MIN_RLX_CMD_BYTES + cmd) {
471 /* Fill leftover bytes with no-ops */
472 if (cmd_buffer_end > cmd)
473 memset(cmd, 0xAF, cmd_buffer_end - cmd);
474 cmd = (uint8_t *) cmd_buffer_end;
475 }
398 476
399 dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 477 *command_buffer_ptr = cmd;
478 *pixel_start_ptr = pixel;
479 *device_address_ptr = dev_addr;
400 480
401 mutex_unlock(&dev_info->bulk_mutex); 481 return;
402} 482}
403 483
404static int copyfb(struct dlfb_data *dev_info) 484/*
485 * There are 3 copies of every pixel: The front buffer that the fbdev
486 * client renders to, the actual framebuffer across the USB bus in hardware
487 * (that we can only write to, slowly, and can never read), and (optionally)
488 * our shadow copy that tracks what's been sent to that hardware buffer.
489 */
490static void dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
491 const char *front, char **urb_buf_ptr,
492 u32 byte_offset, u32 byte_width,
493 int *ident_ptr, int *sent_ptr)
405{ 494{
406 int base; 495 const u8 *line_start, *line_end, *next_pixel;
407 int source; 496 u32 dev_addr = dev->base16 + byte_offset;
408 int rem; 497 struct urb *urb = *urb_ptr;
409 int i, ret; 498 u8 *cmd = *urb_buf_ptr;
410 499 u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
411 char *bufptr; 500
412 501 line_start = (u8 *) (front + byte_offset);
413 base = dev_info->base16d; 502 next_pixel = line_start;
414 503 line_end = next_pixel + byte_width;
415 mutex_lock(&dev_info->bulk_mutex); 504
416 505 if (dev->backing_buffer) {
417 source = dev_info->base16; 506 int offset;
418 507 const u8 *back_start = (u8 *) (dev->backing_buffer
419 bufptr = dev_info->buf; 508 + byte_offset);
420 509
421 for (i = 0; i < dev_info->info->var.yres; i++) { 510 *ident_ptr += dlfb_trim_hline(back_start, &next_pixel,
422 511 &byte_width);
423 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 512
424 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 513 offset = next_pixel - line_start;
425 bufptr = dev_info->buf; 514 line_end = next_pixel + byte_width;
426 } 515 dev_addr += offset;
427 516 back_start += offset;
428 rem = dev_info->info->var.xres; 517 line_start += offset;
429 518
430 while (rem) { 519 memcpy((char *)back_start, (char *) line_start,
431 520 byte_width);
432 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 521 }
433 ret =
434 dlfb_bulk_msg(dev_info,
435 bufptr - dev_info->buf);
436 bufptr = dev_info->buf;
437
438 }
439
440 *bufptr++ = 0xAF;
441 *bufptr++ = 0x6A;
442
443 *bufptr++ = (char)(base >> 16);
444 *bufptr++ = (char)(base >> 8);
445 *bufptr++ = (char)(base);
446
447 if (rem > 255) {
448 *bufptr++ = 255;
449 *bufptr++ = (char)(source >> 16);
450 *bufptr++ = (char)(source >> 8);
451 *bufptr++ = (char)(source);
452
453 rem -= 255;
454 base += 255 * 2;
455 source += 255 * 2;
456
457 } else {
458 *bufptr++ = rem;
459 *bufptr++ = (char)(source >> 16);
460 *bufptr++ = (char)(source >> 8);
461 *bufptr++ = (char)(source);
462 522
463 base += rem * 2; 523 while (next_pixel < line_end) {
464 source += rem * 2; 524
465 rem = 0; 525 dlfb_compress_hline((const uint16_t **) &next_pixel,
466 } 526 (const uint16_t *) line_end, &dev_addr,
527 (u8 **) &cmd, (u8 *) cmd_end);
528
529 if (cmd >= cmd_end) {
530 int len = cmd - (u8 *) urb->transfer_buffer;
531 if (dlfb_submit_urb(dev, urb, len))
532 return; /* lost pixels is set */
533 *sent_ptr += len;
534 urb = dlfb_get_urb(dev);
535 if (!urb)
536 return; /* lost_pixels is set */
537 *urb_ptr = urb;
538 cmd = urb->transfer_buffer;
539 cmd_end = &cmd[urb->transfer_buffer_length];
467 } 540 }
468 } 541 }
469 542
470 if (bufptr > dev_info->buf) 543 *urb_buf_ptr = cmd;
471 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
472
473 mutex_unlock(&dev_info->bulk_mutex);
474
475 return 1;
476
477} 544}
478 545
479static int 546int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
480copyarea(struct dlfb_data *dev_info, int dx, int dy, int sx, int sy, 547 int width, int height, char *data)
481 int width, int height)
482{ 548{
483 int base;
484 int source;
485 int rem;
486 int i, ret; 549 int i, ret;
487 550 char *cmd;
488 char *bufptr; 551 cycles_t start_cycles, end_cycles;
489 552 int bytes_sent = 0;
490 if (dx + width > dev_info->info->var.xres) 553 int bytes_identical = 0;
554 struct urb *urb;
555 int aligned_x;
556
557 start_cycles = get_cycles();
558
559 aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long));
560 width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long));
561 x = aligned_x;
562
563 if ((width <= 0) ||
564 (x + width > dev->info->var.xres) ||
565 (y + height > dev->info->var.yres))
491 return -EINVAL; 566 return -EINVAL;
492 567
493 if (dy + height > dev_info->info->var.yres) 568 if (!atomic_read(&dev->usb_active))
494 return -EINVAL; 569 return 0;
495
496 mutex_lock(&dev_info->bulk_mutex);
497 570
498 base = 571 urb = dlfb_get_urb(dev);
499 dev_info->base16 + (dev_info->info->var.xres * 2 * dy) + (dx * 2); 572 if (!urb)
500 source = (dev_info->info->var.xres * 2 * sy) + (sx * 2); 573 return 0;
574 cmd = urb->transfer_buffer;
501 575
502 bufptr = dev_info->buf; 576 for (i = y; i < y + height ; i++) {
577 const int line_offset = dev->info->fix.line_length * i;
578 const int byte_offset = line_offset + (x * BPP);
503 579
504 for (i = sy; i < sy + height; i++) { 580 dlfb_render_hline(dev, &urb, (char *) dev->info->fix.smem_start,
581 &cmd, byte_offset, width * BPP,
582 &bytes_identical, &bytes_sent);
583 }
505 584
506 memcpy(dev_info->backing_buffer + base - dev_info->base16, 585 if (cmd > (char *) urb->transfer_buffer) {
507 dev_info->backing_buffer + source, width * 2); 586 /* Send partial buffer remaining before exiting */
587 int len = cmd - (char *) urb->transfer_buffer;
588 ret = dlfb_submit_urb(dev, urb, len);
589 bytes_sent += len;
590 } else
591 dlfb_urb_completion(urb);
592
593 atomic_add(bytes_sent, &dev->bytes_sent);
594 atomic_add(bytes_identical, &dev->bytes_identical);
595 atomic_add(width*height*2, &dev->bytes_rendered);
596 end_cycles = get_cycles();
597 atomic_add(((unsigned int) ((end_cycles - start_cycles)
598 >> 10)), /* Kcycles */
599 &dev->cpu_kcycles_used);
508 600
509 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 601 return 0;
510 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 602}
511 bufptr = dev_info->buf;
512 }
513
514 rem = width;
515 603
516 while (rem) { 604/* hardware has native COPY command (see libdlo), but not worth it for fbcon */
605static void dlfb_ops_copyarea(struct fb_info *info,
606 const struct fb_copyarea *area)
607{
517 608
518 if (dev_info->bufend - bufptr < BUF_HIGH_WATER_MARK) { 609 struct dlfb_data *dev = info->par;
519 ret =
520 dlfb_bulk_msg(dev_info,
521 bufptr - dev_info->buf);
522 bufptr = dev_info->buf;
523 }
524 610
525 *bufptr++ = 0xAF; 611#if defined CONFIG_FB_SYS_COPYAREA || defined CONFIG_FB_SYS_COPYAREA_MODULE
526 *bufptr++ = 0x6A;
527 612
528 *bufptr++ = (char)(base >> 16); 613 sys_copyarea(info, area);
529 *bufptr++ = (char)(base >> 8);
530 *bufptr++ = (char)(base);
531 614
532 if (rem > 255) { 615 dlfb_handle_damage(dev, area->dx, area->dy,
533 *bufptr++ = 255; 616 area->width, area->height, info->screen_base);
534 *bufptr++ = (char)(source >> 16); 617#endif
535 *bufptr++ = (char)(source >> 8); 618 atomic_inc(&dev->copy_count);
536 *bufptr++ = (char)(source);
537 619
538 rem -= 255; 620}
539 base += 255 * 2;
540 source += 255 * 2;
541 621
542 } else { 622static void dlfb_ops_imageblit(struct fb_info *info,
543 *bufptr++ = rem; 623 const struct fb_image *image)
544 *bufptr++ = (char)(source >> 16); 624{
545 *bufptr++ = (char)(source >> 8); 625 struct dlfb_data *dev = info->par;
546 *bufptr++ = (char)(source);
547 626
548 base += rem * 2; 627#if defined CONFIG_FB_SYS_IMAGEBLIT || defined CONFIG_FB_SYS_IMAGEBLIT_MODULE
549 source += rem * 2;
550 rem = 0;
551 }
552 }
553 628
554 base += (dev_info->info->var.xres * 2) - (width * 2); 629 sys_imageblit(info, image);
555 source += (dev_info->info->var.xres * 2) - (width * 2);
556 }
557 630
558 if (bufptr > dev_info->buf) 631 dlfb_handle_damage(dev, image->dx, image->dy,
559 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 632 image->width, image->height, info->screen_base);
560 633
561 mutex_unlock(&dev_info->bulk_mutex); 634#endif
562 635
563 return 1; 636 atomic_inc(&dev->blit_count);
564} 637}
565 638
566static void dlfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 639static void dlfb_ops_fillrect(struct fb_info *info,
640 const struct fb_fillrect *rect)
567{ 641{
568
569 struct dlfb_data *dev = info->par; 642 struct dlfb_data *dev = info->par;
570 643
571 copyarea(dev, area->dx, area->dy, area->sx, area->sy, area->width, 644#if defined CONFIG_FB_SYS_FILLRECT || defined CONFIG_FB_SYS_FILLRECT_MODULE
572 area->height);
573 645
574 /* printk("COPY AREA %d %d %d %d %d %d !!!\n", area->dx, area->dy, area->sx, area->sy, area->width, area->height); */ 646 sys_fillrect(info, rect);
575 647
576} 648 dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width,
649 rect->height, info->screen_base);
650#endif
577 651
578static void dlfb_imageblit(struct fb_info *info, const struct fb_image *image) 652 atomic_inc(&dev->fill_count);
579{
580 653
581 int ret;
582 struct dlfb_data *dev = info->par;
583 /* printk("IMAGE BLIT (1) %d %d %d %d DEPTH %d {%p}!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev); */
584 cfb_imageblit(info, image);
585 ret =
586 image_blit(dev, image->dx, image->dy, image->width, image->height,
587 info->screen_base);
588 /* printk("IMAGE BLIT (2) %d %d %d %d DEPTH %d {%p} %d!!!\n", image->dx, image->dy, image->width, image->height, image->depth, dev->udev, ret); */
589} 654}
590 655
591static void dlfb_fillrect(struct fb_info *info, 656static void dlfb_get_edid(struct dlfb_data *dev)
592 const struct fb_fillrect *region)
593{ 657{
594 658 int i;
595 unsigned char red, green, blue; 659 int ret;
596 struct dlfb_data *dev = info->par; 660 char rbuf[2];
597 661
598 memcpy(&red, &region->color, 1); 662 for (i = 0; i < sizeof(dev->edid); i++) {
599 memcpy(&green, &region->color + 1, 1); 663 ret = usb_control_msg(dev->udev,
600 memcpy(&blue, &region->color + 2, 1); 664 usb_rcvctrlpipe(dev->udev, 0), (0x02),
601 draw_rect(dev, region->dx, region->dy, region->width, region->height, 665 (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
602 red, green, blue); 666 0);
603 /* printk("FILL RECT %d %d !!!\n", region->dx, region->dy); */ 667 dev->edid[i] = rbuf[1];
604 668 }
605} 669}
606 670
607static int dlfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 671static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
672 unsigned long arg)
608{ 673{
609 674
610 struct dlfb_data *dev_info = info->par; 675 struct dlfb_data *dev = info->par;
611 struct dloarea *area = NULL; 676 struct dloarea *area = NULL;
612 677
613 if (cmd == 0xAD) { 678 if (!atomic_read(&dev->usb_active))
679 return 0;
680
681 /* TODO: Update X server to get this from sysfs instead */
682 if (cmd == DLFB_IOCTL_RETURN_EDID) {
614 char *edid = (char *)arg; 683 char *edid = (char *)arg;
615 dlfb_edid(dev_info); 684 dlfb_get_edid(dev);
616 if (copy_to_user(edid, dev_info->edid, 128)) { 685 if (copy_to_user(edid, dev->edid, sizeof(dev->edid)))
617 return -EFAULT; 686 return -EFAULT;
618 }
619 return 0; 687 return 0;
620 } 688 }
621 689
622 if (cmd == 0xAA || cmd == 0xAB || cmd == 0xAC) { 690 /* TODO: Help propose a standard fb.h ioctl to report mmap damage */
691 if (cmd == DLFB_IOCTL_REPORT_DAMAGE) {
623 692
624 area = (struct dloarea *)arg; 693 area = (struct dloarea *)arg;
625 694
@@ -634,36 +703,20 @@ static int dlfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
634 703
635 if (area->y > info->var.yres) 704 if (area->y > info->var.yres)
636 area->y = info->var.yres; 705 area->y = info->var.yres;
637 }
638 706
639 if (cmd == 0xAA) { 707 atomic_set(&dev->use_defio, 0);
640 image_blit(dev_info, area->x, area->y, area->w, area->h, 708
709 dlfb_handle_damage(dev, area->x, area->y, area->w, area->h,
641 info->screen_base); 710 info->screen_base);
711 atomic_inc(&dev->damage_count);
642 } 712 }
643 if (cmd == 0xAC) {
644 copyfb(dev_info);
645 image_blit(dev_info, area->x, area->y, area->w, area->h,
646 info->screen_base);
647 swapfb(dev_info);
648 } else if (cmd == 0xAB) {
649
650 if (area->x2 < 0)
651 area->x2 = 0;
652
653 if (area->y2 < 0)
654 area->y2 = 0;
655 713
656 copyarea(dev_info,
657 area->x2, area->y2, area->x, area->y, area->w,
658 area->h);
659 }
660 return 0; 714 return 0;
661} 715}
662 716
663/* taken from vesafb */ 717/* taken from vesafb */
664
665static int 718static int
666dlfb_setcolreg(unsigned regno, unsigned red, unsigned green, 719dlfb_ops_setcolreg(unsigned regno, unsigned red, unsigned green,
667 unsigned blue, unsigned transp, struct fb_info *info) 720 unsigned blue, unsigned transp, struct fb_info *info)
668{ 721{
669 int err = 0; 722 int err = 0;
@@ -688,234 +741,698 @@ dlfb_setcolreg(unsigned regno, unsigned red, unsigned green,
688 return err; 741 return err;
689} 742}
690 743
691static int dlfb_release(struct fb_info *info, int user) 744/*
745 * It's common for several clients to have framebuffer open simultaneously.
746 * e.g. both fbcon and X. Makes things interesting.
747 */
748static int dlfb_ops_open(struct fb_info *info, int user)
749{
750 struct dlfb_data *dev = info->par;
751
752/* if (user == 0)
753 * We could special case kernel mode clients (fbcon) here
754 */
755
756 mutex_lock(&dev->fb_open_lock);
757
758 dev->fb_count++;
759
760#ifdef CONFIG_FB_DEFERRED_IO
761 if ((atomic_read(&dev->use_defio)) && (info->fbdefio == NULL)) {
762 /* enable defio */
763 info->fbdefio = &dlfb_defio;
764 fb_deferred_io_init(info);
765 }
766#endif
767
768 dl_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
769 info->node, user, info, dev->fb_count);
770
771 mutex_unlock(&dev->fb_open_lock);
772
773 return 0;
774}
775
776static int dlfb_ops_release(struct fb_info *info, int user)
777{
778 struct dlfb_data *dev = info->par;
779
780 mutex_lock(&dev->fb_open_lock);
781
782 dev->fb_count--;
783
784#ifdef CONFIG_FB_DEFERRED_IO
785 if ((dev->fb_count == 0) && (info->fbdefio)) {
786 fb_deferred_io_cleanup(info);
787 info->fbdefio = NULL;
788 info->fbops->fb_mmap = dlfb_ops_mmap;
789 }
790#endif
791
792 dl_notice("release /dev/fb%d user=%d count=%d\n",
793 info->node, user, dev->fb_count);
794
795 mutex_unlock(&dev->fb_open_lock);
796
797 return 0;
798}
799
800/*
801 * Called when all client interfaces to start transactions have been disabled,
802 * and all references to our device instance (dlfb_data) are released.
803 * Every transaction must have a reference, so we know are fully spun down
804 */
805static void dlfb_delete(struct kref *kref)
806{
807 struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
808
809 if (dev->backing_buffer)
810 vfree(dev->backing_buffer);
811
812 mutex_destroy(&dev->fb_open_lock);
813
814 kfree(dev);
815}
816
817/*
818 * Called by fbdev as last part of unregister_framebuffer() process
819 * No new clients can open connections. Deallocate everything fb_info.
820 */
821static void dlfb_ops_destroy(struct fb_info *info)
822{
823 struct dlfb_data *dev = info->par;
824
825 if (info->cmap.len != 0)
826 fb_dealloc_cmap(&info->cmap);
827 if (info->monspecs.modedb)
828 fb_destroy_modedb(info->monspecs.modedb);
829 if (info->screen_base)
830 vfree(info->screen_base);
831
832 fb_destroy_modelist(&info->modelist);
833
834 framebuffer_release(info);
835
836 /* ref taken before register_framebuffer() for dlfb_data clients */
837 kref_put(&dev->kref, dlfb_delete);
838}
839
840/*
841 * Check whether a video mode is supported by the DisplayLink chip
842 * We start from monitor's modes, so don't need to filter that here
843 */
844static int dlfb_is_valid_mode(struct fb_videomode *mode,
845 struct fb_info *info)
846{
847 struct dlfb_data *dev = info->par;
848
849 if (mode->xres * mode->yres > dev->sku_pixel_limit)
850 return 0;
851
852 return 1;
853}
854
855static void dlfb_var_color_format(struct fb_var_screeninfo *var)
856{
857 const struct fb_bitfield red = { 11, 5, 0 };
858 const struct fb_bitfield green = { 5, 6, 0 };
859 const struct fb_bitfield blue = { 0, 5, 0 };
860
861 var->bits_per_pixel = 16;
862 var->red = red;
863 var->green = green;
864 var->blue = blue;
865}
866
867static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
868 struct fb_info *info)
692{ 869{
693 struct dlfb_data *dev_info = info->par; 870 struct fb_videomode mode;
694 image_blit(dev_info, 0, 0, info->var.xres, info->var.yres, 871
695 info->screen_base); 872 /* TODO: support dynamically changing framebuffer size */
873 if ((var->xres * var->yres * 2) > info->fix.smem_len)
874 return -EINVAL;
875
876 /* set device-specific elements of var unrelated to mode */
877 dlfb_var_color_format(var);
878
879 fb_var_to_videomode(&mode, var);
880
881 if (!dlfb_is_valid_mode(&mode, info))
882 return -EINVAL;
883
696 return 0; 884 return 0;
697} 885}
698 886
699static int dlfb_blank(int blank_mode, struct fb_info *info) 887static int dlfb_ops_set_par(struct fb_info *info)
700{ 888{
701 struct dlfb_data *dev_info = info->par; 889 struct dlfb_data *dev = info->par;
702 char *bufptr = dev_info->buf; 890
891 dl_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres);
703 892
704 bufptr = dlfb_set_register(bufptr, 0xFF, 0x00); 893 return dlfb_set_video_mode(dev, &info->var);
894}
895
896static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
897{
898 struct dlfb_data *dev = info->par;
899 char *bufptr;
900 struct urb *urb;
901
902 urb = dlfb_get_urb(dev);
903 if (!urb)
904 return 0;
905 bufptr = (char *) urb->transfer_buffer;
906
907 /* overloading usb_active. UNBLANK can conflict with teardown */
908
909 bufptr = dlfb_vidreg_lock(bufptr);
705 if (blank_mode != FB_BLANK_UNBLANK) { 910 if (blank_mode != FB_BLANK_UNBLANK) {
706 bufptr = dlfb_set_register(bufptr, 0x1F, 0x01); 911 atomic_set(&dev->usb_active, 0);
912 bufptr = dlfb_enable_hvsync(bufptr, false);
707 } else { 913 } else {
708 bufptr = dlfb_set_register(bufptr, 0x1F, 0x00); 914 atomic_set(&dev->usb_active, 1);
915 bufptr = dlfb_enable_hvsync(bufptr, true);
709 } 916 }
710 bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF); 917 bufptr = dlfb_vidreg_unlock(bufptr);
711 918
712 dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 919 dlfb_submit_urb(dev, urb, bufptr - (char *) urb->transfer_buffer);
713 920
714 return 0; 921 return 0;
715} 922}
716 923
717static struct fb_ops dlfb_ops = { 924static struct fb_ops dlfb_ops = {
718 .fb_setcolreg = dlfb_setcolreg, 925 .owner = THIS_MODULE,
719 .fb_fillrect = dlfb_fillrect, 926 .fb_setcolreg = dlfb_ops_setcolreg,
720 .fb_copyarea = dlfb_copyarea, 927 .fb_fillrect = dlfb_ops_fillrect,
721 .fb_imageblit = dlfb_imageblit, 928 .fb_copyarea = dlfb_ops_copyarea,
722 .fb_mmap = dlfb_mmap, 929 .fb_imageblit = dlfb_ops_imageblit,
723 .fb_ioctl = dlfb_ioctl, 930 .fb_mmap = dlfb_ops_mmap,
724 .fb_release = dlfb_release, 931 .fb_ioctl = dlfb_ops_ioctl,
725 .fb_blank = dlfb_blank, 932 .fb_open = dlfb_ops_open,
933 .fb_release = dlfb_ops_release,
934 .fb_blank = dlfb_ops_blank,
935 .fb_check_var = dlfb_ops_check_var,
936 .fb_set_par = dlfb_ops_set_par,
726}; 937};
727 938
728static int 939/*
729dlfb_probe(struct usb_interface *interface, const struct usb_device_id *id) 940 * Calls dlfb_get_edid() to query the EDID of attached monitor via usb cmds
941 * Then parses EDID into three places used by various parts of fbdev:
942 * fb_var_screeninfo contains the timing of the monitor's preferred mode
943 * fb_info.monspecs is full parsed EDID info, including monspecs.modedb
944 * fb_info.modelist is a linked list of all monitor & VESA modes which work
945 *
946 * If EDID is not readable/valid, then modelist is all VESA modes,
947 * monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode
948 * Returns 0 if EDID parses successfully
949 */
950static int dlfb_parse_edid(struct dlfb_data *dev,
951 struct fb_var_screeninfo *var,
952 struct fb_info *info)
730{ 953{
731 struct dlfb_data *dev_info; 954 int i;
732 struct fb_info *info; 955 const struct fb_videomode *default_vmode = NULL;
956 int result = 0;
733 957
734 int ret; 958 fb_destroy_modelist(&info->modelist);
735 char rbuf[4]; 959 memset(&info->monspecs, 0, sizeof(info->monspecs));
736 960
737 dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); 961 dlfb_get_edid(dev);
738 if (dev_info == NULL) { 962 fb_edid_to_monspecs(dev->edid, &info->monspecs);
739 printk("cannot allocate dev_info structure.\n"); 963
740 return -ENOMEM; 964 if (info->monspecs.modedb_len > 0) {
965
966 for (i = 0; i < info->monspecs.modedb_len; i++) {
967 if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
968 fb_add_videomode(&info->monspecs.modedb[i],
969 &info->modelist);
970 }
971
972 default_vmode = fb_find_best_display(&info->monspecs,
973 &info->modelist);
974 } else {
975 struct fb_videomode fb_vmode = {0};
976
977 dl_err("Unable to get valid EDID from device/display\n");
978 result = 1;
979
980 /*
981 * Add the standard VESA modes to our modelist
982 * Since we don't have EDID, there may be modes that
983 * overspec monitor and/or are incorrect aspect ratio, etc.
984 * But at least the user has a chance to choose
985 */
986 for (i = 0; i < VESA_MODEDB_SIZE; i++) {
987 if (dlfb_is_valid_mode((struct fb_videomode *)
988 &vesa_modes[i], info))
989 fb_add_videomode(&vesa_modes[i],
990 &info->modelist);
991 }
992
993 /*
994 * default to resolution safe for projectors
995 * (since they are most common case without EDID)
996 */
997 fb_vmode.xres = 800;
998 fb_vmode.yres = 600;
999 fb_vmode.refresh = 60;
1000 default_vmode = fb_find_nearest_mode(&fb_vmode,
1001 &info->modelist);
741 } 1002 }
742 1003
743 mutex_init(&dev_info->bulk_mutex); 1004 fb_videomode_to_var(var, default_vmode);
1005 dlfb_var_color_format(var);
744 1006
745 dev_info->udev = usb_get_dev(interface_to_usbdev(interface)); 1007 return result;
746 dev_info->interface = interface; 1008}
747 1009
748 printk("DisplayLink device attached\n"); 1010static ssize_t metrics_bytes_rendered_show(struct device *fbdev,
1011 struct device_attribute *a, char *buf) {
1012 struct fb_info *fb_info = dev_get_drvdata(fbdev);
1013 struct dlfb_data *dev = fb_info->par;
1014 return snprintf(buf, PAGE_SIZE, "%u\n",
1015 atomic_read(&dev->bytes_rendered));
1016}
749 1017
750 /* add framebuffer info to usb interface */ 1018static ssize_t metrics_bytes_identical_show(struct device *fbdev,
751 usb_set_intfdata(interface, dev_info); 1019 struct device_attribute *a, char *buf) {
1020 struct fb_info *fb_info = dev_get_drvdata(fbdev);
1021 struct dlfb_data *dev = fb_info->par;
1022 return snprintf(buf, PAGE_SIZE, "%u\n",
1023 atomic_read(&dev->bytes_identical));
1024}
752 1025
753 dev_info->buf = kmalloc(BUF_SIZE, GFP_KERNEL); 1026static ssize_t metrics_bytes_sent_show(struct device *fbdev,
754 /* usb_buffer_alloc(dev_info->udev, BUF_SIZE , GFP_KERNEL, &dev_info->tx_urb->transfer_dma); */ 1027 struct device_attribute *a, char *buf) {
1028 struct fb_info *fb_info = dev_get_drvdata(fbdev);
1029 struct dlfb_data *dev = fb_info->par;
1030 return snprintf(buf, PAGE_SIZE, "%u\n",
1031 atomic_read(&dev->bytes_sent));
1032}
755 1033
756 if (dev_info->buf == NULL) { 1034static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev,
757 printk("unable to allocate memory for dlfb commands\n"); 1035 struct device_attribute *a, char *buf) {
758 goto out; 1036 struct fb_info *fb_info = dev_get_drvdata(fbdev);
759 } 1037 struct dlfb_data *dev = fb_info->par;
760 dev_info->bufend = dev_info->buf + BUF_SIZE; 1038 return snprintf(buf, PAGE_SIZE, "%u\n",
1039 atomic_read(&dev->cpu_kcycles_used));
1040}
761 1041
762 dev_info->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 1042static ssize_t metrics_misc_show(struct device *fbdev,
763 usb_fill_bulk_urb(dev_info->tx_urb, dev_info->udev, 1043 struct device_attribute *a, char *buf) {
764 usb_sndbulkpipe(dev_info->udev, 1), dev_info->buf, 0, 1044 struct fb_info *fb_info = dev_get_drvdata(fbdev);
765 dlfb_bulk_callback, dev_info); 1045 struct dlfb_data *dev = fb_info->par;
1046 return snprintf(buf, PAGE_SIZE,
1047 "Calls to\ndamage: %u\nblit: %u\n"
1048 "defio faults: %u\ncopy: %u\n"
1049 "fill: %u\n\n"
1050 "active framebuffer clients: %d\n"
1051 "urbs available %d(%d)\n"
1052 "Shadow framebuffer in use? %s\n"
1053 "Any lost pixels? %s\n",
1054 atomic_read(&dev->damage_count),
1055 atomic_read(&dev->blit_count),
1056 atomic_read(&dev->defio_fault_count),
1057 atomic_read(&dev->copy_count),
1058 atomic_read(&dev->fill_count),
1059 dev->fb_count,
1060 dev->urbs.available, dev->urbs.limit_sem.count,
1061 (dev->backing_buffer) ? "yes" : "no",
1062 atomic_read(&dev->lost_pixels) ? "yes" : "no");
1063}
766 1064
767 ret = 1065static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *a,
768 usb_control_msg(dev_info->udev, usb_rcvctrlpipe(dev_info->udev, 0), 1066 char *buf, loff_t off, size_t count) {
769 (0x06), (0x80 | (0x02 << 5)), 0, 0, rbuf, 4, 0); 1067 struct device *fbdev = container_of(kobj, struct device, kobj);
770 printk("ret control msg 0: %d %x%x%x%x\n", ret, rbuf[0], rbuf[1], 1068 struct fb_info *fb_info = dev_get_drvdata(fbdev);
771 rbuf[2], rbuf[3]); 1069 struct dlfb_data *dev = fb_info->par;
1070 char *edid = &dev->edid[0];
1071 const size_t size = sizeof(dev->edid);
772 1072
773 dlfb_edid(dev_info); 1073 if (dlfb_parse_edid(dev, &fb_info->var, fb_info))
1074 return 0;
774 1075
775 info = framebuffer_alloc(sizeof(u32) * 256, &dev_info->udev->dev); 1076 if (off >= size)
1077 return 0;
776 1078
777 if (!info) { 1079 if (off + count > size)
778 printk("non posso allocare il framebuffer displaylink"); 1080 count = size - off;
779 goto out; 1081 memcpy(buf, edid + off, count);
780 }
781 1082
782 fb_parse_edid(dev_info->edid, &info->var); 1083 return count;
1084}
783 1085
784 printk("EDID XRES %d YRES %d\n", info->var.xres, info->var.yres);
785 1086
786 if (dlfb_set_video_mode(dev_info, info->var.xres, info->var.yres) != 0) { 1087static ssize_t metrics_reset_store(struct device *fbdev,
787 info->var.xres = 1280; 1088 struct device_attribute *attr,
788 info->var.yres = 1024; 1089 const char *buf, size_t count)
789 if (dlfb_set_video_mode 1090{
790 (dev_info, info->var.xres, info->var.yres) != 0) { 1091 struct fb_info *fb_info = dev_get_drvdata(fbdev);
791 goto out; 1092 struct dlfb_data *dev = fb_info->par;
792 } 1093
1094 atomic_set(&dev->bytes_rendered, 0);
1095 atomic_set(&dev->bytes_identical, 0);
1096 atomic_set(&dev->bytes_sent, 0);
1097 atomic_set(&dev->cpu_kcycles_used, 0);
1098 atomic_set(&dev->blit_count, 0);
1099 atomic_set(&dev->copy_count, 0);
1100 atomic_set(&dev->fill_count, 0);
1101 atomic_set(&dev->defio_fault_count, 0);
1102 atomic_set(&dev->damage_count, 0);
1103
1104 return count;
1105}
1106
1107static ssize_t use_defio_show(struct device *fbdev,
1108 struct device_attribute *a, char *buf) {
1109 struct fb_info *fb_info = dev_get_drvdata(fbdev);
1110 struct dlfb_data *dev = fb_info->par;
1111 return snprintf(buf, PAGE_SIZE, "%d\n",
1112 atomic_read(&dev->use_defio));
1113}
1114
1115static ssize_t use_defio_store(struct device *fbdev,
1116 struct device_attribute *attr,
1117 const char *buf, size_t count)
1118{
1119 struct fb_info *fb_info = dev_get_drvdata(fbdev);
1120 struct dlfb_data *dev = fb_info->par;
1121
1122 if (count > 0) {
1123 if (buf[0] == '0')
1124 atomic_set(&dev->use_defio, 0);
1125 if (buf[0] == '1')
1126 atomic_set(&dev->use_defio, 1);
793 } 1127 }
1128 return count;
1129}
794 1130
795 printk("found valid mode...%d\n", info->var.pixclock); 1131static struct bin_attribute edid_attr = {
1132 .attr.name = "edid",
1133 .attr.mode = 0444,
1134 .size = 128,
1135 .read = edid_show,
1136};
796 1137
797 info->pseudo_palette = info->par; 1138static struct device_attribute fb_device_attrs[] = {
798 info->par = dev_info; 1139 __ATTR_RO(metrics_bytes_rendered),
1140 __ATTR_RO(metrics_bytes_identical),
1141 __ATTR_RO(metrics_bytes_sent),
1142 __ATTR_RO(metrics_cpu_kcycles_used),
1143 __ATTR_RO(metrics_misc),
1144 __ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
1145 __ATTR_RW(use_defio),
1146};
799 1147
800 dev_info->info = info; 1148#ifdef CONFIG_FB_DEFERRED_IO
1149static void dlfb_dpy_deferred_io(struct fb_info *info,
1150 struct list_head *pagelist)
1151{
1152 struct page *cur;
1153 struct fb_deferred_io *fbdefio = info->fbdefio;
1154 struct dlfb_data *dev = info->par;
1155 struct urb *urb;
1156 char *cmd;
1157 cycles_t start_cycles, end_cycles;
1158 int bytes_sent = 0;
1159 int bytes_identical = 0;
1160 int bytes_rendered = 0;
1161 int fault_count = 0;
1162
1163 if (!atomic_read(&dev->use_defio))
1164 return;
801 1165
802 info->flags = 1166 if (!atomic_read(&dev->usb_active))
803 FBINFO_DEFAULT | FBINFO_READS_FAST | FBINFO_HWACCEL_IMAGEBLIT | 1167 return;
804 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; 1168
805 info->fbops = &dlfb_ops; 1169 start_cycles = get_cycles();
806 info->screen_base = rvmalloc(dev_info->screen_size);
807 1170
808 if (info->screen_base == NULL) { 1171 urb = dlfb_get_urb(dev);
809 printk 1172 if (!urb)
810 ("cannot allocate framebuffer virtual memory of %d bytes\n", 1173 return;
811 dev_info->screen_size); 1174 cmd = urb->transfer_buffer;
812 goto out0; 1175
1176 /* walk the written page list and render each to device */
1177 list_for_each_entry(cur, &fbdefio->pagelist, lru) {
1178 dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
1179 &cmd, cur->index << PAGE_SHIFT,
1180 PAGE_SIZE, &bytes_identical, &bytes_sent);
1181 bytes_rendered += PAGE_SIZE;
1182 fault_count++;
813 } 1183 }
814 1184
815 printk("screen base allocated !!!\n"); 1185 if (cmd > (char *) urb->transfer_buffer) {
1186 /* Send partial buffer remaining before exiting */
1187 int len = cmd - (char *) urb->transfer_buffer;
1188 dlfb_submit_urb(dev, urb, len);
1189 bytes_sent += len;
1190 } else
1191 dlfb_urb_completion(urb);
1192
1193 atomic_add(fault_count, &dev->defio_fault_count);
1194 atomic_add(bytes_sent, &dev->bytes_sent);
1195 atomic_add(bytes_identical, &dev->bytes_identical);
1196 atomic_add(bytes_rendered, &dev->bytes_rendered);
1197 end_cycles = get_cycles();
1198 atomic_add(((unsigned int) ((end_cycles - start_cycles)
1199 >> 10)), /* Kcycles */
1200 &dev->cpu_kcycles_used);
1201}
816 1202
817 dev_info->backing_buffer = kzalloc(dev_info->screen_size, GFP_KERNEL); 1203static struct fb_deferred_io dlfb_defio = {
1204 .delay = 5,
1205 .deferred_io = dlfb_dpy_deferred_io,
1206};
818 1207
819 if (!dev_info->backing_buffer) 1208#endif
820 printk("non posso allocare il backing buffer\n");
821 1209
822 /* info->var = dev_info->si; */ 1210/*
1211 * This is necessary before we can communicate with the display controller.
1212 */
1213static int dlfb_select_std_channel(struct dlfb_data *dev)
1214{
1215 int ret;
1216 u8 set_def_chn[] = { 0x57, 0xCD, 0xDC, 0xA7,
1217 0x1C, 0x88, 0x5E, 0x15,
1218 0x60, 0xFE, 0xC6, 0x97,
1219 0x16, 0x3D, 0x47, 0xF2 };
1220
1221 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
1222 NR_USB_REQUEST_CHANNEL,
1223 (USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
1224 set_def_chn, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
1225 return ret;
1226}
823 1227
824 info->var.bits_per_pixel = 16;
825 info->var.activate = FB_ACTIVATE_TEST;
826 info->var.vmode = FB_VMODE_NONINTERLACED;
827 1228
828 info->var.red.offset = 11; 1229static int dlfb_usb_probe(struct usb_interface *interface,
829 info->var.red.length = 5; 1230 const struct usb_device_id *id)
830 info->var.red.msb_right = 0; 1231{
1232 struct usb_device *usbdev;
1233 struct dlfb_data *dev;
1234 struct fb_info *info;
1235 int videomemorysize;
1236 int i;
1237 unsigned char *videomemory;
1238 int retval = -ENOMEM;
1239 struct fb_var_screeninfo *var;
1240 int registered = 0;
1241 u16 *pix_framebuffer;
1242
1243 /* usb initialization */
1244
1245 usbdev = interface_to_usbdev(interface);
1246
1247 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1248 if (dev == NULL) {
1249 err("dlfb_usb_probe: failed alloc of dev struct\n");
1250 goto error;
1251 }
831 1252
832 info->var.green.offset = 5; 1253 /* we need to wait for both usb and fbdev to spin down on disconnect */
833 info->var.green.length = 6; 1254 kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
834 info->var.green.msb_right = 0; 1255 kref_get(&dev->kref); /* matching kref_put in .fb_destroy function*/
835 1256
836 info->var.blue.offset = 0; 1257 dev->udev = usbdev;
837 info->var.blue.length = 5; 1258 dev->gdev = &usbdev->dev; /* our generic struct device * */
838 info->var.blue.msb_right = 0; 1259 usb_set_intfdata(interface, dev);
839 1260
840 /* info->var.pixclock = (10000000 / FB_W * 1000 / FB_H)/2 ; */ 1261 if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
1262 retval = -ENOMEM;
1263 dl_err("dlfb_alloc_urb_list failed\n");
1264 goto error;
1265 }
841 1266
842 info->fix.smem_start = (unsigned long)info->screen_base; 1267 mutex_init(&dev->fb_open_lock);
843 info->fix.smem_len = PAGE_ALIGN(dev_info->screen_size); 1268
844 if (strlen(dev_info->udev->product) > 15) { 1269 /* We don't register a new USB class. Our client interface is fbdev */
845 memcpy(info->fix.id, dev_info->udev->product, 15); 1270
846 } else { 1271 /* allocates framebuffer driver structure, not framebuffer memory */
847 memcpy(info->fix.id, dev_info->udev->product, 1272 info = framebuffer_alloc(0, &usbdev->dev);
848 strlen(dev_info->udev->product)); 1273 if (!info) {
1274 retval = -ENOMEM;
1275 dl_err("framebuffer_alloc failed\n");
1276 goto error;
1277 }
1278 dev->info = info;
1279 info->par = dev;
1280 info->pseudo_palette = dev->pseudo_palette;
1281 info->fbops = &dlfb_ops;
1282
1283 var = &info->var;
1284
1285 /* TODO set limit based on actual SKU detection */
1286 dev->sku_pixel_limit = 2048 * 1152;
1287
1288 INIT_LIST_HEAD(&info->modelist);
1289 dlfb_parse_edid(dev, var, info);
1290
1291 /*
1292 * ok, now that we've got the size info, we can alloc our framebuffer.
1293 */
1294 info->fix = dlfb_fix;
1295 info->fix.line_length = var->xres * (var->bits_per_pixel / 8);
1296 videomemorysize = info->fix.line_length * var->yres;
1297
1298 /*
1299 * The big chunk of system memory we use as a virtual framebuffer.
1300 * TODO: Handle fbcon cursor code calling blit in interrupt context
1301 */
1302 videomemory = vmalloc(videomemorysize);
1303 if (!videomemory) {
1304 retval = -ENOMEM;
1305 dl_err("Virtual framebuffer alloc failed\n");
1306 goto error;
849 } 1307 }
850 info->fix.type = FB_TYPE_PACKED_PIXELS;
851 info->fix.visual = FB_VISUAL_TRUECOLOR;
852 info->fix.accel = info->flags;
853 info->fix.line_length = dev_info->line_length;
854 1308
855 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 1309 info->screen_base = videomemory;
856 goto out1; 1310 info->fix.smem_len = PAGE_ALIGN(videomemorysize);
1311 info->fix.smem_start = (unsigned long) videomemory;
1312 info->flags = udlfb_info_flags;
1313
1314
1315 /*
1316 * Second framebuffer copy, mirroring the state of the framebuffer
1317 * on the physical USB device. We can function without this.
1318 * But with imperfect damage info we may end up sending pixels over USB
1319 * that were, in fact, unchanged -- wasting limited USB bandwidth
1320 */
1321 dev->backing_buffer = vmalloc(videomemorysize);
1322 if (!dev->backing_buffer)
1323 dl_warn("No shadow/backing buffer allcoated\n");
1324 else
1325 memset(dev->backing_buffer, 0, videomemorysize);
1326
1327 retval = fb_alloc_cmap(&info->cmap, 256, 0);
1328 if (retval < 0) {
1329 dl_err("fb_alloc_cmap failed %x\n", retval);
1330 goto error;
1331 }
1332
1333 /* ready to begin using device */
1334
1335#ifdef CONFIG_FB_DEFERRED_IO
1336 atomic_set(&dev->use_defio, 1);
1337#endif
1338 atomic_set(&dev->usb_active, 1);
1339 dlfb_select_std_channel(dev);
1340
1341 dlfb_ops_check_var(var, info);
1342 dlfb_ops_set_par(info);
1343
1344 /* paint greenscreen */
1345 pix_framebuffer = (u16 *) videomemory;
1346 for (i = 0; i < videomemorysize / 2; i++)
1347 pix_framebuffer[i] = 0x37e6;
1348
1349 dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres,
1350 videomemory);
857 1351
858 printk("colormap allocated\n"); 1352 retval = register_framebuffer(info);
859 if (register_framebuffer(info) < 0) 1353 if (retval < 0) {
860 goto out2; 1354 dl_err("register_framebuffer failed %d\n", retval);
1355 goto error;
1356 }
1357 registered = 1;
1358
1359 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
1360 device_create_file(info->dev, &fb_device_attrs[i]);
861 1361
862 draw_rect(dev_info, 0, 0, dev_info->info->var.xres, 1362 device_create_bin_file(info->dev, &edid_attr);
863 dev_info->info->var.yres, 0x30, 0xff, 0x30);
864 1363
1364 dl_err("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
1365 " Using %dK framebuffer memory\n", info->node,
1366 var->xres, var->yres,
1367 ((dev->backing_buffer) ?
1368 videomemorysize * 2 : videomemorysize) >> 10);
865 return 0; 1369 return 0;
866 1370
867out2: 1371error:
868 fb_dealloc_cmap(&info->cmap); 1372 if (dev) {
869out1: 1373 if (registered) {
870 rvfree(info->screen_base, dev_info->screen_size); 1374 unregister_framebuffer(info);
871out0: 1375 dlfb_ops_destroy(info);
872 framebuffer_release(info); 1376 } else
873out: 1377 kref_put(&dev->kref, dlfb_delete);
874 usb_set_intfdata(interface, NULL); 1378
875 usb_put_dev(dev_info->udev); 1379 if (dev->urbs.count > 0)
876 kfree(dev_info); 1380 dlfb_free_urb_list(dev);
877 return -ENOMEM; 1381 kref_put(&dev->kref, dlfb_delete); /* last ref from kref_init */
1382
1383 /* dev has been deallocated. Do not dereference */
1384 }
878 1385
1386 return retval;
879} 1387}
880 1388
881static void dlfb_disconnect(struct usb_interface *interface) 1389static void dlfb_usb_disconnect(struct usb_interface *interface)
882{ 1390{
883 struct dlfb_data *dev_info = usb_get_intfdata(interface); 1391 struct dlfb_data *dev;
1392 struct fb_info *info;
1393 int i;
1394
1395 dev = usb_get_intfdata(interface);
1396 info = dev->info;
884 1397
885 mutex_unlock(&dev_info->bulk_mutex); 1398 /* when non-active we'll update virtual framebuffer, but no new urbs */
1399 atomic_set(&dev->usb_active, 0);
886 1400
887 usb_kill_urb(dev_info->tx_urb);
888 usb_free_urb(dev_info->tx_urb);
889 usb_set_intfdata(interface, NULL); 1401 usb_set_intfdata(interface, NULL);
890 usb_put_dev(dev_info->udev);
891 1402
892 if (dev_info->info) { 1403 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
893 unregister_framebuffer(dev_info->info); 1404 device_remove_file(info->dev, &fb_device_attrs[i]);
894 fb_dealloc_cmap(&dev_info->info->cmap); 1405
895 rvfree(dev_info->info->screen_base, dev_info->screen_size); 1406 device_remove_bin_file(info->dev, &edid_attr);
896 kfree(dev_info->backing_buffer);
897 framebuffer_release(dev_info->info);
898 1407
1408 /* this function will wait for all in-flight urbs to complete */
1409 dlfb_free_urb_list(dev);
1410
1411 if (info) {
1412 dl_notice("Detaching /dev/fb%d\n", info->node);
1413 unregister_framebuffer(info);
1414 dlfb_ops_destroy(info);
899 } 1415 }
900 1416
901 kfree(dev_info); 1417 /* release reference taken by kref_init in probe() */
1418 kref_put(&dev->kref, dlfb_delete);
1419
1420 /* consider dlfb_data freed */
902 1421
903 printk("DisplayLink device disconnected\n"); 1422 return;
904} 1423}
905 1424
906static struct usb_driver dlfb_driver = { 1425static struct usb_driver dlfb_driver = {
907 .name = "udlfb", 1426 .name = "udlfb",
908 .probe = dlfb_probe, 1427 .probe = dlfb_usb_probe,
909 .disconnect = dlfb_disconnect, 1428 .disconnect = dlfb_usb_disconnect,
910 .id_table = id_table, 1429 .id_table = id_table,
911}; 1430};
912 1431
913static int __init dlfb_init(void) 1432static int __init dlfb_module_init(void)
914{ 1433{
915 int res; 1434 int res;
916 1435
917 dlfb_init_modes();
918
919 res = usb_register(&dlfb_driver); 1436 res = usb_register(&dlfb_driver);
920 if (res) 1437 if (res)
921 err("usb_register failed. Error number %d", res); 1438 err("usb_register failed. Error number %d", res);
@@ -925,14 +1442,186 @@ static int __init dlfb_init(void)
925 return res; 1442 return res;
926} 1443}
927 1444
928static void __exit dlfb_exit(void) 1445static void __exit dlfb_module_exit(void)
929{ 1446{
930 usb_deregister(&dlfb_driver); 1447 usb_deregister(&dlfb_driver);
931} 1448}
932 1449
933module_init(dlfb_init); 1450module_init(dlfb_module_init);
934module_exit(dlfb_exit); 1451module_exit(dlfb_module_exit);
935 1452
936MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>"); 1453static void dlfb_urb_completion(struct urb *urb)
937MODULE_DESCRIPTION(DRIVER_VERSION); 1454{
1455 struct urb_node *unode = urb->context;
1456 struct dlfb_data *dev = unode->dev;
1457 unsigned long flags;
1458
1459 /* sync/async unlink faults aren't errors */
1460 if (urb->status) {
1461 if (!(urb->status == -ENOENT ||
1462 urb->status == -ECONNRESET ||
1463 urb->status == -ESHUTDOWN)) {
1464 dl_err("%s - nonzero write bulk status received: %d\n",
1465 __func__, urb->status);
1466 atomic_set(&dev->lost_pixels, 1);
1467 }
1468 }
1469
1470 urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */
1471
1472 spin_lock_irqsave(&dev->urbs.lock, flags);
1473 list_add_tail(&unode->entry, &dev->urbs.list);
1474 dev->urbs.available++;
1475 spin_unlock_irqrestore(&dev->urbs.lock, flags);
1476
1477 up(&dev->urbs.limit_sem);
1478}
1479
1480static void dlfb_free_urb_list(struct dlfb_data *dev)
1481{
1482 int count = dev->urbs.count;
1483 struct list_head *node;
1484 struct urb_node *unode;
1485 struct urb *urb;
1486 int ret;
1487 unsigned long flags;
1488
1489 dl_notice("Waiting for completes and freeing all render urbs\n");
1490
1491 /* keep waiting and freeing, until we've got 'em all */
1492 while (count--) {
1493 /* Timeout means a memory leak and/or fault */
1494 ret = down_timeout(&dev->urbs.limit_sem, FREE_URB_TIMEOUT);
1495 if (ret) {
1496 BUG_ON(ret);
1497 break;
1498 }
1499 spin_lock_irqsave(&dev->urbs.lock, flags);
1500
1501 node = dev->urbs.list.next; /* have reserved one with sem */
1502 list_del_init(node);
1503
1504 spin_unlock_irqrestore(&dev->urbs.lock, flags);
1505
1506 unode = list_entry(node, struct urb_node, entry);
1507 urb = unode->urb;
1508
1509 /* Free each separately allocated piece */
1510 usb_buffer_free(urb->dev, dev->urbs.size,
1511 urb->transfer_buffer, urb->transfer_dma);
1512 usb_free_urb(urb);
1513 kfree(node);
1514 }
1515
1516 kref_put(&dev->kref, dlfb_delete);
1517
1518}
1519
1520static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
1521{
1522 int i = 0;
1523 struct urb *urb;
1524 struct urb_node *unode;
1525 char *buf;
1526
1527 spin_lock_init(&dev->urbs.lock);
1528
1529 dev->urbs.size = size;
1530 INIT_LIST_HEAD(&dev->urbs.list);
1531
1532 while (i < count) {
1533 unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
1534 if (!unode)
1535 break;
1536 unode->dev = dev;
1537
1538 urb = usb_alloc_urb(0, GFP_KERNEL);
1539 if (!urb) {
1540 kfree(unode);
1541 break;
1542 }
1543 unode->urb = urb;
1544
1545 buf = usb_buffer_alloc(dev->udev, MAX_TRANSFER, GFP_KERNEL,
1546 &urb->transfer_dma);
1547 if (!buf) {
1548 kfree(unode);
1549 usb_free_urb(urb);
1550 break;
1551 }
1552
1553 /* urb->transfer_buffer_length set to actual before submit */
1554 usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1),
1555 buf, size, dlfb_urb_completion, unode);
1556 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1557
1558 list_add_tail(&unode->entry, &dev->urbs.list);
1559
1560 i++;
1561 }
1562
1563 sema_init(&dev->urbs.limit_sem, i);
1564 dev->urbs.count = i;
1565 dev->urbs.available = i;
1566
1567 kref_get(&dev->kref); /* released in free_render_urbs() */
1568
1569 dl_notice("allocated %d %d byte urbs \n", i, (int) size);
1570
1571 return i;
1572}
1573
1574static struct urb *dlfb_get_urb(struct dlfb_data *dev)
1575{
1576 int ret = 0;
1577 struct list_head *entry;
1578 struct urb_node *unode;
1579 struct urb *urb = NULL;
1580 unsigned long flags;
1581
1582 /* Wait for an in-flight buffer to complete and get re-queued */
1583 ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT);
1584 if (ret) {
1585 atomic_set(&dev->lost_pixels, 1);
1586 dl_err("wait for urb interrupted: %x\n", ret);
1587 goto error;
1588 }
1589
1590 spin_lock_irqsave(&dev->urbs.lock, flags);
1591
1592 BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */
1593 entry = dev->urbs.list.next;
1594 list_del_init(entry);
1595 dev->urbs.available--;
1596
1597 spin_unlock_irqrestore(&dev->urbs.lock, flags);
1598
1599 unode = list_entry(entry, struct urb_node, entry);
1600 urb = unode->urb;
1601
1602error:
1603 return urb;
1604}
1605
1606static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len)
1607{
1608 int ret;
1609
1610 BUG_ON(len > dev->urbs.size);
1611
1612 urb->transfer_buffer_length = len; /* set to actual payload len */
1613 ret = usb_submit_urb(urb, GFP_KERNEL);
1614 if (ret) {
1615 dlfb_urb_completion(urb); /* because no one else will */
1616 atomic_set(&dev->lost_pixels, 1);
1617 dl_err("usb_submit_urb error %x\n", ret);
1618 }
1619 return ret;
1620}
1621
1622MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, "
1623 "Jaya Kumar <jayakumar.lkml@gmail.com>, "
1624 "Bernie Thompson <bernie@plugable.com>");
1625MODULE_DESCRIPTION("DisplayLink kernel framebuffer driver");
938MODULE_LICENSE("GPL"); 1626MODULE_LICENSE("GPL");
1627
diff --git a/drivers/staging/udlfb/udlfb.h b/drivers/staging/udlfb/udlfb.h
index 40ad85ea8e67..b07a69371f1f 100644
--- a/drivers/staging/udlfb/udlfb.h
+++ b/drivers/staging/udlfb/udlfb.h
@@ -1,225 +1,106 @@
1#ifndef UDLFB_H 1#ifndef UDLFB_H
2#define UDLFB_H 2#define UDLFB_H
3 3
4#define MAX_VMODES 4 4/*
5#define FB_BPP 16 5 * TODO: Propose standard fb.h ioctl for reporting damage,
6 * using _IOWR() and one of the existing area structs from fb.h
7 * Consider these ioctls deprecated, but they're still used by the
8 * DisplayLink X server as yet - need both to be modified in tandem
9 * when new ioctl(s) are ready.
10 */
11#define DLFB_IOCTL_RETURN_EDID 0xAD
12#define DLFB_IOCTL_REPORT_DAMAGE 0xAA
13struct dloarea {
14 int x, y;
15 int w, h;
16 int x2, y2;
17};
6 18
7#define STD_CHANNEL "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15" \ 19struct urb_node {
8 "\x60\xFE\xC6\x97\x16\x3D\x47\xF2" 20 struct list_head entry;
21 struct dlfb_data *dev;
22 struct urb *urb;
23};
9 24
10/* as libdlo */ 25struct urb_list {
11#define BUF_HIGH_WATER_MARK 1024 26 struct list_head list;
12#define BUF_SIZE (64*1024) 27 spinlock_t lock;
28 struct semaphore limit_sem;
29 int available;
30 int count;
31 size_t size;
32};
13 33
14struct dlfb_data { 34struct dlfb_data {
15 struct usb_device *udev; 35 struct usb_device *udev;
16 struct usb_interface *interface; 36 struct device *gdev; /* &udev->dev */
17 struct urb *tx_urb, *ctrl_urb;
18 struct usb_ctrlrequest dr;
19 struct fb_info *info; 37 struct fb_info *info;
20 char *buf; 38 struct urb_list urbs;
21 char *bufend; 39 struct kref kref;
22 char *backing_buffer; 40 char *backing_buffer;
23 struct mutex bulk_mutex; 41 struct delayed_work deferred_work;
42 struct mutex fb_open_lock;
43 int fb_count;
44 atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
45 atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
46 atomic_t use_defio; /* 0 = rely on ioctls and blit/copy/fill rects */
24 char edid[128]; 47 char edid[128];
25 int screen_size; 48 int sku_pixel_limit;
26 int line_length;
27 struct completion done;
28 int base16; 49 int base16;
29 int base16d;
30 int base8; 50 int base8;
31 int base8d; 51 u32 pseudo_palette[256];
52 /* blit-only rendering path metrics, exposed through sysfs */
53 atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */
54 atomic_t bytes_identical; /* saved effort with backbuffer comparison */
55 atomic_t bytes_sent; /* to usb, after compression including overhead */
56 atomic_t cpu_kcycles_used; /* transpired during pixel processing */
57 /* interface usage metrics. Clients can call driver via several */
58 atomic_t blit_count;
59 atomic_t copy_count;
60 atomic_t fill_count;
61 atomic_t damage_count;
62 atomic_t defio_fault_count;
32}; 63};
33 64
34struct dlfb_video_mode { 65#define NR_USB_REQUEST_I2C_SUB_IO 0x02
35 uint8_t col; 66#define NR_USB_REQUEST_CHANNEL 0x12
36 uint32_t hclock;
37 uint32_t vclock;
38 uint8_t unknown1[6];
39 uint16_t xres;
40 uint8_t unknown2[6];
41 uint16_t yres;
42 uint8_t unknown3[4];
43} __attribute__ ((__packed__));
44
45static struct dlfb_video_mode dlfb_video_modes[MAX_VMODES];
46
47static void dlfb_bulk_callback(struct urb *urb)
48{
49 struct dlfb_data *dev_info = urb->context;
50 complete(&dev_info->done);
51}
52
53static void dlfb_edid(struct dlfb_data *dev_info)
54{
55 int i;
56 int ret;
57 char rbuf[2];
58
59 for (i = 0; i < 128; i++) {
60 ret =
61 usb_control_msg(dev_info->udev,
62 usb_rcvctrlpipe(dev_info->udev, 0), (0x02),
63 (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
64 0);
65 /*printk("ret control msg edid %d: %d [%d]\n",i, ret, rbuf[1]); */
66 dev_info->edid[i] = rbuf[1];
67 }
68
69}
70
71static int dlfb_bulk_msg(struct dlfb_data *dev_info, int len)
72{
73 int ret;
74
75 init_completion(&dev_info->done);
76
77 dev_info->tx_urb->actual_length = 0;
78 dev_info->tx_urb->transfer_buffer_length = len;
79
80 ret = usb_submit_urb(dev_info->tx_urb, GFP_KERNEL);
81 if (!wait_for_completion_timeout(&dev_info->done, 1000)) {
82 usb_kill_urb(dev_info->tx_urb);
83 printk("usb timeout !!!\n");
84 }
85
86 return dev_info->tx_urb->actual_length;
87}
88
89static void dlfb_init_modes(void)
90{
91 dlfb_video_modes[0].col = 0;
92 memcpy(&dlfb_video_modes[0].hclock, "\x20\x3C\x7A\xC9", 4);
93 memcpy(&dlfb_video_modes[0].vclock, "\xF2\x6C\x48\xF9", 4);
94 memcpy(&dlfb_video_modes[0].unknown1, "\x70\x53\xFF\xFF\x21\x27", 6);
95 dlfb_video_modes[0].xres = 800;
96 memcpy(&dlfb_video_modes[0].unknown2, "\x91\xF3\xFF\xFF\xFF\xF9", 6);
97 dlfb_video_modes[0].yres = 480;
98 memcpy(&dlfb_video_modes[0].unknown3, "\x01\x02\xC8\x19", 4);
99
100 dlfb_video_modes[1].col = 0;
101 memcpy(&dlfb_video_modes[1].hclock, "\x36\x18\xD5\x10", 4);
102 memcpy(&dlfb_video_modes[1].vclock, "\x60\xA9\x7B\x33", 4);
103 memcpy(&dlfb_video_modes[1].unknown1, "\xA1\x2B\x27\x32\xFF\xFF", 6);
104 dlfb_video_modes[1].xres = 1024;
105 memcpy(&dlfb_video_modes[1].unknown2, "\xD9\x9A\xFF\xCA\xFF\xFF", 6);
106 dlfb_video_modes[1].yres = 768;
107 memcpy(&dlfb_video_modes[1].unknown3, "\x04\x03\xC8\x32", 4);
108
109 dlfb_video_modes[2].col = 0;
110 memcpy(&dlfb_video_modes[2].hclock, "\x98\xF8\x0D\x57", 4);
111 memcpy(&dlfb_video_modes[2].vclock, "\x2A\x55\x4D\x54", 4);
112 memcpy(&dlfb_video_modes[2].unknown1, "\xCA\x0D\xFF\xFF\x94\x43", 6);
113 dlfb_video_modes[2].xres = 1280;
114 memcpy(&dlfb_video_modes[2].unknown2, "\x9A\xA8\xFF\xFF\xFF\xF9", 6);
115 dlfb_video_modes[2].yres = 1024;
116 memcpy(&dlfb_video_modes[2].unknown3, "\x04\x02\x60\x54", 4);
117
118 dlfb_video_modes[3].col = 0;
119 memcpy(&dlfb_video_modes[3].hclock, "\x42\x24\x38\x36", 4);
120 memcpy(&dlfb_video_modes[3].vclock, "\xC1\x52\xD9\x29", 4);
121 memcpy(&dlfb_video_modes[3].unknown1, "\xEA\xB8\x32\x60\xFF\xFF", 6);
122 dlfb_video_modes[3].xres = 1400;
123 memcpy(&dlfb_video_modes[3].unknown2, "\xC9\x4E\xFF\xFF\xFF\xF2", 6);
124 dlfb_video_modes[3].yres = 1050;
125 memcpy(&dlfb_video_modes[3].unknown3, "\x04\x02\x1E\x5F", 4);
126}
127
128static char *dlfb_set_register(char *bufptr, uint8_t reg, uint8_t val)
129{
130 *bufptr++ = 0xAF;
131 *bufptr++ = 0x20;
132 *bufptr++ = reg;
133 *bufptr++ = val;
134
135 return bufptr;
136}
137
138static int dlfb_set_video_mode(struct dlfb_data *dev_info, int width, int height)
139{
140 int i, ret;
141 unsigned char j;
142 char *bufptr = dev_info->buf;
143 uint8_t *vdata;
144
145 for (i = 0; i < MAX_VMODES; i++) {
146 printk("INIT VIDEO %d %d %d\n", i, dlfb_video_modes[i].xres,
147 dlfb_video_modes[i].yres);
148 if (dlfb_video_modes[i].xres == width
149 && dlfb_video_modes[i].yres == height) {
150
151 dev_info->base16 = 0;
152 dev_info->base16d = width * height * (FB_BPP / 8);
153
154 //dev_info->base8 = width * height * (FB_BPP / 8);
155
156 dev_info->base8 = dev_info->base16;
157 dev_info->base8d = dev_info->base16d;
158
159 /* set encryption key (null) */
160 memcpy(dev_info->buf, STD_CHANNEL, 16);
161 ret =
162 usb_control_msg(dev_info->udev,
163 usb_sndctrlpipe(dev_info->udev, 0),
164 0x12, (0x02 << 5), 0, 0,
165 dev_info->buf, 16, 0);
166 printk("ret control msg 1 (STD_CHANNEL): %d\n", ret);
167
168 /* set registers */
169 bufptr = dlfb_set_register(bufptr, 0xFF, 0x00);
170
171 /* set color depth */
172 bufptr = dlfb_set_register(bufptr, 0x00, 0x00);
173
174 /* set addresses */
175 bufptr =
176 dlfb_set_register(bufptr, 0x20,
177 (char)(dev_info->base16 >> 16));
178 bufptr =
179 dlfb_set_register(bufptr, 0x21,
180 (char)(dev_info->base16 >> 8));
181 bufptr =
182 dlfb_set_register(bufptr, 0x22,
183 (char)(dev_info->base16));
184
185 bufptr =
186 dlfb_set_register(bufptr, 0x26,
187 (char)(dev_info->base8 >> 16));
188 bufptr =
189 dlfb_set_register(bufptr, 0x27,
190 (char)(dev_info->base8 >> 8));
191 bufptr =
192 dlfb_set_register(bufptr, 0x28,
193 (char)(dev_info->base8));
194 67
195 /* set video mode */ 68/* -BULK_SIZE as per usb-skeleton. Can we get full page and avoid overhead? */
196 vdata = (uint8_t *)&dlfb_video_modes[i]; 69#define BULK_SIZE 512
197 for (j = 0; j < 29; j++) 70#define MAX_TRANSFER (PAGE_SIZE*16 - BULK_SIZE)
198 bufptr = dlfb_set_register(bufptr, j, vdata[j]); 71#define WRITES_IN_FLIGHT (4)
199 72
200 /* blank */ 73#define GET_URB_TIMEOUT HZ
201 bufptr = dlfb_set_register(bufptr, 0x1F, 0x00); 74#define FREE_URB_TIMEOUT (HZ*2)
202 75
203 /* end registers */ 76#define BPP 2
204 bufptr = dlfb_set_register(bufptr, 0xFF, 0xFF); 77#define MAX_CMD_PIXELS 255
205 78
206 /* send */ 79#define RLX_HEADER_BYTES 7
207 ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf); 80#define MIN_RLX_PIX_BYTES 4
208 printk("ret bulk 2: %d %td\n", ret, 81#define MIN_RLX_CMD_BYTES (RLX_HEADER_BYTES + MIN_RLX_PIX_BYTES)
209 bufptr - dev_info->buf);
210 82
211 /* flush */ 83#define RLE_HEADER_BYTES 6
212 ret = dlfb_bulk_msg(dev_info, 0); 84#define MIN_RLE_PIX_BYTES 3
213 printk("ret bulk 3: %d\n", ret); 85#define MIN_RLE_CMD_BYTES (RLE_HEADER_BYTES + MIN_RLE_PIX_BYTES)
214 86
215 dev_info->screen_size = width * height * (FB_BPP / 8); 87#define RAW_HEADER_BYTES 6
216 dev_info->line_length = width * (FB_BPP / 8); 88#define MIN_RAW_PIX_BYTES 2
89#define MIN_RAW_CMD_BYTES (RAW_HEADER_BYTES + MIN_RAW_PIX_BYTES)
217 90
218 return 0; 91/* remove these once align.h patch is taken into kernel */
219 } 92#define DL_ALIGN_UP(x, a) ALIGN(x, a)
220 } 93#define DL_ALIGN_DOWN(x, a) ALIGN(x-(a-1), a)
221 94
222 return -1; 95/* remove once this gets added to sysfs.h */
223} 96#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store)
224 97
98#define dl_err(format, arg...) \
99 dev_err(dev->gdev, "dlfb: " format, ## arg)
100#define dl_warn(format, arg...) \
101 dev_warn(dev->gdev, "dlfb: " format, ## arg)
102#define dl_notice(format, arg...) \
103 dev_notice(dev->gdev, "dlfb: " format, ## arg)
104#define dl_info(format, arg...) \
105 dev_info(dev->gdev, "dlfb: " format, ## arg)
225#endif 106#endif
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig
index 350d5d65ccf3..2c1d10acb8b5 100644
--- a/drivers/staging/usbip/Kconfig
+++ b/drivers/staging/usbip/Kconfig
@@ -34,3 +34,10 @@ config USB_IP_HOST
34 34
35 To compile this driver as a module, choose M here: the 35 To compile this driver as a module, choose M here: the
36 module will be called usbip. 36 module will be called usbip.
37
38config USB_IP_DEBUG_ENABLE
39 bool "USB-IP Debug Enable"
40 depends on USB_IP_COMMON
41 default N
42 ---help---
43 This enables the debug messages from the USB-IP drivers.
diff --git a/drivers/staging/usbip/Makefile b/drivers/staging/usbip/Makefile
index 179f4211f96b..6f2916b1807a 100644
--- a/drivers/staging/usbip/Makefile
+++ b/drivers/staging/usbip/Makefile
@@ -7,6 +7,6 @@ vhci-hcd-objs := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
7obj-$(CONFIG_USB_IP_HOST) += usbip.o 7obj-$(CONFIG_USB_IP_HOST) += usbip.o
8usbip-objs := stub_dev.o stub_main.o stub_rx.o stub_tx.o 8usbip-objs := stub_dev.o stub_main.o stub_rx.o stub_tx.o
9 9
10ifeq ($(CONFIG_USB_DEBUG),y) 10ifeq ($(CONFIG_USB_IP_DEBUG_ENABLE),y)
11 EXTRA_CFLAGS += -DDEBUG 11 EXTRA_CFLAGS += -DDEBUG
12endif 12endif
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index ddb6f5fd04d5..7a45da8f9565 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -33,7 +33,7 @@
33/*-------------------------------------------------------------------------*/ 33/*-------------------------------------------------------------------------*/
34/* debug routines */ 34/* debug routines */
35 35
36#ifdef CONFIG_USB_DEBUG 36#ifdef CONFIG_USB_IP_DEBUG_ENABLE
37unsigned long usbip_debug_flag = 0xffffffff; 37unsigned long usbip_debug_flag = 0xffffffff;
38#else 38#else
39unsigned long usbip_debug_flag; 39unsigned long usbip_debug_flag;
@@ -55,10 +55,7 @@ static ssize_t show_flag(struct device *dev, struct device_attribute *attr,
55static ssize_t store_flag(struct device *dev, struct device_attribute *attr, 55static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
56 const char *buf, size_t count) 56 const char *buf, size_t count)
57{ 57{
58 unsigned long flag; 58 sscanf(buf, "%lx", &usbip_debug_flag);
59
60 sscanf(buf, "%lx", &flag);
61 usbip_debug_flag = flag;
62 59
63 return count; 60 return count;
64} 61}
@@ -66,33 +63,8 @@ DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
66 63
67static void usbip_dump_buffer(char *buff, int bufflen) 64static void usbip_dump_buffer(char *buff, int bufflen)
68{ 65{
69 int i; 66 print_hex_dump(KERN_DEBUG, "usb-ip", DUMP_PREFIX_OFFSET, 16, 4,
70 67 buff, bufflen, false);
71 if (bufflen > 128) {
72 for (i = 0; i < 128; i++) {
73 if (i%24 == 0)
74 printk(KERN_DEBUG " ");
75 printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
76 if (i%4 == 3)
77 printk(KERN_DEBUG "| ");
78 if (i%24 == 23)
79 printk(KERN_DEBUG "\n");
80 }
81 printk(KERN_DEBUG "... (%d byte)\n", bufflen);
82 return;
83 }
84
85 for (i = 0; i < bufflen; i++) {
86 if (i%24 == 0)
87 printk(KERN_DEBUG " ");
88 printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
89 if (i%4 == 3)
90 printk(KERN_DEBUG "| ");
91 if (i%24 == 23)
92 printk(KERN_DEBUG "\n");
93 }
94 printk(KERN_DEBUG "\n");
95
96} 68}
97 69
98static void usbip_dump_pipe(unsigned int p) 70static void usbip_dump_pipe(unsigned int p)
@@ -558,60 +530,6 @@ err:
558} 530}
559EXPORT_SYMBOL_GPL(usbip_xmit); 531EXPORT_SYMBOL_GPL(usbip_xmit);
560 532
561
562/* now a usrland utility should set options. */
563#if 0
564int setquickack(struct socket *socket)
565{
566 mm_segment_t oldfs;
567 int val = 1;
568 int ret;
569
570 oldfs = get_fs();
571 set_fs(get_ds());
572 ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
573 (char __user *) &val, sizeof(ret));
574 set_fs(oldfs);
575
576 return ret;
577}
578
579int setnodelay(struct socket *socket)
580{
581 mm_segment_t oldfs;
582 int val = 1;
583 int ret;
584
585 oldfs = get_fs();
586 set_fs(get_ds());
587 ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
588 (char __user *) &val, sizeof(ret));
589 set_fs(oldfs);
590
591 return ret;
592}
593
594int setkeepalive(struct socket *socket)
595{
596 mm_segment_t oldfs;
597 int val = 1;
598 int ret;
599
600 oldfs = get_fs();
601 set_fs(get_ds());
602 ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
603 (char __user *) &val, sizeof(ret));
604 set_fs(oldfs);
605
606 return ret;
607}
608
609void setreuse(struct socket *socket)
610{
611 socket->sk->sk_reuse = 1;
612}
613#endif
614
615struct socket *sockfd_to_socket(unsigned int sockfd) 533struct socket *sockfd_to_socket(unsigned int sockfd)
616{ 534{
617 struct socket *socket; 535 struct socket *socket;
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index 1ca3eab8af18..6f1dcb197d13 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -33,12 +33,12 @@
33 */ 33 */
34 34
35/** 35/**
36 * usbip_udbg - print debug messages if CONFIG_USB_DEBUG is defined 36 * usbip_udbg - print debug messages if CONFIG_USB_IP_DEBUG_ENABLE is defined
37 * @fmt: 37 * @fmt:
38 * @args: 38 * @args:
39 */ 39 */
40 40
41#ifdef CONFIG_USB_DEBUG 41#ifdef CONFIG_USB_IP_DEBUG_ENABLE
42 42
43#define usbip_udbg(fmt, args...) \ 43#define usbip_udbg(fmt, args...) \
44 do { \ 44 do { \
@@ -47,11 +47,11 @@
47 __FILE__, __LINE__, __func__, ##args); \ 47 __FILE__, __LINE__, __func__, ##args); \
48 } while (0) 48 } while (0)
49 49
50#else /* CONFIG_USB_DEBUG */ 50#else /* CONFIG_USB_IP_DEBUG_ENABLE */
51 51
52#define usbip_udbg(fmt, args...) do { } while (0) 52#define usbip_udbg(fmt, args...) do { } while (0)
53 53
54#endif /* CONFIG_USB_DEBUG */ 54#endif /* CONFIG_USB_IP_DEBUG_ENABLE */
55 55
56 56
57enum { 57enum {
diff --git a/drivers/staging/vme/Kconfig b/drivers/staging/vme/Kconfig
index ae628a58b0c6..6411ae51ed3f 100644
--- a/drivers/staging/vme/Kconfig
+++ b/drivers/staging/vme/Kconfig
@@ -14,4 +14,6 @@ source "drivers/staging/vme/bridges/Kconfig"
14 14
15source "drivers/staging/vme/devices/Kconfig" 15source "drivers/staging/vme/devices/Kconfig"
16 16
17source "drivers/staging/vme/boards/Kconfig"
18
17endif # VME 19endif # VME
diff --git a/drivers/staging/vme/Makefile b/drivers/staging/vme/Makefile
index 8c3b90ee5853..b4ea3f8d0a50 100644
--- a/drivers/staging/vme/Makefile
+++ b/drivers/staging/vme/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_VME_BUS) += vme.o
5 5
6obj-y += bridges/ 6obj-y += bridges/
7obj-y += devices/ 7obj-y += devices/
8obj-y += boards/
diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO
index 2201ff6f74d1..82c222b4a146 100644
--- a/drivers/staging/vme/TODO
+++ b/drivers/staging/vme/TODO
@@ -4,28 +4,6 @@
4API 4API
5=== 5===
6 6
7DMA Resource Allocation incomplete
8----------------------------------
9
10The current DMA resource Allocation provides no means of selecting the
11suitability of a DMA controller based on it's supported modes of operation, as
12opposed to the resource allocation mechanisms for master and slave windows:
13
14 struct vme_resource *vme_dma_request(struct device *dev);
15
16As opposed to:
17
18 struct vme_resource * vme_master_request(struct device *dev,
19 vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
20
21The TSI148 can perform, VME-to-PCI, PCI-to-VME, PATTERN-to-VME, PATTERN-to-PCI,
22VME-to-VME and PCI-to-PCI transfers. The CA91C142 can only provide VME-to-PCI
23and PCI-to-VME.
24
25Add a mechanism to select a VME controller based on source/target type,
26required aspace, cycle and width requirements.
27
28
29Master window broadcast select mask 7Master window broadcast select mask
30----------------------------------- 8-----------------------------------
31 9
@@ -59,7 +37,6 @@ chips. They are currently not supported at all by the API.
59Core 37Core
60==== 38====
61 39
62- Rename vme_master_resource's "pci_resource" to be bus agnostic.
63- Improve generic sanity checks (Such as does an offset and size fit within a 40- Improve generic sanity checks (Such as does an offset and size fit within a
64 window and parameter checking). 41 window and parameter checking).
65 42
@@ -69,7 +46,6 @@ Bridge Support
69Tempe (tsi148) 46Tempe (tsi148)
70-------------- 47--------------
71 48
72- Driver can currently only support a single bridge.
73- 2eSST Broadcast mode. 49- 2eSST Broadcast mode.
74- Mailboxes unsupported. 50- Mailboxes unsupported.
75- Improve error detection. 51- Improve error detection.
@@ -80,10 +56,6 @@ Tempe (tsi148)
80Universe II (ca91c142) 56Universe II (ca91c142)
81---------------------- 57----------------------
82 58
83- Driver can currently only support a single bridge.
84- DMA unsupported.
85- RMW transactions unsupported.
86- Location Monitors unsupported.
87- Mailboxes unsupported. 59- Mailboxes unsupported.
88- Error Detection. 60- Error Detection.
89- Control of prefetch size, threshold. 61- Control of prefetch size, threshold.
diff --git a/drivers/staging/vme/boards/Kconfig b/drivers/staging/vme/boards/Kconfig
new file mode 100644
index 000000000000..761631353527
--- /dev/null
+++ b/drivers/staging/vme/boards/Kconfig
@@ -0,0 +1,9 @@
1comment "VME Board Drivers"
2
3config VMIVME_7805
4 tristate "VMIVME-7805"
5 help
6 If you say Y here you get support for the VMIVME-7805 board.
7 This board has an additional control interface to the Universe II
8 chip. This driver has to be included if you want to access VME bus
9 with VMIVME-7805 board.
diff --git a/drivers/staging/vme/boards/Makefile b/drivers/staging/vme/boards/Makefile
new file mode 100644
index 000000000000..43658340885d
--- /dev/null
+++ b/drivers/staging/vme/boards/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the VME board drivers.
3#
4
5obj-$(CONFIG_VMIVME_7805) += vme_vmivme7805.o
diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c
new file mode 100644
index 000000000000..843c9edde555
--- /dev/null
+++ b/drivers/staging/vme/boards/vme_vmivme7805.c
@@ -0,0 +1,124 @@
1/*
2 * Support for the VMIVME-7805 board access to the Universe II bridge.
3 *
4 * Author: Arthur Benilov <arthur.benilov@iba-group.com>
5 * Copyright 2010 Ion Beam Application, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/errno.h>
17#include <linux/pci.h>
18#include <linux/poll.h>
19#include <linux/io.h>
20
21#include "vme_vmivme7805.h"
22
23static int __init vmic_init(void);
24static int vmic_probe(struct pci_dev *, const struct pci_device_id *);
25static void vmic_remove(struct pci_dev *);
26static void __exit vmic_exit(void);
27
28/** Base address to access FPGA register */
29static void *vmic_base;
30
31static char driver_name[] = "vmivme_7805";
32
33static struct pci_device_id vmic_ids[] = {
34 { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) },
35 { },
36};
37
38static struct pci_driver vmic_driver = {
39 .name = driver_name,
40 .id_table = vmic_ids,
41 .probe = vmic_probe,
42 .remove = vmic_remove,
43};
44
45static int __init vmic_init(void)
46{
47 return pci_register_driver(&vmic_driver);
48}
49
50static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id)
51{
52 int retval;
53 u32 data;
54
55 /* Enable the device */
56 retval = pci_enable_device(pdev);
57 if (retval) {
58 dev_err(&pdev->dev, "Unable to enable device\n");
59 goto err;
60 }
61
62 /* Map Registers */
63 retval = pci_request_regions(pdev, driver_name);
64 if (retval) {
65 dev_err(&pdev->dev, "Unable to reserve resources\n");
66 goto err_resource;
67 }
68
69 /* Map registers in BAR 0 */
70 vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16);
71 if (!vmic_base) {
72 dev_err(&pdev->dev, "Unable to remap CRG region\n");
73 retval = -EIO;
74 goto err_remap;
75 }
76
77 /* Clear the FPGA VME IF contents */
78 iowrite32(0, vmic_base + VME_CONTROL);
79
80 /* Clear any initial BERR */
81 data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
82 data |= BM_VME_CONTROL_BERRST;
83 iowrite32(data, vmic_base + VME_CONTROL);
84
85 /* Enable the vme interface and byte swapping */
86 data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF;
87 data = data | BM_VME_CONTROL_MASTER_ENDIAN |
88 BM_VME_CONTROL_SLAVE_ENDIAN |
89 BM_VME_CONTROL_ABLE |
90 BM_VME_CONTROL_BERRI |
91 BM_VME_CONTROL_BPENA |
92 BM_VME_CONTROL_VBENA;
93 iowrite32(data, vmic_base + VME_CONTROL);
94
95 return 0;
96
97err_remap:
98 pci_release_regions(pdev);
99err_resource:
100 pci_disable_device(pdev);
101err:
102 return retval;
103}
104
105static void vmic_remove(struct pci_dev *pdev)
106{
107 iounmap(vmic_base);
108 pci_release_regions(pdev);
109 pci_disable_device(pdev);
110
111}
112
113static void __exit vmic_exit(void)
114{
115 pci_unregister_driver(&vmic_driver);
116}
117
118MODULE_DESCRIPTION("VMIVME-7805 board support driver");
119MODULE_AUTHOR("Arthur Benilov <arthur.benilov@iba-group.com>");
120MODULE_LICENSE("GPL");
121
122module_init(vmic_init);
123module_exit(vmic_exit);
124
diff --git a/drivers/staging/vme/boards/vme_vmivme7805.h b/drivers/staging/vme/boards/vme_vmivme7805.h
new file mode 100644
index 000000000000..44c2c449808c
--- /dev/null
+++ b/drivers/staging/vme/boards/vme_vmivme7805.h
@@ -0,0 +1,37 @@
1/*
2 * vmivme_7805.h
3 *
4 * Support for the VMIVME-7805 board access to the Universe II bridge.
5 *
6 * Author: Arthur Benilov <arthur.benilov@iba-group.com>
7 * Copyright 2010 Ion Beam Application, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15
16#ifndef _VMIVME_7805_H
17#define _VMIVME_7805_H
18
19#ifndef PCI_VENDOR_ID_VMIC
20#define PCI_VENDOR_ID_VMIC 0x114A
21#endif
22
23#ifndef PCI_DEVICE_ID_VTIMR
24#define PCI_DEVICE_ID_VTIMR 0x0004
25#endif
26
27#define VME_CONTROL 0x0000
28#define BM_VME_CONTROL_MASTER_ENDIAN 0x0001
29#define BM_VME_CONTROL_SLAVE_ENDIAN 0x0002
30#define BM_VME_CONTROL_ABLE 0x0004
31#define BM_VME_CONTROL_BERRI 0x0040
32#define BM_VME_CONTROL_BERRST 0x0080
33#define BM_VME_CONTROL_BPENA 0x0400
34#define BM_VME_CONTROL_VBENA 0x0800
35
36#endif /* _VMIVME_7805_H */
37
diff --git a/drivers/staging/vme/bridges/Kconfig b/drivers/staging/vme/bridges/Kconfig
index 023cceba0c59..9331064e0476 100644
--- a/drivers/staging/vme/bridges/Kconfig
+++ b/drivers/staging/vme/bridges/Kconfig
@@ -2,12 +2,14 @@ comment "VME Bridge Drivers"
2 2
3config VME_CA91CX42 3config VME_CA91CX42
4 tristate "Universe II" 4 tristate "Universe II"
5 depends on VIRT_TO_BUS
5 help 6 help
6 If you say Y here you get support for the Tundra CA91C142 7 If you say Y here you get support for the Tundra CA91C142
7 (Universe II) VME bridge chip. 8 (Universe II) VME bridge chip.
8 9
9config VME_TSI148 10config VME_TSI148
10 tristate "Tempe" 11 tristate "Tempe"
12 depends on VIRT_TO_BUS
11 help 13 help
12 If you say Y here you get support for the Tundra TSI148 VME bridge 14 If you say Y here you get support for the Tundra TSI148 VME bridge
13 chip. 15 chip.
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
index 1cf3e91db59d..2795ff2411e0 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.c
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Support for the Tundra Universe I/II VME-PCI Bridge Chips 2 * Support for the Tundra Universe I/II VME-PCI Bridge Chips
3 * 3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com> 4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 5 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
6 * 6 *
7 * Based on work by Tom Armistead and Ajit Prem 7 * Based on work by Tom Armistead and Ajit Prem
8 * Copyright 2004 Motorola Inc. 8 * Copyright 2004 Motorola Inc.
@@ -38,25 +38,12 @@ static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *);
38static void ca91cx42_remove(struct pci_dev *); 38static void ca91cx42_remove(struct pci_dev *);
39static void __exit ca91cx42_exit(void); 39static void __exit ca91cx42_exit(void);
40 40
41struct vme_bridge *ca91cx42_bridge; 41/* Module parameters */
42wait_queue_head_t dma_queue; 42static int geoid;
43wait_queue_head_t iack_queue;
44wait_queue_head_t lm_queue;
45wait_queue_head_t mbox_queue;
46
47void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */
48void *crcsr_kernel;
49dma_addr_t crcsr_bus;
50
51struct mutex vme_rmw; /* Only one RMW cycle at a time */
52struct mutex vme_int; /*
53 * Only one VME interrupt can be
54 * generated at a time, provide locking
55 */
56 43
57static char driver_name[] = "vme_ca91cx42"; 44static char driver_name[] = "vme_ca91cx42";
58 45
59static struct pci_device_id ca91cx42_ids[] = { 46static const struct pci_device_id ca91cx42_ids[] = {
60 { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, 47 { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) },
61 { }, 48 { },
62}; 49};
@@ -68,14 +55,14 @@ static struct pci_driver ca91cx42_driver = {
68 .remove = ca91cx42_remove, 55 .remove = ca91cx42_remove,
69}; 56};
70 57
71static u32 ca91cx42_DMA_irqhandler(void) 58static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge)
72{ 59{
73 wake_up(&dma_queue); 60 wake_up(&(bridge->dma_queue));
74 61
75 return CA91CX42_LINT_DMA; 62 return CA91CX42_LINT_DMA;
76} 63}
77 64
78static u32 ca91cx42_LM_irqhandler(u32 stat) 65static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat)
79{ 66{
80 int i; 67 int i;
81 u32 serviced = 0; 68 u32 serviced = 0;
@@ -83,7 +70,7 @@ static u32 ca91cx42_LM_irqhandler(u32 stat)
83 for (i = 0; i < 4; i++) { 70 for (i = 0; i < 4; i++) {
84 if (stat & CA91CX42_LINT_LM[i]) { 71 if (stat & CA91CX42_LINT_LM[i]) {
85 /* We only enable interrupts if the callback is set */ 72 /* We only enable interrupts if the callback is set */
86 lm_callback[i](i); 73 bridge->lm_callback[i](i);
87 serviced |= CA91CX42_LINT_LM[i]; 74 serviced |= CA91CX42_LINT_LM[i];
88 } 75 }
89 } 76 }
@@ -92,40 +79,25 @@ static u32 ca91cx42_LM_irqhandler(u32 stat)
92} 79}
93 80
94/* XXX This needs to be split into 4 queues */ 81/* XXX This needs to be split into 4 queues */
95static u32 ca91cx42_MB_irqhandler(int mbox_mask) 82static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask)
96{ 83{
97 wake_up(&mbox_queue); 84 wake_up(&(bridge->mbox_queue));
98 85
99 return CA91CX42_LINT_MBOX; 86 return CA91CX42_LINT_MBOX;
100} 87}
101 88
102static u32 ca91cx42_IACK_irqhandler(void) 89static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge)
103{ 90{
104 wake_up(&iack_queue); 91 wake_up(&(bridge->iack_queue));
105 92
106 return CA91CX42_LINT_SW_IACK; 93 return CA91CX42_LINT_SW_IACK;
107} 94}
108 95
109#if 0 96static u32 ca91cx42_VERR_irqhandler(struct ca91cx42_driver *bridge)
110int ca91cx42_bus_error_chk(int clrflag)
111{
112 int tmp;
113 tmp = ioread32(ca91cx42_bridge->base + PCI_COMMAND);
114 if (tmp & 0x08000000) { /* S_TA is Set */
115 if (clrflag)
116 iowrite32(tmp | 0x08000000,
117 ca91cx42_bridge->base + PCI_COMMAND);
118 return 1;
119 }
120 return 0;
121}
122#endif
123
124static u32 ca91cx42_VERR_irqhandler(void)
125{ 97{
126 int val; 98 int val;
127 99
128 val = ioread32(ca91cx42_bridge->base + DGCS); 100 val = ioread32(bridge->base + DGCS);
129 101
130 if (!(val & 0x00000800)) { 102 if (!(val & 0x00000800)) {
131 printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read " 103 printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read "
@@ -135,11 +107,11 @@ static u32 ca91cx42_VERR_irqhandler(void)
135 return CA91CX42_LINT_VERR; 107 return CA91CX42_LINT_VERR;
136} 108}
137 109
138static u32 ca91cx42_LERR_irqhandler(void) 110static u32 ca91cx42_LERR_irqhandler(struct ca91cx42_driver *bridge)
139{ 111{
140 int val; 112 int val;
141 113
142 val = ioread32(ca91cx42_bridge->base + DGCS); 114 val = ioread32(bridge->base + DGCS);
143 115
144 if (!(val & 0x00000800)) { 116 if (!(val & 0x00000800)) {
145 printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read " 117 printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read "
@@ -151,13 +123,18 @@ static u32 ca91cx42_LERR_irqhandler(void)
151} 123}
152 124
153 125
154static u32 ca91cx42_VIRQ_irqhandler(int stat) 126static u32 ca91cx42_VIRQ_irqhandler(struct vme_bridge *ca91cx42_bridge,
127 int stat)
155{ 128{
156 int vec, i, serviced = 0; 129 int vec, i, serviced = 0;
130 struct ca91cx42_driver *bridge;
131
132 bridge = ca91cx42_bridge->driver_priv;
133
157 134
158 for (i = 7; i > 0; i--) { 135 for (i = 7; i > 0; i--) {
159 if (stat & (1 << i)) { 136 if (stat & (1 << i)) {
160 vec = ioread32(ca91cx42_bridge->base + 137 vec = ioread32(bridge->base +
161 CA91CX42_V_STATID[i]) & 0xff; 138 CA91CX42_V_STATID[i]) & 0xff;
162 139
163 vme_irq_handler(ca91cx42_bridge, i, vec); 140 vme_irq_handler(ca91cx42_bridge, i, vec);
@@ -169,15 +146,18 @@ static u32 ca91cx42_VIRQ_irqhandler(int stat)
169 return serviced; 146 return serviced;
170} 147}
171 148
172static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id) 149static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr)
173{ 150{
174 u32 stat, enable, serviced = 0; 151 u32 stat, enable, serviced = 0;
152 struct vme_bridge *ca91cx42_bridge;
153 struct ca91cx42_driver *bridge;
175 154
176 if (dev_id != ca91cx42_bridge->base) 155 ca91cx42_bridge = ptr;
177 return IRQ_NONE;
178 156
179 enable = ioread32(ca91cx42_bridge->base + LINT_EN); 157 bridge = ca91cx42_bridge->driver_priv;
180 stat = ioread32(ca91cx42_bridge->base + LINT_STAT); 158
159 enable = ioread32(bridge->base + LINT_EN);
160 stat = ioread32(bridge->base + LINT_STAT);
181 161
182 /* Only look at unmasked interrupts */ 162 /* Only look at unmasked interrupts */
183 stat &= enable; 163 stat &= enable;
@@ -186,42 +166,45 @@ static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id)
186 return IRQ_NONE; 166 return IRQ_NONE;
187 167
188 if (stat & CA91CX42_LINT_DMA) 168 if (stat & CA91CX42_LINT_DMA)
189 serviced |= ca91cx42_DMA_irqhandler(); 169 serviced |= ca91cx42_DMA_irqhandler(bridge);
190 if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | 170 if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 |
191 CA91CX42_LINT_LM3)) 171 CA91CX42_LINT_LM3))
192 serviced |= ca91cx42_LM_irqhandler(stat); 172 serviced |= ca91cx42_LM_irqhandler(bridge, stat);
193 if (stat & CA91CX42_LINT_MBOX) 173 if (stat & CA91CX42_LINT_MBOX)
194 serviced |= ca91cx42_MB_irqhandler(stat); 174 serviced |= ca91cx42_MB_irqhandler(bridge, stat);
195 if (stat & CA91CX42_LINT_SW_IACK) 175 if (stat & CA91CX42_LINT_SW_IACK)
196 serviced |= ca91cx42_IACK_irqhandler(); 176 serviced |= ca91cx42_IACK_irqhandler(bridge);
197 if (stat & CA91CX42_LINT_VERR) 177 if (stat & CA91CX42_LINT_VERR)
198 serviced |= ca91cx42_VERR_irqhandler(); 178 serviced |= ca91cx42_VERR_irqhandler(bridge);
199 if (stat & CA91CX42_LINT_LERR) 179 if (stat & CA91CX42_LINT_LERR)
200 serviced |= ca91cx42_LERR_irqhandler(); 180 serviced |= ca91cx42_LERR_irqhandler(bridge);
201 if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | 181 if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 |
202 CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | 182 CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 |
203 CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | 183 CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 |
204 CA91CX42_LINT_VIRQ7)) 184 CA91CX42_LINT_VIRQ7))
205 serviced |= ca91cx42_VIRQ_irqhandler(stat); 185 serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat);
206 186
207 /* Clear serviced interrupts */ 187 /* Clear serviced interrupts */
208 iowrite32(stat, ca91cx42_bridge->base + LINT_STAT); 188 iowrite32(stat, bridge->base + LINT_STAT);
209 189
210 return IRQ_HANDLED; 190 return IRQ_HANDLED;
211} 191}
212 192
213static int ca91cx42_irq_init(struct vme_bridge *bridge) 193static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge)
214{ 194{
215 int result, tmp; 195 int result, tmp;
216 struct pci_dev *pdev; 196 struct pci_dev *pdev;
197 struct ca91cx42_driver *bridge;
198
199 bridge = ca91cx42_bridge->driver_priv;
217 200
218 /* Need pdev */ 201 /* Need pdev */
219 pdev = container_of(bridge->parent, struct pci_dev, dev); 202 pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev);
220 203
221 /* Initialise list for VME bus errors */ 204 /* Initialise list for VME bus errors */
222 INIT_LIST_HEAD(&(bridge->vme_errors)); 205 INIT_LIST_HEAD(&(ca91cx42_bridge->vme_errors));
223 206
224 mutex_init(&(bridge->irq_mtx)); 207 mutex_init(&(ca91cx42_bridge->irq_mtx));
225 208
226 /* Disable interrupts from PCI to VME */ 209 /* Disable interrupts from PCI to VME */
227 iowrite32(0, bridge->base + VINT_EN); 210 iowrite32(0, bridge->base + VINT_EN);
@@ -232,7 +215,7 @@ static int ca91cx42_irq_init(struct vme_bridge *bridge)
232 iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); 215 iowrite32(0x00FFFFFF, bridge->base + LINT_STAT);
233 216
234 result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED, 217 result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED,
235 driver_name, pdev); 218 driver_name, ca91cx42_bridge);
236 if (result) { 219 if (result) {
237 dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", 220 dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
238 pdev->irq); 221 pdev->irq);
@@ -254,15 +237,16 @@ static int ca91cx42_irq_init(struct vme_bridge *bridge)
254 return 0; 237 return 0;
255} 238}
256 239
257static void ca91cx42_irq_exit(struct pci_dev *pdev) 240static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge,
241 struct pci_dev *pdev)
258{ 242{
259 /* Disable interrupts from PCI to VME */ 243 /* Disable interrupts from PCI to VME */
260 iowrite32(0, ca91cx42_bridge->base + VINT_EN); 244 iowrite32(0, bridge->base + VINT_EN);
261 245
262 /* Disable PCI interrupts */ 246 /* Disable PCI interrupts */
263 iowrite32(0, ca91cx42_bridge->base + LINT_EN); 247 iowrite32(0, bridge->base + LINT_EN);
264 /* Clear Any Pending PCI Interrupts */ 248 /* Clear Any Pending PCI Interrupts */
265 iowrite32(0x00FFFFFF, ca91cx42_bridge->base + LINT_STAT); 249 iowrite32(0x00FFFFFF, bridge->base + LINT_STAT);
266 250
267 free_irq(pdev->irq, pdev); 251 free_irq(pdev->irq, pdev);
268} 252}
@@ -270,21 +254,25 @@ static void ca91cx42_irq_exit(struct pci_dev *pdev)
270/* 254/*
271 * Set up an VME interrupt 255 * Set up an VME interrupt
272 */ 256 */
273void ca91cx42_irq_set(int level, int state, int sync) 257void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, int state,
258 int sync)
274 259
275{ 260{
276 struct pci_dev *pdev; 261 struct pci_dev *pdev;
277 u32 tmp; 262 u32 tmp;
263 struct ca91cx42_driver *bridge;
264
265 bridge = ca91cx42_bridge->driver_priv;
278 266
279 /* Enable IRQ level */ 267 /* Enable IRQ level */
280 tmp = ioread32(ca91cx42_bridge->base + LINT_EN); 268 tmp = ioread32(bridge->base + LINT_EN);
281 269
282 if (state == 0) 270 if (state == 0)
283 tmp &= ~CA91CX42_LINT_VIRQ[level]; 271 tmp &= ~CA91CX42_LINT_VIRQ[level];
284 else 272 else
285 tmp |= CA91CX42_LINT_VIRQ[level]; 273 tmp |= CA91CX42_LINT_VIRQ[level];
286 274
287 iowrite32(tmp, ca91cx42_bridge->base + LINT_EN); 275 iowrite32(tmp, bridge->base + LINT_EN);
288 276
289 if ((state == 0) && (sync != 0)) { 277 if ((state == 0) && (sync != 0)) {
290 pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, 278 pdev = container_of(ca91cx42_bridge->parent, struct pci_dev,
@@ -294,34 +282,38 @@ void ca91cx42_irq_set(int level, int state, int sync)
294 } 282 }
295} 283}
296 284
297int ca91cx42_irq_generate(int level, int statid) 285int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level,
286 int statid)
298{ 287{
299 u32 tmp; 288 u32 tmp;
289 struct ca91cx42_driver *bridge;
290
291 bridge = ca91cx42_bridge->driver_priv;
300 292
301 /* Universe can only generate even vectors */ 293 /* Universe can only generate even vectors */
302 if (statid & 1) 294 if (statid & 1)
303 return -EINVAL; 295 return -EINVAL;
304 296
305 mutex_lock(&(vme_int)); 297 mutex_lock(&(bridge->vme_int));
306 298
307 tmp = ioread32(ca91cx42_bridge->base + VINT_EN); 299 tmp = ioread32(bridge->base + VINT_EN);
308 300
309 /* Set Status/ID */ 301 /* Set Status/ID */
310 iowrite32(statid << 24, ca91cx42_bridge->base + STATID); 302 iowrite32(statid << 24, bridge->base + STATID);
311 303
312 /* Assert VMEbus IRQ */ 304 /* Assert VMEbus IRQ */
313 tmp = tmp | (1 << (level + 24)); 305 tmp = tmp | (1 << (level + 24));
314 iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); 306 iowrite32(tmp, bridge->base + VINT_EN);
315 307
316 /* Wait for IACK */ 308 /* Wait for IACK */
317 wait_event_interruptible(iack_queue, 0); 309 wait_event_interruptible(bridge->iack_queue, 0);
318 310
319 /* Return interrupt to low state */ 311 /* Return interrupt to low state */
320 tmp = ioread32(ca91cx42_bridge->base + VINT_EN); 312 tmp = ioread32(bridge->base + VINT_EN);
321 tmp = tmp & ~(1 << (level + 24)); 313 tmp = tmp & ~(1 << (level + 24));
322 iowrite32(tmp, ca91cx42_bridge->base + VINT_EN); 314 iowrite32(tmp, bridge->base + VINT_EN);
323 315
324 mutex_unlock(&(vme_int)); 316 mutex_unlock(&(bridge->vme_int));
325 317
326 return 0; 318 return 0;
327} 319}
@@ -330,9 +322,12 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
330 unsigned long long vme_base, unsigned long long size, 322 unsigned long long vme_base, unsigned long long size,
331 dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle) 323 dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
332{ 324{
333 unsigned int i, addr = 0, granularity = 0; 325 unsigned int i, addr = 0, granularity;
334 unsigned int temp_ctl = 0; 326 unsigned int temp_ctl = 0;
335 unsigned int vme_bound, pci_offset; 327 unsigned int vme_bound, pci_offset;
328 struct ca91cx42_driver *bridge;
329
330 bridge = image->parent->driver_priv;
336 331
337 i = image->number; 332 i = image->number;
338 333
@@ -366,13 +361,9 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
366 * Bound address is a valid address for the window, adjust 361 * Bound address is a valid address for the window, adjust
367 * accordingly 362 * accordingly
368 */ 363 */
369 vme_bound = vme_base + size - granularity; 364 vme_bound = vme_base + size;
370 pci_offset = pci_base - vme_base; 365 pci_offset = pci_base - vme_base;
371 366
372 /* XXX Need to check that vme_base, vme_bound and pci_offset aren't
373 * too big for registers
374 */
375
376 if ((i == 0) || (i == 4)) 367 if ((i == 0) || (i == 4))
377 granularity = 0x1000; 368 granularity = 0x1000;
378 else 369 else
@@ -392,26 +383,14 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
392 } 383 }
393 384
394 /* Disable while we are mucking around */ 385 /* Disable while we are mucking around */
395 temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 386 temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]);
396 temp_ctl &= ~CA91CX42_VSI_CTL_EN; 387 temp_ctl &= ~CA91CX42_VSI_CTL_EN;
397 iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 388 iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
398 389
399 /* Setup mapping */ 390 /* Setup mapping */
400 iowrite32(vme_base, ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); 391 iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]);
401 iowrite32(vme_bound, ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); 392 iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]);
402 iowrite32(pci_offset, ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); 393 iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]);
403
404/* XXX Prefetch stuff currently unsupported */
405#if 0
406 if (vmeIn->wrPostEnable)
407 temp_ctl |= CA91CX42_VSI_CTL_PWEN;
408 if (vmeIn->prefetchEnable)
409 temp_ctl |= CA91CX42_VSI_CTL_PREN;
410 if (vmeIn->rmwLock)
411 temp_ctl |= CA91CX42_VSI_CTL_LLRMW;
412 if (vmeIn->data64BitCapable)
413 temp_ctl |= CA91CX42_VSI_CTL_LD64EN;
414#endif
415 394
416 /* Setup address space */ 395 /* Setup address space */
417 temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M; 396 temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M;
@@ -429,12 +408,12 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
429 temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA; 408 temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA;
430 409
431 /* Write ctl reg without enable */ 410 /* Write ctl reg without enable */
432 iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 411 iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
433 412
434 if (enabled) 413 if (enabled)
435 temp_ctl |= CA91CX42_VSI_CTL_EN; 414 temp_ctl |= CA91CX42_VSI_CTL_EN;
436 415
437 iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 416 iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]);
438 417
439 return 0; 418 return 0;
440} 419}
@@ -445,6 +424,9 @@ int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled,
445{ 424{
446 unsigned int i, granularity = 0, ctl = 0; 425 unsigned int i, granularity = 0, ctl = 0;
447 unsigned long long vme_bound, pci_offset; 426 unsigned long long vme_bound, pci_offset;
427 struct ca91cx42_driver *bridge;
428
429 bridge = image->parent->driver_priv;
448 430
449 i = image->number; 431 i = image->number;
450 432
@@ -454,11 +436,11 @@ int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled,
454 granularity = 0x10000; 436 granularity = 0x10000;
455 437
456 /* Read Registers */ 438 /* Read Registers */
457 ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]); 439 ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]);
458 440
459 *vme_base = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BS[i]); 441 *vme_base = ioread32(bridge->base + CA91CX42_VSI_BS[i]);
460 vme_bound = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BD[i]); 442 vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]);
461 pci_offset = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_TO[i]); 443 pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]);
462 444
463 *pci_base = (dma_addr_t)vme_base + pci_offset; 445 *pci_base = (dma_addr_t)vme_base + pci_offset;
464 *size = (unsigned long long)((vme_bound - *vme_base) + granularity); 446 *size = (unsigned long long)((vme_bound - *vme_base) + granularity);
@@ -502,6 +484,9 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
502 unsigned long long existing_size; 484 unsigned long long existing_size;
503 int retval = 0; 485 int retval = 0;
504 struct pci_dev *pdev; 486 struct pci_dev *pdev;
487 struct vme_bridge *ca91cx42_bridge;
488
489 ca91cx42_bridge = image->parent;
505 490
506 /* Find pci_dev container of dev */ 491 /* Find pci_dev container of dev */
507 if (ca91cx42_bridge->parent == NULL) { 492 if (ca91cx42_bridge->parent == NULL) {
@@ -510,8 +495,8 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
510 } 495 }
511 pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); 496 pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev);
512 497
513 existing_size = (unsigned long long)(image->pci_resource.end - 498 existing_size = (unsigned long long)(image->bus_resource.end -
514 image->pci_resource.start); 499 image->bus_resource.start);
515 500
516 /* If the existing size is OK, return */ 501 /* If the existing size is OK, return */
517 if (existing_size == (size - 1)) 502 if (existing_size == (size - 1))
@@ -520,15 +505,15 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
520 if (existing_size != 0) { 505 if (existing_size != 0) {
521 iounmap(image->kern_base); 506 iounmap(image->kern_base);
522 image->kern_base = NULL; 507 image->kern_base = NULL;
523 if (image->pci_resource.name != NULL) 508 if (image->bus_resource.name != NULL)
524 kfree(image->pci_resource.name); 509 kfree(image->bus_resource.name);
525 release_resource(&(image->pci_resource)); 510 release_resource(&(image->bus_resource));
526 memset(&(image->pci_resource), 0, sizeof(struct resource)); 511 memset(&(image->bus_resource), 0, sizeof(struct resource));
527 } 512 }
528 513
529 if (image->pci_resource.name == NULL) { 514 if (image->bus_resource.name == NULL) {
530 image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); 515 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
531 if (image->pci_resource.name == NULL) { 516 if (image->bus_resource.name == NULL) {
532 printk(KERN_ERR "Unable to allocate memory for resource" 517 printk(KERN_ERR "Unable to allocate memory for resource"
533 " name\n"); 518 " name\n");
534 retval = -ENOMEM; 519 retval = -ENOMEM;
@@ -536,26 +521,26 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
536 } 521 }
537 } 522 }
538 523
539 sprintf((char *)image->pci_resource.name, "%s.%d", 524 sprintf((char *)image->bus_resource.name, "%s.%d",
540 ca91cx42_bridge->name, image->number); 525 ca91cx42_bridge->name, image->number);
541 526
542 image->pci_resource.start = 0; 527 image->bus_resource.start = 0;
543 image->pci_resource.end = (unsigned long)size; 528 image->bus_resource.end = (unsigned long)size;
544 image->pci_resource.flags = IORESOURCE_MEM; 529 image->bus_resource.flags = IORESOURCE_MEM;
545 530
546 retval = pci_bus_alloc_resource(pdev->bus, 531 retval = pci_bus_alloc_resource(pdev->bus,
547 &(image->pci_resource), size, size, PCIBIOS_MIN_MEM, 532 &(image->bus_resource), size, size, PCIBIOS_MIN_MEM,
548 0, NULL, NULL); 533 0, NULL, NULL);
549 if (retval) { 534 if (retval) {
550 printk(KERN_ERR "Failed to allocate mem resource for " 535 printk(KERN_ERR "Failed to allocate mem resource for "
551 "window %d size 0x%lx start 0x%lx\n", 536 "window %d size 0x%lx start 0x%lx\n",
552 image->number, (unsigned long)size, 537 image->number, (unsigned long)size,
553 (unsigned long)image->pci_resource.start); 538 (unsigned long)image->bus_resource.start);
554 goto err_resource; 539 goto err_resource;
555 } 540 }
556 541
557 image->kern_base = ioremap_nocache( 542 image->kern_base = ioremap_nocache(
558 image->pci_resource.start, size); 543 image->bus_resource.start, size);
559 if (image->kern_base == NULL) { 544 if (image->kern_base == NULL) {
560 printk(KERN_ERR "Failed to remap resource\n"); 545 printk(KERN_ERR "Failed to remap resource\n");
561 retval = -ENOMEM; 546 retval = -ENOMEM;
@@ -567,24 +552,24 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image,
567 iounmap(image->kern_base); 552 iounmap(image->kern_base);
568 image->kern_base = NULL; 553 image->kern_base = NULL;
569err_remap: 554err_remap:
570 release_resource(&(image->pci_resource)); 555 release_resource(&(image->bus_resource));
571err_resource: 556err_resource:
572 kfree(image->pci_resource.name); 557 kfree(image->bus_resource.name);
573 memset(&(image->pci_resource), 0, sizeof(struct resource)); 558 memset(&(image->bus_resource), 0, sizeof(struct resource));
574err_name: 559err_name:
575 return retval; 560 return retval;
576} 561}
577 562
578/* 563/*
579 * * Free and unmap PCI Resource 564 * Free and unmap PCI Resource
580 * */ 565 */
581static void ca91cx42_free_resource(struct vme_master_resource *image) 566static void ca91cx42_free_resource(struct vme_master_resource *image)
582{ 567{
583 iounmap(image->kern_base); 568 iounmap(image->kern_base);
584 image->kern_base = NULL; 569 image->kern_base = NULL;
585 release_resource(&(image->pci_resource)); 570 release_resource(&(image->bus_resource));
586 kfree(image->pci_resource.name); 571 kfree(image->bus_resource.name);
587 memset(&(image->pci_resource), 0, sizeof(struct resource)); 572 memset(&(image->bus_resource), 0, sizeof(struct resource));
588} 573}
589 574
590 575
@@ -593,17 +578,27 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
593 vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) 578 vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
594{ 579{
595 int retval = 0; 580 int retval = 0;
596 unsigned int i; 581 unsigned int i, granularity = 0;
597 unsigned int temp_ctl = 0; 582 unsigned int temp_ctl = 0;
598 unsigned long long pci_bound, vme_offset, pci_base; 583 unsigned long long pci_bound, vme_offset, pci_base;
584 struct ca91cx42_driver *bridge;
585
586 bridge = image->parent->driver_priv;
587
588 i = image->number;
589
590 if ((i == 0) || (i == 4))
591 granularity = 0x1000;
592 else
593 granularity = 0x10000;
599 594
600 /* Verify input data */ 595 /* Verify input data */
601 if (vme_base & 0xFFF) { 596 if (vme_base & (granularity - 1)) {
602 printk(KERN_ERR "Invalid VME Window alignment\n"); 597 printk(KERN_ERR "Invalid VME Window alignment\n");
603 retval = -EINVAL; 598 retval = -EINVAL;
604 goto err_window; 599 goto err_window;
605 } 600 }
606 if (size & 0xFFF) { 601 if (size & (granularity - 1)) {
607 printk(KERN_ERR "Invalid VME Window alignment\n"); 602 printk(KERN_ERR "Invalid VME Window alignment\n");
608 retval = -EINVAL; 603 retval = -EINVAL;
609 goto err_window; 604 goto err_window;
@@ -611,9 +606,6 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
611 606
612 spin_lock(&(image->lock)); 607 spin_lock(&(image->lock));
613 608
614 /* XXX We should do this much later, so that we can exit without
615 * needing to redo the mapping...
616 */
617 /* 609 /*
618 * Let's allocate the resource here rather than further up the stack as 610 * Let's allocate the resource here rather than further up the stack as
619 * it avoids pushing loads of bus dependant stuff up the stack 611 * it avoids pushing loads of bus dependant stuff up the stack
@@ -627,27 +619,19 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
627 goto err_res; 619 goto err_res;
628 } 620 }
629 621
630 pci_base = (unsigned long long)image->pci_resource.start; 622 pci_base = (unsigned long long)image->bus_resource.start;
631 623
632 /* 624 /*
633 * Bound address is a valid address for the window, adjust 625 * Bound address is a valid address for the window, adjust
634 * according to window granularity. 626 * according to window granularity.
635 */ 627 */
636 pci_bound = pci_base + (size - 0x1000); 628 pci_bound = pci_base + size;
637 vme_offset = vme_base - pci_base; 629 vme_offset = vme_base - pci_base;
638 630
639 i = image->number;
640
641 /* Disable while we are mucking around */ 631 /* Disable while we are mucking around */
642 temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 632 temp_ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]);
643 temp_ctl &= ~CA91CX42_LSI_CTL_EN; 633 temp_ctl &= ~CA91CX42_LSI_CTL_EN;
644 iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 634 iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
645
646/* XXX Prefetch stuff currently unsupported */
647#if 0
648 if (vmeOut->wrPostEnable)
649 temp_ctl |= 0x40000000;
650#endif
651 635
652 /* Setup cycle types */ 636 /* Setup cycle types */
653 temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M; 637 temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M;
@@ -718,17 +702,17 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
718 temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM; 702 temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM;
719 703
720 /* Setup mapping */ 704 /* Setup mapping */
721 iowrite32(pci_base, ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 705 iowrite32(pci_base, bridge->base + CA91CX42_LSI_BS[i]);
722 iowrite32(pci_bound, ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 706 iowrite32(pci_bound, bridge->base + CA91CX42_LSI_BD[i]);
723 iowrite32(vme_offset, ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 707 iowrite32(vme_offset, bridge->base + CA91CX42_LSI_TO[i]);
724 708
725 /* Write ctl reg without enable */ 709 /* Write ctl reg without enable */
726 iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 710 iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
727 711
728 if (enabled) 712 if (enabled)
729 temp_ctl |= CA91CX42_LSI_CTL_EN; 713 temp_ctl |= CA91CX42_LSI_CTL_EN;
730 714
731 iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 715 iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]);
732 716
733 spin_unlock(&(image->lock)); 717 spin_unlock(&(image->lock));
734 return 0; 718 return 0;
@@ -747,17 +731,20 @@ int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
747{ 731{
748 unsigned int i, ctl; 732 unsigned int i, ctl;
749 unsigned long long pci_base, pci_bound, vme_offset; 733 unsigned long long pci_base, pci_bound, vme_offset;
734 struct ca91cx42_driver *bridge;
735
736 bridge = image->parent->driver_priv;
750 737
751 i = image->number; 738 i = image->number;
752 739
753 ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]); 740 ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]);
754 741
755 pci_base = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]); 742 pci_base = ioread32(bridge->base + CA91CX42_LSI_BS[i]);
756 vme_offset = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]); 743 vme_offset = ioread32(bridge->base + CA91CX42_LSI_TO[i]);
757 pci_bound = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]); 744 pci_bound = ioread32(bridge->base + CA91CX42_LSI_BD[i]);
758 745
759 *vme_base = pci_base + vme_offset; 746 *vme_base = pci_base + vme_offset;
760 *size = (pci_bound - pci_base) + 0x1000; 747 *size = (unsigned long long)(pci_bound - pci_base);
761 748
762 *enabled = 0; 749 *enabled = 0;
763 *aspace = 0; 750 *aspace = 0;
@@ -822,12 +809,6 @@ int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
822 break; 809 break;
823 } 810 }
824 811
825/* XXX Prefetch stuff currently unsupported */
826#if 0
827 if (ctl & 0x40000000)
828 vmeOut->wrPostEnable = 1;
829#endif
830
831 return 0; 812 return 0;
832} 813}
833 814
@@ -850,7 +831,7 @@ int ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
850ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf, 831ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf,
851 size_t count, loff_t offset) 832 size_t count, loff_t offset)
852{ 833{
853 int retval; 834 ssize_t retval;
854 835
855 spin_lock(&(image->lock)); 836 spin_lock(&(image->lock));
856 837
@@ -877,12 +858,528 @@ ssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf,
877 return retval; 858 return retval;
878} 859}
879 860
880int ca91cx42_slot_get(void) 861unsigned int ca91cx42_master_rmw(struct vme_master_resource *image,
862 unsigned int mask, unsigned int compare, unsigned int swap,
863 loff_t offset)
864{
865 u32 pci_addr, result;
866 int i;
867 struct ca91cx42_driver *bridge;
868 struct device *dev;
869
870 bridge = image->parent->driver_priv;
871 dev = image->parent->parent;
872
873 /* Find the PCI address that maps to the desired VME address */
874 i = image->number;
875
876 /* Locking as we can only do one of these at a time */
877 mutex_lock(&(bridge->vme_rmw));
878
879 /* Lock image */
880 spin_lock(&(image->lock));
881
882 pci_addr = (u32)image->kern_base + offset;
883
884 /* Address must be 4-byte aligned */
885 if (pci_addr & 0x3) {
886 dev_err(dev, "RMW Address not 4-byte aligned\n");
887 return -EINVAL;
888 }
889
890 /* Ensure RMW Disabled whilst configuring */
891 iowrite32(0, bridge->base + SCYC_CTL);
892
893 /* Configure registers */
894 iowrite32(mask, bridge->base + SCYC_EN);
895 iowrite32(compare, bridge->base + SCYC_CMP);
896 iowrite32(swap, bridge->base + SCYC_SWP);
897 iowrite32(pci_addr, bridge->base + SCYC_ADDR);
898
899 /* Enable RMW */
900 iowrite32(CA91CX42_SCYC_CTL_CYC_RMW, bridge->base + SCYC_CTL);
901
902 /* Kick process off with a read to the required address. */
903 result = ioread32(image->kern_base + offset);
904
905 /* Disable RMW */
906 iowrite32(0, bridge->base + SCYC_CTL);
907
908 spin_unlock(&(image->lock));
909
910 mutex_unlock(&(bridge->vme_rmw));
911
912 return result;
913}
914
915int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
916 struct vme_dma_attr *dest, size_t count)
917{
918 struct ca91cx42_dma_entry *entry, *prev;
919 struct vme_dma_pci *pci_attr;
920 struct vme_dma_vme *vme_attr;
921 dma_addr_t desc_ptr;
922 int retval = 0;
923
924 /* XXX descriptor must be aligned on 64-bit boundaries */
925 entry = (struct ca91cx42_dma_entry *)
926 kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL);
927 if (entry == NULL) {
928 printk(KERN_ERR "Failed to allocate memory for dma resource "
929 "structure\n");
930 retval = -ENOMEM;
931 goto err_mem;
932 }
933
934 /* Test descriptor alignment */
935 if ((unsigned long)&(entry->descriptor) & CA91CX42_DCPP_M) {
936 printk("Descriptor not aligned to 16 byte boundary as "
937 "required: %p\n", &(entry->descriptor));
938 retval = -EINVAL;
939 goto err_align;
940 }
941
942 memset(&(entry->descriptor), 0, sizeof(struct ca91cx42_dma_descriptor));
943
944 if (dest->type == VME_DMA_VME) {
945 entry->descriptor.dctl |= CA91CX42_DCTL_L2V;
946 vme_attr = (struct vme_dma_vme *)dest->private;
947 pci_attr = (struct vme_dma_pci *)src->private;
948 } else {
949 vme_attr = (struct vme_dma_vme *)src->private;
950 pci_attr = (struct vme_dma_pci *)dest->private;
951 }
952
953 /* Check we can do fullfill required attributes */
954 if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 |
955 VME_USER2)) != 0) {
956
957 printk(KERN_ERR "Unsupported cycle type\n");
958 retval = -EINVAL;
959 goto err_aspace;
960 }
961
962 if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER |
963 VME_PROG | VME_DATA)) != 0) {
964
965 printk(KERN_ERR "Unsupported cycle type\n");
966 retval = -EINVAL;
967 goto err_cycle;
968 }
969
970 /* Check to see if we can fullfill source and destination */
971 if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) ||
972 ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) {
973
974 printk(KERN_ERR "Cannot perform transfer with this "
975 "source-destination combination\n");
976 retval = -EINVAL;
977 goto err_direct;
978 }
979
980 /* Setup cycle types */
981 if (vme_attr->cycle & VME_BLT)
982 entry->descriptor.dctl |= CA91CX42_DCTL_VCT_BLT;
983
984 /* Setup data width */
985 switch (vme_attr->dwidth) {
986 case VME_D8:
987 entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D8;
988 break;
989 case VME_D16:
990 entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D16;
991 break;
992 case VME_D32:
993 entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D32;
994 break;
995 case VME_D64:
996 entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64;
997 break;
998 default:
999 printk(KERN_ERR "Invalid data width\n");
1000 return -EINVAL;
1001 }
1002
1003 /* Setup address space */
1004 switch (vme_attr->aspace) {
1005 case VME_A16:
1006 entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A16;
1007 break;
1008 case VME_A24:
1009 entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A24;
1010 break;
1011 case VME_A32:
1012 entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A32;
1013 break;
1014 case VME_USER1:
1015 entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER1;
1016 break;
1017 case VME_USER2:
1018 entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2;
1019 break;
1020 default:
1021 printk(KERN_ERR "Invalid address space\n");
1022 return -EINVAL;
1023 break;
1024 }
1025
1026 if (vme_attr->cycle & VME_SUPER)
1027 entry->descriptor.dctl |= CA91CX42_DCTL_SUPER_SUPR;
1028 if (vme_attr->cycle & VME_PROG)
1029 entry->descriptor.dctl |= CA91CX42_DCTL_PGM_PGM;
1030
1031 entry->descriptor.dtbc = count;
1032 entry->descriptor.dla = pci_attr->address;
1033 entry->descriptor.dva = vme_attr->address;
1034 entry->descriptor.dcpp = CA91CX42_DCPP_NULL;
1035
1036 /* Add to list */
1037 list_add_tail(&(entry->list), &(list->entries));
1038
1039 /* Fill out previous descriptors "Next Address" */
1040 if (entry->list.prev != &(list->entries)) {
1041 prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry,
1042 list);
1043 /* We need the bus address for the pointer */
1044 desc_ptr = virt_to_bus(&(entry->descriptor));
1045 prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M;
1046 }
1047
1048 return 0;
1049
1050err_cycle:
1051err_aspace:
1052err_direct:
1053err_align:
1054 kfree(entry);
1055err_mem:
1056 return retval;
1057}
1058
1059static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge)
1060{
1061 u32 tmp;
1062 struct ca91cx42_driver *bridge;
1063
1064 bridge = ca91cx42_bridge->driver_priv;
1065
1066 tmp = ioread32(bridge->base + DGCS);
1067
1068 if (tmp & CA91CX42_DGCS_ACT)
1069 return 0;
1070 else
1071 return 1;
1072}
1073
1074int ca91cx42_dma_list_exec(struct vme_dma_list *list)
1075{
1076 struct vme_dma_resource *ctrlr;
1077 struct ca91cx42_dma_entry *entry;
1078 int retval = 0;
1079 dma_addr_t bus_addr;
1080 u32 val;
1081
1082 struct ca91cx42_driver *bridge;
1083
1084 ctrlr = list->parent;
1085
1086 bridge = ctrlr->parent->driver_priv;
1087
1088 mutex_lock(&(ctrlr->mtx));
1089
1090 if (!(list_empty(&(ctrlr->running)))) {
1091 /*
1092 * XXX We have an active DMA transfer and currently haven't
1093 * sorted out the mechanism for "pending" DMA transfers.
1094 * Return busy.
1095 */
1096 /* Need to add to pending here */
1097 mutex_unlock(&(ctrlr->mtx));
1098 return -EBUSY;
1099 } else {
1100 list_add(&(list->list), &(ctrlr->running));
1101 }
1102
1103 /* Get first bus address and write into registers */
1104 entry = list_first_entry(&(list->entries), struct ca91cx42_dma_entry,
1105 list);
1106
1107 bus_addr = virt_to_bus(&(entry->descriptor));
1108
1109 mutex_unlock(&(ctrlr->mtx));
1110
1111 iowrite32(0, bridge->base + DTBC);
1112 iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP);
1113
1114 /* Start the operation */
1115 val = ioread32(bridge->base + DGCS);
1116
1117 /* XXX Could set VMEbus On and Off Counters here */
1118 val &= (CA91CX42_DGCS_VON_M | CA91CX42_DGCS_VOFF_M);
1119
1120 val |= (CA91CX42_DGCS_CHAIN | CA91CX42_DGCS_STOP | CA91CX42_DGCS_HALT |
1121 CA91CX42_DGCS_DONE | CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR |
1122 CA91CX42_DGCS_PERR);
1123
1124 iowrite32(val, bridge->base + DGCS);
1125
1126 val |= CA91CX42_DGCS_GO;
1127
1128 iowrite32(val, bridge->base + DGCS);
1129
1130 wait_event_interruptible(bridge->dma_queue,
1131 ca91cx42_dma_busy(ctrlr->parent));
1132
1133 /*
1134 * Read status register, this register is valid until we kick off a
1135 * new transfer.
1136 */
1137 val = ioread32(bridge->base + DGCS);
1138
1139 if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR |
1140 CA91CX42_DGCS_PERR)) {
1141
1142 printk(KERN_ERR "ca91c042: DMA Error. DGCS=%08X\n", val);
1143 val = ioread32(bridge->base + DCTL);
1144 }
1145
1146 /* Remove list from running list */
1147 mutex_lock(&(ctrlr->mtx));
1148 list_del(&(list->list));
1149 mutex_unlock(&(ctrlr->mtx));
1150
1151 return retval;
1152
1153}
1154
1155int ca91cx42_dma_list_empty(struct vme_dma_list *list)
1156{
1157 struct list_head *pos, *temp;
1158 struct ca91cx42_dma_entry *entry;
1159
1160 /* detach and free each entry */
1161 list_for_each_safe(pos, temp, &(list->entries)) {
1162 list_del(pos);
1163 entry = list_entry(pos, struct ca91cx42_dma_entry, list);
1164 kfree(entry);
1165 }
1166
1167 return 0;
1168}
1169
1170/*
1171 * All 4 location monitors reside at the same base - this is therefore a
1172 * system wide configuration.
1173 *
1174 * This does not enable the LM monitor - that should be done when the first
1175 * callback is attached and disabled when the last callback is removed.
1176 */
1177int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
1178 vme_address_t aspace, vme_cycle_t cycle)
1179{
1180 u32 temp_base, lm_ctl = 0;
1181 int i;
1182 struct ca91cx42_driver *bridge;
1183 struct device *dev;
1184
1185 bridge = lm->parent->driver_priv;
1186 dev = lm->parent->parent;
1187
1188 /* Check the alignment of the location monitor */
1189 temp_base = (u32)lm_base;
1190 if (temp_base & 0xffff) {
1191 dev_err(dev, "Location monitor must be aligned to 64KB "
1192 "boundary");
1193 return -EINVAL;
1194 }
1195
1196 mutex_lock(&(lm->mtx));
1197
1198 /* If we already have a callback attached, we can't move it! */
1199 for (i = 0; i < lm->monitors; i++) {
1200 if (bridge->lm_callback[i] != NULL) {
1201 mutex_unlock(&(lm->mtx));
1202 dev_err(dev, "Location monitor callback attached, "
1203 "can't reset\n");
1204 return -EBUSY;
1205 }
1206 }
1207
1208 switch (aspace) {
1209 case VME_A16:
1210 lm_ctl |= CA91CX42_LM_CTL_AS_A16;
1211 break;
1212 case VME_A24:
1213 lm_ctl |= CA91CX42_LM_CTL_AS_A24;
1214 break;
1215 case VME_A32:
1216 lm_ctl |= CA91CX42_LM_CTL_AS_A32;
1217 break;
1218 default:
1219 mutex_unlock(&(lm->mtx));
1220 dev_err(dev, "Invalid address space\n");
1221 return -EINVAL;
1222 break;
1223 }
1224
1225 if (cycle & VME_SUPER)
1226 lm_ctl |= CA91CX42_LM_CTL_SUPR;
1227 if (cycle & VME_USER)
1228 lm_ctl |= CA91CX42_LM_CTL_NPRIV;
1229 if (cycle & VME_PROG)
1230 lm_ctl |= CA91CX42_LM_CTL_PGM;
1231 if (cycle & VME_DATA)
1232 lm_ctl |= CA91CX42_LM_CTL_DATA;
1233
1234 iowrite32(lm_base, bridge->base + LM_BS);
1235 iowrite32(lm_ctl, bridge->base + LM_CTL);
1236
1237 mutex_unlock(&(lm->mtx));
1238
1239 return 0;
1240}
1241
1242/* Get configuration of the callback monitor and return whether it is enabled
1243 * or disabled.
1244 */
1245int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base,
1246 vme_address_t *aspace, vme_cycle_t *cycle)
1247{
1248 u32 lm_ctl, enabled = 0;
1249 struct ca91cx42_driver *bridge;
1250
1251 bridge = lm->parent->driver_priv;
1252
1253 mutex_lock(&(lm->mtx));
1254
1255 *lm_base = (unsigned long long)ioread32(bridge->base + LM_BS);
1256 lm_ctl = ioread32(bridge->base + LM_CTL);
1257
1258 if (lm_ctl & CA91CX42_LM_CTL_EN)
1259 enabled = 1;
1260
1261 if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A16)
1262 *aspace = VME_A16;
1263 if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A24)
1264 *aspace = VME_A24;
1265 if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A32)
1266 *aspace = VME_A32;
1267
1268 *cycle = 0;
1269 if (lm_ctl & CA91CX42_LM_CTL_SUPR)
1270 *cycle |= VME_SUPER;
1271 if (lm_ctl & CA91CX42_LM_CTL_NPRIV)
1272 *cycle |= VME_USER;
1273 if (lm_ctl & CA91CX42_LM_CTL_PGM)
1274 *cycle |= VME_PROG;
1275 if (lm_ctl & CA91CX42_LM_CTL_DATA)
1276 *cycle |= VME_DATA;
1277
1278 mutex_unlock(&(lm->mtx));
1279
1280 return enabled;
1281}
1282
1283/*
1284 * Attach a callback to a specific location monitor.
1285 *
1286 * Callback will be passed the monitor triggered.
1287 */
1288int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor,
1289 void (*callback)(int))
1290{
1291 u32 lm_ctl, tmp;
1292 struct ca91cx42_driver *bridge;
1293 struct device *dev;
1294
1295 bridge = lm->parent->driver_priv;
1296 dev = lm->parent->parent;
1297
1298 mutex_lock(&(lm->mtx));
1299
1300 /* Ensure that the location monitor is configured - need PGM or DATA */
1301 lm_ctl = ioread32(bridge->base + LM_CTL);
1302 if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) {
1303 mutex_unlock(&(lm->mtx));
1304 dev_err(dev, "Location monitor not properly configured\n");
1305 return -EINVAL;
1306 }
1307
1308 /* Check that a callback isn't already attached */
1309 if (bridge->lm_callback[monitor] != NULL) {
1310 mutex_unlock(&(lm->mtx));
1311 dev_err(dev, "Existing callback attached\n");
1312 return -EBUSY;
1313 }
1314
1315 /* Attach callback */
1316 bridge->lm_callback[monitor] = callback;
1317
1318 /* Enable Location Monitor interrupt */
1319 tmp = ioread32(bridge->base + LINT_EN);
1320 tmp |= CA91CX42_LINT_LM[monitor];
1321 iowrite32(tmp, bridge->base + LINT_EN);
1322
1323 /* Ensure that global Location Monitor Enable set */
1324 if ((lm_ctl & CA91CX42_LM_CTL_EN) == 0) {
1325 lm_ctl |= CA91CX42_LM_CTL_EN;
1326 iowrite32(lm_ctl, bridge->base + LM_CTL);
1327 }
1328
1329 mutex_unlock(&(lm->mtx));
1330
1331 return 0;
1332}
1333
1334/*
1335 * Detach a callback function forn a specific location monitor.
1336 */
1337int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor)
1338{
1339 u32 tmp;
1340 struct ca91cx42_driver *bridge;
1341
1342 bridge = lm->parent->driver_priv;
1343
1344 mutex_lock(&(lm->mtx));
1345
1346 /* Disable Location Monitor and ensure previous interrupts are clear */
1347 tmp = ioread32(bridge->base + LINT_EN);
1348 tmp &= ~CA91CX42_LINT_LM[monitor];
1349 iowrite32(tmp, bridge->base + LINT_EN);
1350
1351 iowrite32(CA91CX42_LINT_LM[monitor],
1352 bridge->base + LINT_STAT);
1353
1354 /* Detach callback */
1355 bridge->lm_callback[monitor] = NULL;
1356
1357 /* If all location monitors disabled, disable global Location Monitor */
1358 if ((tmp & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 |
1359 CA91CX42_LINT_LM3)) == 0) {
1360 tmp = ioread32(bridge->base + LM_CTL);
1361 tmp &= ~CA91CX42_LM_CTL_EN;
1362 iowrite32(tmp, bridge->base + LM_CTL);
1363 }
1364
1365 mutex_unlock(&(lm->mtx));
1366
1367 return 0;
1368}
1369
1370int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge)
881{ 1371{
882 u32 slot = 0; 1372 u32 slot = 0;
1373 struct ca91cx42_driver *bridge;
1374
1375 bridge = ca91cx42_bridge->driver_priv;
1376
1377 if (!geoid) {
1378 slot = ioread32(bridge->base + VCSR_BS);
1379 slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27);
1380 } else
1381 slot = geoid;
883 1382
884 slot = ioread32(ca91cx42_bridge->base + VCSR_BS);
885 slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27);
886 return (int)slot; 1383 return (int)slot;
887 1384
888} 1385}
@@ -900,19 +1397,21 @@ static int __init ca91cx42_init(void)
900 * Auto-ID or Geographic address. This function ensures that the window is 1397 * Auto-ID or Geographic address. This function ensures that the window is
901 * enabled at an offset consistent with the boards geopgraphic address. 1398 * enabled at an offset consistent with the boards geopgraphic address.
902 */ 1399 */
903static int ca91cx42_crcsr_init(struct pci_dev *pdev) 1400static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge,
1401 struct pci_dev *pdev)
904{ 1402{
905 unsigned int crcsr_addr; 1403 unsigned int crcsr_addr;
906 int tmp, slot; 1404 int tmp, slot;
1405 struct ca91cx42_driver *bridge;
1406
1407 bridge = ca91cx42_bridge->driver_priv;
1408
1409 slot = ca91cx42_slot_get(ca91cx42_bridge);
1410
1411 /* Write CSR Base Address if slot ID is supplied as a module param */
1412 if (geoid)
1413 iowrite32(geoid << 27, bridge->base + VCSR_BS);
907 1414
908/* XXX We may need to set this somehow as the Universe II does not support
909 * geographical addressing.
910 */
911#if 0
912 if (vme_slotnum != -1)
913 iowrite32(vme_slotnum << 27, ca91cx42_bridge->base + VCSR_BS);
914#endif
915 slot = ca91cx42_slot_get();
916 dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot); 1415 dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot);
917 if (slot == 0) { 1416 if (slot == 0) {
918 dev_err(&pdev->dev, "Slot number is unset, not configuring " 1417 dev_err(&pdev->dev, "Slot number is unset, not configuring "
@@ -921,39 +1420,44 @@ static int ca91cx42_crcsr_init(struct pci_dev *pdev)
921 } 1420 }
922 1421
923 /* Allocate mem for CR/CSR image */ 1422 /* Allocate mem for CR/CSR image */
924 crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, 1423 bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
925 &crcsr_bus); 1424 &(bridge->crcsr_bus));
926 if (crcsr_kernel == NULL) { 1425 if (bridge->crcsr_kernel == NULL) {
927 dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " 1426 dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
928 "image\n"); 1427 "image\n");
929 return -ENOMEM; 1428 return -ENOMEM;
930 } 1429 }
931 1430
932 memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); 1431 memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
933 1432
934 crcsr_addr = slot * (512 * 1024); 1433 crcsr_addr = slot * (512 * 1024);
935 iowrite32(crcsr_bus - crcsr_addr, ca91cx42_bridge->base + VCSR_TO); 1434 iowrite32(bridge->crcsr_bus - crcsr_addr, bridge->base + VCSR_TO);
936 1435
937 tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); 1436 tmp = ioread32(bridge->base + VCSR_CTL);
938 tmp |= CA91CX42_VCSR_CTL_EN; 1437 tmp |= CA91CX42_VCSR_CTL_EN;
939 iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); 1438 iowrite32(tmp, bridge->base + VCSR_CTL);
940 1439
941 return 0; 1440 return 0;
942} 1441}
943 1442
944static void ca91cx42_crcsr_exit(struct pci_dev *pdev) 1443static void ca91cx42_crcsr_exit(struct vme_bridge *ca91cx42_bridge,
1444 struct pci_dev *pdev)
945{ 1445{
946 u32 tmp; 1446 u32 tmp;
1447 struct ca91cx42_driver *bridge;
1448
1449 bridge = ca91cx42_bridge->driver_priv;
947 1450
948 /* Turn off CR/CSR space */ 1451 /* Turn off CR/CSR space */
949 tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL); 1452 tmp = ioread32(bridge->base + VCSR_CTL);
950 tmp &= ~CA91CX42_VCSR_CTL_EN; 1453 tmp &= ~CA91CX42_VCSR_CTL_EN;
951 iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL); 1454 iowrite32(tmp, bridge->base + VCSR_CTL);
952 1455
953 /* Free image */ 1456 /* Free image */
954 iowrite32(0, ca91cx42_bridge->base + VCSR_TO); 1457 iowrite32(0, bridge->base + VCSR_TO);
955 1458
956 pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus); 1459 pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
1460 bridge->crcsr_bus);
957} 1461}
958 1462
959static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1463static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -961,11 +1465,11 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
961 int retval, i; 1465 int retval, i;
962 u32 data; 1466 u32 data;
963 struct list_head *pos = NULL; 1467 struct list_head *pos = NULL;
1468 struct vme_bridge *ca91cx42_bridge;
1469 struct ca91cx42_driver *ca91cx42_device;
964 struct vme_master_resource *master_image; 1470 struct vme_master_resource *master_image;
965 struct vme_slave_resource *slave_image; 1471 struct vme_slave_resource *slave_image;
966#if 0
967 struct vme_dma_resource *dma_ctrlr; 1472 struct vme_dma_resource *dma_ctrlr;
968#endif
969 struct vme_lm_resource *lm; 1473 struct vme_lm_resource *lm;
970 1474
971 /* We want to support more than one of each bridge so we need to 1475 /* We want to support more than one of each bridge so we need to
@@ -982,6 +1486,19 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
982 1486
983 memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge)); 1487 memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge));
984 1488
1489 ca91cx42_device = kmalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL);
1490
1491 if (ca91cx42_device == NULL) {
1492 dev_err(&pdev->dev, "Failed to allocate memory for device "
1493 "structure\n");
1494 retval = -ENOMEM;
1495 goto err_driver;
1496 }
1497
1498 memset(ca91cx42_device, 0, sizeof(struct ca91cx42_driver));
1499
1500 ca91cx42_bridge->driver_priv = ca91cx42_device;
1501
985 /* Enable the device */ 1502 /* Enable the device */
986 retval = pci_enable_device(pdev); 1503 retval = pci_enable_device(pdev);
987 if (retval) { 1504 if (retval) {
@@ -997,16 +1514,16 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
997 } 1514 }
998 1515
999 /* map registers in BAR 0 */ 1516 /* map registers in BAR 0 */
1000 ca91cx42_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 1517 ca91cx42_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
1001 4096); 1518 4096);
1002 if (!ca91cx42_bridge->base) { 1519 if (!ca91cx42_device->base) {
1003 dev_err(&pdev->dev, "Unable to remap CRG region\n"); 1520 dev_err(&pdev->dev, "Unable to remap CRG region\n");
1004 retval = -EIO; 1521 retval = -EIO;
1005 goto err_remap; 1522 goto err_remap;
1006 } 1523 }
1007 1524
1008 /* Check to see if the mapping worked out */ 1525 /* Check to see if the mapping worked out */
1009 data = ioread32(ca91cx42_bridge->base + CA91CX42_PCI_ID) & 0x0000FFFF; 1526 data = ioread32(ca91cx42_device->base + CA91CX42_PCI_ID) & 0x0000FFFF;
1010 if (data != PCI_VENDOR_ID_TUNDRA) { 1527 if (data != PCI_VENDOR_ID_TUNDRA) {
1011 dev_err(&pdev->dev, "PCI_ID check failed\n"); 1528 dev_err(&pdev->dev, "PCI_ID check failed\n");
1012 retval = -EIO; 1529 retval = -EIO;
@@ -1014,11 +1531,10 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1014 } 1531 }
1015 1532
1016 /* Initialize wait queues & mutual exclusion flags */ 1533 /* Initialize wait queues & mutual exclusion flags */
1017 /* XXX These need to be moved to the vme_bridge structure */ 1534 init_waitqueue_head(&(ca91cx42_device->dma_queue));
1018 init_waitqueue_head(&dma_queue); 1535 init_waitqueue_head(&(ca91cx42_device->iack_queue));
1019 init_waitqueue_head(&iack_queue); 1536 mutex_init(&(ca91cx42_device->vme_int));
1020 mutex_init(&(vme_int)); 1537 mutex_init(&(ca91cx42_device->vme_rmw));
1021 mutex_init(&(vme_rmw));
1022 1538
1023 ca91cx42_bridge->parent = &(pdev->dev); 1539 ca91cx42_bridge->parent = &(pdev->dev);
1024 strcpy(ca91cx42_bridge->name, driver_name); 1540 strcpy(ca91cx42_bridge->name, driver_name);
@@ -1050,7 +1566,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1050 master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | 1566 master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
1051 VME_SUPER | VME_USER | VME_PROG | VME_DATA; 1567 VME_SUPER | VME_USER | VME_PROG | VME_DATA;
1052 master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; 1568 master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64;
1053 memset(&(master_image->pci_resource), 0, 1569 memset(&(master_image->bus_resource), 0,
1054 sizeof(struct resource)); 1570 sizeof(struct resource));
1055 master_image->kern_base = NULL; 1571 master_image->kern_base = NULL;
1056 list_add_tail(&(master_image->list), 1572 list_add_tail(&(master_image->list),
@@ -1084,7 +1600,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1084 list_add_tail(&(slave_image->list), 1600 list_add_tail(&(slave_image->list),
1085 &(ca91cx42_bridge->slave_resources)); 1601 &(ca91cx42_bridge->slave_resources));
1086 } 1602 }
1087#if 0 1603
1088 /* Add dma engines to list */ 1604 /* Add dma engines to list */
1089 INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources)); 1605 INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources));
1090 for (i = 0; i < CA91C142_MAX_DMA; i++) { 1606 for (i = 0; i < CA91C142_MAX_DMA; i++) {
@@ -1100,12 +1616,14 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1100 mutex_init(&(dma_ctrlr->mtx)); 1616 mutex_init(&(dma_ctrlr->mtx));
1101 dma_ctrlr->locked = 0; 1617 dma_ctrlr->locked = 0;
1102 dma_ctrlr->number = i; 1618 dma_ctrlr->number = i;
1619 dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
1620 VME_DMA_MEM_TO_VME;
1103 INIT_LIST_HEAD(&(dma_ctrlr->pending)); 1621 INIT_LIST_HEAD(&(dma_ctrlr->pending));
1104 INIT_LIST_HEAD(&(dma_ctrlr->running)); 1622 INIT_LIST_HEAD(&(dma_ctrlr->running));
1105 list_add_tail(&(dma_ctrlr->list), 1623 list_add_tail(&(dma_ctrlr->list),
1106 &(ca91cx42_bridge->dma_resources)); 1624 &(ca91cx42_bridge->dma_resources));
1107 } 1625 }
1108#endif 1626
1109 /* Add location monitor to list */ 1627 /* Add location monitor to list */
1110 INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources)); 1628 INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources));
1111 lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); 1629 lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
@@ -1128,33 +1646,26 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1128 ca91cx42_bridge->master_set = ca91cx42_master_set; 1646 ca91cx42_bridge->master_set = ca91cx42_master_set;
1129 ca91cx42_bridge->master_read = ca91cx42_master_read; 1647 ca91cx42_bridge->master_read = ca91cx42_master_read;
1130 ca91cx42_bridge->master_write = ca91cx42_master_write; 1648 ca91cx42_bridge->master_write = ca91cx42_master_write;
1131#if 0
1132 ca91cx42_bridge->master_rmw = ca91cx42_master_rmw; 1649 ca91cx42_bridge->master_rmw = ca91cx42_master_rmw;
1133 ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add; 1650 ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add;
1134 ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; 1651 ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec;
1135 ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; 1652 ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty;
1136#endif
1137 ca91cx42_bridge->irq_set = ca91cx42_irq_set; 1653 ca91cx42_bridge->irq_set = ca91cx42_irq_set;
1138 ca91cx42_bridge->irq_generate = ca91cx42_irq_generate; 1654 ca91cx42_bridge->irq_generate = ca91cx42_irq_generate;
1139#if 0
1140 ca91cx42_bridge->lm_set = ca91cx42_lm_set; 1655 ca91cx42_bridge->lm_set = ca91cx42_lm_set;
1141 ca91cx42_bridge->lm_get = ca91cx42_lm_get; 1656 ca91cx42_bridge->lm_get = ca91cx42_lm_get;
1142 ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; 1657 ca91cx42_bridge->lm_attach = ca91cx42_lm_attach;
1143 ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; 1658 ca91cx42_bridge->lm_detach = ca91cx42_lm_detach;
1144#endif
1145 ca91cx42_bridge->slot_get = ca91cx42_slot_get; 1659 ca91cx42_bridge->slot_get = ca91cx42_slot_get;
1146 1660
1147 data = ioread32(ca91cx42_bridge->base + MISC_CTL); 1661 data = ioread32(ca91cx42_device->base + MISC_CTL);
1148 dev_info(&pdev->dev, "Board is%s the VME system controller\n", 1662 dev_info(&pdev->dev, "Board is%s the VME system controller\n",
1149 (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not"); 1663 (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not");
1150 dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get()); 1664 dev_info(&pdev->dev, "Slot ID is %d\n",
1665 ca91cx42_slot_get(ca91cx42_bridge));
1151 1666
1152 if (ca91cx42_crcsr_init(pdev)) { 1667 if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) {
1153 dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); 1668 dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
1154 retval = -EINVAL;
1155#if 0
1156 goto err_crcsr;
1157#endif
1158 } 1669 }
1159 1670
1160 /* Need to save ca91cx42_bridge pointer locally in link list for use in 1671 /* Need to save ca91cx42_bridge pointer locally in link list for use in
@@ -1166,14 +1677,13 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1166 goto err_reg; 1677 goto err_reg;
1167 } 1678 }
1168 1679
1680 pci_set_drvdata(pdev, ca91cx42_bridge);
1681
1169 return 0; 1682 return 0;
1170 1683
1171 vme_unregister_bridge(ca91cx42_bridge); 1684 vme_unregister_bridge(ca91cx42_bridge);
1172err_reg: 1685err_reg:
1173 ca91cx42_crcsr_exit(pdev); 1686 ca91cx42_crcsr_exit(ca91cx42_bridge, pdev);
1174#if 0
1175err_crcsr:
1176#endif
1177err_lm: 1687err_lm:
1178 /* resources are stored in link list */ 1688 /* resources are stored in link list */
1179 list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { 1689 list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
@@ -1181,7 +1691,6 @@ err_lm:
1181 list_del(pos); 1691 list_del(pos);
1182 kfree(lm); 1692 kfree(lm);
1183 } 1693 }
1184#if 0
1185err_dma: 1694err_dma:
1186 /* resources are stored in link list */ 1695 /* resources are stored in link list */
1187 list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { 1696 list_for_each(pos, &(ca91cx42_bridge->dma_resources)) {
@@ -1189,7 +1698,6 @@ err_dma:
1189 list_del(pos); 1698 list_del(pos);
1190 kfree(dma_ctrlr); 1699 kfree(dma_ctrlr);
1191 } 1700 }
1192#endif
1193err_slave: 1701err_slave:
1194 /* resources are stored in link list */ 1702 /* resources are stored in link list */
1195 list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { 1703 list_for_each(pos, &(ca91cx42_bridge->slave_resources)) {
@@ -1206,15 +1714,17 @@ err_master:
1206 kfree(master_image); 1714 kfree(master_image);
1207 } 1715 }
1208 1716
1209 ca91cx42_irq_exit(pdev); 1717 ca91cx42_irq_exit(ca91cx42_device, pdev);
1210err_irq: 1718err_irq:
1211err_test: 1719err_test:
1212 iounmap(ca91cx42_bridge->base); 1720 iounmap(ca91cx42_device->base);
1213err_remap: 1721err_remap:
1214 pci_release_regions(pdev); 1722 pci_release_regions(pdev);
1215err_resource: 1723err_resource:
1216 pci_disable_device(pdev); 1724 pci_disable_device(pdev);
1217err_enable: 1725err_enable:
1726 kfree(ca91cx42_device);
1727err_driver:
1218 kfree(ca91cx42_bridge); 1728 kfree(ca91cx42_bridge);
1219err_struct: 1729err_struct:
1220 return retval; 1730 return retval;
@@ -1228,32 +1738,37 @@ void ca91cx42_remove(struct pci_dev *pdev)
1228 struct vme_slave_resource *slave_image; 1738 struct vme_slave_resource *slave_image;
1229 struct vme_dma_resource *dma_ctrlr; 1739 struct vme_dma_resource *dma_ctrlr;
1230 struct vme_lm_resource *lm; 1740 struct vme_lm_resource *lm;
1741 struct ca91cx42_driver *bridge;
1742 struct vme_bridge *ca91cx42_bridge = pci_get_drvdata(pdev);
1743
1744 bridge = ca91cx42_bridge->driver_priv;
1745
1231 1746
1232 /* Turn off Ints */ 1747 /* Turn off Ints */
1233 iowrite32(0, ca91cx42_bridge->base + LINT_EN); 1748 iowrite32(0, bridge->base + LINT_EN);
1234 1749
1235 /* Turn off the windows */ 1750 /* Turn off the windows */
1236 iowrite32(0x00800000, ca91cx42_bridge->base + LSI0_CTL); 1751 iowrite32(0x00800000, bridge->base + LSI0_CTL);
1237 iowrite32(0x00800000, ca91cx42_bridge->base + LSI1_CTL); 1752 iowrite32(0x00800000, bridge->base + LSI1_CTL);
1238 iowrite32(0x00800000, ca91cx42_bridge->base + LSI2_CTL); 1753 iowrite32(0x00800000, bridge->base + LSI2_CTL);
1239 iowrite32(0x00800000, ca91cx42_bridge->base + LSI3_CTL); 1754 iowrite32(0x00800000, bridge->base + LSI3_CTL);
1240 iowrite32(0x00800000, ca91cx42_bridge->base + LSI4_CTL); 1755 iowrite32(0x00800000, bridge->base + LSI4_CTL);
1241 iowrite32(0x00800000, ca91cx42_bridge->base + LSI5_CTL); 1756 iowrite32(0x00800000, bridge->base + LSI5_CTL);
1242 iowrite32(0x00800000, ca91cx42_bridge->base + LSI6_CTL); 1757 iowrite32(0x00800000, bridge->base + LSI6_CTL);
1243 iowrite32(0x00800000, ca91cx42_bridge->base + LSI7_CTL); 1758 iowrite32(0x00800000, bridge->base + LSI7_CTL);
1244 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI0_CTL); 1759 iowrite32(0x00F00000, bridge->base + VSI0_CTL);
1245 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI1_CTL); 1760 iowrite32(0x00F00000, bridge->base + VSI1_CTL);
1246 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI2_CTL); 1761 iowrite32(0x00F00000, bridge->base + VSI2_CTL);
1247 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI3_CTL); 1762 iowrite32(0x00F00000, bridge->base + VSI3_CTL);
1248 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI4_CTL); 1763 iowrite32(0x00F00000, bridge->base + VSI4_CTL);
1249 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI5_CTL); 1764 iowrite32(0x00F00000, bridge->base + VSI5_CTL);
1250 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI6_CTL); 1765 iowrite32(0x00F00000, bridge->base + VSI6_CTL);
1251 iowrite32(0x00F00000, ca91cx42_bridge->base + VSI7_CTL); 1766 iowrite32(0x00F00000, bridge->base + VSI7_CTL);
1252 1767
1253 vme_unregister_bridge(ca91cx42_bridge); 1768 vme_unregister_bridge(ca91cx42_bridge);
1254#if 0 1769
1255 ca91cx42_crcsr_exit(pdev); 1770 ca91cx42_crcsr_exit(ca91cx42_bridge, pdev);
1256#endif 1771
1257 /* resources are stored in link list */ 1772 /* resources are stored in link list */
1258 list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { 1773 list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
1259 lm = list_entry(pos, struct vme_lm_resource, list); 1774 lm = list_entry(pos, struct vme_lm_resource, list);
@@ -1283,9 +1798,9 @@ void ca91cx42_remove(struct pci_dev *pdev)
1283 kfree(master_image); 1798 kfree(master_image);
1284 } 1799 }
1285 1800
1286 ca91cx42_irq_exit(pdev); 1801 ca91cx42_irq_exit(bridge, pdev);
1287 1802
1288 iounmap(ca91cx42_bridge->base); 1803 iounmap(bridge->base);
1289 1804
1290 pci_release_regions(pdev); 1805 pci_release_regions(pdev);
1291 1806
@@ -1299,588 +1814,11 @@ static void __exit ca91cx42_exit(void)
1299 pci_unregister_driver(&ca91cx42_driver); 1814 pci_unregister_driver(&ca91cx42_driver);
1300} 1815}
1301 1816
1817MODULE_PARM_DESC(geoid, "Override geographical addressing");
1818module_param(geoid, int, 0);
1819
1302MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); 1820MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge");
1303MODULE_LICENSE("GPL"); 1821MODULE_LICENSE("GPL");
1304 1822
1305module_init(ca91cx42_init); 1823module_init(ca91cx42_init);
1306module_exit(ca91cx42_exit); 1824module_exit(ca91cx42_exit);
1307
1308/*----------------------------------------------------------------------------
1309 * STAGING
1310 *--------------------------------------------------------------------------*/
1311
1312#if 0
1313#define SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >> 8) | ((X & 0x0000FF00) << 8) | ((X & 0x000000FF) << 24))
1314
1315int ca91cx42_master_rmw(vmeRmwCfg_t *vmeRmw)
1316{
1317 int temp_ctl = 0;
1318 int tempBS = 0;
1319 int tempBD = 0;
1320 int tempTO = 0;
1321 int vmeBS = 0;
1322 int vmeBD = 0;
1323 int *rmw_pci_data_ptr = NULL;
1324 int *vaDataPtr = NULL;
1325 int i;
1326 vmeOutWindowCfg_t vmeOut;
1327 if (vmeRmw->maxAttempts < 1) {
1328 return -EINVAL;
1329 }
1330 if (vmeRmw->targetAddrU) {
1331 return -EINVAL;
1332 }
1333 /* Find the PCI address that maps to the desired VME address */
1334 for (i = 0; i < 8; i++) {
1335 temp_ctl = ioread32(ca91cx42_bridge->base +
1336 CA91CX42_LSI_CTL[i]);
1337 if ((temp_ctl & 0x80000000) == 0) {
1338 continue;
1339 }
1340 memset(&vmeOut, 0, sizeof(vmeOut));
1341 vmeOut.windowNbr = i;
1342 ca91cx42_get_out_bound(&vmeOut);
1343 if (vmeOut.addrSpace != vmeRmw->addrSpace) {
1344 continue;
1345 }
1346 tempBS = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
1347 tempBD = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
1348 tempTO = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
1349 vmeBS = tempBS + tempTO;
1350 vmeBD = tempBD + tempTO;
1351 if ((vmeRmw->targetAddr >= vmeBS) &&
1352 (vmeRmw->targetAddr < vmeBD)) {
1353 rmw_pci_data_ptr =
1354 (int *)(tempBS + (vmeRmw->targetAddr - vmeBS));
1355 vaDataPtr =
1356 (int *)(out_image_va[i] +
1357 (vmeRmw->targetAddr - vmeBS));
1358 break;
1359 }
1360 }
1361
1362 /* If no window - fail. */
1363 if (rmw_pci_data_ptr == NULL) {
1364 return -EINVAL;
1365 }
1366 /* Setup the RMW registers. */
1367 iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
1368 iowrite32(SWIZZLE(vmeRmw->enableMask), ca91cx42_bridge->base + SCYC_EN);
1369 iowrite32(SWIZZLE(vmeRmw->compareData), ca91cx42_bridge->base +
1370 SCYC_CMP);
1371 iowrite32(SWIZZLE(vmeRmw->swapData), ca91cx42_bridge->base + SCYC_SWP);
1372 iowrite32((int)rmw_pci_data_ptr, ca91cx42_bridge->base + SCYC_ADDR);
1373 iowrite32(1, ca91cx42_bridge->base + SCYC_CTL);
1374
1375 /* Run the RMW cycle until either success or max attempts. */
1376 vmeRmw->numAttempts = 1;
1377 while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) {
1378
1379 if ((ioread32(vaDataPtr) & vmeRmw->enableMask) ==
1380 (vmeRmw->swapData & vmeRmw->enableMask)) {
1381
1382 iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
1383 break;
1384
1385 }
1386 vmeRmw->numAttempts++;
1387 }
1388
1389 /* If no success, set num Attempts to be greater than max attempts */
1390 if (vmeRmw->numAttempts > vmeRmw->maxAttempts) {
1391 vmeRmw->numAttempts = vmeRmw->maxAttempts + 1;
1392 }
1393
1394 return 0;
1395}
1396
1397int uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn)
1398{
1399 unsigned int dctlreg = 0x80;
1400 struct vmeAttr *vmeAttr;
1401
1402 if (vmeDma->srcBus == VME_DMA_VME) {
1403 dctlreg = 0;
1404 vmeAttr = &vmeDma->srcVmeAttr;
1405 } else {
1406 dctlreg = 0x80000000;
1407 vmeAttr = &vmeDma->dstVmeAttr;
1408 }
1409
1410 switch (vmeAttr->maxDataWidth) {
1411 case VME_D8:
1412 break;
1413 case VME_D16:
1414 dctlreg |= 0x00400000;
1415 break;
1416 case VME_D32:
1417 dctlreg |= 0x00800000;
1418 break;
1419 case VME_D64:
1420 dctlreg |= 0x00C00000;
1421 break;
1422 }
1423
1424 switch (vmeAttr->addrSpace) {
1425 case VME_A16:
1426 break;
1427 case VME_A24:
1428 dctlreg |= 0x00010000;
1429 break;
1430 case VME_A32:
1431 dctlreg |= 0x00020000;
1432 break;
1433 case VME_USER1:
1434 dctlreg |= 0x00060000;
1435 break;
1436 case VME_USER2:
1437 dctlreg |= 0x00070000;
1438 break;
1439
1440 case VME_A64: /* not supported in Universe DMA */
1441 case VME_CRCSR:
1442 case VME_USER3:
1443 case VME_USER4:
1444 return -EINVAL;
1445 break;
1446 }
1447 if (vmeAttr->userAccessType == VME_PROG) {
1448 dctlreg |= 0x00004000;
1449 }
1450 if (vmeAttr->dataAccessType == VME_SUPER) {
1451 dctlreg |= 0x00001000;
1452 }
1453 if (vmeAttr->xferProtocol != VME_SCT) {
1454 dctlreg |= 0x00000100;
1455 }
1456 *dctlregreturn = dctlreg;
1457 return 0;
1458}
1459
1460unsigned int
1461ca91cx42_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet *vmeLL)
1462{
1463 unsigned int val;
1464
1465 /* Setup registers as needed for direct or chained. */
1466 if (dgcsreg & 0x8000000) {
1467 iowrite32(0, ca91cx42_bridge->base + DTBC);
1468 iowrite32((unsigned int)vmeLL, ca91cx42_bridge->base + DCPP);
1469 } else {
1470#if 0
1471 printk(KERN_ERR "Starting: DGCS = %08x\n", dgcsreg);
1472 printk(KERN_ERR "Starting: DVA = %08x\n",
1473 ioread32(&vmeLL->dva));
1474 printk(KERN_ERR "Starting: DLV = %08x\n",
1475 ioread32(&vmeLL->dlv));
1476 printk(KERN_ERR "Starting: DTBC = %08x\n",
1477 ioread32(&vmeLL->dtbc));
1478 printk(KERN_ERR "Starting: DCTL = %08x\n",
1479 ioread32(&vmeLL->dctl));
1480#endif
1481 /* Write registers */
1482 iowrite32(ioread32(&vmeLL->dva), ca91cx42_bridge->base + DVA);
1483 iowrite32(ioread32(&vmeLL->dlv), ca91cx42_bridge->base + DLA);
1484 iowrite32(ioread32(&vmeLL->dtbc), ca91cx42_bridge->base + DTBC);
1485 iowrite32(ioread32(&vmeLL->dctl), ca91cx42_bridge->base + DCTL);
1486 iowrite32(0, ca91cx42_bridge->base + DCPP);
1487 }
1488
1489 /* Start the operation */
1490 iowrite32(dgcsreg, ca91cx42_bridge->base + DGCS);
1491 val = get_tbl();
1492 iowrite32(dgcsreg | 0x8000000F, ca91cx42_bridge->base + DGCS);
1493 return val;
1494}
1495
1496TDMA_Cmd_Packet *ca91cx42_setup_dma(vmeDmaPacket_t * vmeDma)
1497{
1498 vmeDmaPacket_t *vmeCur;
1499 int maxPerPage;
1500 int currentLLcount;
1501 TDMA_Cmd_Packet *startLL;
1502 TDMA_Cmd_Packet *currentLL;
1503 TDMA_Cmd_Packet *nextLL;
1504 unsigned int dctlreg = 0;
1505
1506 maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1;
1507 startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0);
1508 if (startLL == 0) {
1509 return startLL;
1510 }
1511 /* First allocate pages for descriptors and create linked list */
1512 vmeCur = vmeDma;
1513 currentLL = startLL;
1514 currentLLcount = 0;
1515 while (vmeCur != 0) {
1516 if (vmeCur->pNextPacket != 0) {
1517 currentLL->dcpp = (unsigned int)(currentLL + 1);
1518 currentLLcount++;
1519 if (currentLLcount >= maxPerPage) {
1520 currentLL->dcpp =
1521 __get_free_pages(GFP_KERNEL, 0);
1522 currentLLcount = 0;
1523 }
1524 currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
1525 } else {
1526 currentLL->dcpp = (unsigned int)0;
1527 }
1528 vmeCur = vmeCur->pNextPacket;
1529 }
1530
1531 /* Next fill in information for each descriptor */
1532 vmeCur = vmeDma;
1533 currentLL = startLL;
1534 while (vmeCur != 0) {
1535 if (vmeCur->srcBus == VME_DMA_VME) {
1536 iowrite32(vmeCur->srcAddr, &currentLL->dva);
1537 iowrite32(vmeCur->dstAddr, &currentLL->dlv);
1538 } else {
1539 iowrite32(vmeCur->srcAddr, &currentLL->dlv);
1540 iowrite32(vmeCur->dstAddr, &currentLL->dva);
1541 }
1542 uniSetupDctlReg(vmeCur, &dctlreg);
1543 iowrite32(dctlreg, &currentLL->dctl);
1544 iowrite32(vmeCur->byteCount, &currentLL->dtbc);
1545
1546 currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
1547 vmeCur = vmeCur->pNextPacket;
1548 }
1549
1550 /* Convert Links to PCI addresses. */
1551 currentLL = startLL;
1552 while (currentLL != 0) {
1553 nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
1554 if (nextLL == 0) {
1555 iowrite32(1, &currentLL->dcpp);
1556 } else {
1557 iowrite32((unsigned int)virt_to_bus(nextLL),
1558 &currentLL->dcpp);
1559 }
1560 currentLL = nextLL;
1561 }
1562
1563 /* Return pointer to descriptors list */
1564 return startLL;
1565}
1566
1567int ca91cx42_free_dma(TDMA_Cmd_Packet *startLL)
1568{
1569 TDMA_Cmd_Packet *currentLL;
1570 TDMA_Cmd_Packet *prevLL;
1571 TDMA_Cmd_Packet *nextLL;
1572 unsigned int dcppreg;
1573
1574 /* Convert Links to virtual addresses. */
1575 currentLL = startLL;
1576 while (currentLL != 0) {
1577 dcppreg = ioread32(&currentLL->dcpp);
1578 dcppreg &= ~6;
1579 if (dcppreg & 1) {
1580 currentLL->dcpp = 0;
1581 } else {
1582 currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg);
1583 }
1584 currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
1585 }
1586
1587 /* Free all pages associated with the descriptors. */
1588 currentLL = startLL;
1589 prevLL = currentLL;
1590 while (currentLL != 0) {
1591 nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
1592 if (currentLL + 1 != nextLL) {
1593 free_pages((int)prevLL, 0);
1594 prevLL = nextLL;
1595 }
1596 currentLL = nextLL;
1597 }
1598
1599 /* Return pointer to descriptors list */
1600 return 0;
1601}
1602
1603int ca91cx42_do_dma(vmeDmaPacket_t *vmeDma)
1604{
1605 unsigned int dgcsreg = 0;
1606 unsigned int dctlreg = 0;
1607 int val;
1608 int channel, x;
1609 vmeDmaPacket_t *curDma;
1610 TDMA_Cmd_Packet *dmaLL;
1611
1612 /* Sanity check the VME chain. */
1613 channel = vmeDma->channel_number;
1614 if (channel > 0) {
1615 return -EINVAL;
1616 }
1617 curDma = vmeDma;
1618 while (curDma != 0) {
1619 if (curDma->byteCount == 0) {
1620 return -EINVAL;
1621 }
1622 if (curDma->byteCount >= 0x1000000) {
1623 return -EINVAL;
1624 }
1625 if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) {
1626 return -EINVAL;
1627 }
1628 switch (curDma->srcBus) {
1629 case VME_DMA_PCI:
1630 if (curDma->dstBus != VME_DMA_VME) {
1631 return -EINVAL;
1632 }
1633 break;
1634 case VME_DMA_VME:
1635 if (curDma->dstBus != VME_DMA_PCI) {
1636 return -EINVAL;
1637 }
1638 break;
1639 default:
1640 return -EINVAL;
1641 break;
1642 }
1643 if (uniSetupDctlReg(curDma, &dctlreg) < 0) {
1644 return -EINVAL;
1645 }
1646
1647 curDma = curDma->pNextPacket;
1648 if (curDma == vmeDma) { /* Endless Loop! */
1649 return -EINVAL;
1650 }
1651 }
1652
1653 /* calculate control register */
1654 if (vmeDma->pNextPacket != 0) {
1655 dgcsreg = 0x8000000;
1656 } else {
1657 dgcsreg = 0;
1658 }
1659
1660 for (x = 0; x < 8; x++) { /* vme block size */
1661 if ((256 << x) >= vmeDma->maxVmeBlockSize) {
1662 break;
1663 }
1664 }
1665 if (x == 8)
1666 x = 7;
1667 dgcsreg |= (x << 20);
1668
1669 if (vmeDma->vmeBackOffTimer) {
1670 for (x = 1; x < 8; x++) { /* vme timer */
1671 if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
1672 break;
1673 }
1674 }
1675 if (x == 8)
1676 x = 7;
1677 dgcsreg |= (x << 16);
1678 }
1679 /*` Setup the dma chain */
1680 dmaLL = ca91cx42_setup_dma(vmeDma);
1681
1682 /* Start the DMA */
1683 if (dgcsreg & 0x8000000) {
1684 vmeDma->vmeDmaStartTick =
1685 ca91cx42_start_dma(channel, dgcsreg,
1686 (TDMA_Cmd_Packet *) virt_to_phys(dmaLL));
1687 } else {
1688 vmeDma->vmeDmaStartTick =
1689 ca91cx42_start_dma(channel, dgcsreg, dmaLL);
1690 }
1691
1692 wait_event_interruptible(dma_queue,
1693 ioread32(ca91cx42_bridge->base + DGCS) & 0x800);
1694
1695 val = ioread32(ca91cx42_bridge->base + DGCS);
1696 iowrite32(val | 0xF00, ca91cx42_bridge->base + DGCS);
1697
1698 vmeDma->vmeDmaStatus = 0;
1699
1700 if (!(val & 0x00000800)) {
1701 vmeDma->vmeDmaStatus = val & 0x700;
1702 printk(KERN_ERR "ca91c042: DMA Error in ca91cx42_DMA_irqhandler"
1703 " DGCS=%08X\n", val);
1704 val = ioread32(ca91cx42_bridge->base + DCPP);
1705 printk(KERN_ERR "ca91c042: DCPP=%08X\n", val);
1706 val = ioread32(ca91cx42_bridge->base + DCTL);
1707 printk(KERN_ERR "ca91c042: DCTL=%08X\n", val);
1708 val = ioread32(ca91cx42_bridge->base + DTBC);
1709 printk(KERN_ERR "ca91c042: DTBC=%08X\n", val);
1710 val = ioread32(ca91cx42_bridge->base + DLA);
1711 printk(KERN_ERR "ca91c042: DLA=%08X\n", val);
1712 val = ioread32(ca91cx42_bridge->base + DVA);
1713 printk(KERN_ERR "ca91c042: DVA=%08X\n", val);
1714
1715 }
1716 /* Free the dma chain */
1717 ca91cx42_free_dma(dmaLL);
1718
1719 return 0;
1720}
1721
1722int ca91cx42_lm_set(vmeLmCfg_t *vmeLm)
1723{
1724 int temp_ctl = 0;
1725
1726 if (vmeLm->addrU)
1727 return -EINVAL;
1728
1729 switch (vmeLm->addrSpace) {
1730 case VME_A64:
1731 case VME_USER3:
1732 case VME_USER4:
1733 return -EINVAL;
1734 case VME_A16:
1735 temp_ctl |= 0x00000;
1736 break;
1737 case VME_A24:
1738 temp_ctl |= 0x10000;
1739 break;
1740 case VME_A32:
1741 temp_ctl |= 0x20000;
1742 break;
1743 case VME_CRCSR:
1744 temp_ctl |= 0x50000;
1745 break;
1746 case VME_USER1:
1747 temp_ctl |= 0x60000;
1748 break;
1749 case VME_USER2:
1750 temp_ctl |= 0x70000;
1751 break;
1752 }
1753
1754 /* Disable while we are mucking around */
1755 iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
1756
1757 iowrite32(vmeLm->addr, ca91cx42_bridge->base + LM_BS);
1758
1759 /* Setup CTL register. */
1760 if (vmeLm->userAccessType & VME_SUPER)
1761 temp_ctl |= 0x00200000;
1762 if (vmeLm->userAccessType & VME_USER)
1763 temp_ctl |= 0x00100000;
1764 if (vmeLm->dataAccessType & VME_PROG)
1765 temp_ctl |= 0x00800000;
1766 if (vmeLm->dataAccessType & VME_DATA)
1767 temp_ctl |= 0x00400000;
1768
1769
1770 /* Write ctl reg and enable */
1771 iowrite32(0x80000000 | temp_ctl, ca91cx42_bridge->base + LM_CTL);
1772 temp_ctl = ioread32(ca91cx42_bridge->base + LM_CTL);
1773
1774 return 0;
1775}
1776
1777int ca91cx42_wait_lm(vmeLmCfg_t *vmeLm)
1778{
1779 unsigned long flags;
1780 unsigned int tmp;
1781
1782 spin_lock_irqsave(&lm_lock, flags);
1783 spin_unlock_irqrestore(&lm_lock, flags);
1784 if (tmp == 0) {
1785 if (vmeLm->lmWait < 10)
1786 vmeLm->lmWait = 10;
1787 interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait);
1788 }
1789 iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
1790
1791 return 0;
1792}
1793
1794
1795
1796int ca91cx42_set_arbiter(vmeArbiterCfg_t *vmeArb)
1797{
1798 int temp_ctl = 0;
1799 int vbto = 0;
1800
1801 temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
1802 temp_ctl &= 0x00FFFFFF;
1803
1804 if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
1805 vbto = 7;
1806 } else if (vmeArb->globalTimeoutTimer > 1024) {
1807 return -EINVAL;
1808 } else if (vmeArb->globalTimeoutTimer == 0) {
1809 vbto = 0;
1810 } else {
1811 vbto = 1;
1812 while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer)
1813 vbto += 1;
1814 }
1815 temp_ctl |= (vbto << 28);
1816
1817 if (vmeArb->arbiterMode == VME_PRIORITY_MODE)
1818 temp_ctl |= 1 << 26;
1819
1820 if (vmeArb->arbiterTimeoutFlag)
1821 temp_ctl |= 2 << 24;
1822
1823 iowrite32(temp_ctl, ca91cx42_bridge->base + MISC_CTL);
1824 return 0;
1825}
1826
1827int ca91cx42_get_arbiter(vmeArbiterCfg_t *vmeArb)
1828{
1829 int temp_ctl = 0;
1830 int vbto = 0;
1831
1832 temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
1833
1834 vbto = (temp_ctl >> 28) & 0xF;
1835 if (vbto != 0)
1836 vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1)));
1837
1838 if (temp_ctl & (1 << 26))
1839 vmeArb->arbiterMode = VME_PRIORITY_MODE;
1840 else
1841 vmeArb->arbiterMode = VME_R_ROBIN_MODE;
1842
1843 if (temp_ctl & (3 << 24))
1844 vmeArb->arbiterTimeoutFlag = 1;
1845
1846 return 0;
1847}
1848
1849int ca91cx42_set_requestor(vmeRequesterCfg_t *vmeReq)
1850{
1851 int temp_ctl = 0;
1852
1853 temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
1854 temp_ctl &= 0xFF0FFFFF;
1855
1856 if (vmeReq->releaseMode == 1)
1857 temp_ctl |= (1 << 20);
1858
1859 if (vmeReq->fairMode == 1)
1860 temp_ctl |= (1 << 21);
1861
1862 temp_ctl |= (vmeReq->requestLevel << 22);
1863
1864 iowrite32(temp_ctl, ca91cx42_bridge->base + MAST_CTL);
1865 return 0;
1866}
1867
1868int ca91cx42_get_requestor(vmeRequesterCfg_t *vmeReq)
1869{
1870 int temp_ctl = 0;
1871
1872 temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
1873
1874 if (temp_ctl & (1 << 20))
1875 vmeReq->releaseMode = 1;
1876
1877 if (temp_ctl & (1 << 21))
1878 vmeReq->fairMode = 1;
1879
1880 vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22;
1881
1882 return 0;
1883}
1884
1885
1886#endif
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.h b/drivers/staging/vme/bridges/vme_ca91cx42.h
index 95a42c240a20..e72c65b193ec 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.h
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.h
@@ -7,8 +7,8 @@
7 * Updated by Ajit Prem 7 * Updated by Ajit Prem
8 * Copyright 2004 Motorola Inc. 8 * Copyright 2004 Motorola Inc.
9 * 9 *
10 * Further updated by Martyn Welch <martyn.welch@gefanuc.com> 10 * Further updated by Martyn Welch <martyn.welch@ge.com>
11 * Copyright 2009 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 11 * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
12 * 12 *
13 * Derived from ca91c042.h by Michael Wyrick 13 * Derived from ca91c042.h by Michael Wyrick
14 * 14 *
@@ -37,11 +37,27 @@
37#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */ 37#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */
38#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */ 38#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */
39 39
40/* Structure used to hold driver specific information */
41struct ca91cx42_driver {
42 void *base; /* Base Address of device registers */
43 wait_queue_head_t dma_queue;
44 wait_queue_head_t iack_queue;
45 wait_queue_head_t mbox_queue;
46 void (*lm_callback[4])(int); /* Called in interrupt handler */
47 void *crcsr_kernel;
48 dma_addr_t crcsr_bus;
49 struct mutex vme_rmw; /* Only one RMW cycle at a time */
50 struct mutex vme_int; /*
51 * Only one VME interrupt can be
52 * generated at a time, provide locking
53 */
54};
55
40/* See Page 2-77 in the Universe User Manual */ 56/* See Page 2-77 in the Universe User Manual */
41struct ca91cx42_dma_descriptor { 57struct ca91cx42_dma_descriptor {
42 unsigned int dctl; /* DMA Control */ 58 unsigned int dctl; /* DMA Control */
43 unsigned int dtbc; /* Transfer Byte Count */ 59 unsigned int dtbc; /* Transfer Byte Count */
44 unsigned int dlv; /* PCI Address */ 60 unsigned int dla; /* PCI Address */
45 unsigned int res1; /* Reserved */ 61 unsigned int res1; /* Reserved */
46 unsigned int dva; /* Vme Address */ 62 unsigned int dva; /* Vme Address */
47 unsigned int res2; /* Reserved */ 63 unsigned int res2; /* Reserved */
@@ -237,32 +253,6 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
237#define VCSR_SET 0x0FF8 253#define VCSR_SET 0x0FF8
238#define VCSR_BS 0x0FFC 254#define VCSR_BS 0x0FFC
239 255
240// DMA General Control/Status Register DGCS (0x220)
241// 32-24 || GO | STOPR | HALTR | 0 || CHAIN | 0 | 0 | 0 ||
242// 23-16 || VON || VOFF ||
243// 15-08 || ACT | STOP | HALT | 0 || DONE | LERR | VERR | P_ERR ||
244// 07-00 || 0 | INT_S | INT_H | 0 || I_DNE | I_LER | I_VER | I_PER ||
245
246// VON - Length Per DMA VMEBus Transfer
247// 0000 = None
248// 0001 = 256 Bytes
249// 0010 = 512
250// 0011 = 1024
251// 0100 = 2048
252// 0101 = 4096
253// 0110 = 8192
254// 0111 = 16384
255
256// VOFF - wait between DMA tenures
257// 0000 = 0 us
258// 0001 = 16
259// 0010 = 32
260// 0011 = 64
261// 0100 = 128
262// 0101 = 256
263// 0110 = 512
264// 0111 = 1024
265
266/* 256/*
267 * PCI Class Register 257 * PCI Class Register
268 * offset 008 258 * offset 008
@@ -326,6 +316,16 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
326#define CA91CX42_LSI_CTL_VCT_MBLT (1<<8) 316#define CA91CX42_LSI_CTL_VCT_MBLT (1<<8)
327#define CA91CX42_LSI_CTL_LAS (1<<0) 317#define CA91CX42_LSI_CTL_LAS (1<<0)
328 318
319/*
320 * SCYC_CTL Register
321 * offset 178
322 */
323#define CA91CX42_SCYC_CTL_LAS_PCIMEM 0
324#define CA91CX42_SCYC_CTL_LAS_PCIIO (1<<2)
325
326#define CA91CX42_SCYC_CTL_CYC_M (3<<0)
327#define CA91CX42_SCYC_CTL_CYC_RMW (1<<0)
328#define CA91CX42_SCYC_CTL_CYC_ADOH (1<<1)
329 329
330/* 330/*
331 * LMISC Register 331 * LMISC Register
@@ -355,6 +355,71 @@ static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
355#define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000 355#define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000
356 356
357/* 357/*
358 * DCTL Register
359 * offset 200
360 */
361#define CA91CX42_DCTL_L2V (1<<31)
362#define CA91CX42_DCTL_VDW_M (3<<22)
363#define CA91CX42_DCTL_VDW_M (3<<22)
364#define CA91CX42_DCTL_VDW_D8 0
365#define CA91CX42_DCTL_VDW_D16 (1<<22)
366#define CA91CX42_DCTL_VDW_D32 (1<<23)
367#define CA91CX42_DCTL_VDW_D64 (3<<22)
368
369#define CA91CX42_DCTL_VAS_M (7<<16)
370#define CA91CX42_DCTL_VAS_A16 0
371#define CA91CX42_DCTL_VAS_A24 (1<<16)
372#define CA91CX42_DCTL_VAS_A32 (1<<17)
373#define CA91CX42_DCTL_VAS_USER1 (3<<17)
374#define CA91CX42_DCTL_VAS_USER2 (7<<16)
375
376#define CA91CX42_DCTL_PGM_M (1<<14)
377#define CA91CX42_DCTL_PGM_DATA 0
378#define CA91CX42_DCTL_PGM_PGM (1<<14)
379
380#define CA91CX42_DCTL_SUPER_M (1<<12)
381#define CA91CX42_DCTL_SUPER_NPRIV 0
382#define CA91CX42_DCTL_SUPER_SUPR (1<<12)
383
384#define CA91CX42_DCTL_VCT_M (1<<8)
385#define CA91CX42_DCTL_VCT_BLT (1<<8)
386#define CA91CX42_DCTL_LD64EN (1<<7)
387
388/*
389 * DCPP Register
390 * offset 218
391 */
392#define CA91CX42_DCPP_M 0xf
393#define CA91CX42_DCPP_NULL (1<<0)
394
395/*
396 * DMA General Control/Status Register (DGCS)
397 * offset 220
398 */
399#define CA91CX42_DGCS_GO (1<<31)
400#define CA91CX42_DGCS_STOP_REQ (1<<30)
401#define CA91CX42_DGCS_HALT_REQ (1<<29)
402#define CA91CX42_DGCS_CHAIN (1<<27)
403
404#define CA91CX42_DGCS_VON_M (7<<20)
405
406#define CA91CX42_DGCS_VOFF_M (0xf<<16)
407
408#define CA91CX42_DGCS_ACT (1<<15)
409#define CA91CX42_DGCS_STOP (1<<14)
410#define CA91CX42_DGCS_HALT (1<<13)
411#define CA91CX42_DGCS_DONE (1<<11)
412#define CA91CX42_DGCS_LERR (1<<10)
413#define CA91CX42_DGCS_VERR (1<<9)
414#define CA91CX42_DGCS_PERR (1<<8)
415#define CA91CX42_DGCS_INT_STOP (1<<6)
416#define CA91CX42_DGCS_INT_HALT (1<<5)
417#define CA91CX42_DGCS_INT_DONE (1<<3)
418#define CA91CX42_DGCS_INT_LERR (1<<2)
419#define CA91CX42_DGCS_INT_VERR (1<<1)
420#define CA91CX42_DGCS_INT_PERR (1<<0)
421
422/*
358 * PCI Interrupt Enable Register 423 * PCI Interrupt Enable Register
359 * offset 300 424 * offset 300
360 */ 425 */
@@ -475,6 +540,19 @@ static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1,
475#define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0) 540#define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0)
476#define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1) 541#define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1)
477 542
543/* LM_CTL Register
544 * offset F64
545 */
546#define CA91CX42_LM_CTL_EN (1<<31)
547#define CA91CX42_LM_CTL_PGM (1<<23)
548#define CA91CX42_LM_CTL_DATA (1<<22)
549#define CA91CX42_LM_CTL_SUPR (1<<21)
550#define CA91CX42_LM_CTL_NPRIV (1<<20)
551#define CA91CX42_LM_CTL_AS_M (5<<16)
552#define CA91CX42_LM_CTL_AS_A16 0
553#define CA91CX42_LM_CTL_AS_A24 (1<<16)
554#define CA91CX42_LM_CTL_AS_A32 (1<<17)
555
478/* 556/*
479 * VRAI_CTL Register 557 * VRAI_CTL Register
480 * offset F70 558 * offset F70
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index 89a7dccb934f..faf652edb70f 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Support for the Tundra TSI148 VME-PCI Bridge Chip 2 * Support for the Tundra TSI148 VME-PCI Bridge Chip
3 * 3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com> 4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 5 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
6 * 6 *
7 * Based on work by Tom Armistead and Ajit Prem 7 * Based on work by Tom Armistead and Ajit Prem
8 * Copyright 2004 Motorola Inc. 8 * Copyright 2004 Motorola Inc.
@@ -59,28 +59,14 @@ int tsi148_dma_list_add (struct vme_dma_list *, struct vme_dma_attr *,
59int tsi148_dma_list_exec(struct vme_dma_list *); 59int tsi148_dma_list_exec(struct vme_dma_list *);
60int tsi148_dma_list_empty(struct vme_dma_list *); 60int tsi148_dma_list_empty(struct vme_dma_list *);
61int tsi148_generate_irq(int, int); 61int tsi148_generate_irq(int, int);
62int tsi148_slot_get(void); 62
63 63/* Module parameter */
64/* Modue parameter */ 64static int err_chk;
65int err_chk = 0; 65static int geoid;
66
67/* XXX These should all be in a per device structure */
68struct vme_bridge *tsi148_bridge;
69wait_queue_head_t dma_queue[2];
70wait_queue_head_t iack_queue;
71void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */
72void *crcsr_kernel;
73dma_addr_t crcsr_bus;
74struct vme_master_resource *flush_image;
75struct mutex vme_rmw; /* Only one RMW cycle at a time */
76struct mutex vme_int; /*
77 * Only one VME interrupt can be
78 * generated at a time, provide locking
79 */
80 66
81static char driver_name[] = "vme_tsi148"; 67static char driver_name[] = "vme_tsi148";
82 68
83static struct pci_device_id tsi148_ids[] = { 69static const struct pci_device_id tsi148_ids[] = {
84 { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, 70 { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) },
85 { }, 71 { },
86}; 72};
@@ -109,16 +95,17 @@ static void reg_split(unsigned long long variable, unsigned int *high,
109/* 95/*
110 * Wakes up DMA queue. 96 * Wakes up DMA queue.
111 */ 97 */
112static u32 tsi148_DMA_irqhandler(int channel_mask) 98static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge,
99 int channel_mask)
113{ 100{
114 u32 serviced = 0; 101 u32 serviced = 0;
115 102
116 if (channel_mask & TSI148_LCSR_INTS_DMA0S) { 103 if (channel_mask & TSI148_LCSR_INTS_DMA0S) {
117 wake_up(&dma_queue[0]); 104 wake_up(&(bridge->dma_queue[0]));
118 serviced |= TSI148_LCSR_INTC_DMA0C; 105 serviced |= TSI148_LCSR_INTC_DMA0C;
119 } 106 }
120 if (channel_mask & TSI148_LCSR_INTS_DMA1S) { 107 if (channel_mask & TSI148_LCSR_INTS_DMA1S) {
121 wake_up(&dma_queue[1]); 108 wake_up(&(bridge->dma_queue[1]));
122 serviced |= TSI148_LCSR_INTC_DMA1C; 109 serviced |= TSI148_LCSR_INTC_DMA1C;
123 } 110 }
124 111
@@ -128,7 +115,7 @@ static u32 tsi148_DMA_irqhandler(int channel_mask)
128/* 115/*
129 * Wake up location monitor queue 116 * Wake up location monitor queue
130 */ 117 */
131static u32 tsi148_LM_irqhandler(u32 stat) 118static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat)
132{ 119{
133 int i; 120 int i;
134 u32 serviced = 0; 121 u32 serviced = 0;
@@ -136,7 +123,7 @@ static u32 tsi148_LM_irqhandler(u32 stat)
136 for (i = 0; i < 4; i++) { 123 for (i = 0; i < 4; i++) {
137 if(stat & TSI148_LCSR_INTS_LMS[i]) { 124 if(stat & TSI148_LCSR_INTS_LMS[i]) {
138 /* We only enable interrupts if the callback is set */ 125 /* We only enable interrupts if the callback is set */
139 lm_callback[i](i); 126 bridge->lm_callback[i](i);
140 serviced |= TSI148_LCSR_INTC_LMC[i]; 127 serviced |= TSI148_LCSR_INTC_LMC[i];
141 } 128 }
142 } 129 }
@@ -149,7 +136,7 @@ static u32 tsi148_LM_irqhandler(u32 stat)
149 * 136 *
150 * XXX This functionality is not exposed up though API. 137 * XXX This functionality is not exposed up though API.
151 */ 138 */
152static u32 tsi148_MB_irqhandler(u32 stat) 139static u32 tsi148_MB_irqhandler(struct tsi148_driver *bridge, u32 stat)
153{ 140{
154 int i; 141 int i;
155 u32 val; 142 u32 val;
@@ -157,8 +144,7 @@ static u32 tsi148_MB_irqhandler(u32 stat)
157 144
158 for (i = 0; i < 4; i++) { 145 for (i = 0; i < 4; i++) {
159 if(stat & TSI148_LCSR_INTS_MBS[i]) { 146 if(stat & TSI148_LCSR_INTS_MBS[i]) {
160 val = ioread32be(tsi148_bridge->base + 147 val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]);
161 TSI148_GCSR_MBOX[i]);
162 printk("VME Mailbox %d received: 0x%x\n", i, val); 148 printk("VME Mailbox %d received: 0x%x\n", i, val);
163 serviced |= TSI148_LCSR_INTC_MBC[i]; 149 serviced |= TSI148_LCSR_INTC_MBC[i];
164 } 150 }
@@ -170,22 +156,21 @@ static u32 tsi148_MB_irqhandler(u32 stat)
170/* 156/*
171 * Display error & status message when PERR (PCI) exception interrupt occurs. 157 * Display error & status message when PERR (PCI) exception interrupt occurs.
172 */ 158 */
173static u32 tsi148_PERR_irqhandler(void) 159static u32 tsi148_PERR_irqhandler(struct tsi148_driver *bridge)
174{ 160{
175 printk(KERN_ERR 161 printk(KERN_ERR
176 "PCI Exception at address: 0x%08x:%08x, attributes: %08x\n", 162 "PCI Exception at address: 0x%08x:%08x, attributes: %08x\n",
177 ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAU), 163 ioread32be(bridge->base + TSI148_LCSR_EDPAU),
178 ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAL), 164 ioread32be(bridge->base + TSI148_LCSR_EDPAL),
179 ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAT) 165 ioread32be(bridge->base + TSI148_LCSR_EDPAT)
180 ); 166 );
181 printk(KERN_ERR 167 printk(KERN_ERR
182 "PCI-X attribute reg: %08x, PCI-X split completion reg: %08x\n", 168 "PCI-X attribute reg: %08x, PCI-X split completion reg: %08x\n",
183 ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXA), 169 ioread32be(bridge->base + TSI148_LCSR_EDPXA),
184 ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXS) 170 ioread32be(bridge->base + TSI148_LCSR_EDPXS)
185 ); 171 );
186 172
187 iowrite32be(TSI148_LCSR_EDPAT_EDPCL, 173 iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT);
188 tsi148_bridge->base + TSI148_LCSR_EDPAT);
189 174
190 return TSI148_LCSR_INTC_PERRC; 175 return TSI148_LCSR_INTC_PERRC;
191} 176}
@@ -193,16 +178,19 @@ static u32 tsi148_PERR_irqhandler(void)
193/* 178/*
194 * Save address and status when VME error interrupt occurs. 179 * Save address and status when VME error interrupt occurs.
195 */ 180 */
196static u32 tsi148_VERR_irqhandler(void) 181static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge)
197{ 182{
198 unsigned int error_addr_high, error_addr_low; 183 unsigned int error_addr_high, error_addr_low;
199 unsigned long long error_addr; 184 unsigned long long error_addr;
200 u32 error_attrib; 185 u32 error_attrib;
201 struct vme_bus_error *error; 186 struct vme_bus_error *error;
187 struct tsi148_driver *bridge;
188
189 bridge = tsi148_bridge->driver_priv;
202 190
203 error_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAU); 191 error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU);
204 error_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAL); 192 error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL);
205 error_attrib = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAT); 193 error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT);
206 194
207 reg_join(error_addr_high, error_addr_low, &error_addr); 195 reg_join(error_addr_high, error_addr_low, &error_addr);
208 196
@@ -226,8 +214,7 @@ static u32 tsi148_VERR_irqhandler(void)
226 } 214 }
227 215
228 /* Clear Status */ 216 /* Clear Status */
229 iowrite32be(TSI148_LCSR_VEAT_VESCL, 217 iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT);
230 tsi148_bridge->base + TSI148_LCSR_VEAT);
231 218
232 return TSI148_LCSR_INTC_VERRC; 219 return TSI148_LCSR_INTC_VERRC;
233} 220}
@@ -235,9 +222,9 @@ static u32 tsi148_VERR_irqhandler(void)
235/* 222/*
236 * Wake up IACK queue. 223 * Wake up IACK queue.
237 */ 224 */
238static u32 tsi148_IACK_irqhandler(void) 225static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge)
239{ 226{
240 wake_up(&iack_queue); 227 wake_up(&(bridge->iack_queue));
241 228
242 return TSI148_LCSR_INTC_IACKC; 229 return TSI148_LCSR_INTC_IACKC;
243} 230}
@@ -245,9 +232,13 @@ static u32 tsi148_IACK_irqhandler(void)
245/* 232/*
246 * Calling VME bus interrupt callback if provided. 233 * Calling VME bus interrupt callback if provided.
247 */ 234 */
248static u32 tsi148_VIRQ_irqhandler(u32 stat) 235static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge,
236 u32 stat)
249{ 237{
250 int vec, i, serviced = 0; 238 int vec, i, serviced = 0;
239 struct tsi148_driver *bridge;
240
241 bridge = tsi148_bridge->driver_priv;
251 242
252 for (i = 7; i > 0; i--) { 243 for (i = 7; i > 0; i--) {
253 if (stat & (1 << i)) { 244 if (stat & (1 << i)) {
@@ -257,8 +248,7 @@ static u32 tsi148_VIRQ_irqhandler(u32 stat)
257 * 8-bit IACK cycles on the bus, read from offset 248 * 8-bit IACK cycles on the bus, read from offset
258 * 3. 249 * 3.
259 */ 250 */
260 vec = ioread8(tsi148_bridge->base + 251 vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3);
261 TSI148_LCSR_VIACK[i] + 3);
262 252
263 vme_irq_handler(tsi148_bridge, i, vec); 253 vme_irq_handler(tsi148_bridge, i, vec);
264 254
@@ -273,13 +263,19 @@ static u32 tsi148_VIRQ_irqhandler(u32 stat)
273 * Top level interrupt handler. Clears appropriate interrupt status bits and 263 * Top level interrupt handler. Clears appropriate interrupt status bits and
274 * then calls appropriate sub handler(s). 264 * then calls appropriate sub handler(s).
275 */ 265 */
276static irqreturn_t tsi148_irqhandler(int irq, void *dev_id) 266static irqreturn_t tsi148_irqhandler(int irq, void *ptr)
277{ 267{
278 u32 stat, enable, serviced = 0; 268 u32 stat, enable, serviced = 0;
269 struct vme_bridge *tsi148_bridge;
270 struct tsi148_driver *bridge;
271
272 tsi148_bridge = ptr;
273
274 bridge = tsi148_bridge->driver_priv;
279 275
280 /* Determine which interrupts are unmasked and set */ 276 /* Determine which interrupts are unmasked and set */
281 enable = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); 277 enable = ioread32be(bridge->base + TSI148_LCSR_INTEO);
282 stat = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTS); 278 stat = ioread32be(bridge->base + TSI148_LCSR_INTS);
283 279
284 /* Only look at unmasked interrupts */ 280 /* Only look at unmasked interrupts */
285 stat &= enable; 281 stat &= enable;
@@ -291,61 +287,63 @@ static irqreturn_t tsi148_irqhandler(int irq, void *dev_id)
291 /* Call subhandlers as appropriate */ 287 /* Call subhandlers as appropriate */
292 /* DMA irqs */ 288 /* DMA irqs */
293 if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S)) 289 if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S))
294 serviced |= tsi148_DMA_irqhandler(stat); 290 serviced |= tsi148_DMA_irqhandler(bridge, stat);
295 291
296 /* Location monitor irqs */ 292 /* Location monitor irqs */
297 if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S | 293 if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S |
298 TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S)) 294 TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S))
299 serviced |= tsi148_LM_irqhandler(stat); 295 serviced |= tsi148_LM_irqhandler(bridge, stat);
300 296
301 /* Mail box irqs */ 297 /* Mail box irqs */
302 if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S | 298 if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S |
303 TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S)) 299 TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S))
304 serviced |= tsi148_MB_irqhandler(stat); 300 serviced |= tsi148_MB_irqhandler(bridge, stat);
305 301
306 /* PCI bus error */ 302 /* PCI bus error */
307 if (stat & TSI148_LCSR_INTS_PERRS) 303 if (stat & TSI148_LCSR_INTS_PERRS)
308 serviced |= tsi148_PERR_irqhandler(); 304 serviced |= tsi148_PERR_irqhandler(bridge);
309 305
310 /* VME bus error */ 306 /* VME bus error */
311 if (stat & TSI148_LCSR_INTS_VERRS) 307 if (stat & TSI148_LCSR_INTS_VERRS)
312 serviced |= tsi148_VERR_irqhandler(); 308 serviced |= tsi148_VERR_irqhandler(tsi148_bridge);
313 309
314 /* IACK irq */ 310 /* IACK irq */
315 if (stat & TSI148_LCSR_INTS_IACKS) 311 if (stat & TSI148_LCSR_INTS_IACKS)
316 serviced |= tsi148_IACK_irqhandler(); 312 serviced |= tsi148_IACK_irqhandler(bridge);
317 313
318 /* VME bus irqs */ 314 /* VME bus irqs */
319 if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S | 315 if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S |
320 TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S | 316 TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S |
321 TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S | 317 TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S |
322 TSI148_LCSR_INTS_IRQ1S)) 318 TSI148_LCSR_INTS_IRQ1S))
323 serviced |= tsi148_VIRQ_irqhandler(stat); 319 serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat);
324 320
325 /* Clear serviced interrupts */ 321 /* Clear serviced interrupts */
326 iowrite32be(serviced, tsi148_bridge->base + TSI148_LCSR_INTC); 322 iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC);
327 323
328 return IRQ_HANDLED; 324 return IRQ_HANDLED;
329} 325}
330 326
331static int tsi148_irq_init(struct vme_bridge *bridge) 327static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
332{ 328{
333 int result; 329 int result;
334 unsigned int tmp; 330 unsigned int tmp;
335 struct pci_dev *pdev; 331 struct pci_dev *pdev;
332 struct tsi148_driver *bridge;
333
334 pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
336 335
337 /* Need pdev */ 336 bridge = tsi148_bridge->driver_priv;
338 pdev = container_of(bridge->parent, struct pci_dev, dev);
339 337
340 /* Initialise list for VME bus errors */ 338 /* Initialise list for VME bus errors */
341 INIT_LIST_HEAD(&(bridge->vme_errors)); 339 INIT_LIST_HEAD(&(tsi148_bridge->vme_errors));
342 340
343 mutex_init(&(bridge->irq_mtx)); 341 mutex_init(&(tsi148_bridge->irq_mtx));
344 342
345 result = request_irq(pdev->irq, 343 result = request_irq(pdev->irq,
346 tsi148_irqhandler, 344 tsi148_irqhandler,
347 IRQF_SHARED, 345 IRQF_SHARED,
348 driver_name, pdev); 346 driver_name, tsi148_bridge);
349 if (result) { 347 if (result) {
350 dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", 348 dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
351 pdev->irq); 349 pdev->irq);
@@ -359,7 +357,7 @@ static int tsi148_irq_init(struct vme_bridge *bridge)
359 TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO | 357 TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO |
360 TSI148_LCSR_INTEO_IACKEO; 358 TSI148_LCSR_INTEO_IACKEO;
361 359
362 /* XXX This leaves the following interrupts masked. 360 /* This leaves the following interrupts masked.
363 * TSI148_LCSR_INTEO_VIEEO 361 * TSI148_LCSR_INTEO_VIEEO
364 * TSI148_LCSR_INTEO_SYSFLEO 362 * TSI148_LCSR_INTEO_SYSFLEO
365 * TSI148_LCSR_INTEO_ACFLEO 363 * TSI148_LCSR_INTEO_ACFLEO
@@ -392,14 +390,14 @@ static int tsi148_irq_init(struct vme_bridge *bridge)
392 return 0; 390 return 0;
393} 391}
394 392
395static void tsi148_irq_exit(struct pci_dev *pdev) 393static void tsi148_irq_exit(struct tsi148_driver *bridge, struct pci_dev *pdev)
396{ 394{
397 /* Turn off interrupts */ 395 /* Turn off interrupts */
398 iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEO); 396 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO);
399 iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEN); 397 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN);
400 398
401 /* Clear all interrupts */ 399 /* Clear all interrupts */
402 iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTC); 400 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC);
403 401
404 /* Detach interrupt handler */ 402 /* Detach interrupt handler */
405 free_irq(pdev->irq, pdev); 403 free_irq(pdev->irq, pdev);
@@ -408,11 +406,11 @@ static void tsi148_irq_exit(struct pci_dev *pdev)
408/* 406/*
409 * Check to see if an IACk has been received, return true (1) or false (0). 407 * Check to see if an IACk has been received, return true (1) or false (0).
410 */ 408 */
411int tsi148_iack_received(void) 409int tsi148_iack_received(struct tsi148_driver *bridge)
412{ 410{
413 u32 tmp; 411 u32 tmp;
414 412
415 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR); 413 tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
416 414
417 if (tmp & TSI148_LCSR_VICR_IRQS) 415 if (tmp & TSI148_LCSR_VICR_IRQS)
418 return 0; 416 return 0;
@@ -423,20 +421,24 @@ int tsi148_iack_received(void)
423/* 421/*
424 * Configure VME interrupt 422 * Configure VME interrupt
425 */ 423 */
426void tsi148_irq_set(int level, int state, int sync) 424void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
425 int state, int sync)
427{ 426{
428 struct pci_dev *pdev; 427 struct pci_dev *pdev;
429 u32 tmp; 428 u32 tmp;
429 struct tsi148_driver *bridge;
430
431 bridge = tsi148_bridge->driver_priv;
430 432
431 /* We need to do the ordering differently for enabling and disabling */ 433 /* We need to do the ordering differently for enabling and disabling */
432 if (state == 0) { 434 if (state == 0) {
433 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); 435 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
434 tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1]; 436 tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
435 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); 437 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
436 438
437 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); 439 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
438 tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1]; 440 tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
439 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); 441 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
440 442
441 if (sync != 0) { 443 if (sync != 0) {
442 pdev = container_of(tsi148_bridge->parent, 444 pdev = container_of(tsi148_bridge->parent,
@@ -445,13 +447,13 @@ void tsi148_irq_set(int level, int state, int sync)
445 synchronize_irq(pdev->irq); 447 synchronize_irq(pdev->irq);
446 } 448 }
447 } else { 449 } else {
448 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); 450 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
449 tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1]; 451 tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
450 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); 452 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
451 453
452 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); 454 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
453 tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; 455 tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
454 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); 456 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
455 } 457 }
456} 458}
457 459
@@ -459,28 +461,32 @@ void tsi148_irq_set(int level, int state, int sync)
459 * Generate a VME bus interrupt at the requested level & vector. Wait for 461 * Generate a VME bus interrupt at the requested level & vector. Wait for
460 * interrupt to be acked. 462 * interrupt to be acked.
461 */ 463 */
462int tsi148_irq_generate(int level, int statid) 464int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid)
463{ 465{
464 u32 tmp; 466 u32 tmp;
467 struct tsi148_driver *bridge;
468
469 bridge = tsi148_bridge->driver_priv;
465 470
466 mutex_lock(&(vme_int)); 471 mutex_lock(&(bridge->vme_int));
467 472
468 /* Read VICR register */ 473 /* Read VICR register */
469 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR); 474 tmp = ioread32be(bridge->base + TSI148_LCSR_VICR);
470 475
471 /* Set Status/ID */ 476 /* Set Status/ID */
472 tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) | 477 tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) |
473 (statid & TSI148_LCSR_VICR_STID_M); 478 (statid & TSI148_LCSR_VICR_STID_M);
474 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR); 479 iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
475 480
476 /* Assert VMEbus IRQ */ 481 /* Assert VMEbus IRQ */
477 tmp = tmp | TSI148_LCSR_VICR_IRQL[level]; 482 tmp = tmp | TSI148_LCSR_VICR_IRQL[level];
478 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR); 483 iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR);
479 484
480 /* XXX Consider implementing a timeout? */ 485 /* XXX Consider implementing a timeout? */
481 wait_event_interruptible(iack_queue, tsi148_iack_received()); 486 wait_event_interruptible(bridge->iack_queue,
487 tsi148_iack_received(bridge));
482 488
483 mutex_unlock(&(vme_int)); 489 mutex_unlock(&(bridge->vme_int));
484 490
485 return 0; 491 return 0;
486} 492}
@@ -488,8 +494,8 @@ int tsi148_irq_generate(int level, int statid)
488/* 494/*
489 * Find the first error in this address range 495 * Find the first error in this address range
490 */ 496 */
491static struct vme_bus_error *tsi148_find_error(vme_address_t aspace, 497static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge,
492 unsigned long long address, size_t count) 498 vme_address_t aspace, unsigned long long address, size_t count)
493{ 499{
494 struct list_head *err_pos; 500 struct list_head *err_pos;
495 struct vme_bus_error *vme_err, *valid = NULL; 501 struct vme_bus_error *vme_err, *valid = NULL;
@@ -520,8 +526,8 @@ static struct vme_bus_error *tsi148_find_error(vme_address_t aspace,
520/* 526/*
521 * Clear errors in the provided address range. 527 * Clear errors in the provided address range.
522 */ 528 */
523static void tsi148_clear_errors(vme_address_t aspace, 529static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge,
524 unsigned long long address, size_t count) 530 vme_address_t aspace, unsigned long long address, size_t count)
525{ 531{
526 struct list_head *err_pos, *temp; 532 struct list_head *err_pos, *temp;
527 struct vme_bus_error *vme_err; 533 struct vme_bus_error *vme_err;
@@ -561,16 +567,9 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
561 unsigned int vme_bound_low, vme_bound_high; 567 unsigned int vme_bound_low, vme_bound_high;
562 unsigned int pci_offset_low, pci_offset_high; 568 unsigned int pci_offset_low, pci_offset_high;
563 unsigned long long vme_bound, pci_offset; 569 unsigned long long vme_bound, pci_offset;
570 struct tsi148_driver *bridge;
564 571
565#if 0 572 bridge = image->parent->driver_priv;
566 printk("Set slave image %d to:\n", image->number);
567 printk("\tEnabled: %s\n", (enabled == 1)? "yes" : "no");
568 printk("\tVME Base:0x%llx\n", vme_base);
569 printk("\tWindow Size:0x%llx\n", size);
570 printk("\tPCI Base:0x%lx\n", (unsigned long)pci_base);
571 printk("\tAddress Space:0x%x\n", aspace);
572 printk("\tTransfer Cycle Properties:0x%x\n", cycle);
573#endif
574 573
575 i = image->number; 574 i = image->number;
576 575
@@ -627,49 +626,27 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
627 return -EINVAL; 626 return -EINVAL;
628 } 627 }
629 628
630#if 0
631 printk("\tVME Bound:0x%llx\n", vme_bound);
632 printk("\tPCI Offset:0x%llx\n", pci_offset);
633#endif
634
635 /* Disable while we are mucking around */ 629 /* Disable while we are mucking around */
636 temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 630 temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
637 TSI148_LCSR_OFFSET_ITAT); 631 TSI148_LCSR_OFFSET_ITAT);
638 temp_ctl &= ~TSI148_LCSR_ITAT_EN; 632 temp_ctl &= ~TSI148_LCSR_ITAT_EN;
639 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] + 633 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
640 TSI148_LCSR_OFFSET_ITAT); 634 TSI148_LCSR_OFFSET_ITAT);
641 635
642 /* Setup mapping */ 636 /* Setup mapping */
643 iowrite32be(vme_base_high, tsi148_bridge->base + TSI148_LCSR_IT[i] + 637 iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] +
644 TSI148_LCSR_OFFSET_ITSAU); 638 TSI148_LCSR_OFFSET_ITSAU);
645 iowrite32be(vme_base_low, tsi148_bridge->base + TSI148_LCSR_IT[i] + 639 iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] +
646 TSI148_LCSR_OFFSET_ITSAL); 640 TSI148_LCSR_OFFSET_ITSAL);
647 iowrite32be(vme_bound_high, tsi148_bridge->base + TSI148_LCSR_IT[i] + 641 iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] +
648 TSI148_LCSR_OFFSET_ITEAU); 642 TSI148_LCSR_OFFSET_ITEAU);
649 iowrite32be(vme_bound_low, tsi148_bridge->base + TSI148_LCSR_IT[i] + 643 iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] +
650 TSI148_LCSR_OFFSET_ITEAL); 644 TSI148_LCSR_OFFSET_ITEAL);
651 iowrite32be(pci_offset_high, tsi148_bridge->base + TSI148_LCSR_IT[i] + 645 iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] +
652 TSI148_LCSR_OFFSET_ITOFU); 646 TSI148_LCSR_OFFSET_ITOFU);
653 iowrite32be(pci_offset_low, tsi148_bridge->base + TSI148_LCSR_IT[i] + 647 iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] +
654 TSI148_LCSR_OFFSET_ITOFL); 648 TSI148_LCSR_OFFSET_ITOFL);
655 649
656/* XXX Prefetch stuff currently unsupported */
657#if 0
658
659 for (x = 0; x < 4; x++) {
660 if ((64 << x) >= vmeIn->prefetchSize) {
661 break;
662 }
663 }
664 if (x == 4)
665 x--;
666 temp_ctl |= (x << 16);
667
668 if (vmeIn->prefetchThreshold)
669 if (vmeIn->prefetchThreshold)
670 temp_ctl |= 0x40000;
671#endif
672
673 /* Setup 2eSST speeds */ 650 /* Setup 2eSST speeds */
674 temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M; 651 temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M;
675 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { 652 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -712,13 +689,13 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
712 temp_ctl |= TSI148_LCSR_ITAT_DATA; 689 temp_ctl |= TSI148_LCSR_ITAT_DATA;
713 690
714 /* Write ctl reg without enable */ 691 /* Write ctl reg without enable */
715 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] + 692 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
716 TSI148_LCSR_OFFSET_ITAT); 693 TSI148_LCSR_OFFSET_ITAT);
717 694
718 if (enabled) 695 if (enabled)
719 temp_ctl |= TSI148_LCSR_ITAT_EN; 696 temp_ctl |= TSI148_LCSR_ITAT_EN;
720 697
721 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] + 698 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] +
722 TSI148_LCSR_OFFSET_ITAT); 699 TSI148_LCSR_OFFSET_ITAT);
723 700
724 return 0; 701 return 0;
@@ -726,8 +703,6 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
726 703
727/* 704/*
728 * Get slave window configuration. 705 * Get slave window configuration.
729 *
730 * XXX Prefetch currently unsupported.
731 */ 706 */
732int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, 707int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
733 unsigned long long *vme_base, unsigned long long *size, 708 unsigned long long *vme_base, unsigned long long *size,
@@ -738,25 +713,27 @@ int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
738 unsigned int vme_bound_low, vme_bound_high; 713 unsigned int vme_bound_low, vme_bound_high;
739 unsigned int pci_offset_low, pci_offset_high; 714 unsigned int pci_offset_low, pci_offset_high;
740 unsigned long long vme_bound, pci_offset; 715 unsigned long long vme_bound, pci_offset;
716 struct tsi148_driver *bridge;
741 717
718 bridge = image->parent->driver_priv;
742 719
743 i = image->number; 720 i = image->number;
744 721
745 /* Read registers */ 722 /* Read registers */
746 ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 723 ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
747 TSI148_LCSR_OFFSET_ITAT); 724 TSI148_LCSR_OFFSET_ITAT);
748 725
749 vme_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 726 vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
750 TSI148_LCSR_OFFSET_ITSAU); 727 TSI148_LCSR_OFFSET_ITSAU);
751 vme_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 728 vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
752 TSI148_LCSR_OFFSET_ITSAL); 729 TSI148_LCSR_OFFSET_ITSAL);
753 vme_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 730 vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
754 TSI148_LCSR_OFFSET_ITEAU); 731 TSI148_LCSR_OFFSET_ITEAU);
755 vme_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 732 vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
756 TSI148_LCSR_OFFSET_ITEAL); 733 TSI148_LCSR_OFFSET_ITEAL);
757 pci_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 734 pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
758 TSI148_LCSR_OFFSET_ITOFU); 735 TSI148_LCSR_OFFSET_ITOFU);
759 pci_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] + 736 pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] +
760 TSI148_LCSR_OFFSET_ITOFL); 737 TSI148_LCSR_OFFSET_ITOFL);
761 738
762 /* Convert 64-bit variables to 2x 32-bit variables */ 739 /* Convert 64-bit variables to 2x 32-bit variables */
@@ -833,6 +810,9 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
833 unsigned long long existing_size; 810 unsigned long long existing_size;
834 int retval = 0; 811 int retval = 0;
835 struct pci_dev *pdev; 812 struct pci_dev *pdev;
813 struct vme_bridge *tsi148_bridge;
814
815 tsi148_bridge = image->parent;
836 816
837 /* Find pci_dev container of dev */ 817 /* Find pci_dev container of dev */
838 if (tsi148_bridge->parent == NULL) { 818 if (tsi148_bridge->parent == NULL) {
@@ -841,8 +821,8 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
841 } 821 }
842 pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); 822 pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
843 823
844 existing_size = (unsigned long long)(image->pci_resource.end - 824 existing_size = (unsigned long long)(image->bus_resource.end -
845 image->pci_resource.start); 825 image->bus_resource.start);
846 826
847 /* If the existing size is OK, return */ 827 /* If the existing size is OK, return */
848 if ((size != 0) && (existing_size == (size - 1))) 828 if ((size != 0) && (existing_size == (size - 1)))
@@ -851,10 +831,10 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
851 if (existing_size != 0) { 831 if (existing_size != 0) {
852 iounmap(image->kern_base); 832 iounmap(image->kern_base);
853 image->kern_base = NULL; 833 image->kern_base = NULL;
854 if (image->pci_resource.name != NULL) 834 if (image->bus_resource.name != NULL)
855 kfree(image->pci_resource.name); 835 kfree(image->bus_resource.name);
856 release_resource(&(image->pci_resource)); 836 release_resource(&(image->bus_resource));
857 memset(&(image->pci_resource), 0, sizeof(struct resource)); 837 memset(&(image->bus_resource), 0, sizeof(struct resource));
858 } 838 }
859 839
860 /* Exit here if size is zero */ 840 /* Exit here if size is zero */
@@ -862,9 +842,9 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
862 return 0; 842 return 0;
863 } 843 }
864 844
865 if (image->pci_resource.name == NULL) { 845 if (image->bus_resource.name == NULL) {
866 image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); 846 image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
867 if (image->pci_resource.name == NULL) { 847 if (image->bus_resource.name == NULL) {
868 printk(KERN_ERR "Unable to allocate memory for resource" 848 printk(KERN_ERR "Unable to allocate memory for resource"
869 " name\n"); 849 " name\n");
870 retval = -ENOMEM; 850 retval = -ENOMEM;
@@ -872,26 +852,26 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
872 } 852 }
873 } 853 }
874 854
875 sprintf((char *)image->pci_resource.name, "%s.%d", tsi148_bridge->name, 855 sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name,
876 image->number); 856 image->number);
877 857
878 image->pci_resource.start = 0; 858 image->bus_resource.start = 0;
879 image->pci_resource.end = (unsigned long)size; 859 image->bus_resource.end = (unsigned long)size;
880 image->pci_resource.flags = IORESOURCE_MEM; 860 image->bus_resource.flags = IORESOURCE_MEM;
881 861
882 retval = pci_bus_alloc_resource(pdev->bus, 862 retval = pci_bus_alloc_resource(pdev->bus,
883 &(image->pci_resource), size, size, PCIBIOS_MIN_MEM, 863 &(image->bus_resource), size, size, PCIBIOS_MIN_MEM,
884 0, NULL, NULL); 864 0, NULL, NULL);
885 if (retval) { 865 if (retval) {
886 printk(KERN_ERR "Failed to allocate mem resource for " 866 printk(KERN_ERR "Failed to allocate mem resource for "
887 "window %d size 0x%lx start 0x%lx\n", 867 "window %d size 0x%lx start 0x%lx\n",
888 image->number, (unsigned long)size, 868 image->number, (unsigned long)size,
889 (unsigned long)image->pci_resource.start); 869 (unsigned long)image->bus_resource.start);
890 goto err_resource; 870 goto err_resource;
891 } 871 }
892 872
893 image->kern_base = ioremap_nocache( 873 image->kern_base = ioremap_nocache(
894 image->pci_resource.start, size); 874 image->bus_resource.start, size);
895 if (image->kern_base == NULL) { 875 if (image->kern_base == NULL) {
896 printk(KERN_ERR "Failed to remap resource\n"); 876 printk(KERN_ERR "Failed to remap resource\n");
897 retval = -ENOMEM; 877 retval = -ENOMEM;
@@ -903,10 +883,10 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
903 iounmap(image->kern_base); 883 iounmap(image->kern_base);
904 image->kern_base = NULL; 884 image->kern_base = NULL;
905err_remap: 885err_remap:
906 release_resource(&(image->pci_resource)); 886 release_resource(&(image->bus_resource));
907err_resource: 887err_resource:
908 kfree(image->pci_resource.name); 888 kfree(image->bus_resource.name);
909 memset(&(image->pci_resource), 0, sizeof(struct resource)); 889 memset(&(image->bus_resource), 0, sizeof(struct resource));
910err_name: 890err_name:
911 return retval; 891 return retval;
912} 892}
@@ -918,9 +898,9 @@ static void tsi148_free_resource(struct vme_master_resource *image)
918{ 898{
919 iounmap(image->kern_base); 899 iounmap(image->kern_base);
920 image->kern_base = NULL; 900 image->kern_base = NULL;
921 release_resource(&(image->pci_resource)); 901 release_resource(&(image->bus_resource));
922 kfree(image->pci_resource.name); 902 kfree(image->bus_resource.name);
923 memset(&(image->pci_resource), 0, sizeof(struct resource)); 903 memset(&(image->bus_resource), 0, sizeof(struct resource));
924} 904}
925 905
926/* 906/*
@@ -937,6 +917,9 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
937 unsigned int pci_bound_low, pci_bound_high; 917 unsigned int pci_bound_low, pci_bound_high;
938 unsigned int vme_offset_low, vme_offset_high; 918 unsigned int vme_offset_low, vme_offset_high;
939 unsigned long long pci_bound, vme_offset, pci_base; 919 unsigned long long pci_bound, vme_offset, pci_base;
920 struct tsi148_driver *bridge;
921
922 bridge = image->parent->driver_priv;
940 923
941 /* Verify input data */ 924 /* Verify input data */
942 if (vme_base & 0xFFFF) { 925 if (vme_base & 0xFFFF) {
@@ -970,7 +953,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
970 pci_bound = 0; 953 pci_bound = 0;
971 vme_offset = 0; 954 vme_offset = 0;
972 } else { 955 } else {
973 pci_base = (unsigned long long)image->pci_resource.start; 956 pci_base = (unsigned long long)image->bus_resource.start;
974 957
975 /* 958 /*
976 * Bound address is a valid address for the window, adjust 959 * Bound address is a valid address for the window, adjust
@@ -1007,26 +990,12 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
1007 i = image->number; 990 i = image->number;
1008 991
1009 /* Disable while we are mucking around */ 992 /* Disable while we are mucking around */
1010 temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 993 temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1011 TSI148_LCSR_OFFSET_OTAT); 994 TSI148_LCSR_OFFSET_OTAT);
1012 temp_ctl &= ~TSI148_LCSR_OTAT_EN; 995 temp_ctl &= ~TSI148_LCSR_OTAT_EN;
1013 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] + 996 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
1014 TSI148_LCSR_OFFSET_OTAT); 997 TSI148_LCSR_OFFSET_OTAT);
1015 998
1016/* XXX Prefetch stuff currently unsupported */
1017#if 0
1018 if (vmeOut->prefetchEnable) {
1019 temp_ctl |= 0x40000;
1020 for (x = 0; x < 4; x++) {
1021 if ((2 << x) >= vmeOut->prefetchSize)
1022 break;
1023 }
1024 if (x == 4)
1025 x = 3;
1026 temp_ctl |= (x << 16);
1027 }
1028#endif
1029
1030 /* Setup 2eSST speeds */ 999 /* Setup 2eSST speeds */
1031 temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M; 1000 temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M;
1032 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { 1001 switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
@@ -1126,33 +1095,27 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
1126 temp_ctl |= TSI148_LCSR_OTAT_PGM; 1095 temp_ctl |= TSI148_LCSR_OTAT_PGM;
1127 1096
1128 /* Setup mapping */ 1097 /* Setup mapping */
1129 iowrite32be(pci_base_high, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1098 iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] +
1130 TSI148_LCSR_OFFSET_OTSAU); 1099 TSI148_LCSR_OFFSET_OTSAU);
1131 iowrite32be(pci_base_low, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1100 iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] +
1132 TSI148_LCSR_OFFSET_OTSAL); 1101 TSI148_LCSR_OFFSET_OTSAL);
1133 iowrite32be(pci_bound_high, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1102 iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] +
1134 TSI148_LCSR_OFFSET_OTEAU); 1103 TSI148_LCSR_OFFSET_OTEAU);
1135 iowrite32be(pci_bound_low, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1104 iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] +
1136 TSI148_LCSR_OFFSET_OTEAL); 1105 TSI148_LCSR_OFFSET_OTEAL);
1137 iowrite32be(vme_offset_high, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1106 iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] +
1138 TSI148_LCSR_OFFSET_OTOFU); 1107 TSI148_LCSR_OFFSET_OTOFU);
1139 iowrite32be(vme_offset_low, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1108 iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] +
1140 TSI148_LCSR_OFFSET_OTOFL); 1109 TSI148_LCSR_OFFSET_OTOFL);
1141 1110
1142/* XXX We need to deal with OTBS */
1143#if 0
1144 iowrite32be(vmeOut->bcastSelect2esst, tsi148_bridge->base +
1145 TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTBS);
1146#endif
1147
1148 /* Write ctl reg without enable */ 1111 /* Write ctl reg without enable */
1149 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1112 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
1150 TSI148_LCSR_OFFSET_OTAT); 1113 TSI148_LCSR_OFFSET_OTAT);
1151 1114
1152 if (enabled) 1115 if (enabled)
1153 temp_ctl |= TSI148_LCSR_OTAT_EN; 1116 temp_ctl |= TSI148_LCSR_OTAT_EN;
1154 1117
1155 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] + 1118 iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] +
1156 TSI148_LCSR_OFFSET_OTAT); 1119 TSI148_LCSR_OFFSET_OTAT);
1157 1120
1158 spin_unlock(&(image->lock)); 1121 spin_unlock(&(image->lock));
@@ -1183,23 +1146,26 @@ int __tsi148_master_get( struct vme_master_resource *image, int *enabled,
1183 unsigned int vme_offset_low, vme_offset_high; 1146 unsigned int vme_offset_low, vme_offset_high;
1184 1147
1185 unsigned long long pci_base, pci_bound, vme_offset; 1148 unsigned long long pci_base, pci_bound, vme_offset;
1149 struct tsi148_driver *bridge;
1150
1151 bridge = image->parent->driver_priv;
1186 1152
1187 i = image->number; 1153 i = image->number;
1188 1154
1189 ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1155 ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1190 TSI148_LCSR_OFFSET_OTAT); 1156 TSI148_LCSR_OFFSET_OTAT);
1191 1157
1192 pci_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1158 pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1193 TSI148_LCSR_OFFSET_OTSAU); 1159 TSI148_LCSR_OFFSET_OTSAU);
1194 pci_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1160 pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1195 TSI148_LCSR_OFFSET_OTSAL); 1161 TSI148_LCSR_OFFSET_OTSAL);
1196 pci_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1162 pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1197 TSI148_LCSR_OFFSET_OTEAU); 1163 TSI148_LCSR_OFFSET_OTEAU);
1198 pci_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1164 pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1199 TSI148_LCSR_OFFSET_OTEAL); 1165 TSI148_LCSR_OFFSET_OTEAL);
1200 vme_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1166 vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1201 TSI148_LCSR_OFFSET_OTOFU); 1167 TSI148_LCSR_OFFSET_OTOFU);
1202 vme_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1168 vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1203 TSI148_LCSR_OFFSET_OTOFL); 1169 TSI148_LCSR_OFFSET_OTOFL);
1204 1170
1205 /* Convert 64-bit variables to 2x 32-bit variables */ 1171 /* Convert 64-bit variables to 2x 32-bit variables */
@@ -1305,6 +1271,9 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
1305 vme_cycle_t cycle; 1271 vme_cycle_t cycle;
1306 vme_width_t dwidth; 1272 vme_width_t dwidth;
1307 struct vme_bus_error *vme_err = NULL; 1273 struct vme_bus_error *vme_err = NULL;
1274 struct vme_bridge *tsi148_bridge;
1275
1276 tsi148_bridge = image->parent;
1308 1277
1309 spin_lock(&(image->lock)); 1278 spin_lock(&(image->lock));
1310 1279
@@ -1317,13 +1286,15 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
1317 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, 1286 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
1318 &dwidth); 1287 &dwidth);
1319 1288
1320 vme_err = tsi148_find_error(aspace, vme_base + offset, count); 1289 vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
1290 count);
1321 if(vme_err != NULL) { 1291 if(vme_err != NULL) {
1322 dev_err(image->parent->parent, "First VME read error detected " 1292 dev_err(image->parent->parent, "First VME read error detected "
1323 "an at address 0x%llx\n", vme_err->address); 1293 "an at address 0x%llx\n", vme_err->address);
1324 retval = vme_err->address - (vme_base + offset); 1294 retval = vme_err->address - (vme_base + offset);
1325 /* Clear down save errors in this address range */ 1295 /* Clear down save errors in this address range */
1326 tsi148_clear_errors(aspace, vme_base + offset, count); 1296 tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
1297 count);
1327 } 1298 }
1328 1299
1329skip_chk: 1300skip_chk:
@@ -1333,9 +1304,6 @@ skip_chk:
1333} 1304}
1334 1305
1335 1306
1336/* XXX We need to change vme_master_resource->mtx to a spinlock so that read
1337 * and write functions can be used in an interrupt context
1338 */
1339ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, 1307ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
1340 size_t count, loff_t offset) 1308 size_t count, loff_t offset)
1341{ 1309{
@@ -1346,6 +1314,12 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
1346 vme_width_t dwidth; 1314 vme_width_t dwidth;
1347 1315
1348 struct vme_bus_error *vme_err = NULL; 1316 struct vme_bus_error *vme_err = NULL;
1317 struct vme_bridge *tsi148_bridge;
1318 struct tsi148_driver *bridge;
1319
1320 tsi148_bridge = image->parent;
1321
1322 bridge = tsi148_bridge->driver_priv;
1349 1323
1350 spin_lock(&(image->lock)); 1324 spin_lock(&(image->lock));
1351 1325
@@ -1373,15 +1347,17 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
1373 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, 1347 __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
1374 &dwidth); 1348 &dwidth);
1375 1349
1376 ioread16(flush_image->kern_base + 0x7F000); 1350 ioread16(bridge->flush_image->kern_base + 0x7F000);
1377 1351
1378 vme_err = tsi148_find_error(aspace, vme_base + offset, count); 1352 vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset,
1353 count);
1379 if(vme_err != NULL) { 1354 if(vme_err != NULL) {
1380 printk("First VME write error detected an at address 0x%llx\n", 1355 printk("First VME write error detected an at address 0x%llx\n",
1381 vme_err->address); 1356 vme_err->address);
1382 retval = vme_err->address - (vme_base + offset); 1357 retval = vme_err->address - (vme_base + offset);
1383 /* Clear down save errors in this address range */ 1358 /* Clear down save errors in this address range */
1384 tsi148_clear_errors(aspace, vme_base + offset, count); 1359 tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset,
1360 count);
1385 } 1361 }
1386 1362
1387skip_chk: 1363skip_chk:
@@ -1403,48 +1379,50 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image,
1403 unsigned int pci_addr_high, pci_addr_low; 1379 unsigned int pci_addr_high, pci_addr_low;
1404 u32 tmp, result; 1380 u32 tmp, result;
1405 int i; 1381 int i;
1382 struct tsi148_driver *bridge;
1406 1383
1384 bridge = image->parent->driver_priv;
1407 1385
1408 /* Find the PCI address that maps to the desired VME address */ 1386 /* Find the PCI address that maps to the desired VME address */
1409 i = image->number; 1387 i = image->number;
1410 1388
1411 /* Locking as we can only do one of these at a time */ 1389 /* Locking as we can only do one of these at a time */
1412 mutex_lock(&(vme_rmw)); 1390 mutex_lock(&(bridge->vme_rmw));
1413 1391
1414 /* Lock image */ 1392 /* Lock image */
1415 spin_lock(&(image->lock)); 1393 spin_lock(&(image->lock));
1416 1394
1417 pci_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1395 pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1418 TSI148_LCSR_OFFSET_OTSAU); 1396 TSI148_LCSR_OFFSET_OTSAU);
1419 pci_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] + 1397 pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] +
1420 TSI148_LCSR_OFFSET_OTSAL); 1398 TSI148_LCSR_OFFSET_OTSAL);
1421 1399
1422 reg_join(pci_addr_high, pci_addr_low, &pci_addr); 1400 reg_join(pci_addr_high, pci_addr_low, &pci_addr);
1423 reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low); 1401 reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low);
1424 1402
1425 /* Configure registers */ 1403 /* Configure registers */
1426 iowrite32be(mask, tsi148_bridge->base + TSI148_LCSR_RMWEN); 1404 iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN);
1427 iowrite32be(compare, tsi148_bridge->base + TSI148_LCSR_RMWC); 1405 iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC);
1428 iowrite32be(swap, tsi148_bridge->base + TSI148_LCSR_RMWS); 1406 iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS);
1429 iowrite32be(pci_addr_high, tsi148_bridge->base + TSI148_LCSR_RMWAU); 1407 iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU);
1430 iowrite32be(pci_addr_low, tsi148_bridge->base + TSI148_LCSR_RMWAL); 1408 iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL);
1431 1409
1432 /* Enable RMW */ 1410 /* Enable RMW */
1433 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL); 1411 tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
1434 tmp |= TSI148_LCSR_VMCTRL_RMWEN; 1412 tmp |= TSI148_LCSR_VMCTRL_RMWEN;
1435 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL); 1413 iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
1436 1414
1437 /* Kick process off with a read to the required address. */ 1415 /* Kick process off with a read to the required address. */
1438 result = ioread32be(image->kern_base + offset); 1416 result = ioread32be(image->kern_base + offset);
1439 1417
1440 /* Disable RMW */ 1418 /* Disable RMW */
1441 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL); 1419 tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL);
1442 tmp &= ~TSI148_LCSR_VMCTRL_RMWEN; 1420 tmp &= ~TSI148_LCSR_VMCTRL_RMWEN;
1443 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL); 1421 iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL);
1444 1422
1445 spin_unlock(&(image->lock)); 1423 spin_unlock(&(image->lock));
1446 1424
1447 mutex_unlock(&(vme_rmw)); 1425 mutex_unlock(&(bridge->vme_rmw));
1448 1426
1449 return result; 1427 return result;
1450} 1428}
@@ -1637,8 +1615,6 @@ static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace,
1637 1615
1638/* 1616/*
1639 * Add a link list descriptor to the list 1617 * Add a link list descriptor to the list
1640 *
1641 * XXX Need to handle 2eSST Broadcast select bits
1642 */ 1618 */
1643int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src, 1619int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src,
1644 struct vme_dma_attr *dest, size_t count) 1620 struct vme_dma_attr *dest, size_t count)
@@ -1651,7 +1627,7 @@ int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src,
1651 dma_addr_t desc_ptr; 1627 dma_addr_t desc_ptr;
1652 int retval = 0; 1628 int retval = 0;
1653 1629
1654 /* XXX descriptor must be aligned on 64-bit boundaries */ 1630 /* Descriptor must be aligned on 64-bit boundaries */
1655 entry = (struct tsi148_dma_entry *)kmalloc( 1631 entry = (struct tsi148_dma_entry *)kmalloc(
1656 sizeof(struct tsi148_dma_entry), GFP_KERNEL); 1632 sizeof(struct tsi148_dma_entry), GFP_KERNEL);
1657 if (entry == NULL) { 1633 if (entry == NULL) {
@@ -1788,11 +1764,14 @@ err_mem:
1788/* 1764/*
1789 * Check to see if the provided DMA channel is busy. 1765 * Check to see if the provided DMA channel is busy.
1790 */ 1766 */
1791static int tsi148_dma_busy(int channel) 1767static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel)
1792{ 1768{
1793 u32 tmp; 1769 u32 tmp;
1770 struct tsi148_driver *bridge;
1771
1772 bridge = tsi148_bridge->driver_priv;
1794 1773
1795 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] + 1774 tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
1796 TSI148_LCSR_OFFSET_DSTA); 1775 TSI148_LCSR_OFFSET_DSTA);
1797 1776
1798 if (tmp & TSI148_LCSR_DSTA_BSY) 1777 if (tmp & TSI148_LCSR_DSTA_BSY)
@@ -1815,12 +1794,12 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
1815 dma_addr_t bus_addr; 1794 dma_addr_t bus_addr;
1816 u32 bus_addr_high, bus_addr_low; 1795 u32 bus_addr_high, bus_addr_low;
1817 u32 val, dctlreg = 0; 1796 u32 val, dctlreg = 0;
1818#if 0 1797 struct tsi148_driver *bridge;
1819 int x;
1820#endif
1821 1798
1822 ctrlr = list->parent; 1799 ctrlr = list->parent;
1823 1800
1801 bridge = ctrlr->parent->driver_priv;
1802
1824 mutex_lock(&(ctrlr->mtx)); 1803 mutex_lock(&(ctrlr->mtx));
1825 1804
1826 channel = ctrlr->number; 1805 channel = ctrlr->number;
@@ -1837,48 +1816,6 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
1837 } else { 1816 } else {
1838 list_add(&(list->list), &(ctrlr->running)); 1817 list_add(&(list->list), &(ctrlr->running));
1839 } 1818 }
1840#if 0
1841 /* XXX Still todo */
1842 for (x = 0; x < 8; x++) { /* vme block size */
1843 if ((32 << x) >= vmeDma->maxVmeBlockSize) {
1844 break;
1845 }
1846 }
1847 if (x == 8)
1848 x = 7;
1849 dctlreg |= (x << 12);
1850
1851 for (x = 0; x < 8; x++) { /* pci block size */
1852 if ((32 << x) >= vmeDma->maxPciBlockSize) {
1853 break;
1854 }
1855 }
1856 if (x == 8)
1857 x = 7;
1858 dctlreg |= (x << 4);
1859
1860 if (vmeDma->vmeBackOffTimer) {
1861 for (x = 1; x < 8; x++) { /* vme timer */
1862 if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
1863 break;
1864 }
1865 }
1866 if (x == 8)
1867 x = 7;
1868 dctlreg |= (x << 8);
1869 }
1870
1871 if (vmeDma->pciBackOffTimer) {
1872 for (x = 1; x < 8; x++) { /* pci timer */
1873 if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
1874 break;
1875 }
1876 }
1877 if (x == 8)
1878 x = 7;
1879 dctlreg |= (x << 0);
1880 }
1881#endif
1882 1819
1883 /* Get first bus address and write into registers */ 1820 /* Get first bus address and write into registers */
1884 entry = list_first_entry(&(list->entries), struct tsi148_dma_entry, 1821 entry = list_first_entry(&(list->entries), struct tsi148_dma_entry,
@@ -1890,21 +1827,22 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
1890 1827
1891 reg_split(bus_addr, &bus_addr_high, &bus_addr_low); 1828 reg_split(bus_addr, &bus_addr_high, &bus_addr_low);
1892 1829
1893 iowrite32be(bus_addr_high, tsi148_bridge->base + 1830 iowrite32be(bus_addr_high, bridge->base +
1894 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU); 1831 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
1895 iowrite32be(bus_addr_low, tsi148_bridge->base + 1832 iowrite32be(bus_addr_low, bridge->base +
1896 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL); 1833 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
1897 1834
1898 /* Start the operation */ 1835 /* Start the operation */
1899 iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, tsi148_bridge->base + 1836 iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base +
1900 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL); 1837 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
1901 1838
1902 wait_event_interruptible(dma_queue[channel], tsi148_dma_busy(channel)); 1839 wait_event_interruptible(bridge->dma_queue[channel],
1840 tsi148_dma_busy(ctrlr->parent, channel));
1903 /* 1841 /*
1904 * Read status register, this register is valid until we kick off a 1842 * Read status register, this register is valid until we kick off a
1905 * new transfer. 1843 * new transfer.
1906 */ 1844 */
1907 val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] + 1845 val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] +
1908 TSI148_LCSR_OFFSET_DSTA); 1846 TSI148_LCSR_OFFSET_DSTA);
1909 1847
1910 if (val & TSI148_LCSR_DSTA_VBE) { 1848 if (val & TSI148_LCSR_DSTA_VBE) {
@@ -1952,12 +1890,15 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
1952{ 1890{
1953 u32 lm_base_high, lm_base_low, lm_ctl = 0; 1891 u32 lm_base_high, lm_base_low, lm_ctl = 0;
1954 int i; 1892 int i;
1893 struct tsi148_driver *bridge;
1894
1895 bridge = lm->parent->driver_priv;
1955 1896
1956 mutex_lock(&(lm->mtx)); 1897 mutex_lock(&(lm->mtx));
1957 1898
1958 /* If we already have a callback attached, we can't move it! */ 1899 /* If we already have a callback attached, we can't move it! */
1959 for (i = 0; i < lm->monitors; i++) { 1900 for (i = 0; i < lm->monitors; i++) {
1960 if(lm_callback[i] != NULL) { 1901 if (bridge->lm_callback[i] != NULL) {
1961 mutex_unlock(&(lm->mtx)); 1902 mutex_unlock(&(lm->mtx));
1962 printk("Location monitor callback attached, can't " 1903 printk("Location monitor callback attached, can't "
1963 "reset\n"); 1904 "reset\n");
@@ -1996,9 +1937,9 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
1996 1937
1997 reg_split(lm_base, &lm_base_high, &lm_base_low); 1938 reg_split(lm_base, &lm_base_high, &lm_base_low);
1998 1939
1999 iowrite32be(lm_base_high, tsi148_bridge->base + TSI148_LCSR_LMBAU); 1940 iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU);
2000 iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL); 1941 iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL);
2001 iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); 1942 iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
2002 1943
2003 mutex_unlock(&(lm->mtx)); 1944 mutex_unlock(&(lm->mtx));
2004 1945
@@ -2012,12 +1953,15 @@ int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base,
2012 vme_address_t *aspace, vme_cycle_t *cycle) 1953 vme_address_t *aspace, vme_cycle_t *cycle)
2013{ 1954{
2014 u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; 1955 u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
1956 struct tsi148_driver *bridge;
1957
1958 bridge = lm->parent->driver_priv;
2015 1959
2016 mutex_lock(&(lm->mtx)); 1960 mutex_lock(&(lm->mtx));
2017 1961
2018 lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU); 1962 lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU);
2019 lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL); 1963 lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL);
2020 lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); 1964 lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
2021 1965
2022 reg_join(lm_base_high, lm_base_low, lm_base); 1966 reg_join(lm_base_high, lm_base_low, lm_base);
2023 1967
@@ -2060,11 +2004,14 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
2060 void (*callback)(int)) 2004 void (*callback)(int))
2061{ 2005{
2062 u32 lm_ctl, tmp; 2006 u32 lm_ctl, tmp;
2007 struct tsi148_driver *bridge;
2008
2009 bridge = lm->parent->driver_priv;
2063 2010
2064 mutex_lock(&(lm->mtx)); 2011 mutex_lock(&(lm->mtx));
2065 2012
2066 /* Ensure that the location monitor is configured - need PGM or DATA */ 2013 /* Ensure that the location monitor is configured - need PGM or DATA */
2067 lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); 2014 lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT);
2068 if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { 2015 if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
2069 mutex_unlock(&(lm->mtx)); 2016 mutex_unlock(&(lm->mtx));
2070 printk("Location monitor not properly configured\n"); 2017 printk("Location monitor not properly configured\n");
@@ -2072,28 +2019,28 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
2072 } 2019 }
2073 2020
2074 /* Check that a callback isn't already attached */ 2021 /* Check that a callback isn't already attached */
2075 if (lm_callback[monitor] != NULL) { 2022 if (bridge->lm_callback[monitor] != NULL) {
2076 mutex_unlock(&(lm->mtx)); 2023 mutex_unlock(&(lm->mtx));
2077 printk("Existing callback attached\n"); 2024 printk("Existing callback attached\n");
2078 return -EBUSY; 2025 return -EBUSY;
2079 } 2026 }
2080 2027
2081 /* Attach callback */ 2028 /* Attach callback */
2082 lm_callback[monitor] = callback; 2029 bridge->lm_callback[monitor] = callback;
2083 2030
2084 /* Enable Location Monitor interrupt */ 2031 /* Enable Location Monitor interrupt */
2085 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); 2032 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN);
2086 tmp |= TSI148_LCSR_INTEN_LMEN[monitor]; 2033 tmp |= TSI148_LCSR_INTEN_LMEN[monitor];
2087 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); 2034 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
2088 2035
2089 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); 2036 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
2090 tmp |= TSI148_LCSR_INTEO_LMEO[monitor]; 2037 tmp |= TSI148_LCSR_INTEO_LMEO[monitor];
2091 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); 2038 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
2092 2039
2093 /* Ensure that global Location Monitor Enable set */ 2040 /* Ensure that global Location Monitor Enable set */
2094 if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) { 2041 if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) {
2095 lm_ctl |= TSI148_LCSR_LMAT_EN; 2042 lm_ctl |= TSI148_LCSR_LMAT_EN;
2096 iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); 2043 iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT);
2097 } 2044 }
2098 2045
2099 mutex_unlock(&(lm->mtx)); 2046 mutex_unlock(&(lm->mtx));
@@ -2107,30 +2054,33 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
2107int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) 2054int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
2108{ 2055{
2109 u32 lm_en, tmp; 2056 u32 lm_en, tmp;
2057 struct tsi148_driver *bridge;
2058
2059 bridge = lm->parent->driver_priv;
2110 2060
2111 mutex_lock(&(lm->mtx)); 2061 mutex_lock(&(lm->mtx));
2112 2062
2113 /* Disable Location Monitor and ensure previous interrupts are clear */ 2063 /* Disable Location Monitor and ensure previous interrupts are clear */
2114 lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); 2064 lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN);
2115 lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor]; 2065 lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor];
2116 iowrite32be(lm_en, tsi148_bridge->base + TSI148_LCSR_INTEN); 2066 iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN);
2117 2067
2118 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO); 2068 tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO);
2119 tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor]; 2069 tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor];
2120 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO); 2070 iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
2121 2071
2122 iowrite32be(TSI148_LCSR_INTC_LMC[monitor], 2072 iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
2123 tsi148_bridge->base + TSI148_LCSR_INTC); 2073 bridge->base + TSI148_LCSR_INTC);
2124 2074
2125 /* Detach callback */ 2075 /* Detach callback */
2126 lm_callback[monitor] = NULL; 2076 bridge->lm_callback[monitor] = NULL;
2127 2077
2128 /* If all location monitors disabled, disable global Location Monitor */ 2078 /* If all location monitors disabled, disable global Location Monitor */
2129 if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S | 2079 if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S |
2130 TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) { 2080 TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) {
2131 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); 2081 tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT);
2132 tmp &= ~TSI148_LCSR_LMAT_EN; 2082 tmp &= ~TSI148_LCSR_LMAT_EN;
2133 iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT); 2083 iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT);
2134 } 2084 }
2135 2085
2136 mutex_unlock(&(lm->mtx)); 2086 mutex_unlock(&(lm->mtx));
@@ -2141,12 +2091,19 @@ int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
2141/* 2091/*
2142 * Determine Geographical Addressing 2092 * Determine Geographical Addressing
2143 */ 2093 */
2144int tsi148_slot_get(void) 2094int tsi148_slot_get(struct vme_bridge *tsi148_bridge)
2145{ 2095{
2146 u32 slot = 0; 2096 u32 slot = 0;
2097 struct tsi148_driver *bridge;
2098
2099 bridge = tsi148_bridge->driver_priv;
2100
2101 if (!geoid) {
2102 slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT);
2103 slot = slot & TSI148_LCSR_VSTAT_GA_M;
2104 } else
2105 slot = geoid;
2147 2106
2148 slot = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
2149 slot = slot & TSI148_LCSR_VSTAT_GA_M;
2150 return (int)slot; 2107 return (int)slot;
2151} 2108}
2152 2109
@@ -2167,45 +2124,50 @@ static int __init tsi148_init(void)
2167 * boards registers, this means there is a fix length 508kB window which must 2124 * boards registers, this means there is a fix length 508kB window which must
2168 * be mapped onto PCI memory. 2125 * be mapped onto PCI memory.
2169 */ 2126 */
2170static int tsi148_crcsr_init(struct pci_dev *pdev) 2127static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge,
2128 struct pci_dev *pdev)
2171{ 2129{
2172 u32 cbar, crat, vstat; 2130 u32 cbar, crat, vstat;
2173 u32 crcsr_bus_high, crcsr_bus_low; 2131 u32 crcsr_bus_high, crcsr_bus_low;
2174 int retval; 2132 int retval;
2133 struct tsi148_driver *bridge;
2134
2135 bridge = tsi148_bridge->driver_priv;
2175 2136
2176 /* Allocate mem for CR/CSR image */ 2137 /* Allocate mem for CR/CSR image */
2177 crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, 2138 bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
2178 &crcsr_bus); 2139 &(bridge->crcsr_bus));
2179 if (crcsr_kernel == NULL) { 2140 if (bridge->crcsr_kernel == NULL) {
2180 dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " 2141 dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
2181 "image\n"); 2142 "image\n");
2182 return -ENOMEM; 2143 return -ENOMEM;
2183 } 2144 }
2184 2145
2185 memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); 2146 memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
2186 2147
2187 reg_split(crcsr_bus, &crcsr_bus_high, &crcsr_bus_low); 2148 reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
2188 2149
2189 iowrite32be(crcsr_bus_high, tsi148_bridge->base + TSI148_LCSR_CROU); 2150 iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU);
2190 iowrite32be(crcsr_bus_low, tsi148_bridge->base + TSI148_LCSR_CROL); 2151 iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL);
2191 2152
2192 /* Ensure that the CR/CSR is configured at the correct offset */ 2153 /* Ensure that the CR/CSR is configured at the correct offset */
2193 cbar = ioread32be(tsi148_bridge->base + TSI148_CBAR); 2154 cbar = ioread32be(bridge->base + TSI148_CBAR);
2194 cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3; 2155 cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3;
2195 2156
2196 vstat = tsi148_slot_get(); 2157 vstat = tsi148_slot_get(tsi148_bridge);
2197 2158
2198 if (cbar != vstat) { 2159 if (cbar != vstat) {
2160 cbar = vstat;
2199 dev_info(&pdev->dev, "Setting CR/CSR offset\n"); 2161 dev_info(&pdev->dev, "Setting CR/CSR offset\n");
2200 iowrite32be(cbar<<3, tsi148_bridge->base + TSI148_CBAR); 2162 iowrite32be(cbar<<3, bridge->base + TSI148_CBAR);
2201 } 2163 }
2202 dev_info(&pdev->dev, "CR/CSR Offset: %d\n", cbar); 2164 dev_info(&pdev->dev, "CR/CSR Offset: %d\n", cbar);
2203 2165
2204 crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT); 2166 crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
2205 if (crat & TSI148_LCSR_CRAT_EN) { 2167 if (crat & TSI148_LCSR_CRAT_EN) {
2206 dev_info(&pdev->dev, "Enabling CR/CSR space\n"); 2168 dev_info(&pdev->dev, "Enabling CR/CSR space\n");
2207 iowrite32be(crat | TSI148_LCSR_CRAT_EN, 2169 iowrite32be(crat | TSI148_LCSR_CRAT_EN,
2208 tsi148_bridge->base + TSI148_LCSR_CRAT); 2170 bridge->base + TSI148_LCSR_CRAT);
2209 } else 2171 } else
2210 dev_info(&pdev->dev, "CR/CSR already enabled\n"); 2172 dev_info(&pdev->dev, "CR/CSR already enabled\n");
2211 2173
@@ -2214,8 +2176,9 @@ static int tsi148_crcsr_init(struct pci_dev *pdev)
2214 * through VME writes. 2176 * through VME writes.
2215 */ 2177 */
2216 if(err_chk) { 2178 if(err_chk) {
2217 retval = tsi148_master_set(flush_image, 1, (vstat * 0x80000), 2179 retval = tsi148_master_set(bridge->flush_image, 1,
2218 0x80000, VME_CRCSR, VME_SCT, VME_D16); 2180 (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT,
2181 VME_D16);
2219 if (retval) 2182 if (retval)
2220 dev_err(&pdev->dev, "Configuring flush image failed\n"); 2183 dev_err(&pdev->dev, "Configuring flush image failed\n");
2221 } 2184 }
@@ -2224,20 +2187,25 @@ static int tsi148_crcsr_init(struct pci_dev *pdev)
2224 2187
2225} 2188}
2226 2189
2227static void tsi148_crcsr_exit(struct pci_dev *pdev) 2190static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge,
2191 struct pci_dev *pdev)
2228{ 2192{
2229 u32 crat; 2193 u32 crat;
2194 struct tsi148_driver *bridge;
2195
2196 bridge = tsi148_bridge->driver_priv;
2230 2197
2231 /* Turn off CR/CSR space */ 2198 /* Turn off CR/CSR space */
2232 crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT); 2199 crat = ioread32be(bridge->base + TSI148_LCSR_CRAT);
2233 iowrite32be(crat & ~TSI148_LCSR_CRAT_EN, 2200 iowrite32be(crat & ~TSI148_LCSR_CRAT_EN,
2234 tsi148_bridge->base + TSI148_LCSR_CRAT); 2201 bridge->base + TSI148_LCSR_CRAT);
2235 2202
2236 /* Free image */ 2203 /* Free image */
2237 iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROU); 2204 iowrite32be(0, bridge->base + TSI148_LCSR_CROU);
2238 iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROL); 2205 iowrite32be(0, bridge->base + TSI148_LCSR_CROL);
2239 2206
2240 pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus); 2207 pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel,
2208 bridge->crcsr_bus);
2241} 2209}
2242 2210
2243static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) 2211static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -2245,6 +2213,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2245 int retval, i, master_num; 2213 int retval, i, master_num;
2246 u32 data; 2214 u32 data;
2247 struct list_head *pos = NULL; 2215 struct list_head *pos = NULL;
2216 struct vme_bridge *tsi148_bridge;
2217 struct tsi148_driver *tsi148_device;
2248 struct vme_master_resource *master_image; 2218 struct vme_master_resource *master_image;
2249 struct vme_slave_resource *slave_image; 2219 struct vme_slave_resource *slave_image;
2250 struct vme_dma_resource *dma_ctrlr; 2220 struct vme_dma_resource *dma_ctrlr;
@@ -2264,6 +2234,18 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2264 2234
2265 memset(tsi148_bridge, 0, sizeof(struct vme_bridge)); 2235 memset(tsi148_bridge, 0, sizeof(struct vme_bridge));
2266 2236
2237 tsi148_device = kmalloc(sizeof(struct tsi148_driver), GFP_KERNEL);
2238 if (tsi148_device == NULL) {
2239 dev_err(&pdev->dev, "Failed to allocate memory for device "
2240 "structure\n");
2241 retval = -ENOMEM;
2242 goto err_driver;
2243 }
2244
2245 memset(tsi148_device, 0, sizeof(struct tsi148_driver));
2246
2247 tsi148_bridge->driver_priv = tsi148_device;
2248
2267 /* Enable the device */ 2249 /* Enable the device */
2268 retval = pci_enable_device(pdev); 2250 retval = pci_enable_device(pdev);
2269 if (retval) { 2251 if (retval) {
@@ -2279,15 +2261,16 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2279 } 2261 }
2280 2262
2281 /* map registers in BAR 0 */ 2263 /* map registers in BAR 0 */
2282 tsi148_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 4096); 2264 tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0),
2283 if (!tsi148_bridge->base) { 2265 4096);
2266 if (!tsi148_device->base) {
2284 dev_err(&pdev->dev, "Unable to remap CRG region\n"); 2267 dev_err(&pdev->dev, "Unable to remap CRG region\n");
2285 retval = -EIO; 2268 retval = -EIO;
2286 goto err_remap; 2269 goto err_remap;
2287 } 2270 }
2288 2271
2289 /* Check to see if the mapping worked out */ 2272 /* Check to see if the mapping worked out */
2290 data = ioread32(tsi148_bridge->base + TSI148_PCFS_ID) & 0x0000FFFF; 2273 data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF;
2291 if (data != PCI_VENDOR_ID_TUNDRA) { 2274 if (data != PCI_VENDOR_ID_TUNDRA) {
2292 dev_err(&pdev->dev, "CRG region check failed\n"); 2275 dev_err(&pdev->dev, "CRG region check failed\n");
2293 retval = -EIO; 2276 retval = -EIO;
@@ -2295,12 +2278,11 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2295 } 2278 }
2296 2279
2297 /* Initialize wait queues & mutual exclusion flags */ 2280 /* Initialize wait queues & mutual exclusion flags */
2298 /* XXX These need to be moved to the vme_bridge structure */ 2281 init_waitqueue_head(&(tsi148_device->dma_queue[0]));
2299 init_waitqueue_head(&dma_queue[0]); 2282 init_waitqueue_head(&(tsi148_device->dma_queue[1]));
2300 init_waitqueue_head(&dma_queue[1]); 2283 init_waitqueue_head(&(tsi148_device->iack_queue));
2301 init_waitqueue_head(&iack_queue); 2284 mutex_init(&(tsi148_device->vme_int));
2302 mutex_init(&(vme_int)); 2285 mutex_init(&(tsi148_device->vme_rmw));
2303 mutex_init(&(vme_rmw));
2304 2286
2305 tsi148_bridge->parent = &(pdev->dev); 2287 tsi148_bridge->parent = &(pdev->dev);
2306 strcpy(tsi148_bridge->name, driver_name); 2288 strcpy(tsi148_bridge->name, driver_name);
@@ -2320,29 +2302,29 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2320 master_num = TSI148_MAX_MASTER; 2302 master_num = TSI148_MAX_MASTER;
2321 if(err_chk){ 2303 if(err_chk){
2322 master_num--; 2304 master_num--;
2323 /* XXX */ 2305
2324 flush_image = (struct vme_master_resource *)kmalloc( 2306 tsi148_device->flush_image = (struct vme_master_resource *)
2325 sizeof(struct vme_master_resource), GFP_KERNEL); 2307 kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL);
2326 if (flush_image == NULL) { 2308 if (tsi148_device->flush_image == NULL) {
2327 dev_err(&pdev->dev, "Failed to allocate memory for " 2309 dev_err(&pdev->dev, "Failed to allocate memory for "
2328 "flush resource structure\n"); 2310 "flush resource structure\n");
2329 retval = -ENOMEM; 2311 retval = -ENOMEM;
2330 goto err_master; 2312 goto err_master;
2331 } 2313 }
2332 flush_image->parent = tsi148_bridge; 2314 tsi148_device->flush_image->parent = tsi148_bridge;
2333 spin_lock_init(&(flush_image->lock)); 2315 spin_lock_init(&(tsi148_device->flush_image->lock));
2334 flush_image->locked = 1; 2316 tsi148_device->flush_image->locked = 1;
2335 flush_image->number = master_num; 2317 tsi148_device->flush_image->number = master_num;
2336 flush_image->address_attr = VME_A16 | VME_A24 | VME_A32 | 2318 tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 |
2337 VME_A64; 2319 VME_A32 | VME_A64;
2338 flush_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | 2320 tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT |
2339 VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | 2321 VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB |
2340 VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | 2322 VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER |
2341 VME_PROG | VME_DATA; 2323 VME_USER | VME_PROG | VME_DATA;
2342 flush_image->width_attr = VME_D16 | VME_D32; 2324 tsi148_device->flush_image->width_attr = VME_D16 | VME_D32;
2343 memset(&(flush_image->pci_resource), 0, 2325 memset(&(tsi148_device->flush_image->bus_resource), 0,
2344 sizeof(struct resource)); 2326 sizeof(struct resource));
2345 flush_image->kern_base = NULL; 2327 tsi148_device->flush_image->kern_base = NULL;
2346 } 2328 }
2347 2329
2348 /* Add master windows to list */ 2330 /* Add master windows to list */
@@ -2367,7 +2349,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2367 VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | 2349 VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
2368 VME_PROG | VME_DATA; 2350 VME_PROG | VME_DATA;
2369 master_image->width_attr = VME_D16 | VME_D32; 2351 master_image->width_attr = VME_D16 | VME_D32;
2370 memset(&(master_image->pci_resource), 0, 2352 memset(&(master_image->bus_resource), 0,
2371 sizeof(struct resource)); 2353 sizeof(struct resource));
2372 master_image->kern_base = NULL; 2354 master_image->kern_base = NULL;
2373 list_add_tail(&(master_image->list), 2355 list_add_tail(&(master_image->list),
@@ -2415,6 +2397,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2415 mutex_init(&(dma_ctrlr->mtx)); 2397 mutex_init(&(dma_ctrlr->mtx));
2416 dma_ctrlr->locked = 0; 2398 dma_ctrlr->locked = 0;
2417 dma_ctrlr->number = i; 2399 dma_ctrlr->number = i;
2400 dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM |
2401 VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME |
2402 VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME |
2403 VME_DMA_PATTERN_TO_MEM;
2418 INIT_LIST_HEAD(&(dma_ctrlr->pending)); 2404 INIT_LIST_HEAD(&(dma_ctrlr->pending));
2419 INIT_LIST_HEAD(&(dma_ctrlr->running)); 2405 INIT_LIST_HEAD(&(dma_ctrlr->running));
2420 list_add_tail(&(dma_ctrlr->list), 2406 list_add_tail(&(dma_ctrlr->list),
@@ -2455,40 +2441,42 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2455 tsi148_bridge->lm_detach = tsi148_lm_detach; 2441 tsi148_bridge->lm_detach = tsi148_lm_detach;
2456 tsi148_bridge->slot_get = tsi148_slot_get; 2442 tsi148_bridge->slot_get = tsi148_slot_get;
2457 2443
2458 data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT); 2444 data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
2459 dev_info(&pdev->dev, "Board is%s the VME system controller\n", 2445 dev_info(&pdev->dev, "Board is%s the VME system controller\n",
2460 (data & TSI148_LCSR_VSTAT_SCONS)? "" : " not"); 2446 (data & TSI148_LCSR_VSTAT_SCONS)? "" : " not");
2461 dev_info(&pdev->dev, "VME geographical address is %d\n", 2447 if (!geoid)
2462 data & TSI148_LCSR_VSTAT_GA_M); 2448 dev_info(&pdev->dev, "VME geographical address is %d\n",
2449 data & TSI148_LCSR_VSTAT_GA_M);
2450 else
2451 dev_info(&pdev->dev, "VME geographical address is set to %d\n",
2452 geoid);
2453
2463 dev_info(&pdev->dev, "VME Write and flush and error check is %s\n", 2454 dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
2464 err_chk ? "enabled" : "disabled"); 2455 err_chk ? "enabled" : "disabled");
2465 2456
2466 if(tsi148_crcsr_init(pdev)) { 2457 if (tsi148_crcsr_init(tsi148_bridge, pdev))
2467 dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); 2458 dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
2468 goto err_crcsr; 2459 goto err_crcsr;
2469 2460
2470 }
2471
2472 /* Need to save tsi148_bridge pointer locally in link list for use in
2473 * tsi148_remove()
2474 */
2475 retval = vme_register_bridge(tsi148_bridge); 2461 retval = vme_register_bridge(tsi148_bridge);
2476 if (retval != 0) { 2462 if (retval != 0) {
2477 dev_err(&pdev->dev, "Chip Registration failed.\n"); 2463 dev_err(&pdev->dev, "Chip Registration failed.\n");
2478 goto err_reg; 2464 goto err_reg;
2479 } 2465 }
2480 2466
2467 pci_set_drvdata(pdev, tsi148_bridge);
2468
2481 /* Clear VME bus "board fail", and "power-up reset" lines */ 2469 /* Clear VME bus "board fail", and "power-up reset" lines */
2482 data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT); 2470 data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT);
2483 data &= ~TSI148_LCSR_VSTAT_BRDFL; 2471 data &= ~TSI148_LCSR_VSTAT_BRDFL;
2484 data |= TSI148_LCSR_VSTAT_CPURST; 2472 data |= TSI148_LCSR_VSTAT_CPURST;
2485 iowrite32be(data, tsi148_bridge->base + TSI148_LCSR_VSTAT); 2473 iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT);
2486 2474
2487 return 0; 2475 return 0;
2488 2476
2489 vme_unregister_bridge(tsi148_bridge); 2477 vme_unregister_bridge(tsi148_bridge);
2490err_reg: 2478err_reg:
2491 tsi148_crcsr_exit(pdev); 2479 tsi148_crcsr_exit(tsi148_bridge, pdev);
2492err_crcsr: 2480err_crcsr:
2493err_lm: 2481err_lm:
2494 /* resources are stored in link list */ 2482 /* resources are stored in link list */
@@ -2519,15 +2507,17 @@ err_master:
2519 kfree(master_image); 2507 kfree(master_image);
2520 } 2508 }
2521 2509
2522 tsi148_irq_exit(pdev); 2510 tsi148_irq_exit(tsi148_device, pdev);
2523err_irq: 2511err_irq:
2524err_test: 2512err_test:
2525 iounmap(tsi148_bridge->base); 2513 iounmap(tsi148_device->base);
2526err_remap: 2514err_remap:
2527 pci_release_regions(pdev); 2515 pci_release_regions(pdev);
2528err_resource: 2516err_resource:
2529 pci_disable_device(pdev); 2517 pci_disable_device(pdev);
2530err_enable: 2518err_enable:
2519 kfree(tsi148_device);
2520err_driver:
2531 kfree(tsi148_bridge); 2521 kfree(tsi148_bridge);
2532err_struct: 2522err_struct:
2533 return retval; 2523 return retval;
@@ -2541,56 +2531,58 @@ static void tsi148_remove(struct pci_dev *pdev)
2541 struct vme_slave_resource *slave_image; 2531 struct vme_slave_resource *slave_image;
2542 struct vme_dma_resource *dma_ctrlr; 2532 struct vme_dma_resource *dma_ctrlr;
2543 int i; 2533 int i;
2534 struct tsi148_driver *bridge;
2535 struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev);
2544 2536
2545 dev_dbg(&pdev->dev, "Driver is being unloaded.\n"); 2537 bridge = tsi148_bridge->driver_priv;
2546 2538
2547 /* XXX We need to find the pdev->dev in the list of vme_bridge->dev's */ 2539
2540 dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
2548 2541
2549 /* 2542 /*
2550 * Shutdown all inbound and outbound windows. 2543 * Shutdown all inbound and outbound windows.
2551 */ 2544 */
2552 for (i = 0; i < 8; i++) { 2545 for (i = 0; i < 8; i++) {
2553 iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_IT[i] + 2546 iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] +
2554 TSI148_LCSR_OFFSET_ITAT); 2547 TSI148_LCSR_OFFSET_ITAT);
2555 iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_OT[i] + 2548 iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] +
2556 TSI148_LCSR_OFFSET_OTAT); 2549 TSI148_LCSR_OFFSET_OTAT);
2557 } 2550 }
2558 2551
2559 /* 2552 /*
2560 * Shutdown Location monitor. 2553 * Shutdown Location monitor.
2561 */ 2554 */
2562 iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_LMAT); 2555 iowrite32be(0, bridge->base + TSI148_LCSR_LMAT);
2563 2556
2564 /* 2557 /*
2565 * Shutdown CRG map. 2558 * Shutdown CRG map.
2566 */ 2559 */
2567 iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CSRAT); 2560 iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT);
2568 2561
2569 /* 2562 /*
2570 * Clear error status. 2563 * Clear error status.
2571 */ 2564 */
2572 iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_EDPAT); 2565 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT);
2573 iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_VEAT); 2566 iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT);
2574 iowrite32be(0x07000700, tsi148_bridge->base + TSI148_LCSR_PSTAT); 2567 iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT);
2575 2568
2576 /* 2569 /*
2577 * Remove VIRQ interrupt (if any) 2570 * Remove VIRQ interrupt (if any)
2578 */ 2571 */
2579 if (ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR) & 0x800) { 2572 if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800)
2580 iowrite32be(0x8000, tsi148_bridge->base + TSI148_LCSR_VICR); 2573 iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR);
2581 }
2582 2574
2583 /* 2575 /*
2584 * Map all Interrupts to PCI INTA 2576 * Map all Interrupts to PCI INTA
2585 */ 2577 */
2586 iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM1); 2578 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1);
2587 iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM2); 2579 iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2);
2588 2580
2589 tsi148_irq_exit(pdev); 2581 tsi148_irq_exit(bridge, pdev);
2590 2582
2591 vme_unregister_bridge(tsi148_bridge); 2583 vme_unregister_bridge(tsi148_bridge);
2592 2584
2593 tsi148_crcsr_exit(pdev); 2585 tsi148_crcsr_exit(tsi148_bridge, pdev);
2594 2586
2595 /* resources are stored in link list */ 2587 /* resources are stored in link list */
2596 list_for_each(pos, &(tsi148_bridge->dma_resources)) { 2588 list_for_each(pos, &(tsi148_bridge->dma_resources)) {
@@ -2608,19 +2600,22 @@ static void tsi148_remove(struct pci_dev *pdev)
2608 2600
2609 /* resources are stored in link list */ 2601 /* resources are stored in link list */
2610 list_for_each(pos, &(tsi148_bridge->master_resources)) { 2602 list_for_each(pos, &(tsi148_bridge->master_resources)) {
2611 master_image = list_entry(pos, struct vme_master_resource, list); 2603 master_image = list_entry(pos, struct vme_master_resource,
2604 list);
2612 list_del(pos); 2605 list_del(pos);
2613 kfree(master_image); 2606 kfree(master_image);
2614 } 2607 }
2615 2608
2616 tsi148_irq_exit(pdev); 2609 tsi148_irq_exit(bridge, pdev);
2617 2610
2618 iounmap(tsi148_bridge->base); 2611 iounmap(bridge->base);
2619 2612
2620 pci_release_regions(pdev); 2613 pci_release_regions(pdev);
2621 2614
2622 pci_disable_device(pdev); 2615 pci_disable_device(pdev);
2623 2616
2617 kfree(tsi148_bridge->driver_priv);
2618
2624 kfree(tsi148_bridge); 2619 kfree(tsi148_bridge);
2625} 2620}
2626 2621
@@ -2634,250 +2629,11 @@ static void __exit tsi148_exit(void)
2634MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes"); 2629MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
2635module_param(err_chk, bool, 0); 2630module_param(err_chk, bool, 0);
2636 2631
2632MODULE_PARM_DESC(geoid, "Override geographical addressing");
2633module_param(geoid, int, 0);
2634
2637MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge"); 2635MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
2638MODULE_LICENSE("GPL"); 2636MODULE_LICENSE("GPL");
2639 2637
2640module_init(tsi148_init); 2638module_init(tsi148_init);
2641module_exit(tsi148_exit); 2639module_exit(tsi148_exit);
2642
2643/*----------------------------------------------------------------------------
2644 * STAGING
2645 *--------------------------------------------------------------------------*/
2646
2647#if 0
2648/*
2649 * Direct Mode DMA transfer
2650 *
2651 * XXX Not looking at direct mode for now, we can always use link list mode
2652 * with a single entry.
2653 */
2654int tsi148_dma_run(struct vme_dma_resource *resource, struct vme_dma_attr src,
2655 struct vme_dma_attr dest, size_t count)
2656{
2657 u32 dctlreg = 0;
2658 unsigned int tmp;
2659 int val;
2660 int channel, x;
2661 struct vmeDmaPacket *cur_dma;
2662 struct tsi148_dma_descriptor *dmaLL;
2663
2664 /* direct mode */
2665 dctlreg = 0x800000;
2666
2667 for (x = 0; x < 8; x++) { /* vme block size */
2668 if ((32 << x) >= vmeDma->maxVmeBlockSize) {
2669 break;
2670 }
2671 }
2672 if (x == 8)
2673 x = 7;
2674 dctlreg |= (x << 12);
2675
2676 for (x = 0; x < 8; x++) { /* pci block size */
2677 if ((32 << x) >= vmeDma->maxPciBlockSize) {
2678 break;
2679 }
2680 }
2681 if (x == 8)
2682 x = 7;
2683 dctlreg |= (x << 4);
2684
2685 if (vmeDma->vmeBackOffTimer) {
2686 for (x = 1; x < 8; x++) { /* vme timer */
2687 if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
2688 break;
2689 }
2690 }
2691 if (x == 8)
2692 x = 7;
2693 dctlreg |= (x << 8);
2694 }
2695
2696 if (vmeDma->pciBackOffTimer) {
2697 for (x = 1; x < 8; x++) { /* pci timer */
2698 if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
2699 break;
2700 }
2701 }
2702 if (x == 8)
2703 x = 7;
2704 dctlreg |= (x << 0);
2705 }
2706
2707 /* Program registers for DMA transfer */
2708 iowrite32be(dmaLL->dsau, tsi148_bridge->base +
2709 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAU);
2710 iowrite32be(dmaLL->dsal, tsi148_bridge->base +
2711 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAL);
2712 iowrite32be(dmaLL->ddau, tsi148_bridge->base +
2713 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAU);
2714 iowrite32be(dmaLL->ddal, tsi148_bridge->base +
2715 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAL);
2716 iowrite32be(dmaLL->dsat, tsi148_bridge->base +
2717 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAT);
2718 iowrite32be(dmaLL->ddat, tsi148_bridge->base +
2719 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAT);
2720 iowrite32be(dmaLL->dcnt, tsi148_bridge->base +
2721 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCNT);
2722 iowrite32be(dmaLL->ddbs, tsi148_bridge->base +
2723 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDBS);
2724
2725 /* Start the operation */
2726 iowrite32be(dctlreg | 0x2000000, tsi148_bridge->base +
2727 TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
2728
2729 tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
2730 TSI148_LCSR_OFFSET_DSTA);
2731 wait_event_interruptible(dma_queue[channel], (tmp & 0x1000000) == 0);
2732
2733 /*
2734 * Read status register, we should probably do this in some error
2735 * handler rather than here so that we can be sure we haven't kicked off
2736 * another DMA transfer.
2737 */
2738 val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
2739 TSI148_LCSR_OFFSET_DSTA);
2740
2741 vmeDma->vmeDmaStatus = 0;
2742 if (val & 0x10000000) {
2743 printk(KERN_ERR
2744 "DMA Error in DMA_tempe_irqhandler DSTA=%08X\n",
2745 val);
2746 vmeDma->vmeDmaStatus = val;
2747
2748 }
2749 return (0);
2750}
2751#endif
2752
2753#if 0
2754
2755/* Global VME controller information */
2756struct pci_dev *vme_pci_dev;
2757
2758/*
2759 * Set the VME bus arbiter with the requested attributes
2760 */
2761int tempe_set_arbiter(vmeArbiterCfg_t * vmeArb)
2762{
2763 int temp_ctl = 0;
2764 int gto = 0;
2765
2766 temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
2767 temp_ctl &= 0xFFEFFF00;
2768
2769 if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
2770 gto = 8;
2771 } else if (vmeArb->globalTimeoutTimer > 2048) {
2772 return (-EINVAL);
2773 } else if (vmeArb->globalTimeoutTimer == 0) {
2774 gto = 0;
2775 } else {
2776 gto = 1;
2777 while ((16 * (1 << (gto - 1))) < vmeArb->globalTimeoutTimer) {
2778 gto += 1;
2779 }
2780 }
2781 temp_ctl |= gto;
2782
2783 if (vmeArb->arbiterMode != VME_PRIORITY_MODE) {
2784 temp_ctl |= 1 << 6;
2785 }
2786
2787 if (vmeArb->arbiterTimeoutFlag) {
2788 temp_ctl |= 1 << 7;
2789 }
2790
2791 if (vmeArb->noEarlyReleaseFlag) {
2792 temp_ctl |= 1 << 20;
2793 }
2794 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VCTRL);
2795
2796 return (0);
2797}
2798
2799/*
2800 * Return the attributes of the VME bus arbiter.
2801 */
2802int tempe_get_arbiter(vmeArbiterCfg_t * vmeArb)
2803{
2804 int temp_ctl = 0;
2805 int gto = 0;
2806
2807
2808 temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
2809
2810 gto = temp_ctl & 0xF;
2811 if (gto != 0) {
2812 vmeArb->globalTimeoutTimer = (16 * (1 << (gto - 1)));
2813 }
2814
2815 if (temp_ctl & (1 << 6)) {
2816 vmeArb->arbiterMode = VME_R_ROBIN_MODE;
2817 } else {
2818 vmeArb->arbiterMode = VME_PRIORITY_MODE;
2819 }
2820
2821 if (temp_ctl & (1 << 7)) {
2822 vmeArb->arbiterTimeoutFlag = 1;
2823 }
2824
2825 if (temp_ctl & (1 << 20)) {
2826 vmeArb->noEarlyReleaseFlag = 1;
2827 }
2828
2829 return (0);
2830}
2831
2832/*
2833 * Set the VME bus requestor with the requested attributes
2834 */
2835int tempe_set_requestor(vmeRequesterCfg_t * vmeReq)
2836{
2837 int temp_ctl = 0;
2838
2839 temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
2840 temp_ctl &= 0xFFFF0000;
2841
2842 if (vmeReq->releaseMode == 1) {
2843 temp_ctl |= (1 << 3);
2844 }
2845
2846 if (vmeReq->fairMode == 1) {
2847 temp_ctl |= (1 << 2);
2848 }
2849
2850 temp_ctl |= (vmeReq->timeonTimeoutTimer & 7) << 8;
2851 temp_ctl |= (vmeReq->timeoffTimeoutTimer & 7) << 12;
2852 temp_ctl |= vmeReq->requestLevel;
2853
2854 iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
2855 return (0);
2856}
2857
2858/*
2859 * Return the attributes of the VME bus requestor
2860 */
2861int tempe_get_requestor(vmeRequesterCfg_t * vmeReq)
2862{
2863 int temp_ctl = 0;
2864
2865 temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
2866
2867 if (temp_ctl & 0x18) {
2868 vmeReq->releaseMode = 1;
2869 }
2870
2871 if (temp_ctl & (1 << 2)) {
2872 vmeReq->fairMode = 1;
2873 }
2874
2875 vmeReq->requestLevel = temp_ctl & 3;
2876 vmeReq->timeonTimeoutTimer = (temp_ctl >> 8) & 7;
2877 vmeReq->timeoffTimeoutTimer = (temp_ctl >> 12) & 7;
2878
2879 return (0);
2880}
2881
2882
2883#endif
diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h
index 6f0f705ce6be..9e5f7fa1d744 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.h
+++ b/drivers/staging/vme/bridges/vme_tsi148.h
@@ -33,6 +33,22 @@
33#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */ 33#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */
34#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */ 34#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */
35 35
36/* Structure used to hold driver specific information */
37struct tsi148_driver {
38 void *base; /* Base Address of device registers */
39 wait_queue_head_t dma_queue[2];
40 wait_queue_head_t iack_queue;
41 void (*lm_callback[4])(int); /* Called in interrupt handler */
42 void *crcsr_kernel;
43 dma_addr_t crcsr_bus;
44 struct vme_master_resource *flush_image;
45 struct mutex vme_rmw; /* Only one RMW cycle at a time */
46 struct mutex vme_int; /*
47 * Only one VME interrupt can be
48 * generated at a time, provide locking
49 */
50};
51
36/* 52/*
37 * Layout of a DMAC Linked-List Descriptor 53 * Layout of a DMAC Linked-List Descriptor
38 * 54 *
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index e228942ee081..c60c80fb241d 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * VMEbus User access driver 2 * VMEbus User access driver
3 * 3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com> 4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 5 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
6 * 6 *
7 * Based on work by: 7 * Based on work by:
8 * Tom Armistead and Ajit Prem 8 * Tom Armistead and Ajit Prem
@@ -400,8 +400,39 @@ static ssize_t vme_user_write(struct file *file, const char *buf, size_t count,
400 400
401static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) 401static loff_t vme_user_llseek(struct file *file, loff_t off, int whence)
402{ 402{
403 printk(KERN_ERR "Llseek currently incomplete\n"); 403 loff_t absolute = -1;
404 return -EINVAL; 404 unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
405 size_t image_size;
406
407 down(&image[minor].sem);
408 image_size = vme_get_size(image[minor].resource);
409
410 switch (whence) {
411 case SEEK_SET:
412 absolute = off;
413 break;
414 case SEEK_CUR:
415 absolute = file->f_pos + off;
416 break;
417 case SEEK_END:
418 absolute = image_size + off;
419 break;
420 default:
421 up(&image[minor].sem);
422 return -EINVAL;
423 break;
424 }
425
426 if ((absolute < 0) || (absolute >= image_size)) {
427 up(&image[minor].sem);
428 return -EINVAL;
429 }
430
431 file->f_pos = absolute;
432
433 up(&image[minor].sem);
434
435 return absolute;
405} 436}
406 437
407/* 438/*
@@ -574,8 +605,8 @@ static int __init vme_user_init(void)
574 * in future revisions if that ever becomes necessary. 605 * in future revisions if that ever becomes necessary.
575 */ 606 */
576 if (bus_num > USER_BUS_MAX) { 607 if (bus_num > USER_BUS_MAX) {
577 printk(KERN_ERR "%s: Driver only able to handle %d PIO2 " 608 printk(KERN_ERR "%s: Driver only able to handle %d buses\n",
578 "Cards\n", driver_name, USER_BUS_MAX); 609 driver_name, USER_BUS_MAX);
579 bus_num = USER_BUS_MAX; 610 bus_num = USER_BUS_MAX;
580 } 611 }
581 612
@@ -670,8 +701,12 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
670 /* Request slave resources and allocate buffers (128kB wide) */ 701 /* Request slave resources and allocate buffers (128kB wide) */
671 for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) { 702 for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
672 /* XXX Need to properly request attributes */ 703 /* XXX Need to properly request attributes */
704 /* For ca91cx42 bridge there are only two slave windows
705 * supporting A16 addressing, so we request A24 supported
706 * by all windows.
707 */
673 image[i].resource = vme_slave_request(vme_user_bridge, 708 image[i].resource = vme_slave_request(vme_user_bridge,
674 VME_A16, VME_SCT); 709 VME_A24, VME_SCT);
675 if (image[i].resource == NULL) { 710 if (image[i].resource == NULL) {
676 printk(KERN_WARNING "Unable to allocate slave " 711 printk(KERN_WARNING "Unable to allocate slave "
677 "resource\n"); 712 "resource\n");
@@ -703,6 +738,14 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
703 "resource\n"); 738 "resource\n");
704 goto err_master; 739 goto err_master;
705 } 740 }
741 image[i].size_buf = PCI_BUF_SIZE;
742 image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
743 if (image[i].kern_buf == NULL) {
744 printk(KERN_WARNING "Unable to allocate memory for "
745 "master window buffers\n");
746 err = -ENOMEM;
747 goto err_master_buf;
748 }
706 } 749 }
707 750
708 /* Create sysfs entries - on udev systems this creates the dev files */ 751 /* Create sysfs entries - on udev systems this creates the dev files */
@@ -756,6 +799,9 @@ err_sysfs:
756 799
757 /* Ensure counter set correcty to unalloc all master windows */ 800 /* Ensure counter set correcty to unalloc all master windows */
758 i = MASTER_MAX + 1; 801 i = MASTER_MAX + 1;
802err_master_buf:
803 for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
804 kfree(image[i].kern_buf);
759err_master: 805err_master:
760 while (i > MASTER_MINOR) { 806 while (i > MASTER_MINOR) {
761 i--; 807 i--;
@@ -791,6 +837,9 @@ static int __exit vme_user_remove(struct device *dev, int cur_bus, int cur_slot)
791 } 837 }
792 class_destroy(vme_user_sysfs_class); 838 class_destroy(vme_user_sysfs_class);
793 839
840 for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
841 kfree(image[i].kern_buf);
842
794 for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) { 843 for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
795 vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0); 844 vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0);
796 vme_slave_free(image[i].resource); 845 vme_slave_free(image[i].resource);
@@ -818,7 +867,7 @@ MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the driver is connected");
818module_param_array(bus, int, &bus_num, 0); 867module_param_array(bus, int, &bus_num, 0);
819 868
820MODULE_DESCRIPTION("VME User Space Access Driver"); 869MODULE_DESCRIPTION("VME User Space Access Driver");
821MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com"); 870MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
822MODULE_LICENSE("GPL"); 871MODULE_LICENSE("GPL");
823 872
824module_init(vme_user_init); 873module_init(vme_user_init);
diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c
index 994fdb9b2127..d6d84ebeeec0 100644
--- a/drivers/staging/vme/vme.c
+++ b/drivers/staging/vme/vme.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * VME Bridge Framework 2 * VME Bridge Framework
3 * 3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com> 4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 5 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
6 * 6 *
7 * Based on work by Tom Armistead and Ajit Prem 7 * Based on work by Tom Armistead and Ajit Prem
8 * Copyright 2004 Motorola Inc. 8 * Copyright 2004 Motorola Inc.
@@ -37,8 +37,8 @@
37static unsigned int vme_bus_numbers; 37static unsigned int vme_bus_numbers;
38DEFINE_MUTEX(vme_bus_num_mtx); 38DEFINE_MUTEX(vme_bus_num_mtx);
39 39
40static void __exit vme_exit (void); 40static void __exit vme_exit(void);
41static int __init vme_init (void); 41static int __init vme_init(void);
42 42
43 43
44/* 44/*
@@ -86,26 +86,26 @@ static struct vme_bridge *find_bridge(struct vme_resource *resource)
86 * XXX VME bridges could be available on buses other than PCI. At the momment 86 * XXX VME bridges could be available on buses other than PCI. At the momment
87 * this framework only supports PCI devices. 87 * this framework only supports PCI devices.
88 */ 88 */
89void * vme_alloc_consistent(struct vme_resource *resource, size_t size, 89void *vme_alloc_consistent(struct vme_resource *resource, size_t size,
90 dma_addr_t *dma) 90 dma_addr_t *dma)
91{ 91{
92 struct vme_bridge *bridge; 92 struct vme_bridge *bridge;
93 struct pci_dev *pdev; 93 struct pci_dev *pdev;
94 94
95 if(resource == NULL) { 95 if (resource == NULL) {
96 printk("No resource\n"); 96 printk(KERN_ERR "No resource\n");
97 return NULL; 97 return NULL;
98 } 98 }
99 99
100 bridge = find_bridge(resource); 100 bridge = find_bridge(resource);
101 if(bridge == NULL) { 101 if (bridge == NULL) {
102 printk("Can't find bridge\n"); 102 printk(KERN_ERR "Can't find bridge\n");
103 return NULL; 103 return NULL;
104 } 104 }
105 105
106 /* Find pci_dev container of dev */ 106 /* Find pci_dev container of dev */
107 if (bridge->parent == NULL) { 107 if (bridge->parent == NULL) {
108 printk("Dev entry NULL\n"); 108 printk(KERN_ERR "Dev entry NULL\n");
109 return NULL; 109 return NULL;
110 } 110 }
111 pdev = container_of(bridge->parent, struct pci_dev, dev); 111 pdev = container_of(bridge->parent, struct pci_dev, dev);
@@ -126,14 +126,14 @@ void vme_free_consistent(struct vme_resource *resource, size_t size,
126 struct vme_bridge *bridge; 126 struct vme_bridge *bridge;
127 struct pci_dev *pdev; 127 struct pci_dev *pdev;
128 128
129 if(resource == NULL) { 129 if (resource == NULL) {
130 printk("No resource\n"); 130 printk(KERN_ERR "No resource\n");
131 return; 131 return;
132 } 132 }
133 133
134 bridge = find_bridge(resource); 134 bridge = find_bridge(resource);
135 if(bridge == NULL) { 135 if (bridge == NULL) {
136 printk("Can't find bridge\n"); 136 printk(KERN_ERR "Can't find bridge\n");
137 return; 137 return;
138 } 138 }
139 139
@@ -216,7 +216,7 @@ static int vme_check_window(vme_address_t aspace, unsigned long long vme_base,
216 /* User Defined */ 216 /* User Defined */
217 break; 217 break;
218 default: 218 default:
219 printk("Invalid address space\n"); 219 printk(KERN_ERR "Invalid address space\n");
220 retval = -EINVAL; 220 retval = -EINVAL;
221 break; 221 break;
222 } 222 }
@@ -228,7 +228,7 @@ static int vme_check_window(vme_address_t aspace, unsigned long long vme_base,
228 * Request a slave image with specific attributes, return some unique 228 * Request a slave image with specific attributes, return some unique
229 * identifier. 229 * identifier.
230 */ 230 */
231struct vme_resource * vme_slave_request(struct device *dev, 231struct vme_resource *vme_slave_request(struct device *dev,
232 vme_address_t address, vme_cycle_t cycle) 232 vme_address_t address, vme_cycle_t cycle)
233{ 233{
234 struct vme_bridge *bridge; 234 struct vme_bridge *bridge;
@@ -249,13 +249,13 @@ struct vme_resource * vme_slave_request(struct device *dev,
249 struct vme_slave_resource, list); 249 struct vme_slave_resource, list);
250 250
251 if (slave_image == NULL) { 251 if (slave_image == NULL) {
252 printk("Registered NULL Slave resource\n"); 252 printk(KERN_ERR "Registered NULL Slave resource\n");
253 continue; 253 continue;
254 } 254 }
255 255
256 /* Find an unlocked and compatible image */ 256 /* Find an unlocked and compatible image */
257 mutex_lock(&(slave_image->mtx)); 257 mutex_lock(&(slave_image->mtx));
258 if(((slave_image->address_attr & address) == address) && 258 if (((slave_image->address_attr & address) == address) &&
259 ((slave_image->cycle_attr & cycle) == cycle) && 259 ((slave_image->cycle_attr & cycle) == cycle) &&
260 (slave_image->locked == 0)) { 260 (slave_image->locked == 0)) {
261 261
@@ -292,7 +292,7 @@ err_bus:
292} 292}
293EXPORT_SYMBOL(vme_slave_request); 293EXPORT_SYMBOL(vme_slave_request);
294 294
295int vme_slave_set (struct vme_resource *resource, int enabled, 295int vme_slave_set(struct vme_resource *resource, int enabled,
296 unsigned long long vme_base, unsigned long long size, 296 unsigned long long vme_base, unsigned long long size,
297 dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle) 297 dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle)
298{ 298{
@@ -301,25 +301,25 @@ int vme_slave_set (struct vme_resource *resource, int enabled,
301 int retval; 301 int retval;
302 302
303 if (resource->type != VME_SLAVE) { 303 if (resource->type != VME_SLAVE) {
304 printk("Not a slave resource\n"); 304 printk(KERN_ERR "Not a slave resource\n");
305 return -EINVAL; 305 return -EINVAL;
306 } 306 }
307 307
308 image = list_entry(resource->entry, struct vme_slave_resource, list); 308 image = list_entry(resource->entry, struct vme_slave_resource, list);
309 309
310 if (bridge->slave_set == NULL) { 310 if (bridge->slave_set == NULL) {
311 printk("Function not supported\n"); 311 printk(KERN_ERR "Function not supported\n");
312 return -ENOSYS; 312 return -ENOSYS;
313 } 313 }
314 314
315 if(!(((image->address_attr & aspace) == aspace) && 315 if (!(((image->address_attr & aspace) == aspace) &&
316 ((image->cycle_attr & cycle) == cycle))) { 316 ((image->cycle_attr & cycle) == cycle))) {
317 printk("Invalid attributes\n"); 317 printk(KERN_ERR "Invalid attributes\n");
318 return -EINVAL; 318 return -EINVAL;
319 } 319 }
320 320
321 retval = vme_check_window(aspace, vme_base, size); 321 retval = vme_check_window(aspace, vme_base, size);
322 if(retval) 322 if (retval)
323 return retval; 323 return retval;
324 324
325 return bridge->slave_set(image, enabled, vme_base, size, buf_base, 325 return bridge->slave_set(image, enabled, vme_base, size, buf_base,
@@ -327,7 +327,7 @@ int vme_slave_set (struct vme_resource *resource, int enabled,
327} 327}
328EXPORT_SYMBOL(vme_slave_set); 328EXPORT_SYMBOL(vme_slave_set);
329 329
330int vme_slave_get (struct vme_resource *resource, int *enabled, 330int vme_slave_get(struct vme_resource *resource, int *enabled,
331 unsigned long long *vme_base, unsigned long long *size, 331 unsigned long long *vme_base, unsigned long long *size,
332 dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle) 332 dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle)
333{ 333{
@@ -335,14 +335,14 @@ int vme_slave_get (struct vme_resource *resource, int *enabled,
335 struct vme_slave_resource *image; 335 struct vme_slave_resource *image;
336 336
337 if (resource->type != VME_SLAVE) { 337 if (resource->type != VME_SLAVE) {
338 printk("Not a slave resource\n"); 338 printk(KERN_ERR "Not a slave resource\n");
339 return -EINVAL; 339 return -EINVAL;
340 } 340 }
341 341
342 image = list_entry(resource->entry, struct vme_slave_resource, list); 342 image = list_entry(resource->entry, struct vme_slave_resource, list);
343 343
344 if (bridge->slave_get == NULL) { 344 if (bridge->slave_get == NULL) {
345 printk("vme_slave_get not supported\n"); 345 printk(KERN_ERR "vme_slave_get not supported\n");
346 return -EINVAL; 346 return -EINVAL;
347 } 347 }
348 348
@@ -356,14 +356,14 @@ void vme_slave_free(struct vme_resource *resource)
356 struct vme_slave_resource *slave_image; 356 struct vme_slave_resource *slave_image;
357 357
358 if (resource->type != VME_SLAVE) { 358 if (resource->type != VME_SLAVE) {
359 printk("Not a slave resource\n"); 359 printk(KERN_ERR "Not a slave resource\n");
360 return; 360 return;
361 } 361 }
362 362
363 slave_image = list_entry(resource->entry, struct vme_slave_resource, 363 slave_image = list_entry(resource->entry, struct vme_slave_resource,
364 list); 364 list);
365 if (slave_image == NULL) { 365 if (slave_image == NULL) {
366 printk("Can't find slave resource\n"); 366 printk(KERN_ERR "Can't find slave resource\n");
367 return; 367 return;
368 } 368 }
369 369
@@ -384,7 +384,7 @@ EXPORT_SYMBOL(vme_slave_free);
384 * Request a master image with specific attributes, return some unique 384 * Request a master image with specific attributes, return some unique
385 * identifier. 385 * identifier.
386 */ 386 */
387struct vme_resource * vme_master_request(struct device *dev, 387struct vme_resource *vme_master_request(struct device *dev,
388 vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth) 388 vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth)
389{ 389{
390 struct vme_bridge *bridge; 390 struct vme_bridge *bridge;
@@ -411,7 +411,7 @@ struct vme_resource * vme_master_request(struct device *dev,
411 411
412 /* Find an unlocked and compatible image */ 412 /* Find an unlocked and compatible image */
413 spin_lock(&(master_image->lock)); 413 spin_lock(&(master_image->lock));
414 if(((master_image->address_attr & address) == address) && 414 if (((master_image->address_attr & address) == address) &&
415 ((master_image->cycle_attr & cycle) == cycle) && 415 ((master_image->cycle_attr & cycle) == cycle) &&
416 ((master_image->width_attr & dwidth) == dwidth) && 416 ((master_image->width_attr & dwidth) == dwidth) &&
417 (master_image->locked == 0)) { 417 (master_image->locked == 0)) {
@@ -452,7 +452,7 @@ err_bus:
452} 452}
453EXPORT_SYMBOL(vme_master_request); 453EXPORT_SYMBOL(vme_master_request);
454 454
455int vme_master_set (struct vme_resource *resource, int enabled, 455int vme_master_set(struct vme_resource *resource, int enabled,
456 unsigned long long vme_base, unsigned long long size, 456 unsigned long long vme_base, unsigned long long size,
457 vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) 457 vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
458{ 458{
@@ -461,26 +461,26 @@ int vme_master_set (struct vme_resource *resource, int enabled,
461 int retval; 461 int retval;
462 462
463 if (resource->type != VME_MASTER) { 463 if (resource->type != VME_MASTER) {
464 printk("Not a master resource\n"); 464 printk(KERN_ERR "Not a master resource\n");
465 return -EINVAL; 465 return -EINVAL;
466 } 466 }
467 467
468 image = list_entry(resource->entry, struct vme_master_resource, list); 468 image = list_entry(resource->entry, struct vme_master_resource, list);
469 469
470 if (bridge->master_set == NULL) { 470 if (bridge->master_set == NULL) {
471 printk("vme_master_set not supported\n"); 471 printk(KERN_WARNING "vme_master_set not supported\n");
472 return -EINVAL; 472 return -EINVAL;
473 } 473 }
474 474
475 if(!(((image->address_attr & aspace) == aspace) && 475 if (!(((image->address_attr & aspace) == aspace) &&
476 ((image->cycle_attr & cycle) == cycle) && 476 ((image->cycle_attr & cycle) == cycle) &&
477 ((image->width_attr & dwidth) == dwidth))) { 477 ((image->width_attr & dwidth) == dwidth))) {
478 printk("Invalid attributes\n"); 478 printk(KERN_WARNING "Invalid attributes\n");
479 return -EINVAL; 479 return -EINVAL;
480 } 480 }
481 481
482 retval = vme_check_window(aspace, vme_base, size); 482 retval = vme_check_window(aspace, vme_base, size);
483 if(retval) 483 if (retval)
484 return retval; 484 return retval;
485 485
486 return bridge->master_set(image, enabled, vme_base, size, aspace, 486 return bridge->master_set(image, enabled, vme_base, size, aspace,
@@ -488,7 +488,7 @@ int vme_master_set (struct vme_resource *resource, int enabled,
488} 488}
489EXPORT_SYMBOL(vme_master_set); 489EXPORT_SYMBOL(vme_master_set);
490 490
491int vme_master_get (struct vme_resource *resource, int *enabled, 491int vme_master_get(struct vme_resource *resource, int *enabled,
492 unsigned long long *vme_base, unsigned long long *size, 492 unsigned long long *vme_base, unsigned long long *size,
493 vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) 493 vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
494{ 494{
@@ -496,14 +496,14 @@ int vme_master_get (struct vme_resource *resource, int *enabled,
496 struct vme_master_resource *image; 496 struct vme_master_resource *image;
497 497
498 if (resource->type != VME_MASTER) { 498 if (resource->type != VME_MASTER) {
499 printk("Not a master resource\n"); 499 printk(KERN_ERR "Not a master resource\n");
500 return -EINVAL; 500 return -EINVAL;
501 } 501 }
502 502
503 image = list_entry(resource->entry, struct vme_master_resource, list); 503 image = list_entry(resource->entry, struct vme_master_resource, list);
504 504
505 if (bridge->master_get == NULL) { 505 if (bridge->master_get == NULL) {
506 printk("vme_master_set not supported\n"); 506 printk(KERN_WARNING "vme_master_set not supported\n");
507 return -EINVAL; 507 return -EINVAL;
508 } 508 }
509 509
@@ -515,7 +515,7 @@ EXPORT_SYMBOL(vme_master_get);
515/* 515/*
516 * Read data out of VME space into a buffer. 516 * Read data out of VME space into a buffer.
517 */ 517 */
518ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count, 518ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count,
519 loff_t offset) 519 loff_t offset)
520{ 520{
521 struct vme_bridge *bridge = find_bridge(resource); 521 struct vme_bridge *bridge = find_bridge(resource);
@@ -523,12 +523,12 @@ ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
523 size_t length; 523 size_t length;
524 524
525 if (bridge->master_read == NULL) { 525 if (bridge->master_read == NULL) {
526 printk("Reading from resource not supported\n"); 526 printk(KERN_WARNING "Reading from resource not supported\n");
527 return -EINVAL; 527 return -EINVAL;
528 } 528 }
529 529
530 if (resource->type != VME_MASTER) { 530 if (resource->type != VME_MASTER) {
531 printk("Not a master resource\n"); 531 printk(KERN_ERR "Not a master resource\n");
532 return -EINVAL; 532 return -EINVAL;
533 } 533 }
534 534
@@ -537,7 +537,7 @@ ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
537 length = vme_get_size(resource); 537 length = vme_get_size(resource);
538 538
539 if (offset > length) { 539 if (offset > length) {
540 printk("Invalid Offset\n"); 540 printk(KERN_WARNING "Invalid Offset\n");
541 return -EFAULT; 541 return -EFAULT;
542 } 542 }
543 543
@@ -552,7 +552,7 @@ EXPORT_SYMBOL(vme_master_read);
552/* 552/*
553 * Write data out to VME space from a buffer. 553 * Write data out to VME space from a buffer.
554 */ 554 */
555ssize_t vme_master_write (struct vme_resource *resource, void *buf, 555ssize_t vme_master_write(struct vme_resource *resource, void *buf,
556 size_t count, loff_t offset) 556 size_t count, loff_t offset)
557{ 557{
558 struct vme_bridge *bridge = find_bridge(resource); 558 struct vme_bridge *bridge = find_bridge(resource);
@@ -560,12 +560,12 @@ ssize_t vme_master_write (struct vme_resource *resource, void *buf,
560 size_t length; 560 size_t length;
561 561
562 if (bridge->master_write == NULL) { 562 if (bridge->master_write == NULL) {
563 printk("Writing to resource not supported\n"); 563 printk(KERN_WARNING "Writing to resource not supported\n");
564 return -EINVAL; 564 return -EINVAL;
565 } 565 }
566 566
567 if (resource->type != VME_MASTER) { 567 if (resource->type != VME_MASTER) {
568 printk("Not a master resource\n"); 568 printk(KERN_ERR "Not a master resource\n");
569 return -EINVAL; 569 return -EINVAL;
570 } 570 }
571 571
@@ -574,7 +574,7 @@ ssize_t vme_master_write (struct vme_resource *resource, void *buf,
574 length = vme_get_size(resource); 574 length = vme_get_size(resource);
575 575
576 if (offset > length) { 576 if (offset > length) {
577 printk("Invalid Offset\n"); 577 printk(KERN_WARNING "Invalid Offset\n");
578 return -EFAULT; 578 return -EFAULT;
579 } 579 }
580 580
@@ -588,19 +588,19 @@ EXPORT_SYMBOL(vme_master_write);
588/* 588/*
589 * Perform RMW cycle to provided location. 589 * Perform RMW cycle to provided location.
590 */ 590 */
591unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask, 591unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
592 unsigned int compare, unsigned int swap, loff_t offset) 592 unsigned int compare, unsigned int swap, loff_t offset)
593{ 593{
594 struct vme_bridge *bridge = find_bridge(resource); 594 struct vme_bridge *bridge = find_bridge(resource);
595 struct vme_master_resource *image; 595 struct vme_master_resource *image;
596 596
597 if (bridge->master_rmw == NULL) { 597 if (bridge->master_rmw == NULL) {
598 printk("Writing to resource not supported\n"); 598 printk(KERN_WARNING "Writing to resource not supported\n");
599 return -EINVAL; 599 return -EINVAL;
600 } 600 }
601 601
602 if (resource->type != VME_MASTER) { 602 if (resource->type != VME_MASTER) {
603 printk("Not a master resource\n"); 603 printk(KERN_ERR "Not a master resource\n");
604 return -EINVAL; 604 return -EINVAL;
605 } 605 }
606 606
@@ -615,14 +615,14 @@ void vme_master_free(struct vme_resource *resource)
615 struct vme_master_resource *master_image; 615 struct vme_master_resource *master_image;
616 616
617 if (resource->type != VME_MASTER) { 617 if (resource->type != VME_MASTER) {
618 printk("Not a master resource\n"); 618 printk(KERN_ERR "Not a master resource\n");
619 return; 619 return;
620 } 620 }
621 621
622 master_image = list_entry(resource->entry, struct vme_master_resource, 622 master_image = list_entry(resource->entry, struct vme_master_resource,
623 list); 623 list);
624 if (master_image == NULL) { 624 if (master_image == NULL) {
625 printk("Can't find master resource\n"); 625 printk(KERN_ERR "Can't find master resource\n");
626 return; 626 return;
627 } 627 }
628 628
@@ -643,7 +643,7 @@ EXPORT_SYMBOL(vme_master_free);
643 * Request a DMA controller with specific attributes, return some unique 643 * Request a DMA controller with specific attributes, return some unique
644 * identifier. 644 * identifier.
645 */ 645 */
646struct vme_resource *vme_dma_request(struct device *dev) 646struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route)
647{ 647{
648 struct vme_bridge *bridge; 648 struct vme_bridge *bridge;
649 struct list_head *dma_pos = NULL; 649 struct list_head *dma_pos = NULL;
@@ -666,13 +666,15 @@ struct vme_resource *vme_dma_request(struct device *dev)
666 struct vme_dma_resource, list); 666 struct vme_dma_resource, list);
667 667
668 if (dma_ctrlr == NULL) { 668 if (dma_ctrlr == NULL) {
669 printk("Registered NULL DMA resource\n"); 669 printk(KERN_ERR "Registered NULL DMA resource\n");
670 continue; 670 continue;
671 } 671 }
672 672
673 /* Find an unlocked controller */ 673 /* Find an unlocked and compatible controller */
674 mutex_lock(&(dma_ctrlr->mtx)); 674 mutex_lock(&(dma_ctrlr->mtx));
675 if(dma_ctrlr->locked == 0) { 675 if (((dma_ctrlr->route_attr & route) == route) &&
676 (dma_ctrlr->locked == 0)) {
677
676 dma_ctrlr->locked = 1; 678 dma_ctrlr->locked = 1;
677 mutex_unlock(&(dma_ctrlr->mtx)); 679 mutex_unlock(&(dma_ctrlr->mtx));
678 allocated_ctrlr = dma_ctrlr; 680 allocated_ctrlr = dma_ctrlr;
@@ -715,16 +717,15 @@ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
715 struct vme_dma_list *dma_list; 717 struct vme_dma_list *dma_list;
716 718
717 if (resource->type != VME_DMA) { 719 if (resource->type != VME_DMA) {
718 printk("Not a DMA resource\n"); 720 printk(KERN_ERR "Not a DMA resource\n");
719 return NULL; 721 return NULL;
720 } 722 }
721 723
722 ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); 724 ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
723 725
724 dma_list = (struct vme_dma_list *)kmalloc( 726 dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL);
725 sizeof(struct vme_dma_list), GFP_KERNEL); 727 if (dma_list == NULL) {
726 if(dma_list == NULL) { 728 printk(KERN_ERR "Unable to allocate memory for new dma list\n");
727 printk("Unable to allocate memory for new dma list\n");
728 return NULL; 729 return NULL;
729 } 730 }
730 INIT_LIST_HEAD(&(dma_list->entries)); 731 INIT_LIST_HEAD(&(dma_list->entries));
@@ -744,17 +745,17 @@ struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern,
744 struct vme_dma_attr *attributes; 745 struct vme_dma_attr *attributes;
745 struct vme_dma_pattern *pattern_attr; 746 struct vme_dma_pattern *pattern_attr;
746 747
747 attributes = (struct vme_dma_attr *)kmalloc( 748 attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
748 sizeof(struct vme_dma_attr), GFP_KERNEL); 749 if (attributes == NULL) {
749 if(attributes == NULL) { 750 printk(KERN_ERR "Unable to allocate memory for attributes "
750 printk("Unable to allocate memory for attributes structure\n"); 751 "structure\n");
751 goto err_attr; 752 goto err_attr;
752 } 753 }
753 754
754 pattern_attr = (struct vme_dma_pattern *)kmalloc( 755 pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL);
755 sizeof(struct vme_dma_pattern), GFP_KERNEL); 756 if (pattern_attr == NULL) {
756 if(pattern_attr == NULL) { 757 printk(KERN_ERR "Unable to allocate memory for pattern "
757 printk("Unable to allocate memory for pattern attributes\n"); 758 "attributes\n");
758 goto err_pat; 759 goto err_pat;
759 } 760 }
760 761
@@ -784,17 +785,17 @@ struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
784 785
785 /* XXX Run some sanity checks here */ 786 /* XXX Run some sanity checks here */
786 787
787 attributes = (struct vme_dma_attr *)kmalloc( 788 attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL);
788 sizeof(struct vme_dma_attr), GFP_KERNEL); 789 if (attributes == NULL) {
789 if(attributes == NULL) { 790 printk(KERN_ERR "Unable to allocate memory for attributes "
790 printk("Unable to allocate memory for attributes structure\n"); 791 "structure\n");
791 goto err_attr; 792 goto err_attr;
792 } 793 }
793 794
794 pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci), 795 pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL);
795 GFP_KERNEL); 796 if (pci_attr == NULL) {
796 if(pci_attr == NULL) { 797 printk(KERN_ERR "Unable to allocate memory for pci "
797 printk("Unable to allocate memory for pci attributes\n"); 798 "attributes\n");
798 goto err_pci; 799 goto err_pci;
799 } 800 }
800 801
@@ -824,19 +825,18 @@ struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
824 struct vme_dma_attr *attributes; 825 struct vme_dma_attr *attributes;
825 struct vme_dma_vme *vme_attr; 826 struct vme_dma_vme *vme_attr;
826 827
827 /* XXX Run some sanity checks here */ 828 attributes = kmalloc(
828
829 attributes = (struct vme_dma_attr *)kmalloc(
830 sizeof(struct vme_dma_attr), GFP_KERNEL); 829 sizeof(struct vme_dma_attr), GFP_KERNEL);
831 if(attributes == NULL) { 830 if (attributes == NULL) {
832 printk("Unable to allocate memory for attributes structure\n"); 831 printk(KERN_ERR "Unable to allocate memory for attributes "
832 "structure\n");
833 goto err_attr; 833 goto err_attr;
834 } 834 }
835 835
836 vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme), 836 vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL);
837 GFP_KERNEL); 837 if (vme_attr == NULL) {
838 if(vme_attr == NULL) { 838 printk(KERN_ERR "Unable to allocate memory for vme "
839 printk("Unable to allocate memory for vme attributes\n"); 839 "attributes\n");
840 goto err_vme; 840 goto err_vme;
841 } 841 }
842 842
@@ -875,12 +875,12 @@ int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
875 int retval; 875 int retval;
876 876
877 if (bridge->dma_list_add == NULL) { 877 if (bridge->dma_list_add == NULL) {
878 printk("Link List DMA generation not supported\n"); 878 printk(KERN_WARNING "Link List DMA generation not supported\n");
879 return -EINVAL; 879 return -EINVAL;
880 } 880 }
881 881
882 if (!mutex_trylock(&(list->mtx))) { 882 if (!mutex_trylock(&(list->mtx))) {
883 printk("Link List already submitted\n"); 883 printk(KERN_ERR "Link List already submitted\n");
884 return -EINVAL; 884 return -EINVAL;
885 } 885 }
886 886
@@ -898,7 +898,7 @@ int vme_dma_list_exec(struct vme_dma_list *list)
898 int retval; 898 int retval;
899 899
900 if (bridge->dma_list_exec == NULL) { 900 if (bridge->dma_list_exec == NULL) {
901 printk("Link List DMA execution not supported\n"); 901 printk(KERN_ERR "Link List DMA execution not supported\n");
902 return -EINVAL; 902 return -EINVAL;
903 } 903 }
904 904
@@ -918,12 +918,12 @@ int vme_dma_list_free(struct vme_dma_list *list)
918 int retval; 918 int retval;
919 919
920 if (bridge->dma_list_empty == NULL) { 920 if (bridge->dma_list_empty == NULL) {
921 printk("Emptying of Link Lists not supported\n"); 921 printk(KERN_WARNING "Emptying of Link Lists not supported\n");
922 return -EINVAL; 922 return -EINVAL;
923 } 923 }
924 924
925 if (!mutex_trylock(&(list->mtx))) { 925 if (!mutex_trylock(&(list->mtx))) {
926 printk("Link List in use\n"); 926 printk(KERN_ERR "Link List in use\n");
927 return -EINVAL; 927 return -EINVAL;
928 } 928 }
929 929
@@ -933,7 +933,7 @@ int vme_dma_list_free(struct vme_dma_list *list)
933 */ 933 */
934 retval = bridge->dma_list_empty(list); 934 retval = bridge->dma_list_empty(list);
935 if (retval) { 935 if (retval) {
936 printk("Unable to empty link-list entries\n"); 936 printk(KERN_ERR "Unable to empty link-list entries\n");
937 mutex_unlock(&(list->mtx)); 937 mutex_unlock(&(list->mtx));
938 return retval; 938 return retval;
939 } 939 }
@@ -949,19 +949,19 @@ int vme_dma_free(struct vme_resource *resource)
949 struct vme_dma_resource *ctrlr; 949 struct vme_dma_resource *ctrlr;
950 950
951 if (resource->type != VME_DMA) { 951 if (resource->type != VME_DMA) {
952 printk("Not a DMA resource\n"); 952 printk(KERN_ERR "Not a DMA resource\n");
953 return -EINVAL; 953 return -EINVAL;
954 } 954 }
955 955
956 ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); 956 ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
957 957
958 if (!mutex_trylock(&(ctrlr->mtx))) { 958 if (!mutex_trylock(&(ctrlr->mtx))) {
959 printk("Resource busy, can't free\n"); 959 printk(KERN_ERR "Resource busy, can't free\n");
960 return -EBUSY; 960 return -EBUSY;
961 } 961 }
962 962
963 if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) { 963 if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) {
964 printk("Resource still processing transfers\n"); 964 printk(KERN_WARNING "Resource still processing transfers\n");
965 mutex_unlock(&(ctrlr->mtx)); 965 mutex_unlock(&(ctrlr->mtx));
966 return -EBUSY; 966 return -EBUSY;
967 } 967 }
@@ -991,7 +991,7 @@ void vme_irq_handler(struct vme_bridge *bridge, int level, int statid)
991EXPORT_SYMBOL(vme_irq_handler); 991EXPORT_SYMBOL(vme_irq_handler);
992 992
993int vme_irq_request(struct device *dev, int level, int statid, 993int vme_irq_request(struct device *dev, int level, int statid,
994 void (*callback)(int level, int vector, void *priv_data), 994 void (*callback)(int, int, void *),
995 void *priv_data) 995 void *priv_data)
996{ 996{
997 struct vme_bridge *bridge; 997 struct vme_bridge *bridge;
@@ -1002,7 +1002,7 @@ int vme_irq_request(struct device *dev, int level, int statid,
1002 return -EINVAL; 1002 return -EINVAL;
1003 } 1003 }
1004 1004
1005 if((level < 1) || (level > 7)) { 1005 if ((level < 1) || (level > 7)) {
1006 printk(KERN_ERR "Invalid interrupt level\n"); 1006 printk(KERN_ERR "Invalid interrupt level\n");
1007 return -EINVAL; 1007 return -EINVAL;
1008 } 1008 }
@@ -1025,7 +1025,7 @@ int vme_irq_request(struct device *dev, int level, int statid,
1025 bridge->irq[level - 1].callback[statid].func = callback; 1025 bridge->irq[level - 1].callback[statid].func = callback;
1026 1026
1027 /* Enable IRQ level */ 1027 /* Enable IRQ level */
1028 bridge->irq_set(level, 1, 1); 1028 bridge->irq_set(bridge, level, 1, 1);
1029 1029
1030 mutex_unlock(&(bridge->irq_mtx)); 1030 mutex_unlock(&(bridge->irq_mtx));
1031 1031
@@ -1043,7 +1043,7 @@ void vme_irq_free(struct device *dev, int level, int statid)
1043 return; 1043 return;
1044 } 1044 }
1045 1045
1046 if((level < 1) || (level > 7)) { 1046 if ((level < 1) || (level > 7)) {
1047 printk(KERN_ERR "Invalid interrupt level\n"); 1047 printk(KERN_ERR "Invalid interrupt level\n");
1048 return; 1048 return;
1049 } 1049 }
@@ -1059,7 +1059,7 @@ void vme_irq_free(struct device *dev, int level, int statid)
1059 1059
1060 /* Disable IRQ level if no more interrupts attached at this level*/ 1060 /* Disable IRQ level if no more interrupts attached at this level*/
1061 if (bridge->irq[level - 1].count == 0) 1061 if (bridge->irq[level - 1].count == 0)
1062 bridge->irq_set(level, 0, 1); 1062 bridge->irq_set(bridge, level, 0, 1);
1063 1063
1064 bridge->irq[level - 1].callback[statid].func = NULL; 1064 bridge->irq[level - 1].callback[statid].func = NULL;
1065 bridge->irq[level - 1].callback[statid].priv_data = NULL; 1065 bridge->irq[level - 1].callback[statid].priv_data = NULL;
@@ -1078,17 +1078,17 @@ int vme_irq_generate(struct device *dev, int level, int statid)
1078 return -EINVAL; 1078 return -EINVAL;
1079 } 1079 }
1080 1080
1081 if((level < 1) || (level > 7)) { 1081 if ((level < 1) || (level > 7)) {
1082 printk(KERN_WARNING "Invalid interrupt level\n"); 1082 printk(KERN_WARNING "Invalid interrupt level\n");
1083 return -EINVAL; 1083 return -EINVAL;
1084 } 1084 }
1085 1085
1086 if (bridge->irq_generate == NULL) { 1086 if (bridge->irq_generate == NULL) {
1087 printk("Interrupt generation not supported\n"); 1087 printk(KERN_WARNING "Interrupt generation not supported\n");
1088 return -EINVAL; 1088 return -EINVAL;
1089 } 1089 }
1090 1090
1091 return bridge->irq_generate(level, statid); 1091 return bridge->irq_generate(bridge, level, statid);
1092} 1092}
1093EXPORT_SYMBOL(vme_irq_generate); 1093EXPORT_SYMBOL(vme_irq_generate);
1094 1094
@@ -1189,8 +1189,6 @@ int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
1189 return -EINVAL; 1189 return -EINVAL;
1190 } 1190 }
1191 1191
1192 /* XXX Check parameters */
1193
1194 return bridge->lm_set(lm, lm_base, aspace, cycle); 1192 return bridge->lm_set(lm, lm_base, aspace, cycle);
1195} 1193}
1196EXPORT_SYMBOL(vme_lm_set); 1194EXPORT_SYMBOL(vme_lm_set);
@@ -1297,11 +1295,11 @@ int vme_slot_get(struct device *bus)
1297 } 1295 }
1298 1296
1299 if (bridge->slot_get == NULL) { 1297 if (bridge->slot_get == NULL) {
1300 printk("vme_slot_get not supported\n"); 1298 printk(KERN_WARNING "vme_slot_get not supported\n");
1301 return -EINVAL; 1299 return -EINVAL;
1302 } 1300 }
1303 1301
1304 return bridge->slot_get(); 1302 return bridge->slot_get(bridge);
1305} 1303}
1306EXPORT_SYMBOL(vme_slot_get); 1304EXPORT_SYMBOL(vme_slot_get);
1307 1305
@@ -1331,7 +1329,7 @@ static void vme_free_bus_num(int bus)
1331 mutex_unlock(&vme_bus_num_mtx); 1329 mutex_unlock(&vme_bus_num_mtx);
1332} 1330}
1333 1331
1334int vme_register_bridge (struct vme_bridge *bridge) 1332int vme_register_bridge(struct vme_bridge *bridge)
1335{ 1333{
1336 struct device *dev; 1334 struct device *dev;
1337 int retval; 1335 int retval;
@@ -1358,7 +1356,7 @@ int vme_register_bridge (struct vme_bridge *bridge)
1358 dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1); 1356 dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1);
1359 1357
1360 retval = device_register(dev); 1358 retval = device_register(dev);
1361 if(retval) 1359 if (retval)
1362 goto err_reg; 1360 goto err_reg;
1363 } 1361 }
1364 1362
@@ -1375,7 +1373,7 @@ err_reg:
1375} 1373}
1376EXPORT_SYMBOL(vme_register_bridge); 1374EXPORT_SYMBOL(vme_register_bridge);
1377 1375
1378void vme_unregister_bridge (struct vme_bridge *bridge) 1376void vme_unregister_bridge(struct vme_bridge *bridge)
1379{ 1377{
1380 int i; 1378 int i;
1381 struct device *dev; 1379 struct device *dev;
@@ -1392,7 +1390,7 @@ EXPORT_SYMBOL(vme_unregister_bridge);
1392 1390
1393/* - Driver Registration --------------------------------------------------- */ 1391/* - Driver Registration --------------------------------------------------- */
1394 1392
1395int vme_register_driver (struct vme_driver *drv) 1393int vme_register_driver(struct vme_driver *drv)
1396{ 1394{
1397 drv->driver.name = drv->name; 1395 drv->driver.name = drv->name;
1398 drv->driver.bus = &vme_bus_type; 1396 drv->driver.bus = &vme_bus_type;
@@ -1401,7 +1399,7 @@ int vme_register_driver (struct vme_driver *drv)
1401} 1399}
1402EXPORT_SYMBOL(vme_register_driver); 1400EXPORT_SYMBOL(vme_register_driver);
1403 1401
1404void vme_unregister_driver (struct vme_driver *drv) 1402void vme_unregister_driver(struct vme_driver *drv)
1405{ 1403{
1406 driver_unregister(&drv->driver); 1404 driver_unregister(&drv->driver);
1407} 1405}
@@ -1418,10 +1416,10 @@ int vme_calc_slot(struct device *dev)
1418 1416
1419 /* Determine slot number */ 1417 /* Determine slot number */
1420 num = 0; 1418 num = 0;
1421 while(num < VME_SLOTS_MAX) { 1419 while (num < VME_SLOTS_MAX) {
1422 if(&(bridge->dev[num]) == dev) { 1420 if (&(bridge->dev[num]) == dev)
1423 break; 1421 break;
1424 } 1422
1425 num++; 1423 num++;
1426 } 1424 }
1427 if (num == VME_SLOTS_MAX) { 1425 if (num == VME_SLOTS_MAX) {
@@ -1437,8 +1435,8 @@ err_dev:
1437 1435
1438static struct vme_driver *dev_to_vme_driver(struct device *dev) 1436static struct vme_driver *dev_to_vme_driver(struct device *dev)
1439{ 1437{
1440 if(dev->driver == NULL) 1438 if (dev->driver == NULL)
1441 printk("Bugger dev->driver is NULL\n"); 1439 printk(KERN_ERR "Bugger dev->driver is NULL\n");
1442 1440
1443 return container_of(dev->driver, struct vme_driver, driver); 1441 return container_of(dev->driver, struct vme_driver, driver);
1444} 1442}
@@ -1462,7 +1460,7 @@ static int vme_bus_match(struct device *dev, struct device_driver *drv)
1462 } 1460 }
1463 1461
1464 i = 0; 1462 i = 0;
1465 while((driver->bind_table[i].bus != 0) || 1463 while ((driver->bind_table[i].bus != 0) ||
1466 (driver->bind_table[i].slot != 0)) { 1464 (driver->bind_table[i].slot != 0)) {
1467 1465
1468 if (bridge->num == driver->bind_table[i].bus) { 1466 if (bridge->num == driver->bind_table[i].bus) {
@@ -1493,9 +1491,8 @@ static int vme_bus_probe(struct device *dev)
1493 driver = dev_to_vme_driver(dev); 1491 driver = dev_to_vme_driver(dev);
1494 bridge = dev_to_bridge(dev); 1492 bridge = dev_to_bridge(dev);
1495 1493
1496 if(driver->probe != NULL) { 1494 if (driver->probe != NULL)
1497 retval = driver->probe(dev, bridge->num, vme_calc_slot(dev)); 1495 retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
1498 }
1499 1496
1500 return retval; 1497 return retval;
1501} 1498}
@@ -1509,9 +1506,8 @@ static int vme_bus_remove(struct device *dev)
1509 driver = dev_to_vme_driver(dev); 1506 driver = dev_to_vme_driver(dev);
1510 bridge = dev_to_bridge(dev); 1507 bridge = dev_to_bridge(dev);
1511 1508
1512 if(driver->remove != NULL) { 1509 if (driver->remove != NULL)
1513 retval = driver->remove(dev, bridge->num, vme_calc_slot(dev)); 1510 retval = driver->remove(dev, bridge->num, vme_calc_slot(dev));
1514 }
1515 1511
1516 return retval; 1512 return retval;
1517} 1513}
@@ -1524,18 +1520,18 @@ struct bus_type vme_bus_type = {
1524}; 1520};
1525EXPORT_SYMBOL(vme_bus_type); 1521EXPORT_SYMBOL(vme_bus_type);
1526 1522
1527static int __init vme_init (void) 1523static int __init vme_init(void)
1528{ 1524{
1529 return bus_register(&vme_bus_type); 1525 return bus_register(&vme_bus_type);
1530} 1526}
1531 1527
1532static void __exit vme_exit (void) 1528static void __exit vme_exit(void)
1533{ 1529{
1534 bus_unregister(&vme_bus_type); 1530 bus_unregister(&vme_bus_type);
1535} 1531}
1536 1532
1537MODULE_DESCRIPTION("VME bridge driver framework"); 1533MODULE_DESCRIPTION("VME bridge driver framework");
1538MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com"); 1534MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
1539MODULE_LICENSE("GPL"); 1535MODULE_LICENSE("GPL");
1540 1536
1541module_init(vme_init); 1537module_init(vme_init);
diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h
index 97dc22e34caf..48768ca97e16 100644
--- a/drivers/staging/vme/vme.h
+++ b/drivers/staging/vme/vme.h
@@ -68,6 +68,14 @@ typedef u32 vme_pattern_t;
68#define VME_DMA_PATTERN_WORD (1<<1) 68#define VME_DMA_PATTERN_WORD (1<<1)
69#define VME_DMA_PATTERN_INCREMENT (1<<2) 69#define VME_DMA_PATTERN_INCREMENT (1<<2)
70 70
71typedef u32 vme_dma_route_t;
72#define VME_DMA_VME_TO_MEM (1<<0)
73#define VME_DMA_MEM_TO_VME (1<<1)
74#define VME_DMA_VME_TO_VME (1<<2)
75#define VME_DMA_MEM_TO_MEM (1<<3)
76#define VME_DMA_PATTERN_TO_VME (1<<4)
77#define VME_DMA_PATTERN_TO_MEM (1<<5)
78
71struct vme_dma_attr { 79struct vme_dma_attr {
72 vme_dma_t type; 80 vme_dma_t type;
73 void *private; 81 void *private;
@@ -98,32 +106,33 @@ struct vme_driver {
98 struct device_driver driver; 106 struct device_driver driver;
99}; 107};
100 108
101void * vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *); 109void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *);
102void vme_free_consistent(struct vme_resource *, size_t, void *, 110void vme_free_consistent(struct vme_resource *, size_t, void *,
103 dma_addr_t); 111 dma_addr_t);
104 112
105size_t vme_get_size(struct vme_resource *); 113size_t vme_get_size(struct vme_resource *);
106 114
107struct vme_resource * vme_slave_request(struct device *, vme_address_t, vme_cycle_t); 115struct vme_resource *vme_slave_request(struct device *, vme_address_t,
108int vme_slave_set (struct vme_resource *, int, unsigned long long, 116 vme_cycle_t);
117int vme_slave_set(struct vme_resource *, int, unsigned long long,
109 unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t); 118 unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
110int vme_slave_get (struct vme_resource *, int *, unsigned long long *, 119int vme_slave_get(struct vme_resource *, int *, unsigned long long *,
111 unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *); 120 unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *);
112void vme_slave_free(struct vme_resource *); 121void vme_slave_free(struct vme_resource *);
113 122
114struct vme_resource * vme_master_request(struct device *, vme_address_t, vme_cycle_t, 123struct vme_resource *vme_master_request(struct device *, vme_address_t,
115 vme_width_t); 124 vme_cycle_t, vme_width_t);
116int vme_master_set (struct vme_resource *, int, unsigned long long, 125int vme_master_set(struct vme_resource *, int, unsigned long long,
117 unsigned long long, vme_address_t, vme_cycle_t, vme_width_t); 126 unsigned long long, vme_address_t, vme_cycle_t, vme_width_t);
118int vme_master_get (struct vme_resource *, int *, unsigned long long *, 127int vme_master_get(struct vme_resource *, int *, unsigned long long *,
119 unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *); 128 unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *);
120ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t); 129ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
121ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t); 130ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
122unsigned int vme_master_rmw (struct vme_resource *, unsigned int, unsigned int, 131unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
123 unsigned int, loff_t); 132 unsigned int, loff_t);
124void vme_master_free(struct vme_resource *); 133void vme_master_free(struct vme_resource *);
125 134
126struct vme_resource *vme_dma_request(struct device *); 135struct vme_resource *vme_dma_request(struct device *, vme_dma_route_t);
127struct vme_dma_list *vme_new_dma_list(struct vme_resource *); 136struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
128struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t); 137struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
129struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t); 138struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
@@ -153,8 +162,8 @@ void vme_lm_free(struct vme_resource *);
153 162
154int vme_slot_get(struct device *); 163int vme_slot_get(struct device *);
155 164
156int vme_register_driver (struct vme_driver *); 165int vme_register_driver(struct vme_driver *);
157void vme_unregister_driver (struct vme_driver *); 166void vme_unregister_driver(struct vme_driver *);
158 167
159 168
160#endif /* _VME_H_ */ 169#endif /* _VME_H_ */
diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt
index a5c1b1cd5fcc..a910a0c4388b 100644
--- a/drivers/staging/vme/vme_api.txt
+++ b/drivers/staging/vme/vme_api.txt
@@ -77,16 +77,21 @@ driver in question:
77 struct vme_resource * vme_slave_request(struct device *dev, 77 struct vme_resource * vme_slave_request(struct device *dev,
78 vme_address_t aspace, vme_cycle_t cycle); 78 vme_address_t aspace, vme_cycle_t cycle);
79 79
80 struct vme_resource *vme_dma_request(struct device *dev); 80 struct vme_resource *vme_dma_request(struct device *dev,
81 vme_dma_route_t route);
81 82
82For slave windows these attributes are split into those of type 'vme_address_t' 83For slave windows these attributes are split into those of type 'vme_address_t'
83and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'. 84and 'vme_cycle_t'. Master windows add a further set of attributes
84These attributes are defined as bitmasks and as such any combination of the 85'vme_cycle_t'. These attributes are defined as bitmasks and as such any
85attributes can be requested for a single window, the core will assign a window 86combination of the attributes can be requested for a single window, the core
86that meets the requirements, returning a pointer of type vme_resource that 87will assign a window that meets the requirements, returning a pointer of type
87should be used to identify the allocated resource when it is used. If an 88vme_resource that should be used to identify the allocated resource when it is
88unallocated window fitting the requirements can not be found a NULL pointer will 89used. For DMA controllers, the request function requires the potential
89be returned. 90direction of any transfers to be provided in the route attributes. This is
91typically VME-to-MEM and/or MEM-to-VME, though some hardware can support
92VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. If an
93unallocated window fitting the requirements can not be found a NULL pointer
94will be returned.
90 95
91Functions are also provided to free window allocations once they are no longer 96Functions are also provided to free window allocations once they are no longer
92required. These functions should be passed the pointer to the resource provided 97required. These functions should be passed the pointer to the resource provided
@@ -237,6 +242,12 @@ covered under "Transfer Attributes"):
237 struct vme_dma_attr *src, struct vme_dma_attr *dest, 242 struct vme_dma_attr *src, struct vme_dma_attr *dest,
238 size_t count); 243 size_t count);
239 244
245NOTE: The detailed attributes of the transfers source and destination
246 are not checked until an entry is added to a DMA list, the request
247 for a DMA channel purely checks the directions in which the
248 controller is expected to transfer data. As a result it is
249 possible for this call to return an error, for example if the
250 source or destination is in an unsupported VME address space.
240 251
241Transfer Attributes 252Transfer Attributes
242------------------- 253-------------------
diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h
index 851fa92559f6..b653ec02e1fc 100644
--- a/drivers/staging/vme/vme_bridge.h
+++ b/drivers/staging/vme/vme_bridge.h
@@ -19,7 +19,7 @@ struct vme_master_resource {
19 vme_address_t address_attr; 19 vme_address_t address_attr;
20 vme_cycle_t cycle_attr; 20 vme_cycle_t cycle_attr;
21 vme_width_t width_attr; 21 vme_width_t width_attr;
22 struct resource pci_resource; /* XXX Rename to be bus agnostic */ 22 struct resource bus_resource;
23 void *kern_base; 23 void *kern_base;
24}; 24};
25 25
@@ -64,6 +64,7 @@ struct vme_dma_resource {
64 int number; 64 int number;
65 struct list_head pending; 65 struct list_head pending;
66 struct list_head running; 66 struct list_head running;
67 vme_dma_route_t route_attr;
67}; 68};
68 69
69struct vme_lm_resource { 70struct vme_lm_resource {
@@ -101,7 +102,7 @@ struct vme_irq {
101 * Currently we assume that all chips are PCI-based 102 * Currently we assume that all chips are PCI-based
102 */ 103 */
103struct vme_bridge { 104struct vme_bridge {
104 char name[VMENAMSIZ]; 105 char name[VMENAMSIZ];
105 int num; 106 int num;
106 struct list_head master_resources; 107 struct list_head master_resources;
107 struct list_head slave_resources; 108 struct list_head slave_resources;
@@ -112,7 +113,7 @@ struct vme_bridge {
112 113
113 /* Bridge Info - XXX Move to private structure? */ 114 /* Bridge Info - XXX Move to private structure? */
114 struct device *parent; /* Generic device struct (pdev->dev for PCI) */ 115 struct device *parent; /* Generic device struct (pdev->dev for PCI) */
115 void * base; /* Base Address of device registers */ 116 void *driver_priv; /* Private pointer for the bridge driver */
116 117
117 struct device dev[VME_SLOTS_MAX]; /* Device registered with 118 struct device dev[VME_SLOTS_MAX]; /* Device registered with
118 * device model on VME bus 119 * device model on VME bus
@@ -151,8 +152,8 @@ struct vme_bridge {
151 int (*dma_list_empty) (struct vme_dma_list *); 152 int (*dma_list_empty) (struct vme_dma_list *);
152 153
153 /* Interrupt Functions */ 154 /* Interrupt Functions */
154 void (*irq_set) (int, int, int); 155 void (*irq_set) (struct vme_bridge *, int, int, int);
155 int (*irq_generate) (int, int); 156 int (*irq_generate) (struct vme_bridge *, int, int);
156 157
157 /* Location monitor functions */ 158 /* Location monitor functions */
158 int (*lm_set) (struct vme_lm_resource *, unsigned long long, 159 int (*lm_set) (struct vme_lm_resource *, unsigned long long,
@@ -163,102 +164,12 @@ struct vme_bridge {
163 int (*lm_detach) (struct vme_lm_resource *, int); 164 int (*lm_detach) (struct vme_lm_resource *, int);
164 165
165 /* CR/CSR space functions */ 166 /* CR/CSR space functions */
166 int (*slot_get) (void); 167 int (*slot_get) (struct vme_bridge *);
167 /* Use standard master read and write functions to access CR/CSR */
168
169#if 0
170 int (*set_prefetch) (void);
171 int (*get_prefetch) (void);
172 int (*set_arbiter) (void);
173 int (*get_arbiter) (void);
174 int (*set_requestor) (void);
175 int (*get_requestor) (void);
176#endif
177}; 168};
178 169
179void vme_irq_handler(struct vme_bridge *, int, int); 170void vme_irq_handler(struct vme_bridge *, int, int);
180 171
181int vme_register_bridge (struct vme_bridge *); 172int vme_register_bridge(struct vme_bridge *);
182void vme_unregister_bridge (struct vme_bridge *); 173void vme_unregister_bridge(struct vme_bridge *);
183 174
184#endif /* _VME_BRIDGE_H_ */ 175#endif /* _VME_BRIDGE_H_ */
185
186#if 0
187/*
188 * VMEbus GET INFO Arg Structure
189 */
190struct vmeInfoCfg {
191 int vmeSlotNum; /* VME slot number of interest */
192 int boardResponded; /* Board responded */
193 char sysConFlag; /* System controller flag */
194 int vmeControllerID; /* Vendor/device ID of VME bridge */
195 int vmeControllerRev; /* Revision of VME bridge */
196 char osName[8]; /* Name of OS e.g. "Linux" */
197 int vmeSharedDataValid; /* Validity of data struct */
198 int vmeDriverRev; /* Revision of VME driver */
199 unsigned int vmeAddrHi[8]; /* Address on VME bus */
200 unsigned int vmeAddrLo[8]; /* Address on VME bus */
201 unsigned int vmeSize[8]; /* Size on VME bus */
202 unsigned int vmeAm[8]; /* Address modifier on VME bus */
203 int reserved; /* For future use */
204};
205typedef struct vmeInfoCfg vmeInfoCfg_t;
206
207/*
208 * VMEbus Requester Arg Structure
209 */
210struct vmeRequesterCfg {
211 int requestLevel; /* Requester Bus Request Level */
212 char fairMode; /* Requester Fairness Mode Indicator */
213 int releaseMode; /* Requester Bus Release Mode */
214 int timeonTimeoutTimer; /* Master Time-on Time-out Timer */
215 int timeoffTimeoutTimer; /* Master Time-off Time-out Timer */
216 int reserved; /* For future use */
217};
218typedef struct vmeRequesterCfg vmeRequesterCfg_t;
219
220/*
221 * VMEbus Arbiter Arg Structure
222 */
223struct vmeArbiterCfg {
224 vme_arbitration_t arbiterMode; /* Arbitration Scheduling Algorithm */
225 char arbiterTimeoutFlag; /* Arbiter Time-out Timer Indicator */
226 int globalTimeoutTimer; /* VMEbus Global Time-out Timer */
227 char noEarlyReleaseFlag; /* No Early Release on BBUSY */
228 int reserved; /* For future use */
229};
230typedef struct vmeArbiterCfg vmeArbiterCfg_t;
231
232
233/*
234 * VMEbus RMW Configuration Data
235 */
236struct vmeRmwCfg {
237 unsigned int targetAddrU; /* VME Address (Upper) to trigger RMW cycle */
238 unsigned int targetAddr; /* VME Address (Lower) to trigger RMW cycle */
239 vme_address_t addrSpace; /* VME Address Space */
240 int enableMask; /* Bit mask defining the bits of interest */
241 int compareData; /* Data to be compared with the data read */
242 int swapData; /* Data written to the VMEbus on success */
243 int maxAttempts; /* Maximum times to try */
244 int numAttempts; /* Number of attempts before success */
245 int reserved; /* For future use */
246
247};
248typedef struct vmeRmwCfg vmeRmwCfg_t;
249
250/*
251 * VMEbus Location Monitor Arg Structure
252 */
253struct vmeLmCfg {
254 unsigned int addrU; /* Location Monitor Address upper */
255 unsigned int addr; /* Location Monitor Address lower */
256 vme_address_t addrSpace; /* Address Space */
257 int userAccessType; /* User/Supervisor Access Type */
258 int dataAccessType; /* Data/Program Access Type */
259 int lmWait; /* Time to wait for access */
260 int lmEvents; /* Lm event mask */
261 int reserved; /* For future use */
262};
263typedef struct vmeLmCfg vmeLmCfg_t;
264#endif
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index db786142717f..bf4fd49709df 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -2788,16 +2788,18 @@ void CARDvUpdateBasicTopRate (PVOID pDeviceHandler)
2788 2788
2789 //Determines the highest basic rate. 2789 //Determines the highest basic rate.
2790 for (ii = RATE_54M; ii >= RATE_6M; ii --) { 2790 for (ii = RATE_54M; ii >= RATE_6M; ii --) {
2791 if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) 2791 if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
2792 byTopOFDM = ii; 2792 byTopOFDM = ii;
2793 break; 2793 break;
2794 }
2794 } 2795 }
2795 pDevice->byTopOFDMBasicRate = byTopOFDM; 2796 pDevice->byTopOFDMBasicRate = byTopOFDM;
2796 2797
2797 for (ii = RATE_11M;; ii --) { 2798 for (ii = RATE_11M;; ii --) {
2798 if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) 2799 if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
2799 byTopCCK = ii; 2800 byTopCCK = ii;
2800 break; 2801 break;
2802 }
2801 if (ii == RATE_1M) 2803 if (ii == RATE_1M)
2802 break; 2804 break;
2803 } 2805 }
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 0dadb765fece..1d643653a7ed 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -1105,10 +1105,7 @@ static void device_print_info(PSDevice pDevice)
1105 struct net_device* dev=pDevice->dev; 1105 struct net_device* dev=pDevice->dev;
1106 1106
1107 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id)); 1107 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id));
1108 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", 1108 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr);
1109 dev->name,
1110 dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2],
1111 dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]);
1112#ifdef IO_MAP 1109#ifdef IO_MAP
1113 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx ",(ULONG) pDevice->ioaddr); 1110 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx ",(ULONG) pDevice->ioaddr);
1114 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq); 1111 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c
index 108830ff3b32..78b49830a255 100644
--- a/drivers/staging/vt6655/iwctl.c
+++ b/drivers/staging/vt6655/iwctl.c
@@ -1472,7 +1472,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
1472 if ( index < 4 ) { 1472 if ( index < 4 ) {
1473 pDevice->byKeyIndex = index; 1473 pDevice->byKeyIndex = index;
1474 } 1474 }
1475 else if(!wrq->flags & IW_ENCODE_MODE) { 1475 else if(!(wrq->flags & IW_ENCODE_MODE)) {
1476 rc = -EINVAL; 1476 rc = -EINVAL;
1477 return rc; 1477 return rc;
1478 } 1478 }
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
index 7d4bd5e8f69b..0a2060bf4f94 100644
--- a/drivers/staging/winbond/core.h
+++ b/drivers/staging/winbond/core.h
@@ -14,7 +14,7 @@
14struct wbsoft_priv { 14struct wbsoft_priv {
15 u32 adapterIndex; // 20060703.4 Add for using padapterContext global adapter point 15 u32 adapterIndex; // 20060703.4 Add for using padapterContext global adapter point
16 16
17 WB_LOCALDESCRIPT sLocalPara; // Myself connected parameters 17 struct wb_local_para sLocalPara; // Myself connected parameters
18 18
19 MLME_FRAME sMlmeFrame; // connect to peerSTA parameters 19 MLME_FRAME sMlmeFrame; // connect to peerSTA parameters
20 20
diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h
index 5626a76d69a4..fcf6a0442dc2 100644
--- a/drivers/staging/winbond/localpara.h
+++ b/drivers/staging/winbond/localpara.h
@@ -110,33 +110,20 @@
110// 20061108 WPS IE buffer 110// 20061108 WPS IE buffer
111#define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes 111#define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes
112 112
113typedef struct _EVENTLOG 113struct chan_info
114{
115 u16 Count; //Total count from start
116 u16 index; //Buffer index, 0 ~ 63
117 u32 EventValue[64]; //BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason
118} Event_Log, *pEvent_Log;
119
120typedef struct _ChanInfo
121{ 114{
122 u8 band; 115 u8 band;
123 u8 ChanNo; 116 u8 ChanNo;
124} ChanInfo, *pChanInfo; 117};
125 118
126typedef struct _CHAN_LIST 119struct radio_off
127{
128 u16 Count;
129 ChanInfo Channel[50]; // 100B
130} CHAN_LIST, *psCHAN_LIST;
131
132typedef struct _RadioOff
133{ 120{
134 u8 boHwRadioOff; 121 u8 boHwRadioOff;
135 u8 boSwRadioOff; 122 u8 boSwRadioOff;
136} RadioOff, *psRadioOff; 123};
137 124
138//=========================================================================== 125//===========================================================================
139typedef struct LOCAL_PARA 126struct wb_local_para
140{ 127{
141 u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard 128 u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard
142 u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually. 129 u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually.
@@ -186,7 +173,7 @@ typedef struct LOCAL_PARA
186 u16 ListenInterval; // The listen interval when SME invoking MLME_ 173 u16 ListenInterval; // The listen interval when SME invoking MLME_
187 // (Re)Associate_Request(). 174 // (Re)Associate_Request().
188 175
189 RadioOff RadioOffStatus; 176 struct radio_off RadioOffStatus;
190 u8 Reserved0[2]; 177 u8 Reserved0[2];
191 178
192 u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID. 179 u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID.
@@ -196,7 +183,7 @@ typedef struct LOCAL_PARA
196 u8 RoamStatus; 183 u8 RoamStatus;
197 u8 reserved7[3]; 184 u8 reserved7[3];
198 185
199 ChanInfo CurrentChan; //Current channel no. and channel band. It may be changed by scanning. 186 struct chan_info CurrentChan; //Current channel no. and channel band. It may be changed by scanning.
200 u8 boHandover; // Roaming, Hnadover to other AP. 187 u8 boHandover; // Roaming, Hnadover to other AP.
201 u8 boCCAbusy; 188 u8 boCCAbusy;
202 189
@@ -253,19 +240,16 @@ typedef struct LOCAL_PARA
253 u32 _dot11WEPUndecryptableCount; 240 u32 _dot11WEPUndecryptableCount;
254 u32 _dot11FrameDuplicateCount; 241 u32 _dot11FrameDuplicateCount;
255 242
256 ChanInfo IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU. 243 struct chan_info IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU.
257 u8 reserved_5[2]; //It may not be used after considering RF type, 244 u8 reserved_5[2]; //It may not be used after considering RF type,
258 //region and modulation type. 245 //region and modulation type.
259 246
260 CHAN_LIST sSupportChanList; // 86B. It will be obtained according to RF type and region
261 u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04 247 u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04
262 248
263 u32 bWepKeyError; 249 u32 bWepKeyError;
264 u32 bToSelfPacketReceived; 250 u32 bToSelfPacketReceived;
265 u32 WepKeyDetectTimerCount; 251 u32 WepKeyDetectTimerCount;
266 252
267 Event_Log EventLog;
268
269 u16 SignalLostTh; 253 u16 SignalLostTh;
270 u16 SignalRoamTh; 254 u16 SignalRoamTh;
271 255
@@ -274,6 +258,6 @@ typedef struct LOCAL_PARA
274 u16 IE_Append_size; 258 u16 IE_Append_size;
275 u16 reserved_7; 259 u16 reserved_7;
276 260
277} WB_LOCALDESCRIPT, *PWB_LOCALDESCRIPT; 261};
278 262
279#endif 263#endif
diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h
index ab1ea535f7db..e09dd4b879d4 100644
--- a/drivers/staging/winbond/mds_f.h
+++ b/drivers/staging/winbond/mds_f.h
@@ -11,9 +11,6 @@ void Mds_SendComplete( struct wbsoft_priv *adapter, PT02_DESCRIPTOR pT02 );
11void Mds_MpduProcess( struct wbsoft_priv *adapter, struct wb35_descriptor *pRxDes ); 11void Mds_MpduProcess( struct wbsoft_priv *adapter, struct wb35_descriptor *pRxDes );
12extern void DataDmp(u8 *pdata, u32 len, u32 offset); 12extern void DataDmp(u8 *pdata, u32 len, u32 offset);
13 13
14// For Asynchronous indicating. The routine collocates with USB.
15void Mds_MsduProcess( struct wbsoft_priv *adapter, PRXLAYER1 pRxLayer1, u8 SlotIndex);
16
17// For data frame sending 20060802 14// For data frame sending 20060802
18u16 MDS_GetPacketSize( struct wbsoft_priv *adapter ); 15u16 MDS_GetPacketSize( struct wbsoft_priv *adapter );
19void MDS_GetNextPacket( struct wbsoft_priv *adapter, struct wb35_descriptor *pDes ); 16void MDS_GetNextPacket( struct wbsoft_priv *adapter, struct wb35_descriptor *pDes );
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
index e8e13bde4744..217ff0819a93 100644
--- a/drivers/staging/winbond/mds_s.h
+++ b/drivers/staging/winbond/mds_s.h
@@ -133,32 +133,4 @@ struct wb35_mds {
133 133
134}; 134};
135 135
136//
137// Reveive Layer 1 Format.
138//----------------------------
139typedef struct _RXLAYER1
140{
141 u16 SequenceNumber; // The sequence number of the last received packet.
142 u16 BufferTotalSize;
143
144 u32 InUsed;
145 u32 DecryptionMethod; // The desired defragment number of the next incoming packet.
146
147 u8 DeFragmentNumber;
148 u8 FrameType;
149 u8 TypeEncapsulated;
150 u8 BufferNumber;
151
152 u32 FirstFrameArrivedTime;
153
154 u8 LastFrameType; // 20061004 for fix intel 3945 's bug
155 u8 RESERVED[3]; //@@ anson
156
157 /////////////////////////////////////////////////////////////////////////////////////////////
158 // For brand-new Rx system
159 u8 ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area
160 u8 *ReservedBufferPoint;// Point to the next availabe address of reserved buffer
161
162}RXLAYER1, * PRXLAYER1;
163
164#endif 136#endif
diff --git a/drivers/staging/winbond/mlme_s.h b/drivers/staging/winbond/mlme_s.h
index ea12684a2b1d..1217a1c025e5 100644
--- a/drivers/staging/winbond/mlme_s.h
+++ b/drivers/staging/winbond/mlme_s.h
@@ -165,14 +165,6 @@ typedef struct _AUTHREQ {
165 165
166} MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA; 166} MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA;
167 167
168struct _Reason_Code {
169
170 u8 peerMACaddr[MAC_ADDR_LENGTH];
171 u16 wReasonCode;
172};
173typedef struct _Reason_Code MLME_DEAUTHREQ_PARA, *psMLME_DEAUTHREQ_PARA;
174typedef struct _Reason_Code MLME_DISASSOCREQ_PARA, *psMLME_DISASSOCREQ_PARA;
175
176typedef struct _ASSOCREQ { 168typedef struct _ASSOCREQ {
177 u8 PeerSTAAddr[MAC_ADDR_LENGTH]; 169 u8 PeerSTAAddr[MAC_ADDR_LENGTH];
178 u16 CapabilityInfo; 170 u16 CapabilityInfo;
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
index 4fe24b0f2791..fb4781d5781b 100644
--- a/drivers/staging/winbond/mto.h
+++ b/drivers/staging/winbond/mto.h
@@ -141,11 +141,6 @@ extern u16 MTO_Frag_Th_Tbl[];
141#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()] 141#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
142#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()] 142#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
143 143
144typedef struct {
145 u8 tx_rate;
146 u8 tx_retry_rate;
147} TXRETRY_REC;
148
149extern void MTO_Init(struct wbsoft_priv *); 144extern void MTO_Init(struct wbsoft_priv *);
150extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *); 145extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
151extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8); 146extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
index d915cbdd38ed..5f5048af26a5 100644
--- a/drivers/staging/winbond/reg.c
+++ b/drivers/staging/winbond/reg.c
@@ -1823,12 +1823,12 @@ BBProcessor_initial( struct hw_data * pHwData )
1823 reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6 1823 reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
1824} 1824}
1825 1825
1826void set_tx_power_per_channel_max2829( struct hw_data * pHwData, ChanInfo Channel) 1826void set_tx_power_per_channel_max2829( struct hw_data * pHwData, struct chan_info Channel)
1827{ 1827{
1828 RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify 1828 RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
1829} 1829}
1830 1830
1831void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Channel ) 1831void set_tx_power_per_channel_al2230( struct hw_data * pHwData, struct chan_info Channel )
1832{ 1832{
1833 u8 index = 100; 1833 u8 index = 100;
1834 1834
@@ -1838,7 +1838,7 @@ void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Chann
1838 RFSynthesizer_SetPowerIndex( pHwData, index ); 1838 RFSynthesizer_SetPowerIndex( pHwData, index );
1839} 1839}
1840 1840
1841void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Channel) 1841void set_tx_power_per_channel_al7230( struct hw_data * pHwData, struct chan_info Channel)
1842{ 1842{
1843 u8 i, index = 100; 1843 u8 i, index = 100;
1844 1844
@@ -1868,7 +1868,7 @@ void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Chann
1868 RFSynthesizer_SetPowerIndex( pHwData, index ); 1868 RFSynthesizer_SetPowerIndex( pHwData, index );
1869} 1869}
1870 1870
1871void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channel) 1871void set_tx_power_per_channel_wb242( struct hw_data * pHwData, struct chan_info Channel)
1872{ 1872{
1873 u8 index = 100; 1873 u8 index = 100;
1874 1874
@@ -1901,7 +1901,7 @@ void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channe
1901// None. 1901// None.
1902//============================================================================================================= 1902//=============================================================================================================
1903void 1903void
1904RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel ) 1904RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel )
1905{ 1905{
1906 struct wb35_reg *reg = &pHwData->reg; 1906 struct wb35_reg *reg = &pHwData->reg;
1907 u32 pltmp[16]; // The 16 is the maximum capability of hardware 1907 u32 pltmp[16]; // The 16 is the maximum capability of hardware
diff --git a/drivers/staging/winbond/scan_s.h b/drivers/staging/winbond/scan_s.h
index 775bb81f23cc..209717f5d47d 100644
--- a/drivers/staging/winbond/scan_s.h
+++ b/drivers/staging/winbond/scan_s.h
@@ -35,7 +35,6 @@ typedef struct _SCAN_REQ_PARA //mandatory parameters for SCAN request
35{ 35{
36 u32 ScanType; //passive/active scan 36 u32 ScanType; //passive/active scan
37 37
38 CHAN_LIST sChannelList; // 86B
39 u8 reserved_1[2]; 38 u8 reserved_1[2];
40 39
41 struct SSID_Element sSSID; // 34B. scan only for this SSID 40 struct SSID_Element sSSID; // 34B. scan only for this SSID
diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h
index 549878302288..b5898294eb8a 100644
--- a/drivers/staging/winbond/sme_api.h
+++ b/drivers/staging/winbond/sme_api.h
@@ -193,8 +193,6 @@ s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin);
193s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax); 193s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax);
194s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff); 194s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff);
195s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff); 195s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff);
196s8 sme_get_radio_mode(void *pcore_data, psRadioOff pRadioOffData);
197s8 sme_set_radio_mode(void *pcore_data, RadioOff RadioOffData);
198 196
199void sme_get_tx_power_level(void *pcore_data, u32 *TxPower); 197void sme_get_tx_power_level(void *pcore_data, u32 *TxPower);
200u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower); 198u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower);
@@ -203,7 +201,7 @@ void sme_get_rx_antenna(void *pcore_data, u32 *RxAntenna);
203u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna); 201u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna);
204void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna); 202void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna);
205s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna); 203s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna);
206s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan); 204s8 sme_set_IBSS_chan(void *pcore_data, struct chan_info chan);
207 205
208//20061108 WPS 206//20061108 WPS
209s8 sme_set_IE_append(void *pcore_data, u8 *buffer, u16 buf_len); 207s8 sme_set_IE_append(void *pcore_data, u8 *buffer, u16 buf_len);
diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h
index 30f5b5ad63ad..d352bce5c171 100644
--- a/drivers/staging/winbond/wb35reg_f.h
+++ b/drivers/staging/winbond/wb35reg_f.h
@@ -14,7 +14,7 @@ void Dxx_initial( struct hw_data * pHwData );
14void Mxx_initial( struct hw_data * pHwData ); 14void Mxx_initial( struct hw_data * pHwData );
15void RFSynthesizer_initial( struct hw_data * pHwData ); 15void RFSynthesizer_initial( struct hw_data * pHwData );
16//void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, s8 Channel ); 16//void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, s8 Channel );
17void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel ); 17void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, struct chan_info Channel );
18void BBProcessor_initial( struct hw_data * pHwData ); 18void BBProcessor_initial( struct hw_data * pHwData );
19void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060613.1 19void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060613.1
20//void RF_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060626.5.c Add 20//void RF_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060626.5.c Add
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index 067082a7d759..3482eec18651 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -23,7 +23,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
23MODULE_LICENSE("GPL"); 23MODULE_LICENSE("GPL");
24MODULE_VERSION("0.1"); 24MODULE_VERSION("0.1");
25 25
26static struct usb_device_id wb35_table[] __devinitdata = { 26static const struct usb_device_id wb35_table[] __devinitconst = {
27 { USB_DEVICE(0x0416, 0x0035) }, 27 { USB_DEVICE(0x0416, 0x0035) },
28 { USB_DEVICE(0x18E8, 0x6201) }, 28 { USB_DEVICE(0x18E8, 0x6201) },
29 { USB_DEVICE(0x18E8, 0x6206) }, 29 { USB_DEVICE(0x18E8, 0x6206) },
@@ -65,17 +65,17 @@ static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
65} 65}
66 66
67static int wbsoft_add_interface(struct ieee80211_hw *dev, 67static int wbsoft_add_interface(struct ieee80211_hw *dev,
68 struct ieee80211_if_init_conf *conf) 68 struct ieee80211_vif *vif)
69{ 69{
70 struct wbsoft_priv *priv = dev->priv; 70 struct wbsoft_priv *priv = dev->priv;
71 71
72 hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int); 72 hal_set_beacon_period(&priv->sHwData, vif->bss_conf.beacon_int);
73 73
74 return 0; 74 return 0;
75} 75}
76 76
77static void wbsoft_remove_interface(struct ieee80211_hw *dev, 77static void wbsoft_remove_interface(struct ieee80211_hw *dev,
78 struct ieee80211_if_init_conf *conf) 78 struct ieee80211_vif *vif)
79{ 79{
80 printk("wbsoft_remove interface called\n"); 80 printk("wbsoft_remove interface called\n");
81} 81}
@@ -92,13 +92,6 @@ static int wbsoft_get_stats(struct ieee80211_hw *hw,
92 return 0; 92 return 0;
93} 93}
94 94
95static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
96 struct ieee80211_tx_queue_stats *stats)
97{
98 printk(KERN_INFO "%s called\n", __func__);
99 return 0;
100}
101
102static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count, 95static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
103 struct dev_addr_list *mc_list) 96 struct dev_addr_list *mc_list)
104{ 97{
@@ -161,7 +154,7 @@ static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
161} 154}
162 155
163static void 156static void
164hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel) 157hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info channel)
165{ 158{
166 struct wb35_reg *reg = &pHwData->reg; 159 struct wb35_reg *reg = &pHwData->reg;
167 160
@@ -180,10 +173,10 @@ hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
180 reg->M28_MacControl &= ~0xff; // Clean channel information field 173 reg->M28_MacControl &= ~0xff; // Clean channel information field
181 reg->M28_MacControl |= channel.ChanNo; 174 reg->M28_MacControl |= channel.ChanNo;
182 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, 175 Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl,
183 (s8 *) & channel, sizeof(ChanInfo)); 176 (s8 *) & channel, sizeof(struct chan_info));
184} 177}
185 178
186static void hal_set_current_channel(struct hw_data *pHwData, ChanInfo channel) 179static void hal_set_current_channel(struct hw_data *pHwData, struct chan_info channel)
187{ 180{
188 hal_set_current_channel_ex(pHwData, channel); 181 hal_set_current_channel_ex(pHwData, channel);
189} 182}
@@ -253,7 +246,7 @@ static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
253static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) 246static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
254{ 247{
255 struct wbsoft_priv *priv = dev->priv; 248 struct wbsoft_priv *priv = dev->priv;
256 ChanInfo ch; 249 struct chan_info ch;
257 250
258 printk("wbsoft_config called\n"); 251 printk("wbsoft_config called\n");
259 252
@@ -287,7 +280,6 @@ static const struct ieee80211_ops wbsoft_ops = {
287 .prepare_multicast = wbsoft_prepare_multicast, 280 .prepare_multicast = wbsoft_prepare_multicast,
288 .configure_filter = wbsoft_configure_filter, 281 .configure_filter = wbsoft_configure_filter,
289 .get_stats = wbsoft_get_stats, 282 .get_stats = wbsoft_get_stats,
290 .get_tx_stats = wbsoft_get_tx_stats,
291 .get_tsf = wbsoft_get_tsf, 283 .get_tsf = wbsoft_get_tsf,
292}; 284};
293 285
diff --git a/drivers/staging/wlags49_h2/wl_main.c b/drivers/staging/wlags49_h2/wl_main.c
index 16764a000942..cf0c38468b20 100644
--- a/drivers/staging/wlags49_h2/wl_main.c
+++ b/drivers/staging/wlags49_h2/wl_main.c
@@ -3792,7 +3792,7 @@ static int write_int(struct file *file, const char *buffer, unsigned long count,
3792 } 3792 }
3793 if (count > 0 ) { 3793 if (count > 0 ) {
3794 proc_number[count] = 0; 3794 proc_number[count] = 0;
3795 nr = wl_atoi( proc_number ); 3795 nr = simple_strtoul(proc_number , NULL, 0);
3796 *(unsigned int *)data = nr; 3796 *(unsigned int *)data = nr;
3797 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this 3797 if ( nr & 0x8000 ) { //;?kludgy but it is unclear to me were else to place this
3798#if DBG 3798#if DBG
diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c
index c33e225bc0e6..fa082d90fcad 100644
--- a/drivers/staging/wlags49_h2/wl_netdev.c
+++ b/drivers/staging/wlags49_h2/wl_netdev.c
@@ -360,7 +360,7 @@ int wl_open(struct net_device *dev)
360 wl_lock( lp, &flags ); 360 wl_lock( lp, &flags );
361 361
362 if( status != HCF_SUCCESS ) { 362 if( status != HCF_SUCCESS ) {
363 // Unsuccesfull, try reset of the card to recover 363 // Unsuccessful, try reset of the card to recover
364 status = wl_reset( dev ); 364 status = wl_reset( dev );
365 } 365 }
366 366
diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c
index a3db111d4a95..01e4bec9fd5b 100644
--- a/drivers/staging/wlags49_h2/wl_pci.c
+++ b/drivers/staging/wlags49_h2/wl_pci.c
@@ -81,7 +81,6 @@
81#include <asm/system.h> 81#include <asm/system.h>
82#include <asm/io.h> 82#include <asm/io.h>
83#include <asm/irq.h> 83#include <asm/irq.h>
84#include <asm/system.h>
85#include <asm/bitops.h> 84#include <asm/bitops.h>
86#include <asm/uaccess.h> 85#include <asm/uaccess.h>
87 86
diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c
index 715f027a923f..1e0c75f28557 100644
--- a/drivers/staging/wlags49_h2/wl_profile.c
+++ b/drivers/staging/wlags49_h2/wl_profile.c
@@ -383,15 +383,15 @@ void translate_option( char *buffer, struct wl_private *lp )
383 DbgInfo->DebugFlag |= DBG_DEFAULTS; 383 DbgInfo->DebugFlag |= DBG_DEFAULTS;
384 } 384 }
385 } else { 385 } else {
386 DbgInfo->DebugFlag = wl_atoi( value ); //;?DebugFlag; 386 DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?DebugFlag;
387 } 387 }
388 DbgInfo->DebugFlag = wl_atoi( value ); //;?Delete ASAP 388 DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); //;?Delete ASAP
389 } 389 }
390#endif /* DBG */ 390#endif /* DBG */
391 if ( strcmp( key, PARM_NAME_AUTH_KEY_MGMT_SUITE ) == 0 ) { 391 if ( strcmp( key, PARM_NAME_AUTH_KEY_MGMT_SUITE ) == 0 ) {
392 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value ); 392 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value );
393 393
394 value_convert = wl_atoi( value ); 394 value_convert = simple_strtoul(value, NULL, 0);
395 if (( value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE ) || ( value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE )) { 395 if (( value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE ) || ( value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE )) {
396 lp->AuthKeyMgmtSuite = value_convert; 396 lp->AuthKeyMgmtSuite = value_convert;
397 } else { 397 } else {
@@ -401,7 +401,7 @@ void translate_option( char *buffer, struct wl_private *lp )
401 else if ( strcmp( key, PARM_NAME_BRSC_2GHZ ) == 0 ) { 401 else if ( strcmp( key, PARM_NAME_BRSC_2GHZ ) == 0 ) {
402 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value ); 402 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value );
403 403
404 value_convert = wl_atoi( value ); 404 value_convert = simple_strtoul(value, NULL, 0);
405 if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) { 405 if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
406 lp->brsc[0] = value_convert; 406 lp->brsc[0] = value_convert;
407 } else { 407 } else {
@@ -411,7 +411,7 @@ void translate_option( char *buffer, struct wl_private *lp )
411 else if ( strcmp( key, PARM_NAME_BRSC_5GHZ ) == 0 ) { 411 else if ( strcmp( key, PARM_NAME_BRSC_5GHZ ) == 0 ) {
412 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value ); 412 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value );
413 413
414 value_convert = wl_atoi( value ); 414 value_convert = simple_strtoul(value, NULL, 0);
415 if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) { 415 if (( value_convert >= PARM_MIN_BRSC ) || ( value_convert <= PARM_MAX_BRSC )) {
416 lp->brsc[1] = value_convert; 416 lp->brsc[1] = value_convert;
417 } else { 417 } else {
@@ -448,7 +448,7 @@ void translate_option( char *buffer, struct wl_private *lp )
448 else if ( strcmp( key, PARM_NAME_ENABLE_ENCRYPTION ) == 0 ) { 448 else if ( strcmp( key, PARM_NAME_ENABLE_ENCRYPTION ) == 0 ) {
449 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value ); 449 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value );
450 450
451 value_convert = wl_atoi( value ); 451 value_convert = simple_strtoul(value, NULL, 0);
452 if (( value_convert >= PARM_MIN_ENABLE_ENCRYPTION ) && ( value_convert <= PARM_MAX_ENABLE_ENCRYPTION )) { 452 if (( value_convert >= PARM_MIN_ENABLE_ENCRYPTION ) && ( value_convert <= PARM_MAX_ENABLE_ENCRYPTION )) {
453 lp->EnableEncryption = value_convert; 453 lp->EnableEncryption = value_convert;
454 } else { 454 } else {
@@ -529,7 +529,7 @@ void translate_option( char *buffer, struct wl_private *lp )
529 else if ( strcmp( key, PARM_NAME_MULTICAST_RATE ) == 0 ) { 529 else if ( strcmp( key, PARM_NAME_MULTICAST_RATE ) == 0 ) {
530 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value ); 530 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value );
531 531
532 value_convert = wl_atoi( value ); 532 value_convert = simple_strtoul(value, NULL, 0);
533 533
534 if (( value_convert >= PARM_MIN_MULTICAST_RATE ) && ( value_convert <= PARM_MAX_MULTICAST_RATE )) { 534 if (( value_convert >= PARM_MIN_MULTICAST_RATE ) && ( value_convert <= PARM_MAX_MULTICAST_RATE )) {
535 lp->MulticastRate[0] = value_convert; 535 lp->MulticastRate[0] = value_convert;
@@ -540,7 +540,7 @@ void translate_option( char *buffer, struct wl_private *lp )
540 else if ( strcmp( key, PARM_NAME_OWN_CHANNEL ) == 0 ) { 540 else if ( strcmp( key, PARM_NAME_OWN_CHANNEL ) == 0 ) {
541 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value ); 541 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value );
542 542
543 value_convert = wl_atoi( value ); 543 value_convert = simple_strtoul(value, NULL, 0);
544 if ( wl_is_a_valid_chan( value_convert )) { 544 if ( wl_is_a_valid_chan( value_convert )) {
545 if ( value_convert > 14 ) { 545 if ( value_convert > 14 ) {
546 value_convert = value_convert | 0x100; 546 value_convert = value_convert | 0x100;
@@ -567,7 +567,7 @@ void translate_option( char *buffer, struct wl_private *lp )
567 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD ) == 0 ) { 567 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD ) == 0 ) {
568 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value ); 568 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value );
569 569
570 value_convert = wl_atoi( value ); 570 value_convert = simple_strtoul(value, NULL, 0);
571 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { 571 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
572 lp->RTSThreshold = value_convert; 572 lp->RTSThreshold = value_convert;
573 } else { 573 } else {
@@ -577,7 +577,7 @@ void translate_option( char *buffer, struct wl_private *lp )
577 else if ( strcmp( key, PARM_NAME_SRSC_2GHZ ) == 0 ) { 577 else if ( strcmp( key, PARM_NAME_SRSC_2GHZ ) == 0 ) {
578 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value ); 578 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value );
579 579
580 value_convert = wl_atoi( value ); 580 value_convert = simple_strtoul(value, NULL, 0);
581 if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) { 581 if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
582 lp->srsc[0] = value_convert; 582 lp->srsc[0] = value_convert;
583 } else { 583 } else {
@@ -587,7 +587,7 @@ void translate_option( char *buffer, struct wl_private *lp )
587 else if ( strcmp( key, PARM_NAME_SRSC_5GHZ ) == 0 ) { 587 else if ( strcmp( key, PARM_NAME_SRSC_5GHZ ) == 0 ) {
588 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value ); 588 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value );
589 589
590 value_convert = wl_atoi( value ); 590 value_convert = simple_strtoul(value, NULL, 0);
591 if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) { 591 if (( value_convert >= PARM_MIN_SRSC ) || ( value_convert <= PARM_MAX_SRSC )) {
592 lp->srsc[1] = value_convert; 592 lp->srsc[1] = value_convert;
593 } else { 593 } else {
@@ -597,7 +597,7 @@ void translate_option( char *buffer, struct wl_private *lp )
597 else if ( strcmp( key, PARM_NAME_SYSTEM_SCALE ) == 0 ) { 597 else if ( strcmp( key, PARM_NAME_SYSTEM_SCALE ) == 0 ) {
598 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value ); 598 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value );
599 599
600 value_convert = wl_atoi( value ); 600 value_convert = simple_strtoul(value, NULL, 0);
601 if (( value_convert >= PARM_MIN_SYSTEM_SCALE ) && ( value_convert <= PARM_MAX_SYSTEM_SCALE )) { 601 if (( value_convert >= PARM_MIN_SYSTEM_SCALE ) && ( value_convert <= PARM_MAX_SYSTEM_SCALE )) {
602 lp->DistanceBetweenAPs = value_convert; 602 lp->DistanceBetweenAPs = value_convert;
603 } else { 603 } else {
@@ -607,9 +607,9 @@ void translate_option( char *buffer, struct wl_private *lp )
607 else if ( strcmp( key, PARM_NAME_TX_KEY ) == 0 ) { 607 else if ( strcmp( key, PARM_NAME_TX_KEY ) == 0 ) {
608 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value ); 608 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value );
609 609
610 value_convert = wl_atoi( value ); 610 value_convert = simple_strtoul(value, NULL, 0);
611 if (( value_convert >= PARM_MIN_TX_KEY ) && ( value_convert <= PARM_MAX_TX_KEY )) { 611 if (( value_convert >= PARM_MIN_TX_KEY ) && ( value_convert <= PARM_MAX_TX_KEY )) {
612 lp->TransmitKeyID = wl_atoi( value ); 612 lp->TransmitKeyID = simple_strtoul(value, NULL, 0);
613 } else { 613 } else {
614 DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY ); 614 DBG_WARNING( DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY );
615 } 615 }
@@ -617,7 +617,7 @@ void translate_option( char *buffer, struct wl_private *lp )
617 else if ( strcmp( key, PARM_NAME_TX_RATE ) == 0 ) { 617 else if ( strcmp( key, PARM_NAME_TX_RATE ) == 0 ) {
618 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value ); 618 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value );
619 619
620 value_convert = wl_atoi( value ); 620 value_convert = simple_strtoul(value, NULL, 0);
621 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { 621 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
622 lp->TxRateControl[0] = value_convert; 622 lp->TxRateControl[0] = value_convert;
623 } else { 623 } else {
@@ -627,7 +627,7 @@ void translate_option( char *buffer, struct wl_private *lp )
627 else if ( strcmp( key, PARM_NAME_TX_POW_LEVEL ) == 0 ) { 627 else if ( strcmp( key, PARM_NAME_TX_POW_LEVEL ) == 0 ) {
628 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value ); 628 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value );
629 629
630 value_convert = wl_atoi( value ); 630 value_convert = simple_strtoul(value, NULL, 0);
631 if (( value_convert >= PARM_MIN_TX_POW_LEVEL ) || ( value_convert <= PARM_MAX_TX_POW_LEVEL )) { 631 if (( value_convert >= PARM_MIN_TX_POW_LEVEL ) || ( value_convert <= PARM_MAX_TX_POW_LEVEL )) {
632 lp->txPowLevel = value_convert; 632 lp->txPowLevel = value_convert;
633 } else { 633 } else {
@@ -645,7 +645,7 @@ void translate_option( char *buffer, struct wl_private *lp )
645 if ( strcmp( key, PARM_NAME_PORT_TYPE ) == 0 ) { 645 if ( strcmp( key, PARM_NAME_PORT_TYPE ) == 0 ) {
646 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value ); 646 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value );
647 647
648 value_convert = wl_atoi( value ); 648 value_convert = simple_strtoul(value, NULL, 0);
649 if (( value_convert == PARM_MIN_PORT_TYPE ) || ( value_convert == PARM_MAX_PORT_TYPE )) { 649 if (( value_convert == PARM_MIN_PORT_TYPE ) || ( value_convert == PARM_MAX_PORT_TYPE )) {
650 lp->PortType = value_convert; 650 lp->PortType = value_convert;
651 } else { 651 } else {
@@ -654,7 +654,7 @@ void translate_option( char *buffer, struct wl_private *lp )
654 } 654 }
655 else if ( strcmp( key, PARM_NAME_PM_ENABLED ) == 0 ) { 655 else if ( strcmp( key, PARM_NAME_PM_ENABLED ) == 0 ) {
656 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value ); 656 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value );
657 value_convert = wl_atoi( value ); 657 value_convert = simple_strtoul(value, NULL, 0);
658 /* ;? how about wl_main.c containing 658 /* ;? how about wl_main.c containing
659 * VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD || 659 * VALID_PARAM( PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
660 * ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD ); 660 * ( PARM_PM_ENABLED & 0x7FFF ) <= WVLAN_PM_STATE_STANDARD );
@@ -677,7 +677,7 @@ void translate_option( char *buffer, struct wl_private *lp )
677 else if ( strcmp( key, PARM_NAME_MAX_SLEEP ) == 0 ) { 677 else if ( strcmp( key, PARM_NAME_MAX_SLEEP ) == 0 ) {
678 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value ); 678 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value );
679 679
680 value_convert = wl_atoi( value ); 680 value_convert = simple_strtoul(value, NULL, 0);
681 if (( value_convert >= 0 ) && ( value_convert <= 65535 )) { 681 if (( value_convert >= 0 ) && ( value_convert <= 65535 )) {
682 lp->MaxSleepDuration = value_convert; 682 lp->MaxSleepDuration = value_convert;
683 } else { 683 } else {
@@ -696,7 +696,7 @@ void translate_option( char *buffer, struct wl_private *lp )
696 else if ( strcmp( key, PARM_NAME_AUTHENTICATION ) == 0 ) { 696 else if ( strcmp( key, PARM_NAME_AUTHENTICATION ) == 0 ) {
697 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value ); 697 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value );
698 698
699 value_convert = wl_atoi( value ); 699 value_convert = simple_strtoul(value, NULL, 0);
700 if (( value_convert >= PARM_MIN_AUTHENTICATION ) && ( value_convert <= PARM_MAX_AUTHENTICATION )) { 700 if (( value_convert >= PARM_MIN_AUTHENTICATION ) && ( value_convert <= PARM_MAX_AUTHENTICATION )) {
701 lp->authentication = value_convert; 701 lp->authentication = value_convert;
702 } else { 702 } else {
@@ -706,7 +706,7 @@ void translate_option( char *buffer, struct wl_private *lp )
706 else if ( strcmp( key, PARM_NAME_OWN_ATIM_WINDOW ) == 0 ) { 706 else if ( strcmp( key, PARM_NAME_OWN_ATIM_WINDOW ) == 0 ) {
707 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value ); 707 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value );
708 708
709 value_convert = wl_atoi( value ); 709 value_convert = simple_strtoul(value, NULL, 0);
710 if (( value_convert >= PARM_MIN_OWN_ATIM_WINDOW ) && ( value_convert <= PARM_MAX_OWN_ATIM_WINDOW )) { 710 if (( value_convert >= PARM_MIN_OWN_ATIM_WINDOW ) && ( value_convert <= PARM_MAX_OWN_ATIM_WINDOW )) {
711 lp->atimWindow = value_convert; 711 lp->atimWindow = value_convert;
712 } else { 712 } else {
@@ -716,7 +716,7 @@ void translate_option( char *buffer, struct wl_private *lp )
716 else if ( strcmp( key, PARM_NAME_PM_HOLDOVER_DURATION ) == 0 ) { 716 else if ( strcmp( key, PARM_NAME_PM_HOLDOVER_DURATION ) == 0 ) {
717 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value ); 717 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value );
718 718
719 value_convert = wl_atoi( value ); 719 value_convert = simple_strtoul(value, NULL, 0);
720 if (( value_convert >= PARM_MIN_PM_HOLDOVER_DURATION ) && ( value_convert <= PARM_MAX_PM_HOLDOVER_DURATION )) { 720 if (( value_convert >= PARM_MIN_PM_HOLDOVER_DURATION ) && ( value_convert <= PARM_MAX_PM_HOLDOVER_DURATION )) {
721 lp->holdoverDuration = value_convert; 721 lp->holdoverDuration = value_convert;
722 } else { 722 } else {
@@ -730,7 +730,7 @@ void translate_option( char *buffer, struct wl_private *lp )
730 else if ( strcmp( key, PARM_NAME_CONNECTION_CONTROL ) == 0 ) { 730 else if ( strcmp( key, PARM_NAME_CONNECTION_CONTROL ) == 0 ) {
731 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value ); 731 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value );
732 732
733 value_convert = wl_atoi( value ); 733 value_convert = simple_strtoul(value, NULL, 0);
734 if (( value_convert >= PARM_MIN_CONNECTION_CONTROL ) && ( value_convert <= PARM_MAX_CONNECTION_CONTROL )) { 734 if (( value_convert >= PARM_MIN_CONNECTION_CONTROL ) && ( value_convert <= PARM_MAX_CONNECTION_CONTROL )) {
735 lp->connectionControl = value_convert; 735 lp->connectionControl = value_convert;
736 } else { 736 } else {
@@ -749,7 +749,7 @@ void translate_option( char *buffer, struct wl_private *lp )
749 if ( strcmp( key, PARM_NAME_OWN_DTIM_PERIOD ) == 0 ) { 749 if ( strcmp( key, PARM_NAME_OWN_DTIM_PERIOD ) == 0 ) {
750 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value ); 750 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value );
751 751
752 value_convert = wl_atoi( value ); 752 value_convert = simple_strtoul(value, NULL, 0);
753 if ( value_convert >= PARM_MIN_OWN_DTIM_PERIOD ) { 753 if ( value_convert >= PARM_MIN_OWN_DTIM_PERIOD ) {
754 lp->DTIMPeriod = value_convert; 754 lp->DTIMPeriod = value_convert;
755 } else { 755 } else {
@@ -775,7 +775,7 @@ void translate_option( char *buffer, struct wl_private *lp )
775 else if ( strcmp( key, PARM_NAME_OWN_BEACON_INTERVAL ) == 0 ) { 775 else if ( strcmp( key, PARM_NAME_OWN_BEACON_INTERVAL ) == 0 ) {
776 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value ); 776 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value );
777 777
778 value_convert = wl_atoi( value ); 778 value_convert = simple_strtoul(value, NULL, 0);
779 if ( value_convert >= PARM_MIN_OWN_BEACON_INTERVAL ) { 779 if ( value_convert >= PARM_MIN_OWN_BEACON_INTERVAL ) {
780 lp->ownBeaconInterval = value_convert; 780 lp->ownBeaconInterval = value_convert;
781 } else { 781 } else {
@@ -785,7 +785,7 @@ void translate_option( char *buffer, struct wl_private *lp )
785 else if ( strcmp( key, PARM_NAME_COEXISTENCE ) == 0 ) { 785 else if ( strcmp( key, PARM_NAME_COEXISTENCE ) == 0 ) {
786 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value ); 786 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value );
787 787
788 value_convert = wl_atoi( value ); 788 value_convert = simple_strtoul(value, NULL, 0);
789 if ( value_convert >= PARM_MIN_COEXISTENCE ) { 789 if ( value_convert >= PARM_MIN_COEXISTENCE ) {
790 lp->coexistence = value_convert; 790 lp->coexistence = value_convert;
791 } else { 791 } else {
@@ -797,7 +797,7 @@ void translate_option( char *buffer, struct wl_private *lp )
797 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD1 ) == 0 ) { 797 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD1 ) == 0 ) {
798 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value ); 798 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value );
799 799
800 value_convert = wl_atoi( value ); 800 value_convert = simple_strtoul(value, NULL, 0);
801 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { 801 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
802 lp->wds_port[0].rtsThreshold = value_convert; 802 lp->wds_port[0].rtsThreshold = value_convert;
803 } else { 803 } else {
@@ -807,7 +807,7 @@ void translate_option( char *buffer, struct wl_private *lp )
807 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD2 ) == 0 ) { 807 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD2 ) == 0 ) {
808 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value ); 808 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value );
809 809
810 value_convert = wl_atoi( value ); 810 value_convert = simple_strtoul(value, NULL, 0);
811 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { 811 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
812 lp->wds_port[1].rtsThreshold = value_convert; 812 lp->wds_port[1].rtsThreshold = value_convert;
813 } else { 813 } else {
@@ -817,7 +817,7 @@ void translate_option( char *buffer, struct wl_private *lp )
817 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD3 ) == 0 ) { 817 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD3 ) == 0 ) {
818 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value ); 818 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value );
819 819
820 value_convert = wl_atoi( value ); 820 value_convert = simple_strtoul(value, NULL, 0);
821 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { 821 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
822 lp->wds_port[2].rtsThreshold = value_convert; 822 lp->wds_port[2].rtsThreshold = value_convert;
823 } else { 823 } else {
@@ -827,7 +827,7 @@ void translate_option( char *buffer, struct wl_private *lp )
827 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD4 ) == 0 ) { 827 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD4 ) == 0 ) {
828 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value ); 828 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value );
829 829
830 value_convert = wl_atoi( value ); 830 value_convert = simple_strtoul(value, NULL, 0);
831 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { 831 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
832 lp->wds_port[3].rtsThreshold = value_convert; 832 lp->wds_port[3].rtsThreshold = value_convert;
833 } else { 833 } else {
@@ -837,7 +837,7 @@ void translate_option( char *buffer, struct wl_private *lp )
837 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD5 ) == 0 ) { 837 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD5 ) == 0 ) {
838 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value ); 838 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value );
839 839
840 value_convert = wl_atoi( value ); 840 value_convert = simple_strtoul(value, NULL, 0);
841 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { 841 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
842 lp->wds_port[4].rtsThreshold = value_convert; 842 lp->wds_port[4].rtsThreshold = value_convert;
843 } else { 843 } else {
@@ -847,7 +847,7 @@ void translate_option( char *buffer, struct wl_private *lp )
847 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD6 ) == 0 ) { 847 else if ( strcmp( key, PARM_NAME_RTS_THRESHOLD6 ) == 0 ) {
848 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value ); 848 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value );
849 849
850 value_convert = wl_atoi( value ); 850 value_convert = simple_strtoul(value, NULL, 0);
851 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) { 851 if (( value_convert >= PARM_MIN_RTS_THRESHOLD ) && ( value_convert <= PARM_MAX_RTS_THRESHOLD )) {
852 lp->wds_port[5].rtsThreshold = value_convert; 852 lp->wds_port[5].rtsThreshold = value_convert;
853 } else { 853 } else {
@@ -857,7 +857,7 @@ void translate_option( char *buffer, struct wl_private *lp )
857 else if ( strcmp( key, PARM_NAME_TX_RATE1 ) == 0 ) { 857 else if ( strcmp( key, PARM_NAME_TX_RATE1 ) == 0 ) {
858 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value ); 858 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value );
859 859
860 value_convert = wl_atoi( value ); 860 value_convert = simple_strtoul(value, NULL, 0);
861 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { 861 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
862 lp->wds_port[0].txRateCntl = value_convert; 862 lp->wds_port[0].txRateCntl = value_convert;
863 } else { 863 } else {
@@ -867,7 +867,7 @@ void translate_option( char *buffer, struct wl_private *lp )
867 else if ( strcmp( key, PARM_NAME_TX_RATE2 ) == 0 ) { 867 else if ( strcmp( key, PARM_NAME_TX_RATE2 ) == 0 ) {
868 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value ); 868 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value );
869 869
870 value_convert = wl_atoi( value ); 870 value_convert = simple_strtoul(value, NULL, 0);
871 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { 871 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
872 lp->wds_port[1].txRateCntl = value_convert; 872 lp->wds_port[1].txRateCntl = value_convert;
873 } else { 873 } else {
@@ -877,7 +877,7 @@ void translate_option( char *buffer, struct wl_private *lp )
877 else if ( strcmp( key, PARM_NAME_TX_RATE3 ) == 0 ) { 877 else if ( strcmp( key, PARM_NAME_TX_RATE3 ) == 0 ) {
878 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value ); 878 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value );
879 879
880 value_convert = wl_atoi( value ); 880 value_convert = simple_strtoul(value, NULL, 0);
881 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { 881 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
882 lp->wds_port[2].txRateCntl = value_convert; 882 lp->wds_port[2].txRateCntl = value_convert;
883 } else { 883 } else {
@@ -887,7 +887,7 @@ void translate_option( char *buffer, struct wl_private *lp )
887 else if ( strcmp( key, PARM_NAME_TX_RATE4 ) == 0 ) { 887 else if ( strcmp( key, PARM_NAME_TX_RATE4 ) == 0 ) {
888 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value ); 888 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value );
889 889
890 value_convert = wl_atoi( value ); 890 value_convert = simple_strtoul(value, NULL, 0);
891 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { 891 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
892 lp->wds_port[3].txRateCntl = value_convert; 892 lp->wds_port[3].txRateCntl = value_convert;
893 } else { 893 } else {
@@ -897,7 +897,7 @@ void translate_option( char *buffer, struct wl_private *lp )
897 else if ( strcmp( key, PARM_NAME_TX_RATE5 ) == 0 ) { 897 else if ( strcmp( key, PARM_NAME_TX_RATE5 ) == 0 ) {
898 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value ); 898 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value );
899 899
900 value_convert = wl_atoi( value ); 900 value_convert = simple_strtoul(value, NULL, 0);
901 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { 901 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
902 lp->wds_port[4].txRateCntl = value_convert; 902 lp->wds_port[4].txRateCntl = value_convert;
903 } else { 903 } else {
@@ -907,7 +907,7 @@ void translate_option( char *buffer, struct wl_private *lp )
907 else if ( strcmp( key, PARM_NAME_TX_RATE6 ) == 0 ) { 907 else if ( strcmp( key, PARM_NAME_TX_RATE6 ) == 0 ) {
908 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value ); 908 DBG_TRACE( DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value );
909 909
910 value_convert = wl_atoi( value ); 910 value_convert = simple_strtoul(value, NULL, 0);
911 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) { 911 if (( value_convert >= PARM_MIN_TX_RATE ) && ( value_convert <= PARM_MAX_TX_RATE )) {
912 lp->wds_port[5].txRateCntl = value_convert; 912 lp->wds_port[5].txRateCntl = value_convert;
913 } else { 913 } else {
diff --git a/drivers/staging/wlags49_h2/wl_util.c b/drivers/staging/wlags49_h2/wl_util.c
index ac1e7f38f982..bbdb9973d1e5 100644
--- a/drivers/staging/wlags49_h2/wl_util.c
+++ b/drivers/staging/wlags49_h2/wl_util.c
@@ -1536,52 +1536,3 @@ int wl_get_tallies(struct wl_private *lp,
1536 return ret; 1536 return ret;
1537} 1537}
1538 1538
1539/*******************************************************************************
1540 * wl_atoi()
1541 *******************************************************************************
1542 *
1543 * DESCRIPTION:
1544 *
1545 * Believe it or not, we need our own implementation of atoi in the kernel.
1546 *
1547 * PARAMETERS:
1548 *
1549 * string - the ASCII string to convert to an integer
1550 *
1551 * RETURNS:
1552 *
1553 * unsigned integer
1554 *
1555 ******************************************************************************/
1556unsigned int wl_atoi( char *string )
1557{
1558unsigned int base = 10; //default to decimal
1559unsigned int value = 0;
1560unsigned int c;
1561int i = strlen( string );
1562
1563 if ( i > 2 && string[0] == '0' && ( string[1] | ('X'^'x') ) == 'x' ) {
1564 base = 16;
1565 string +=2;
1566 }
1567 while ( ( c = *string++ ) != '\0' ) {
1568 if ( value > UINT_MAX / base ) { //test for overrun
1569 DBG_FUNC( "wl_atoi" ); //don't overload the log file with good messages
1570 DBG_ENTER( DbgInfo );
1571 DBG_ERROR( DbgInfo, "string \"%s\", lenght exceeds expectations\n", string );
1572 printk( "<1>string \"%s\", lenght exceeds expectations\n", string );
1573 DBG_LEAVE( DbgInfo );
1574 break;
1575 }
1576 c -= '0';
1577 if ( 0 <= c && c <= 9 ) value = base * value + c;
1578 else if ( base == 16 ) {
1579 c += '0';
1580 c |= 'A'^'a';
1581 c = c - 'a'+ 10;
1582 if ( 10 <= c && c <= 15 ) value = base * value + c;
1583 }
1584 }
1585 return value;
1586} // wl_atoi
1587
diff --git a/drivers/staging/wlags49_h2/wl_util.h b/drivers/staging/wlags49_h2/wl_util.h
index 16cd6c578adb..561e85b5c9b2 100644
--- a/drivers/staging/wlags49_h2/wl_util.h
+++ b/drivers/staging/wlags49_h2/wl_util.h
@@ -100,6 +100,4 @@ void wl_process_updated_record( struct wl_private *lp );
100void wl_process_assoc_status( struct wl_private *lp ); 100void wl_process_assoc_status( struct wl_private *lp );
101void wl_process_security_status( struct wl_private *lp ); 101void wl_process_security_status( struct wl_private *lp );
102 102
103unsigned int wl_atoi( char *string );
104
105#endif // __WL_UTIL_H__ 103#endif // __WL_UTIL_H__
diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig
index f44294b0d8dc..82fcc1665e92 100644
--- a/drivers/staging/wlan-ng/Kconfig
+++ b/drivers/staging/wlan-ng/Kconfig
@@ -1,6 +1,8 @@
1config PRISM2_USB 1config PRISM2_USB
2 tristate "Prism2.5/3 USB driver" 2 tristate "Prism2.5/3 USB driver"
3 depends on WLAN && USB && WIRELESS_EXT 3 depends on WLAN && USB
4 select WIRELESS_EXT
5 select WEXT_PRIV
4 default n 6 default n
5 ---help--- 7 ---help---
6 This is the wlan-ng prism 2.5/3 USB driver for a wide range of 8 This is the wlan-ng prism 2.5/3 USB driver for a wide range of
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 46cce8159e59..1fa42e01e8cb 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -61,17 +61,17 @@
61#include <linux/if_ether.h> 61#include <linux/if_ether.h>
62 62
63/*--- Mins & Maxs -----------------------------------*/ 63/*--- Mins & Maxs -----------------------------------*/
64#define HFA384x_PORTID_MAX ((u16)7) 64#define HFA384x_PORTID_MAX ((u16)7)
65#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1)) 65#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1))
66#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */ 66#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
67#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */ 67#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */
68#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK */ 68#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK*/
69#define HFA384x_SCANRESULT_MAX ((u16)31) 69#define HFA384x_SCANRESULT_MAX ((u16)31)
70#define HFA384x_HSCANRESULT_MAX ((u16)31) 70#define HFA384x_HSCANRESULT_MAX ((u16)31)
71#define HFA384x_CHINFORESULT_MAX ((u16)16) 71#define HFA384x_CHINFORESULT_MAX ((u16)16)
72#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ 72#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
73#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN 73#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN
74#define HFA384x_USB_RWMEM_MAXLEN 2048 74#define HFA384x_USB_RWMEM_MAXLEN 2048
75 75
76/*--- Support Constants -----------------------------*/ 76/*--- Support Constants -----------------------------*/
77#define HFA384x_PORTTYPE_IBSS ((u16)0) 77#define HFA384x_PORTTYPE_IBSS ((u16)0)
@@ -115,8 +115,8 @@
115 115
116/* Make a 32-bit flat address from AUX format 16-bit page and offset */ 116/* Make a 32-bit flat address from AUX format 16-bit page and offset */
117#define HFA384x_ADDR_AUX_MKFLAT(p, o) \ 117#define HFA384x_ADDR_AUX_MKFLAT(p, o) \
118 (((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \ 118 ((((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
119 ((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK)) 119 ((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK)))
120 120
121/* Make CMD format offset and page from a 32-bit flat address */ 121/* Make CMD format offset and page from a 32-bit flat address */
122#define HFA384x_ADDR_CMD_MKPAGE(f) \ 122#define HFA384x_ADDR_CMD_MKPAGE(f) \
@@ -135,12 +135,21 @@
135#define HFA384x_DLSTATE_FLASHENABLED 2 135#define HFA384x_DLSTATE_FLASHENABLED 2
136 136
137/*--- Register Field Masks --------------------------*/ 137/*--- Register Field Masks --------------------------*/
138#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8))) 138#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) \
139#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8))) 139 | BIT(12) | BIT(11) \
140 | BIT(10) | BIT(9) \
141 | BIT(8)))
142#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | \
143 BIT(8)))
140#define HFA384x_CMD_PROGMODE ((u16)(BIT(9) | BIT(8))) 144#define HFA384x_CMD_PROGMODE ((u16)(BIT(9) | BIT(8)))
141#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0))) 145#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | \
146 BIT(3) | BIT(2) | \
147 BIT(1) | BIT(0)))
142 148
143#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8))) 149#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) \
150 | BIT(12) | BIT(11) \
151 | BIT(10) | BIT(9) \
152 | BIT(8)))
144 153
145/*--- Command Code Constants --------------------------*/ 154/*--- Command Code Constants --------------------------*/
146/*--- Controller Commands --------------------------*/ 155/*--- Controller Commands --------------------------*/
@@ -244,8 +253,10 @@ Information RID Lengths: MAC Information
244 This is the length of JUST the DATA part of the RID (does not 253 This is the length of JUST the DATA part of the RID (does not
245 include the len or code fields) 254 include the len or code fields)
246--------------------------------------------------------------------*/ 255--------------------------------------------------------------------*/
247#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((u16)sizeof(hfa384x_dbmcommsquality_t)) 256#define HFA384x_RID_DBMCOMMSQUALITY_LEN \
248#define HFA384x_RID_JOINREQUEST_LEN ((u16)sizeof(hfa384x_JoinRequest_data_t)) 257 ((u16) sizeof(hfa384x_dbmcommsquality_t))
258#define HFA384x_RID_JOINREQUEST_LEN \
259 ((u16)sizeof(hfa384x_JoinRequest_data_t))
249 260
250/*-------------------------------------------------------------------- 261/*--------------------------------------------------------------------
251Information RIDs: Modem Information 262Information RIDs: Modem Information
@@ -322,9 +333,11 @@ PD Record codes
322 333
323/*--- Register Test/Get/Set Field macros ------------------------*/ 334/*--- Register Test/Get/Set Field macros ------------------------*/
324 335
325#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8)) 336#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8))
326#define HFA384x_CMD_MACPORT_SET(value) ((u16)HFA384x_CMD_AINFO_SET(value)) 337#define HFA384x_CMD_MACPORT_SET(value) \
327#define HFA384x_CMD_PROGMODE_SET(value) ((u16)HFA384x_CMD_AINFO_SET((u16)value)) 338 ((u16)HFA384x_CMD_AINFO_SET(value))
339#define HFA384x_CMD_PROGMODE_SET(value) \
340 ((u16)HFA384x_CMD_AINFO_SET((u16)value))
328#define HFA384x_CMD_CMDCODE_SET(value) ((u16)(value)) 341#define HFA384x_CMD_CMDCODE_SET(value) ((u16)(value))
329 342
330#define HFA384x_STATUS_RESULT_SET(value) (((u16)(value)) << 8) 343#define HFA384x_STATUS_RESULT_SET(value) (((u16)(value)) << 8)
@@ -402,7 +415,7 @@ typedef struct hfa384x_authenticateStation_data {
402/*-- Configuration Record: WPAData (data portion only) --*/ 415/*-- Configuration Record: WPAData (data portion only) --*/
403typedef struct hfa384x_WPAData { 416typedef struct hfa384x_WPAData {
404 u16 datalen; 417 u16 datalen;
405 u8 data[0]; // max 80 418 u8 data[0]; /* max 80 */
406} __attribute__ ((packed)) hfa384x_WPAData_t; 419} __attribute__ ((packed)) hfa384x_WPAData_t;
407 420
408/*-------------------------------------------------------------------- 421/*--------------------------------------------------------------------
@@ -479,7 +492,8 @@ Communication Frames: Field Masks for Transmit Frames
479#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT(1)) 492#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT(1))
480#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT(0)) 493#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT(0))
481/*-- Transmit Control Field --*/ 494/*-- Transmit Control Field --*/
482#define HFA384x_TX_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8))) 495#define HFA384x_TX_MACPORT ((u16)(BIT(10) | \
496 BIT(9) | BIT(8)))
483#define HFA384x_TX_STRUCTYPE ((u16)(BIT(4) | BIT(3))) 497#define HFA384x_TX_STRUCTYPE ((u16)(BIT(4) | BIT(3)))
484#define HFA384x_TX_TXEX ((u16)BIT(2)) 498#define HFA384x_TX_TXEX ((u16)BIT(2))
485#define HFA384x_TX_TXOK ((u16)BIT(1)) 499#define HFA384x_TX_TXOK ((u16)BIT(1))
@@ -496,7 +510,8 @@ Communication Frames: Test/Get/Set Field Values for Transmit Frames
496#define HFA384x_TX_SET(v, m, s) ((((u16)(v))<<((u16)(s)))&((u16)(m))) 510#define HFA384x_TX_SET(v, m, s) ((((u16)(v))<<((u16)(s)))&((u16)(m)))
497 511
498#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8) 512#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
499#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3) 513#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, \
514 HFA384x_TX_STRUCTYPE, 3)
500#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2) 515#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
501#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1) 516#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
502/*-------------------------------------------------------------------- 517/*--------------------------------------------------------------------
@@ -534,13 +549,17 @@ Communication Frames: Field Masks for Receive Frames
534--------------------------------------------------------------------*/ 549--------------------------------------------------------------------*/
535 550
536/*-- Status Fields --*/ 551/*-- Status Fields --*/
537#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8))) 552#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | \
553 BIT(9) | \
554 BIT(8)))
538#define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0)) 555#define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0))
539/*-------------------------------------------------------------------- 556/*--------------------------------------------------------------------
540Communication Frames: Test/Get/Set Field Values for Receive Frames 557Communication Frames: Test/Get/Set Field Values for Receive Frames
541--------------------------------------------------------------------*/ 558--------------------------------------------------------------------*/
542#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8)) 559#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) \
543#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) & HFA384x_RXSTATUS_FCSERR)) 560 & HFA384x_RXSTATUS_MACPORT) >> 8))
561#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) \
562 & HFA384x_RXSTATUS_FCSERR))
544/*-------------------------------------------------------------------- 563/*--------------------------------------------------------------------
545 FRAME STRUCTURES: Information Types and Information Frame Structures 564 FRAME STRUCTURES: Information Types and Information Frame Structures
546---------------------------------------------------------------------- 565----------------------------------------------------------------------
@@ -1133,7 +1152,7 @@ struct hfa384x;
1133 1152
1134typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *); 1153typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *);
1135 1154
1136typedef void (*ctlx_usercb_t) (struct hfa384x * hw, 1155typedef void (*ctlx_usercb_t) (struct hfa384x *hw,
1137 void *ctlxresult, void *usercb_data); 1156 void *ctlxresult, void *usercb_data);
1138 1157
1139typedef struct hfa384x_usbctlx { 1158typedef struct hfa384x_usbctlx {
@@ -1174,14 +1193,14 @@ typedef struct hfa484x_metacmd {
1174} hfa384x_metacmd_t; 1193} hfa384x_metacmd_t;
1175 1194
1176#define MAX_GRP_ADDR 32 1195#define MAX_GRP_ADDR 32
1177#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */ 1196#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */
1178 1197
1179#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */ 1198#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */
1180#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */ 1199#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */
1181#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */ 1200#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */
1182#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */ 1201#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */
1183#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */ 1202#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */
1184#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */ 1203#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */
1185 1204
1186/* XXX These are going away ASAP */ 1205/* XXX These are going away ASAP */
1187typedef struct prism2sta_authlist { 1206typedef struct prism2sta_authlist {
@@ -1294,10 +1313,23 @@ typedef struct hfa384x {
1294 hfa384x_caplevel_t cap_sup_ap; 1313 hfa384x_caplevel_t cap_sup_ap;
1295 1314
1296 /* Actor compatibility ranges */ 1315 /* Actor compatibility ranges */
1297 hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */ 1316 hfa384x_caplevel_t cap_act_pri_cfi; /*
1298 hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */ 1317 * pri f/w to controller
1318 * interface
1319 */
1320
1321 hfa384x_caplevel_t cap_act_sta_cfi; /*
1322 * sta f/w to controller
1323 * interface
1324 */
1325
1299 hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */ 1326 hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */
1300 hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */ 1327
1328 hfa384x_caplevel_t cap_act_ap_cfi; /*
1329 * ap f/w to controller
1330 * interface
1331 */
1332
1301 hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */ 1333 hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */
1302 1334
1303 u32 psusercount; /* Power save user count. */ 1335 u32 psusercount; /* Power save user count. */
@@ -1320,25 +1352,25 @@ typedef struct hfa384x {
1320 1352
1321} hfa384x_t; 1353} hfa384x_t;
1322 1354
1323void hfa384x_create(hfa384x_t * hw, struct usb_device *usb); 1355void hfa384x_create(hfa384x_t *hw, struct usb_device *usb);
1324void hfa384x_destroy(hfa384x_t * hw); 1356void hfa384x_destroy(hfa384x_t *hw);
1325 1357
1326int 1358int
1327hfa384x_corereset(hfa384x_t * hw, int holdtime, int settletime, int genesis); 1359hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis);
1328int hfa384x_drvr_commtallies(hfa384x_t * hw); 1360int hfa384x_drvr_commtallies(hfa384x_t *hw);
1329int hfa384x_drvr_disable(hfa384x_t * hw, u16 macport); 1361int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
1330int hfa384x_drvr_enable(hfa384x_t * hw, u16 macport); 1362int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
1331int hfa384x_drvr_flashdl_enable(hfa384x_t * hw); 1363int hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
1332int hfa384x_drvr_flashdl_disable(hfa384x_t * hw); 1364int hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
1333int hfa384x_drvr_flashdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len); 1365int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
1334int hfa384x_drvr_getconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len); 1366int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
1335int hfa384x_drvr_ramdl_enable(hfa384x_t * hw, u32 exeaddr); 1367int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
1336int hfa384x_drvr_ramdl_disable(hfa384x_t * hw); 1368int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
1337int hfa384x_drvr_ramdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len); 1369int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
1338int hfa384x_drvr_readpda(hfa384x_t * hw, void *buf, unsigned int len); 1370int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
1339int hfa384x_drvr_setconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len); 1371int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
1340 1372
1341static inline int hfa384x_drvr_getconfig16(hfa384x_t * hw, u16 rid, void *val) 1373static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
1342{ 1374{
1343 int result = 0; 1375 int result = 0;
1344 result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16)); 1376 result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
@@ -1347,46 +1379,46 @@ static inline int hfa384x_drvr_getconfig16(hfa384x_t * hw, u16 rid, void *val)
1347 return result; 1379 return result;
1348} 1380}
1349 1381
1350static inline int hfa384x_drvr_setconfig16(hfa384x_t * hw, u16 rid, u16 val) 1382static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
1351{ 1383{
1352 u16 value = cpu_to_le16(val); 1384 u16 value = cpu_to_le16(val);
1353 return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); 1385 return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
1354} 1386}
1355 1387
1356int 1388int
1357hfa384x_drvr_getconfig_async(hfa384x_t * hw, 1389hfa384x_drvr_getconfig_async(hfa384x_t *hw,
1358 u16 rid, ctlx_usercb_t usercb, void *usercb_data); 1390 u16 rid, ctlx_usercb_t usercb, void *usercb_data);
1359 1391
1360int 1392int
1361hfa384x_drvr_setconfig_async(hfa384x_t * hw, 1393hfa384x_drvr_setconfig_async(hfa384x_t *hw,
1362 u16 rid, 1394 u16 rid,
1363 void *buf, 1395 void *buf,
1364 u16 len, ctlx_usercb_t usercb, void *usercb_data); 1396 u16 len, ctlx_usercb_t usercb, void *usercb_data);
1365 1397
1366static inline int 1398static inline int
1367hfa384x_drvr_setconfig16_async(hfa384x_t * hw, u16 rid, u16 val) 1399hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
1368{ 1400{
1369 u16 value = cpu_to_le16(val); 1401 u16 value = cpu_to_le16(val);
1370 return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), 1402 return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
1371 NULL, NULL); 1403 NULL, NULL);
1372} 1404}
1373 1405
1374int hfa384x_drvr_start(hfa384x_t * hw); 1406int hfa384x_drvr_start(hfa384x_t *hw);
1375int hfa384x_drvr_stop(hfa384x_t * hw); 1407int hfa384x_drvr_stop(hfa384x_t *hw);
1376int 1408int
1377hfa384x_drvr_txframe(hfa384x_t * hw, struct sk_buff *skb, 1409hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
1378 p80211_hdr_t * p80211_hdr, p80211_metawep_t * p80211_wep); 1410 p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
1379void hfa384x_tx_timeout(wlandevice_t * wlandev); 1411void hfa384x_tx_timeout(wlandevice_t *wlandev);
1380 1412
1381int hfa384x_cmd_initialize(hfa384x_t * hw); 1413int hfa384x_cmd_initialize(hfa384x_t *hw);
1382int hfa384x_cmd_enable(hfa384x_t * hw, u16 macport); 1414int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
1383int hfa384x_cmd_disable(hfa384x_t * hw, u16 macport); 1415int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
1384int hfa384x_cmd_allocate(hfa384x_t * hw, u16 len); 1416int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
1385int hfa384x_cmd_monitor(hfa384x_t * hw, u16 enable); 1417int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
1386int 1418int
1387hfa384x_cmd_download(hfa384x_t * hw, 1419hfa384x_cmd_download(hfa384x_t *hw,
1388 u16 mode, u16 lowaddr, u16 highaddr, u16 codelen); 1420 u16 mode, u16 lowaddr, u16 highaddr, u16 codelen);
1389 1421
1390#endif /* __KERNEL__ */ 1422#endif /*__KERNEL__ */
1391 1423
1392#endif /* _HFA384x_H */ 1424#endif /*_HFA384x_H */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 925678babd9e..5df56f0238d6 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -52,7 +52,7 @@
52* around the register accesses. The next higher level represents C-callable 52* around the register accesses. The next higher level represents C-callable
53* prism2 API functions that match the Intersil documentation as closely 53* prism2 API functions that match the Intersil documentation as closely
54* as is reasonable. The next higher layer implements common sequences 54* as is reasonable. The next higher layer implements common sequences
55* of invokations of the API layer (e.g. write to bap, followed by cmd). 55* of invocations of the API layer (e.g. write to bap, followed by cmd).
56* 56*
57* Common sequences: 57* Common sequences:
58* hfa384x_drvr_xxx Highest level abstractions provided by the 58* hfa384x_drvr_xxx Highest level abstractions provided by the
@@ -118,15 +118,15 @@
118#include <linux/wireless.h> 118#include <linux/wireless.h>
119#include <linux/netdevice.h> 119#include <linux/netdevice.h>
120#include <linux/timer.h> 120#include <linux/timer.h>
121#include <asm/io.h> 121#include <linux/io.h>
122#include <linux/delay.h> 122#include <linux/delay.h>
123#include <asm/byteorder.h> 123#include <asm/byteorder.h>
124#include <asm/bitops.h> 124#include <linux/bitops.h>
125#include <linux/list.h> 125#include <linux/list.h>
126#include <linux/usb.h> 126#include <linux/usb.h>
127#include <linux/byteorder/generic.h> 127#include <linux/byteorder/generic.h>
128 128
129#define SUBMIT_URB(u,f) usb_submit_urb(u,f) 129#define SUBMIT_URB(u, f) usb_submit_urb(u, f)
130 130
131#include "p80211types.h" 131#include "p80211types.h"
132#include "p80211hdr.h" 132#include "p80211hdr.h"
@@ -627,7 +627,7 @@ static hfa384x_usbctlx_t *usbctlx_alloc(void)
627{ 627{
628 hfa384x_usbctlx_t *ctlx; 628 hfa384x_usbctlx_t *ctlx;
629 629
630 ctlx = kmalloc(sizeof(*ctlx), in_interrupt()? GFP_ATOMIC : GFP_KERNEL); 630 ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
631 if (ctlx != NULL) { 631 if (ctlx != NULL) {
632 memset(ctlx, 0, sizeof(*ctlx)); 632 memset(ctlx, 0, sizeof(*ctlx));
633 init_completion(&ctlx->done); 633 init_completion(&ctlx->done);
@@ -675,7 +675,7 @@ struct usbctlx_cmd_completor {
675}; 675};
676typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t; 676typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t;
677 677
678static int usbctlx_cmd_completor_fn(usbctlx_completor_t * head) 678static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head)
679{ 679{
680 usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head; 680 usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head;
681 return usbctlx_get_status(complete->cmdresp, complete->result); 681 return usbctlx_get_status(complete->cmdresp, complete->result);
@@ -1909,18 +1909,19 @@ int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
1909 return -EINVAL; 1909 return -EINVAL;
1910 1910
1911 /* Retrieve the buffer loc&size and timeout */ 1911 /* Retrieve the buffer loc&size and timeout */
1912 if ((result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, 1912 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
1913 &(hw->bufinfo), 1913 &(hw->bufinfo), sizeof(hw->bufinfo));
1914 sizeof(hw->bufinfo)))) { 1914 if (result)
1915 return result; 1915 return result;
1916 } 1916
1917 hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page); 1917 hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page);
1918 hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset); 1918 hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset);
1919 hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len); 1919 hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len);
1920 if ((result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, 1920 result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
1921 &(hw->dltimeout)))) { 1921 &(hw->dltimeout));
1922 if (result)
1922 return result; 1923 return result;
1923 } 1924
1924 hw->dltimeout = le16_to_cpu(hw->dltimeout); 1925 hw->dltimeout = le16_to_cpu(hw->dltimeout);
1925 1926
1926 pr_debug("flashdl_enable\n"); 1927 pr_debug("flashdl_enable\n");
@@ -3071,9 +3072,9 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw)
3071 hfa384x_ctlxout_callback, hw); 3072 hfa384x_ctlxout_callback, hw);
3072 hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK; 3073 hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
3073 3074
3074 /* Now submit the URB and update the CTLX's state 3075 /* Now submit the URB and update the CTLX's state */
3075 */ 3076 result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC);
3076 if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) { 3077 if (result == 0) {
3077 /* This CTLX is now running on the active queue */ 3078 /* This CTLX is now running on the active queue */
3078 head->state = CTLX_REQ_SUBMITTED; 3079 head->state = CTLX_REQ_SUBMITTED;
3079 3080
@@ -3599,7 +3600,8 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
3599 skblen - sizeof(p80211_caphdr_t)); 3600 skblen - sizeof(p80211_caphdr_t));
3600 } 3601 }
3601 3602
3602 if ((skb = dev_alloc_skb(skblen)) == NULL) { 3603 skb = dev_alloc_skb(skblen);
3604 if (skb == NULL) {
3603 printk(KERN_ERR 3605 printk(KERN_ERR
3604 "alloc_skb failed trying to allocate %d bytes\n", 3606 "alloc_skb failed trying to allocate %d bytes\n",
3605 skblen); 3607 skblen);
@@ -3642,7 +3644,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
3642 /* check for unencrypted stuff if WEP bit set. */ 3644 /* check for unencrypted stuff if WEP bit set. */
3643 if (*(datap - hdrlen + 1) & 0x40) /* wep set */ 3645 if (*(datap - hdrlen + 1) & 0x40) /* wep set */
3644 if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa)) 3646 if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa))
3645 *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header! 3647 *(datap - hdrlen + 1) &= 0xbf; /* clear wep; it's the 802.2 header! */
3646 } 3648 }
3647 3649
3648 if (hw->sniff_fcs) { 3650 if (hw->sniff_fcs) {
@@ -3870,9 +3872,9 @@ retry:
3870 3872
3871delresp: 3873delresp:
3872 if (delete_resptimer) { 3874 if (delete_resptimer) {
3873 if ((timer_ok = del_timer(&hw->resptimer)) != 0) { 3875 timer_ok = del_timer(&hw->resptimer);
3876 if (timer_ok != 0)
3874 hw->resp_timer_done = 1; 3877 hw->resp_timer_done = 1;
3875 }
3876 } 3878 }
3877 3879
3878 spin_unlock_irqrestore(&hw->ctlxq.lock, flags); 3880 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 5952c671073f..a1605fbc8092 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -206,12 +206,11 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
206 /* XXXX need to pick keynum other than default? */ 206 /* XXXX need to pick keynum other than default? */
207 207
208 p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); 208 p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
209 209 foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
210 if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, 210 skb->len,
211 skb->len, 211 (wlandev->hostwep &HOSTWEP_DEFAULTKEY_MASK),
212 (wlandev->hostwep & 212 p80211_wep->iv, p80211_wep->icv);
213 HOSTWEP_DEFAULTKEY_MASK), 213 if (foo) {
214 p80211_wep->iv, p80211_wep->icv))) {
215 printk(KERN_WARNING 214 printk(KERN_WARNING
216 "Host en-WEP failed, dropping frame (%d).\n", 215 "Host en-WEP failed, dropping frame (%d).\n",
217 foo); 216 foo);
@@ -323,11 +322,12 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
323 skb->len); 322 skb->len);
324 return 1; 323 return 1;
325 } 324 }
326 if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4, 325 foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
327 payload_length - 8, -1, 326 payload_length - 8, -1,
328 skb->data + payload_offset, 327 skb->data + payload_offset,
329 skb->data + payload_offset + 328 skb->data + payload_offset +
330 payload_length - 4))) { 329 payload_length - 4);
330 if (foo) {
331 /* de-wep failed, drop skb. */ 331 /* de-wep failed, drop skb. */
332 pr_debug("Host de-WEP failed, dropping frame (%d).\n", 332 pr_debug("Host de-WEP failed, dropping frame (%d).\n",
333 foo); 333 foo);
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
index 0c62df19fa7f..6fe163be24f6 100644
--- a/drivers/staging/wlan-ng/p80211conv.h
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -153,8 +153,8 @@ struct wlandevice;
153int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, 153int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
154 struct sk_buff *skb); 154 struct sk_buff *skb);
155int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv, 155int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
156 struct sk_buff *skb, p80211_hdr_t * p80211_hdr, 156 struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
157 p80211_metawep_t * p80211_wep); 157 p80211_metawep_t *p80211_wep);
158 158
159int p80211_stt_findproto(u16 proto); 159int p80211_stt_findproto(u16 proto);
160 160
diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h
index da8b6f53c74f..0ccfba1294de 100644
--- a/drivers/staging/wlan-ng/p80211metadef.h
+++ b/drivers/staging/wlan-ng/p80211metadef.h
@@ -190,9 +190,9 @@
190 (P80211DID_MKSECTION(2) | \ 190 (P80211DID_MKSECTION(2) | \
191 P80211DID_MKGROUP(1)) 191 P80211DID_MKGROUP(1))
192#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \ 192#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \
193 (P80211DID_MKSECTION(2) | \ 193 (P80211DID_MKSECTION(2) | \
194 P80211DID_MKGROUP(1) | \ 194 P80211DID_MKGROUP(1) | \
195 P80211DID_MKITEM(1) | 0x18000000) 195 P80211DID_MKITEM(1) | 0x18000000)
196#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \ 196#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \
197 (P80211DID_MKSECTION(2) | \ 197 (P80211DID_MKSECTION(2) | \
198 P80211DID_MKGROUP(1) | \ 198 P80211DID_MKGROUP(1) | \
@@ -210,18 +210,18 @@
210 P80211DID_MKGROUP(1) | \ 210 P80211DID_MKGROUP(1) | \
211 P80211DID_MKITEM(5) | 0x18000000) 211 P80211DID_MKITEM(5) | 0x18000000)
212#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \ 212#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \
213 (P80211DID_MKSECTION(2) | \ 213 (P80211DID_MKSECTION(2) | \
214 P80211DID_MKGROUP(1) | \ 214 P80211DID_MKGROUP(1) | \
215 P80211DID_MKITEM(6) | 0x10000000) 215 P80211DID_MKITEM(6) | 0x10000000)
216#define DIDmib_cat_dot11phy \ 216#define DIDmib_cat_dot11phy \
217 P80211DID_MKSECTION(3) 217 P80211DID_MKSECTION(3)
218#define DIDmib_dot11phy_dot11PhyOperationTable \ 218#define DIDmib_dot11phy_dot11PhyOperationTable \
219 (P80211DID_MKSECTION(3) | \ 219 (P80211DID_MKSECTION(3) | \
220 P80211DID_MKGROUP(1)) 220 P80211DID_MKGROUP(1))
221#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \ 221#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \
222 (P80211DID_MKSECTION(3) | \ 222 (P80211DID_MKSECTION(3) | \
223 P80211DID_MKGROUP(3) | \ 223 P80211DID_MKGROUP(3) | \
224 P80211DID_MKITEM(10) | 0x18000000) 224 P80211DID_MKITEM(10) | 0x18000000)
225#define DIDmib_dot11phy_dot11PhyDSSSTable \ 225#define DIDmib_dot11phy_dot11PhyDSSSTable \
226 (P80211DID_MKSECTION(3) | \ 226 (P80211DID_MKSECTION(3) | \
227 P80211DID_MKGROUP(5)) 227 P80211DID_MKGROUP(5))
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
index 14cdc86d1676..deb52f5fd780 100644
--- a/drivers/staging/wlan-ng/p80211mgmt.h
+++ b/drivers/staging/wlan-ng/p80211mgmt.h
@@ -100,7 +100,7 @@
100#ifndef _P80211MGMT_H 100#ifndef _P80211MGMT_H
101#define _P80211MGMT_H 101#define _P80211MGMT_H
102 102
103#ifndef _P80211HDR_H 103#ifndef _P80211HDR_H
104#include "p80211hdr.h" 104#include "p80211hdr.h"
105#endif 105#endif
106 106
@@ -496,25 +496,25 @@ typedef struct wlan_fr_deauthen {
496 496
497} wlan_fr_deauthen_t; 497} wlan_fr_deauthen_t;
498 498
499void wlan_mgmt_encode_beacon(wlan_fr_beacon_t * f); 499void wlan_mgmt_encode_beacon(wlan_fr_beacon_t *f);
500void wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f); 500void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f);
501void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t * f); 501void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t *f);
502void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t * f); 502void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f);
503void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t * f); 503void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t *f);
504void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f); 504void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f);
505void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t * f); 505void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t *f);
506void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t * f); 506void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f);
507void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t * f); 507void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t *f);
508void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f); 508void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f);
509void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t * f); 509void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t *f);
510void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t * f); 510void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f);
511void wlan_mgmt_encode_probereq(wlan_fr_probereq_t * f); 511void wlan_mgmt_encode_probereq(wlan_fr_probereq_t *f);
512void wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f); 512void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f);
513void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t * f); 513void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t *f);
514void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f); 514void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f);
515void wlan_mgmt_encode_authen(wlan_fr_authen_t * f); 515void wlan_mgmt_encode_authen(wlan_fr_authen_t *f);
516void wlan_mgmt_decode_authen(wlan_fr_authen_t * f); 516void wlan_mgmt_decode_authen(wlan_fr_authen_t *f);
517void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t * f); 517void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t *f);
518void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t * f); 518void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f);
519 519
520#endif /* _P80211MGMT_H */ 520#endif /* _P80211MGMT_H */
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 22424c8903ee..763ab1187a1c 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -586,7 +586,8 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
586 } 586 }
587 587
588 /* Allocate a buf of size req->len */ 588 /* Allocate a buf of size req->len */
589 if ((msgbuf = kmalloc(req->len, GFP_KERNEL))) { 589 msgbuf = kmalloc(req->len, GFP_KERNEL);
590 if (msgbuf) {
590 if (copy_from_user(msgbuf, (void __user *)req->data, req->len)) 591 if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
591 result = -EFAULT; 592 result = -EFAULT;
592 else 593 else
@@ -646,7 +647,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
646 647
647 /* Set up some convenience pointers. */ 648 /* Set up some convenience pointers. */
648 mibattr = &dot11req.mibattribute; 649 mibattr = &dot11req.mibattribute;
649 macaddr = (p80211item_pstr6_t *) & mibattr->data; 650 macaddr = (p80211item_pstr6_t *) &mibattr->data;
650 resultcode = &dot11req.resultcode; 651 resultcode = &dot11req.resultcode;
651 652
652 /* Set up a dot11req_mibset */ 653 /* Set up a dot11req_mibset */
@@ -674,7 +675,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
674 resultcode->data = 0; 675 resultcode->data = 0;
675 676
676 /* now fire the request */ 677 /* now fire the request */
677 result = p80211req_dorequest(dev->ml_priv, (u8 *) & dot11req); 678 result = p80211req_dorequest(dev->ml_priv, (u8 *) &dot11req);
678 679
679 /* If the request wasn't successful, report an error and don't 680 /* If the request wasn't successful, report an error and don't
680 * change the netdev address 681 * change the netdev address
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index 8bd9dfb3b9b4..3c8c64800567 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -179,16 +179,16 @@ typedef struct wlandevice {
179 unsigned int ethconv; 179 unsigned int ethconv;
180 180
181 /* device methods (init by MSD, used by p80211 */ 181 /* device methods (init by MSD, used by p80211 */
182 int (*open) (struct wlandevice * wlandev); 182 int (*open) (struct wlandevice *wlandev);
183 int (*close) (struct wlandevice * wlandev); 183 int (*close) (struct wlandevice *wlandev);
184 void (*reset) (struct wlandevice * wlandev); 184 void (*reset) (struct wlandevice *wlandev);
185 int (*txframe) (struct wlandevice * wlandev, struct sk_buff * skb, 185 int (*txframe) (struct wlandevice *wlandev, struct sk_buff *skb,
186 p80211_hdr_t * p80211_hdr, 186 p80211_hdr_t *p80211_hdr,
187 p80211_metawep_t * p80211_wep); 187 p80211_metawep_t *p80211_wep);
188 int (*mlmerequest) (struct wlandevice * wlandev, p80211msg_t * msg); 188 int (*mlmerequest) (struct wlandevice *wlandev, p80211msg_t *msg);
189 int (*set_multicast_list) (struct wlandevice * wlandev, 189 int (*set_multicast_list) (struct wlandevice *wlandev,
190 netdevice_t * dev); 190 netdevice_t *dev);
191 void (*tx_timeout) (struct wlandevice * wlandev); 191 void (*tx_timeout) (struct wlandevice *wlandev);
192 192
193 /* 802.11 State */ 193 /* 802.11 State */
194 u8 bssid[WLAN_BSSID_LEN]; 194 u8 bssid[WLAN_BSSID_LEN];
@@ -227,16 +227,16 @@ typedef struct wlandevice {
227} wlandevice_t; 227} wlandevice_t;
228 228
229/* WEP stuff */ 229/* WEP stuff */
230int wep_change_key(wlandevice_t * wlandev, int keynum, u8 * key, int keylen); 230int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen);
231int wep_decrypt(wlandevice_t * wlandev, u8 * buf, u32 len, int key_override, 231int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
232 u8 * iv, u8 * icv); 232 u8 *iv, u8 *icv);
233int wep_encrypt(wlandevice_t * wlandev, u8 * buf, u8 * dst, u32 len, int keynum, 233int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
234 u8 * iv, u8 * icv); 234 u8 *iv, u8 *icv);
235 235
236int wlan_setup(wlandevice_t * wlandev); 236int wlan_setup(wlandevice_t *wlandev);
237int wlan_unsetup(wlandevice_t * wlandev); 237int wlan_unsetup(wlandevice_t *wlandev);
238int register_wlandev(wlandevice_t * wlandev); 238int register_wlandev(wlandevice_t *wlandev);
239int unregister_wlandev(wlandevice_t * wlandev); 239int unregister_wlandev(wlandevice_t *wlandev);
240void p80211netdev_rx(wlandevice_t * wlandev, struct sk_buff *skb); 240void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
241void p80211netdev_hwremoved(wlandevice_t * wlandev); 241void p80211netdev_hwremoved(wlandevice_t *wlandev);
242#endif 242#endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index c88156cdf681..c2e95f166828 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -94,7 +94,7 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev,
94* Potentially blocks the caller, so it's a good idea to 94* Potentially blocks the caller, so it's a good idea to
95* not call this function from an interrupt context. 95* not call this function from an interrupt context.
96----------------------------------------------------------------*/ 96----------------------------------------------------------------*/
97int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf) 97int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
98{ 98{
99 int result = 0; 99 int result = 0;
100 p80211msg_t *msg = (p80211msg_t *) msgbuf; 100 p80211msg_t *msg = (p80211msg_t *) msgbuf;
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
index 5d9176762ba7..a95a45a6814d 100644
--- a/drivers/staging/wlan-ng/p80211req.h
+++ b/drivers/staging/wlan-ng/p80211req.h
@@ -48,6 +48,6 @@
48#ifndef _LINUX_P80211REQ_H 48#ifndef _LINUX_P80211REQ_H
49#define _LINUX_P80211REQ_H 49#define _LINUX_P80211REQ_H
50 50
51int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf); 51int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
52 52
53#endif 53#endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 2b83ab0c711b..41a99c59c6c5 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -168,12 +168,12 @@
168 P80211DID_MASK_ISTABLE, \ 168 P80211DID_MASK_ISTABLE, \
169 P80211DID_LSB_ISTABLE) 169 P80211DID_LSB_ISTABLE)
170 170
171#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \ 171#define P80211DID_MKID(s, g, i, n, t, a) (P80211DID_MKSECTION(s) | \
172 P80211DID_MKGROUP(g) | \ 172 P80211DID_MKGROUP(g) | \
173 P80211DID_MKITEM(i) | \ 173 P80211DID_MKITEM(i) | \
174 P80211DID_MKINDEX(n) | \ 174 P80211DID_MKINDEX(n) | \
175 P80211DID_MKISTABLE(t) | \ 175 P80211DID_MKISTABLE(t) | \
176 (a)) 176 (a))
177 177
178#define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m)) 178#define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m))
179 179
@@ -340,11 +340,11 @@ struct catlistitem;
340/* metadata items. Some components may choose to use more, */ 340/* metadata items. Some components may choose to use more, */
341/* less or different metadata items. */ 341/* less or different metadata items. */
342 342
343typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 * itembuf, 343typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 *itembuf,
344 char *textbuf); 344 char *textbuf);
345typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 * itembuf, 345typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 *itembuf,
346 char *textbuf); 346 char *textbuf);
347typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 * itembuf); 347typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf);
348 348
349/*----------------------------------------------------------------*/ 349/*----------------------------------------------------------------*/
350/* Enumeration Lists */ 350/* Enumeration Lists */
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
index 74d8022adb24..2fa1dfa23783 100644
--- a/drivers/staging/wlan-ng/p80211wext.c
+++ b/drivers/staging/wlan-ng/p80211wext.c
@@ -46,8 +46,8 @@
46#include <linux/wireless.h> 46#include <linux/wireless.h>
47#include <net/iw_handler.h> 47#include <net/iw_handler.h>
48#include <linux/if_arp.h> 48#include <linux/if_arp.h>
49#include <asm/bitops.h> 49#include <linux/bitops.h>
50#include <asm/uaccess.h> 50#include <linux/uaccess.h>
51#include <asm/byteorder.h> 51#include <asm/byteorder.h>
52#include <linux/if_ether.h> 52#include <linux/if_ether.h>
53#include <linux/bitops.h> 53#include <linux/bitops.h>
@@ -134,10 +134,11 @@ static int p80211wext_dorequest(wlandevice_t *wlandev, u32 did, u32 data)
134 int result; 134 int result;
135 135
136 msg.msgcode = DIDmsg_dot11req_mibset; 136 msg.msgcode = DIDmsg_dot11req_mibset;
137 memset(&mibitem, 0, sizeof(mibitem));
137 mibitem.did = did; 138 mibitem.did = did;
138 mibitem.data = data; 139 mibitem.data = data;
139 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 140 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
140 result = p80211req_dorequest(wlandev, (u8 *) & msg); 141 result = p80211req_dorequest(wlandev, (u8 *) &msg);
141 142
142 return result; 143 return result;
143} 144}
@@ -174,7 +175,7 @@ static int p80211wext_autojoin(wlandevice_t *wlandev)
174 memcpy(msg.ssid.data.data, ssid, data.length); 175 memcpy(msg.ssid.data.data, ssid, data.length);
175 msg.ssid.data.len = data.length; 176 msg.ssid.data.len = data.length;
176 177
177 result = p80211req_dorequest(wlandev, (u8 *) & msg); 178 result = p80211req_dorequest(wlandev, (u8 *) &msg);
178 179
179 if (result) { 180 if (result) {
180 err = -EFAULT; 181 err = -EFAULT;
@@ -211,7 +212,7 @@ struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev)
211 if (wlandev->mlmerequest == NULL) 212 if (wlandev->mlmerequest == NULL)
212 return NULL; 213 return NULL;
213 214
214 retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) & quality); 215 retval = wlandev->mlmerequest(wlandev, (p80211msg_t *) &quality);
215 216
216 wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */ 217 wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
217 wstats->qual.level = quality.level.data; /* instant signal level */ 218 wstats->qual.level = quality.level.data; /* instant signal level */
@@ -269,9 +270,10 @@ static int p80211wext_giwfreq(netdevice_t *dev,
269 int err = 0; 270 int err = 0;
270 271
271 msg.msgcode = DIDmsg_dot11req_mibget; 272 msg.msgcode = DIDmsg_dot11req_mibget;
273 memset(&mibitem, 0, sizeof(mibitem));
272 mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; 274 mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
273 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 275 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
274 result = p80211req_dorequest(wlandev, (u8 *) & msg); 276 result = p80211req_dorequest(wlandev, (u8 *) &msg);
275 277
276 if (result) { 278 if (result) {
277 err = -EFAULT; 279 err = -EFAULT;
@@ -309,6 +311,7 @@ static int p80211wext_siwfreq(netdevice_t *dev,
309 } 311 }
310 312
311 msg.msgcode = DIDmsg_dot11req_mibset; 313 msg.msgcode = DIDmsg_dot11req_mibset;
314 memset(&mibitem, 0, sizeof(mibitem));
312 mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; 315 mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
313 mibitem.status = P80211ENUM_msgitem_status_data_ok; 316 mibitem.status = P80211ENUM_msgitem_status_data_ok;
314 317
@@ -318,7 +321,7 @@ static int p80211wext_siwfreq(netdevice_t *dev,
318 mibitem.data = p80211_mhz_to_channel(freq->m); 321 mibitem.data = p80211_mhz_to_channel(freq->m);
319 322
320 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 323 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
321 result = p80211req_dorequest(wlandev, (u8 *) & msg); 324 result = p80211req_dorequest(wlandev, (u8 *) &msg);
322 325
323 if (result) { 326 if (result) {
324 err = -EFAULT; 327 err = -EFAULT;
@@ -396,10 +399,11 @@ static int p80211wext_siwmode(netdevice_t *dev,
396 399
397 /* Set Operation mode to the PORT TYPE RID */ 400 /* Set Operation mode to the PORT TYPE RID */
398 msg.msgcode = DIDmsg_dot11req_mibset; 401 msg.msgcode = DIDmsg_dot11req_mibset;
402 memset(&mibitem, 0, sizeof(mibitem));
399 mibitem.did = DIDmib_p2_p2Static_p2CnfPortType; 403 mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
400 mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1; 404 mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
401 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 405 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
402 result = p80211req_dorequest(wlandev, (u8 *) & msg); 406 result = p80211req_dorequest(wlandev, (u8 *) &msg);
403 407
404 if (result) 408 if (result)
405 err = -EFAULT; 409 err = -EFAULT;
@@ -549,14 +553,14 @@ static int p80211wext_siwencode(netdevice_t *dev,
549 } 553 }
550 554
551 /* Check the Key index first. */ 555 /* Check the Key index first. */
552 if ((i = (erq->flags & IW_ENCODE_INDEX))) { 556 i = (erq->flags & IW_ENCODE_INDEX);
553 557 if (i) {
554 if ((i < 1) || (i > NUM_WEPKEYS)) { 558 if ((i < 1) || (i > NUM_WEPKEYS)) {
555 err = -EINVAL; 559 err = -EINVAL;
556 goto exit; 560 goto exit;
557 } else 561 } else {
558 i--; 562 i--;
559 563 }
560 /* Set current key number only if no keys are given */ 564 /* Set current key number only if no keys are given */
561 if (erq->flags & IW_ENCODE_NOKEY) { 565 if (erq->flags & IW_ENCODE_NOKEY) {
562 result = 566 result =
@@ -621,7 +625,7 @@ static int p80211wext_siwencode(netdevice_t *dev,
621 625
622 msg.msgcode = DIDmsg_dot11req_mibset; 626 msg.msgcode = DIDmsg_dot11req_mibset;
623 memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr)); 627 memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
624 result = p80211req_dorequest(wlandev, (u8 *) & msg); 628 result = p80211req_dorequest(wlandev, (u8 *) &msg);
625 629
626 if (result) { 630 if (result) {
627 err = -EFAULT; 631 err = -EFAULT;
@@ -729,7 +733,7 @@ static int p80211wext_siwessid(netdevice_t *dev,
729 msg.ssid.data.len = length; 733 msg.ssid.data.len = length;
730 734
731 pr_debug("autojoin_ssid for %s \n", essid); 735 pr_debug("autojoin_ssid for %s \n", essid);
732 result = p80211req_dorequest(wlandev, (u8 *) & msg); 736 result = p80211req_dorequest(wlandev, (u8 *) &msg);
733 pr_debug("autojoin_ssid %d\n", result); 737 pr_debug("autojoin_ssid %d\n", result);
734 738
735 if (result) { 739 if (result) {
@@ -771,9 +775,10 @@ static int p80211wext_giwrate(netdevice_t *dev,
771 int err = 0; 775 int err = 0;
772 776
773 msg.msgcode = DIDmsg_dot11req_mibget; 777 msg.msgcode = DIDmsg_dot11req_mibget;
778 memset(&mibitem, 0, sizeof(mibitem));
774 mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate; 779 mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
775 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 780 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
776 result = p80211req_dorequest(wlandev, (u8 *) & msg); 781 result = p80211req_dorequest(wlandev, (u8 *) &msg);
777 782
778 if (result) { 783 if (result) {
779 err = -EFAULT; 784 err = -EFAULT;
@@ -822,9 +827,10 @@ static int p80211wext_giwrts(netdevice_t *dev,
822 int err = 0; 827 int err = 0;
823 828
824 msg.msgcode = DIDmsg_dot11req_mibget; 829 msg.msgcode = DIDmsg_dot11req_mibget;
830 memset(&mibitem, 0, sizeof(mibitem));
825 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; 831 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
826 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 832 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
827 result = p80211req_dorequest(wlandev, (u8 *) & msg); 833 result = p80211req_dorequest(wlandev, (u8 *) &msg);
828 834
829 if (result) { 835 if (result) {
830 err = -EFAULT; 836 err = -EFAULT;
@@ -857,6 +863,7 @@ static int p80211wext_siwrts(netdevice_t *dev,
857 } 863 }
858 864
859 msg.msgcode = DIDmsg_dot11req_mibget; 865 msg.msgcode = DIDmsg_dot11req_mibget;
866 memset(&mibitem, 0, sizeof(mibitem));
860 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; 867 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
861 if (rts->disabled) 868 if (rts->disabled)
862 mibitem.data = 2347; 869 mibitem.data = 2347;
@@ -864,7 +871,7 @@ static int p80211wext_siwrts(netdevice_t *dev,
864 mibitem.data = rts->value; 871 mibitem.data = rts->value;
865 872
866 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 873 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
867 result = p80211req_dorequest(wlandev, (u8 *) & msg); 874 result = p80211req_dorequest(wlandev, (u8 *) &msg);
868 875
869 if (result) { 876 if (result) {
870 err = -EFAULT; 877 err = -EFAULT;
@@ -886,10 +893,11 @@ static int p80211wext_giwfrag(netdevice_t *dev,
886 int err = 0; 893 int err = 0;
887 894
888 msg.msgcode = DIDmsg_dot11req_mibget; 895 msg.msgcode = DIDmsg_dot11req_mibget;
896 memset(&mibitem, 0, sizeof(mibitem));
889 mibitem.did = 897 mibitem.did =
890 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; 898 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
891 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 899 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
892 result = p80211req_dorequest(wlandev, (u8 *) & msg); 900 result = p80211req_dorequest(wlandev, (u8 *) &msg);
893 901
894 if (result) { 902 if (result) {
895 err = -EFAULT; 903 err = -EFAULT;
@@ -922,6 +930,7 @@ static int p80211wext_siwfrag(netdevice_t *dev,
922 } 930 }
923 931
924 msg.msgcode = DIDmsg_dot11req_mibset; 932 msg.msgcode = DIDmsg_dot11req_mibset;
933 memset(&mibitem, 0, sizeof(mibitem));
925 mibitem.did = 934 mibitem.did =
926 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; 935 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
927 936
@@ -931,7 +940,7 @@ static int p80211wext_siwfrag(netdevice_t *dev,
931 mibitem.data = frag->value; 940 mibitem.data = frag->value;
932 941
933 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 942 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
934 result = p80211req_dorequest(wlandev, (u8 *) & msg); 943 result = p80211req_dorequest(wlandev, (u8 *) &msg);
935 944
936 if (result) { 945 if (result) {
937 err = -EFAULT; 946 err = -EFAULT;
@@ -962,10 +971,11 @@ static int p80211wext_giwretry(netdevice_t *dev,
962 u16 shortretry, longretry, lifetime; 971 u16 shortretry, longretry, lifetime;
963 972
964 msg.msgcode = DIDmsg_dot11req_mibget; 973 msg.msgcode = DIDmsg_dot11req_mibget;
974 memset(&mibitem, 0, sizeof(mibitem));
965 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; 975 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
966 976
967 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 977 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
968 result = p80211req_dorequest(wlandev, (u8 *) & msg); 978 result = p80211req_dorequest(wlandev, (u8 *) &msg);
969 979
970 if (result) { 980 if (result) {
971 err = -EFAULT; 981 err = -EFAULT;
@@ -979,7 +989,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
979 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; 989 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
980 990
981 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 991 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
982 result = p80211req_dorequest(wlandev, (u8 *) & msg); 992 result = p80211req_dorequest(wlandev, (u8 *) &msg);
983 993
984 if (result) { 994 if (result) {
985 err = -EFAULT; 995 err = -EFAULT;
@@ -994,7 +1004,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
994 DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; 1004 DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
995 1005
996 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 1006 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
997 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1007 result = p80211req_dorequest(wlandev, (u8 *) &msg);
998 1008
999 if (result) { 1009 if (result) {
1000 err = -EFAULT; 1010 err = -EFAULT;
@@ -1037,6 +1047,8 @@ static int p80211wext_siwretry(netdevice_t *dev,
1037 int result; 1047 int result;
1038 int err = 0; 1048 int err = 0;
1039 1049
1050 memset(&mibitem, 0, sizeof(mibitem));
1051
1040 if (!wlan_wext_write) { 1052 if (!wlan_wext_write) {
1041 err = (-EOPNOTSUPP); 1053 err = (-EOPNOTSUPP);
1042 goto exit; 1054 goto exit;
@@ -1055,7 +1067,7 @@ static int p80211wext_siwretry(netdevice_t *dev,
1055 mibitem.data = rrq->value /= 1024; 1067 mibitem.data = rrq->value /= 1024;
1056 1068
1057 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 1069 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1058 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1070 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1059 1071
1060 if (result) { 1072 if (result) {
1061 err = -EFAULT; 1073 err = -EFAULT;
@@ -1069,7 +1081,7 @@ static int p80211wext_siwretry(netdevice_t *dev,
1069 1081
1070 memcpy(&msg.mibattribute.data, &mibitem, 1082 memcpy(&msg.mibattribute.data, &mibitem,
1071 sizeof(mibitem)); 1083 sizeof(mibitem));
1072 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1084 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1073 1085
1074 if (result) { 1086 if (result) {
1075 err = -EFAULT; 1087 err = -EFAULT;
@@ -1084,7 +1096,7 @@ static int p80211wext_siwretry(netdevice_t *dev,
1084 1096
1085 memcpy(&msg.mibattribute.data, &mibitem, 1097 memcpy(&msg.mibattribute.data, &mibitem,
1086 sizeof(mibitem)); 1098 sizeof(mibitem));
1087 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1099 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1088 1100
1089 if (result) { 1101 if (result) {
1090 err = -EFAULT; 1102 err = -EFAULT;
@@ -1114,6 +1126,7 @@ static int p80211wext_siwtxpow(netdevice_t *dev,
1114 } 1126 }
1115 1127
1116 msg.msgcode = DIDmsg_dot11req_mibset; 1128 msg.msgcode = DIDmsg_dot11req_mibset;
1129 memset(&mibitem, 0, sizeof(mibitem));
1117 mibitem.did = 1130 mibitem.did =
1118 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; 1131 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
1119 if (rrq->fixed == 0) 1132 if (rrq->fixed == 0)
@@ -1121,7 +1134,7 @@ static int p80211wext_siwtxpow(netdevice_t *dev,
1121 else 1134 else
1122 mibitem.data = rrq->value; 1135 mibitem.data = rrq->value;
1123 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 1136 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1124 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1137 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1125 1138
1126 if (result) { 1139 if (result) {
1127 err = -EFAULT; 1140 err = -EFAULT;
@@ -1143,11 +1156,13 @@ static int p80211wext_giwtxpow(netdevice_t *dev,
1143 int err = 0; 1156 int err = 0;
1144 1157
1145 msg.msgcode = DIDmsg_dot11req_mibget; 1158 msg.msgcode = DIDmsg_dot11req_mibget;
1159
1160 memset(&mibitem, 0, sizeof(mibitem));
1146 mibitem.did = 1161 mibitem.did =
1147 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; 1162 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
1148 1163
1149 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); 1164 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1150 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1165 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1151 1166
1152 if (result) { 1167 if (result) {
1153 err = -EFAULT; 1168 err = -EFAULT;
@@ -1295,7 +1310,7 @@ static int p80211wext_siwscan(netdevice_t *dev,
1295 msg.maxchanneltime.data = 250; 1310 msg.maxchanneltime.data = 250;
1296 msg.minchanneltime.data = 200; 1311 msg.minchanneltime.data = 200;
1297 1312
1298 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1313 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1299 if (result) 1314 if (result)
1300 err = prism2_result2err(msg.resultcode.data); 1315 err = prism2_result2err(msg.resultcode.data);
1301 1316
@@ -1414,7 +1429,7 @@ static int p80211wext_giwscan(netdevice_t *dev,
1414 msg.msgcode = DIDmsg_dot11req_scan_results; 1429 msg.msgcode = DIDmsg_dot11req_scan_results;
1415 msg.bssindex.data = i; 1430 msg.bssindex.data = i;
1416 1431
1417 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1432 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1418 if ((result != 0) || 1433 if ((result != 0) ||
1419 (msg.resultcode.data != P80211ENUM_resultcode_success)) { 1434 (msg.resultcode.data != P80211ENUM_resultcode_success)) {
1420 break; 1435 break;
@@ -1489,7 +1504,7 @@ static int p80211wext_set_encodeext(struct net_device *dev,
1489 memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len); 1504 memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
1490 1505
1491 memset(&msg, 0, sizeof(msg)); 1506 memset(&msg, 0, sizeof(msg));
1492 pstr = (p80211item_pstr32_t *) & msg.mibattribute.data; 1507 pstr = (p80211item_pstr32_t *) &msg.mibattribute.data;
1493 memcpy(pstr->data.data, ext->key, ext->key_len); 1508 memcpy(pstr->data.data, ext->key, ext->key_len);
1494 pstr->data.len = ext->key_len; 1509 pstr->data.len = ext->key_len;
1495 switch (idx) { 1510 switch (idx) {
@@ -1513,7 +1528,7 @@ static int p80211wext_set_encodeext(struct net_device *dev,
1513 break; 1528 break;
1514 } 1529 }
1515 msg.msgcode = DIDmsg_dot11req_mibset; 1530 msg.msgcode = DIDmsg_dot11req_mibset;
1516 result = p80211req_dorequest(wlandev, (u8 *) & msg); 1531 result = p80211req_dorequest(wlandev, (u8 *) &msg);
1517 pr_debug("result (%d)\n", result); 1532 pr_debug("result (%d)\n", result);
1518 } 1533 }
1519 return result; 1534 return result;
@@ -1729,15 +1744,11 @@ static iw_handler p80211wext_handlers[] = {
1729 1744
1730struct iw_handler_def p80211wext_handler_def = { 1745struct iw_handler_def p80211wext_handler_def = {
1731 .num_standard = ARRAY_SIZE(p80211wext_handlers), 1746 .num_standard = ARRAY_SIZE(p80211wext_handlers),
1732 .num_private = 0,
1733 .num_private_args = 0,
1734 .standard = p80211wext_handlers, 1747 .standard = p80211wext_handlers,
1735 .private = NULL,
1736 .private_args = NULL,
1737 .get_wireless_stats = p80211wext_get_wireless_stats 1748 .get_wireless_stats = p80211wext_get_wireless_stats
1738}; 1749};
1739 1750
1740int p80211wext_event_associated(wlandevice_t * wlandev, int assoc) 1751int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
1741{ 1752{
1742 union iwreq_data data; 1753 union iwreq_data data;
1743 1754
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index aaa70ed57710..4be54cea6ad7 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -53,6 +53,7 @@
53/* Local Constants */ 53/* Local Constants */
54 54
55#define PRISM2_USB_FWFILE "prism2_ru.fw" 55#define PRISM2_USB_FWFILE "prism2_ru.fw"
56MODULE_FIRMWARE(PRISM2_USB_FWFILE);
56 57
57#define S3DATA_MAX 5000 58#define S3DATA_MAX 5000
58#define S3PLUG_MAX 200 59#define S3PLUG_MAX 200
@@ -108,9 +109,9 @@ typedef struct pda {
108} pda_t; 109} pda_t;
109 110
110typedef struct imgchunk { 111typedef struct imgchunk {
111 u32 addr; /* start address */ 112 u32 addr; /* start address */
112 u32 len; /* in bytes */ 113 u32 len; /* in bytes */
113 u16 crc; /* CRC value (if it falls at a chunk boundary) */ 114 u16 crc; /* CRC value (if it falls at a chunk boundary) */
114 u8 *data; 115 u8 *data;
115} imgchunk_t; 116} imgchunk_t;
116 117
@@ -204,7 +205,7 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev)
204 return 1; 205 return 1;
205 } 206 }
206 207
207 printk(KERN_INFO "prism2_usb: %s will be processed, size %d\n", 208 printk(KERN_INFO "prism2_usb: %s will be processed, size %zu\n",
208 PRISM2_USB_FWFILE, fw_entry->size); 209 PRISM2_USB_FWFILE, fw_entry->size);
209 prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev); 210 prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev);
210 211
@@ -264,7 +265,7 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
264 /* Build the PDA we're going to use. */ 265 /* Build the PDA we're going to use. */
265 if (read_cardpda(&pda, wlandev)) { 266 if (read_cardpda(&pda, wlandev)) {
266 printk(KERN_ERR "load_cardpda failed, exiting.\n"); 267 printk(KERN_ERR "load_cardpda failed, exiting.\n");
267 return (1); 268 return 1;
268 } 269 }
269 270
270 /* read the card's PRI-SUP */ 271 /* read the card's PRI-SUP */
@@ -286,9 +287,8 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
286 287
287 /* DIDmsg_dot11req_mibget */ 288 /* DIDmsg_dot11req_mibget */
288 prism2mgmt_mibset_mibget(wlandev, &getmsg); 289 prism2mgmt_mibset_mibget(wlandev, &getmsg);
289 if (getmsg.resultcode.data != P80211ENUM_resultcode_success) { 290 if (getmsg.resultcode.data != P80211ENUM_resultcode_success)
290 printk(KERN_ERR "Couldn't fetch PRI-SUP info\n"); 291 printk(KERN_ERR "Couldn't fetch PRI-SUP info\n");
291 }
292 292
293 /* Already in host order */ 293 /* Already in host order */
294 priid.role = *data++; 294 priid.role = *data++;
@@ -301,19 +301,19 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
301 result = read_fwfile(rfptr); 301 result = read_fwfile(rfptr);
302 if (result) { 302 if (result) {
303 printk(KERN_ERR "Failed to read the data exiting.\n"); 303 printk(KERN_ERR "Failed to read the data exiting.\n");
304 return (1); 304 return 1;
305 } 305 }
306 306
307 result = validate_identity(); 307 result = validate_identity();
308 308
309 if (result) { 309 if (result) {
310 printk(KERN_ERR "Incompatible firmware image.\n"); 310 printk(KERN_ERR "Incompatible firmware image.\n");
311 return (1); 311 return 1;
312 } 312 }
313 313
314 if (startaddr == 0x00000000) { 314 if (startaddr == 0x00000000) {
315 printk(KERN_ERR "Can't RAM download a Flash image!\n"); 315 printk(KERN_ERR "Can't RAM download a Flash image!\n");
316 return (1); 316 return 1;
317 } 317 }
318 318
319 /* Make the image chunks */ 319 /* Make the image chunks */
@@ -323,20 +323,20 @@ int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
323 result = plugimage(fchunk, nfchunks, s3plug, ns3plug, &pda); 323 result = plugimage(fchunk, nfchunks, s3plug, ns3plug, &pda);
324 if (result) { 324 if (result) {
325 printk(KERN_ERR "Failed to plug data.\n"); 325 printk(KERN_ERR "Failed to plug data.\n");
326 return (1); 326 return 1;
327 } 327 }
328 328
329 /* Insert any CRCs */ 329 /* Insert any CRCs */
330 if (crcimage(fchunk, nfchunks, s3crc, ns3crc)) { 330 if (crcimage(fchunk, nfchunks, s3crc, ns3crc)) {
331 printk(KERN_ERR "Failed to insert all CRCs\n"); 331 printk(KERN_ERR "Failed to insert all CRCs\n");
332 return (1); 332 return 1;
333 } 333 }
334 334
335 /* Write the image */ 335 /* Write the image */
336 result = writeimage(wlandev, fchunk, nfchunks); 336 result = writeimage(wlandev, fchunk, nfchunks);
337 if (result) { 337 if (result) {
338 printk(KERN_ERR "Failed to ramwrite image data.\n"); 338 printk(KERN_ERR "Failed to ramwrite image data.\n");
339 return (1); 339 return 1;
340 } 340 }
341 341
342 /* clear any allocated memory */ 342 /* clear any allocated memory */
@@ -434,9 +434,8 @@ void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks)
434{ 434{
435 int i; 435 int i;
436 for (i = 0; i < *nfchunks; i++) { 436 for (i = 0; i < *nfchunks; i++) {
437 if (fchunk[i].data != NULL) { 437 if (fchunk[i].data != NULL)
438 kfree(fchunk[i].data); 438 kfree(fchunk[i].data);
439 }
440 } 439 }
441 *nfchunks = 0; 440 *nfchunks = 0;
442 memset(fchunk, 0, sizeof(*fchunk)); 441 memset(fchunk, 0, sizeof(*fchunk));
@@ -531,7 +530,7 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt)
531 if (clist[i].data == NULL) { 530 if (clist[i].data == NULL) {
532 printk(KERN_ERR 531 printk(KERN_ERR
533 "failed to allocate image space, exitting.\n"); 532 "failed to allocate image space, exitting.\n");
534 return (1); 533 return 1;
535 } 534 }
536 memset(clist[i].data, 0, clist[i].len); 535 memset(clist[i].data, 0, clist[i].len);
537 pr_debug("chunk[%d]: addr=0x%06x len=%d\n", 536 pr_debug("chunk[%d]: addr=0x%06x len=%d\n",
@@ -545,15 +544,14 @@ int mkimage(imgchunk_t *clist, unsigned int *ccnt)
545 for (j = 0; j < *ccnt; j++) { 544 for (j = 0; j < *ccnt; j++) {
546 cstart = clist[j].addr; 545 cstart = clist[j].addr;
547 cend = cstart + clist[j].len - 1; 546 cend = cstart + clist[j].len - 1;
548 if (s3start >= cstart && s3end <= cend) { 547 if (s3start >= cstart && s3end <= cend)
549 break; 548 break;
550 }
551 } 549 }
552 if (((unsigned int)j) >= (*ccnt)) { 550 if (((unsigned int)j) >= (*ccnt)) {
553 printk(KERN_ERR 551 printk(KERN_ERR
554 "s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n", 552 "s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n",
555 s3start, s3data[i].len); 553 s3start, s3data[i].len);
556 return (1); 554 return 1;
557 } 555 }
558 coffset = s3start - cstart; 556 coffset = s3start - cstart;
559 memcpy(clist[j].data + coffset, s3data[i].data, s3data[i].len); 557 memcpy(clist[j].data + coffset, s3data[i].data, s3data[i].len);
@@ -586,7 +584,7 @@ int mkpdrlist(pda_t *pda)
586 curroff = 0; 584 curroff = 0;
587 while (curroff < (HFA384x_PDA_LEN_MAX / 2) && 585 while (curroff < (HFA384x_PDA_LEN_MAX / 2) &&
588 le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) { 586 le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) {
589 pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]); 587 pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
590 588
591 if (le16_to_cpu(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) { 589 if (le16_to_cpu(pda->rec[pda->nrec]->code) == HFA384x_PDR_NICID) {
592 memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid, 590 memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid,
@@ -623,10 +621,10 @@ int mkpdrlist(pda_t *pda)
623 printk(KERN_ERR 621 printk(KERN_ERR
624 "no end record found or invalid lengths in " 622 "no end record found or invalid lengths in "
625 "PDR data, exiting. %x %d\n", curroff, pda->nrec); 623 "PDR data, exiting. %x %d\n", curroff, pda->nrec);
626 return (1); 624 return 1;
627 } 625 }
628 if (le16_to_cpu(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA) { 626 if (le16_to_cpu(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA) {
629 pda->rec[pda->nrec] = (hfa384x_pdrec_t *) & (pda16[curroff]); 627 pda->rec[pda->nrec] = (hfa384x_pdrec_t *) &(pda16[curroff]);
630 (pda->nrec)++; 628 (pda->nrec)++;
631 } 629 }
632 return result; 630 return result;
@@ -869,7 +867,7 @@ int read_fwfile(const struct ihex_binrec *record)
869 ptr16 = (u16 *) record->data; 867 ptr16 = (u16 *) record->data;
870 868
871 /* parse what was an S3 srec and put it in the right array */ 869 /* parse what was an S3 srec and put it in the right array */
872 switch(addr) { 870 switch (addr) {
873 case S3ADDR_START: 871 case S3ADDR_START:
874 startaddr = *ptr32; 872 startaddr = *ptr32;
875 pr_debug(" S7 start addr, record=%d " 873 pr_debug(" S7 start addr, record=%d "
@@ -890,7 +888,7 @@ int read_fwfile(const struct ihex_binrec *record)
890 s3plug[ns3plug].len); 888 s3plug[ns3plug].len);
891 889
892 ns3plug++; 890 ns3plug++;
893 if ( ns3plug == S3PLUG_MAX ) { 891 if (ns3plug == S3PLUG_MAX) {
894 printk(KERN_ERR "S3 plugrec limit reached - aborting\n"); 892 printk(KERN_ERR "S3 plugrec limit reached - aborting\n");
895 return 1; 893 return 1;
896 } 894 }
@@ -907,7 +905,7 @@ int read_fwfile(const struct ihex_binrec *record)
907 s3crc[ns3crc].len, 905 s3crc[ns3crc].len,
908 s3crc[ns3crc].dowrite); 906 s3crc[ns3crc].dowrite);
909 ns3crc++; 907 ns3crc++;
910 if ( ns3crc == S3CRC_MAX ) { 908 if (ns3crc == S3CRC_MAX) {
911 printk(KERN_ERR "S3 crcrec limit reached - aborting\n"); 909 printk(KERN_ERR "S3 crcrec limit reached - aborting\n");
912 return 1; 910 return 1;
913 } 911 }
@@ -921,12 +919,12 @@ int read_fwfile(const struct ihex_binrec *record)
921 rcnt, 919 rcnt,
922 s3info[ns3info].len, 920 s3info[ns3info].len,
923 s3info[ns3info].type); 921 s3info[ns3info].type);
924 if ( ((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info) ) { 922 if (((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info)) {
925 printk(KERN_ERR " S3 inforec length too long - aborting\n"); 923 printk(KERN_ERR " S3 inforec length too long - aborting\n");
926 return 1; 924 return 1;
927 } 925 }
928 926
929 tmpinfo = (u16*)&(s3info[ns3info].info.version); 927 tmpinfo = (u16 *)&(s3info[ns3info].info.version);
930 pr_debug(" info="); 928 pr_debug(" info=");
931 for (i = 0; i < s3info[ns3info].len - 1; i++) { 929 for (i = 0; i < s3info[ns3info].len - 1; i++) {
932 tmpinfo[i] = *(ptr16 + 2 + i); 930 tmpinfo[i] = *(ptr16 + 2 + i);
@@ -935,7 +933,7 @@ int read_fwfile(const struct ihex_binrec *record)
935 pr_debug("\n"); 933 pr_debug("\n");
936 934
937 ns3info++; 935 ns3info++;
938 if ( ns3info == S3INFO_MAX ) { 936 if (ns3info == S3INFO_MAX) {
939 printk(KERN_ERR "S3 inforec limit reached - aborting\n"); 937 printk(KERN_ERR "S3 inforec limit reached - aborting\n");
940 return 1; 938 return 1;
941 } 939 }
@@ -945,7 +943,7 @@ int read_fwfile(const struct ihex_binrec *record)
945 s3data[ns3data].len = len; 943 s3data[ns3data].len = len;
946 s3data[ns3data].data = (uint8_t *) record->data; 944 s3data[ns3data].data = (uint8_t *) record->data;
947 ns3data++; 945 ns3data++;
948 if ( ns3data == S3DATA_MAX ) { 946 if (ns3data == S3DATA_MAX) {
949 printk(KERN_ERR "S3 datarec limit reached - aborting\n"); 947 printk(KERN_ERR "S3 datarec limit reached - aborting\n");
950 return 1; 948 return 1;
951 } 949 }
@@ -1023,7 +1021,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
1023 rstatemsg.enable.data = P80211ENUM_truth_true; 1021 rstatemsg.enable.data = P80211ENUM_truth_true;
1024 rstatemsg.exeaddr.data = startaddr; 1022 rstatemsg.exeaddr.data = startaddr;
1025 1023
1026 msgp = (p80211msg_t *) & rstatemsg; 1024 msgp = (p80211msg_t *) &rstatemsg;
1027 result = prism2mgmt_ramdl_state(wlandev, msgp); 1025 result = prism2mgmt_ramdl_state(wlandev, msgp);
1028 if (result) { 1026 if (result) {
1029 printk(KERN_ERR 1027 printk(KERN_ERR
@@ -1063,7 +1061,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
1063 ("Sending xxxdl_write message addr=%06x len=%d.\n", 1061 ("Sending xxxdl_write message addr=%06x len=%d.\n",
1064 currdaddr, currlen); 1062 currdaddr, currlen);
1065 1063
1066 msgp = (p80211msg_t *) & rwritemsg; 1064 msgp = (p80211msg_t *) &rwritemsg;
1067 result = prism2mgmt_ramdl_write(wlandev, msgp); 1065 result = prism2mgmt_ramdl_write(wlandev, msgp);
1068 1066
1069 /* Check the results */ 1067 /* Check the results */
@@ -1090,7 +1088,7 @@ int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
1090 rstatemsg.enable.data = P80211ENUM_truth_false; 1088 rstatemsg.enable.data = P80211ENUM_truth_false;
1091 rstatemsg.exeaddr.data = 0; 1089 rstatemsg.exeaddr.data = 0;
1092 1090
1093 msgp = (p80211msg_t *) & rstatemsg; 1091 msgp = (p80211msg_t *) &rstatemsg;
1094 result = prism2mgmt_ramdl_state(wlandev, msgp); 1092 result = prism2mgmt_ramdl_state(wlandev, msgp);
1095 if (result) { 1093 if (result) {
1096 printk(KERN_ERR 1094 printk(KERN_ERR
@@ -1161,7 +1159,7 @@ int validate_identity(void)
1161 /* SEC compat range */ 1159 /* SEC compat range */
1162 if ((s3info[i].info.compat.role == 1) && 1160 if ((s3info[i].info.compat.role == 1) &&
1163 (s3info[i].info.compat.id == 4)) { 1161 (s3info[i].info.compat.id == 4)) {
1164 1162 /* FIXME: isn't something missing here? */
1165 } 1163 }
1166 1164
1167 break; 1165 break;
@@ -1196,8 +1194,9 @@ int validate_identity(void)
1196 pr_debug("Unknown inforec type %d\n", s3info[i].type); 1194 pr_debug("Unknown inforec type %d\n", s3info[i].type);
1197 } 1195 }
1198 } 1196 }
1199 // walk through 1197 /* walk through */
1200 1198
1201 if (trump && (result != 2)) result = 0; 1199 if (trump && (result != 2))
1200 result = 0;
1202 return result; 1201 return result;
1203} 1202}
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index 9f7d96cae8e3..ad163da72ae4 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -67,7 +67,7 @@
67#include <linux/wireless.h> 67#include <linux/wireless.h>
68#include <linux/netdevice.h> 68#include <linux/netdevice.h>
69#include <linux/delay.h> 69#include <linux/delay.h>
70#include <asm/io.h> 70#include <linux/io.h>
71#include <asm/byteorder.h> 71#include <asm/byteorder.h>
72#include <linux/random.h> 72#include <linux/random.h>
73#include <linux/usb.h> 73#include <linux/usb.h>
@@ -541,7 +541,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
541 /*** STATION ***/ 541 /*** STATION ***/
542 /* Set the REQUIRED config items */ 542 /* Set the REQUIRED config items */
543 /* SSID */ 543 /* SSID */
544 pstr = (p80211pstrd_t *) & (msg->ssid.data); 544 pstr = (p80211pstrd_t *) &(msg->ssid.data);
545 prism2mgmt_pstr2bytestr(p2bytestr, pstr); 545 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
546 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID, 546 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
547 bytebuf, HFA384x_RID_CNFOWNSSID_LEN); 547 bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
@@ -1034,7 +1034,7 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
1034 1034
1035 /* Set the ssid */ 1035 /* Set the ssid */
1036 memset(bytebuf, 0, 256); 1036 memset(bytebuf, 0, 256);
1037 pstr = (p80211pstrd_t *) & (msg->ssid.data); 1037 pstr = (p80211pstrd_t *) &(msg->ssid.data);
1038 prism2mgmt_pstr2bytestr(p2bytestr, pstr); 1038 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
1039 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, 1039 result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
1040 bytebuf, 1040 bytebuf,
@@ -1123,8 +1123,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
1123 if (hw->presniff_port_type != 0) { 1123 if (hw->presniff_port_type != 0) {
1124 word = hw->presniff_port_type; 1124 word = hw->presniff_port_type;
1125 result = hfa384x_drvr_setconfig16(hw, 1125 result = hfa384x_drvr_setconfig16(hw,
1126 HFA384x_RID_CNFPORTTYPE, 1126 HFA384x_RID_CNFPORTTYPE,
1127 word); 1127 word);
1128 if (result) { 1128 if (result) {
1129 pr_debug 1129 pr_debug
1130 ("failed to restore porttype, result=%d\n", 1130 ("failed to restore porttype, result=%d\n",
@@ -1156,10 +1156,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
1156 if (wlandev->netdev->type == ARPHRD_ETHER) { 1156 if (wlandev->netdev->type == ARPHRD_ETHER) {
1157 /* Save macport 0 state */ 1157 /* Save macport 0 state */
1158 result = hfa384x_drvr_getconfig16(hw, 1158 result = hfa384x_drvr_getconfig16(hw,
1159 HFA384x_RID_CNFPORTTYPE, 1159 HFA384x_RID_CNFPORTTYPE,
1160 & 1160 &(hw->presniff_port_type));
1161 (hw->
1162 presniff_port_type));
1163 if (result) { 1161 if (result) {
1164 pr_debug 1162 pr_debug
1165 ("failed to read porttype, result=%d\n", 1163 ("failed to read porttype, result=%d\n",
@@ -1168,10 +1166,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
1168 } 1166 }
1169 /* Save the wepflags state */ 1167 /* Save the wepflags state */
1170 result = hfa384x_drvr_getconfig16(hw, 1168 result = hfa384x_drvr_getconfig16(hw,
1171 HFA384x_RID_CNFWEPFLAGS, 1169 HFA384x_RID_CNFWEPFLAGS,
1172 & 1170 &(hw->presniff_wepflags));
1173 (hw->
1174 presniff_wepflags));
1175 if (result) { 1171 if (result) {
1176 pr_debug 1172 pr_debug
1177 ("failed to read wepflags, result=%d\n", 1173 ("failed to read wepflags, result=%d\n",
@@ -1218,8 +1214,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
1218 /* Set the port type to pIbss */ 1214 /* Set the port type to pIbss */
1219 word = HFA384x_PORTTYPE_PSUEDOIBSS; 1215 word = HFA384x_PORTTYPE_PSUEDOIBSS;
1220 result = hfa384x_drvr_setconfig16(hw, 1216 result = hfa384x_drvr_setconfig16(hw,
1221 HFA384x_RID_CNFPORTTYPE, 1217 HFA384x_RID_CNFPORTTYPE,
1222 word); 1218 word);
1223 if (result) { 1219 if (result) {
1224 pr_debug 1220 pr_debug
1225 ("failed to set porttype %d, result=%d\n", 1221 ("failed to set porttype %d, result=%d\n",
@@ -1235,8 +1231,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
1235 HFA384x_WEPFLAGS_DISABLE_RXCRYPT; 1231 HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
1236 result = 1232 result =
1237 hfa384x_drvr_setconfig16(hw, 1233 hfa384x_drvr_setconfig16(hw,
1238 HFA384x_RID_CNFWEPFLAGS, 1234 HFA384x_RID_CNFWEPFLAGS,
1239 word); 1235 word);
1240 } 1236 }
1241 1237
1242 if (result) { 1238 if (result) {
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
index bdf2b3e03253..07eecebeb6cc 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -63,43 +63,43 @@
63extern int prism2_reset_holdtime; 63extern int prism2_reset_holdtime;
64extern int prism2_reset_settletime; 64extern int prism2_reset_settletime;
65 65
66u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate); 66u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
67 67
68void prism2sta_ev_info(wlandevice_t * wlandev, hfa384x_InfFrame_t * inf); 68void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
69void prism2sta_ev_txexc(wlandevice_t * wlandev, u16 status); 69void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
70void prism2sta_ev_tx(wlandevice_t * wlandev, u16 status); 70void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
71void prism2sta_ev_rx(wlandevice_t * wlandev, struct sk_buff *skb); 71void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
72void prism2sta_ev_alloc(wlandevice_t * wlandev); 72void prism2sta_ev_alloc(wlandevice_t *wlandev);
73 73
74int prism2mgmt_mibset_mibget(wlandevice_t * wlandev, void *msgp); 74int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
75int prism2mgmt_scan(wlandevice_t * wlandev, void *msgp); 75int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
76int prism2mgmt_scan_results(wlandevice_t * wlandev, void *msgp); 76int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp);
77int prism2mgmt_start(wlandevice_t * wlandev, void *msgp); 77int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
78int prism2mgmt_wlansniff(wlandevice_t * wlandev, void *msgp); 78int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
79int prism2mgmt_readpda(wlandevice_t * wlandev, void *msgp); 79int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
80int prism2mgmt_ramdl_state(wlandevice_t * wlandev, void *msgp); 80int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
81int prism2mgmt_ramdl_write(wlandevice_t * wlandev, void *msgp); 81int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
82int prism2mgmt_flashdl_state(wlandevice_t * wlandev, void *msgp); 82int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
83int prism2mgmt_flashdl_write(wlandevice_t * wlandev, void *msgp); 83int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
84int prism2mgmt_autojoin(wlandevice_t * wlandev, void *msgp); 84int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp);
85 85
86/*--------------------------------------------------------------- 86/*---------------------------------------------------------------
87* conversion functions going between wlan message data types and 87* conversion functions going between wlan message data types and
88* Prism2 data types 88* Prism2 data types
89---------------------------------------------------------------*/ 89---------------------------------------------------------------*/
90/* byte area conversion functions*/ 90/* byte area conversion functions*/
91void prism2mgmt_pstr2bytearea(u8 * bytearea, p80211pstrd_t * pstr); 91void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr);
92void prism2mgmt_bytearea2pstr(u8 * bytearea, p80211pstrd_t * pstr, int len); 92void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len);
93 93
94/* byte string conversion functions*/ 94/* byte string conversion functions*/
95void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr); 95void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
96void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr); 96void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
97 97
98/* functions to convert Group Addresses */ 98/* functions to convert Group Addresses */
99void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t * pstr, hfa384x_t * priv); 99void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
100int prism2mgmt_set_grpaddr(u32 did, 100int prism2mgmt_set_grpaddr(u32 did,
101 u8 * prism2buf, p80211pstrd_t * pstr, 101 u8 *prism2buf, p80211pstrd_t *pstr,
102 hfa384x_t * priv); 102 hfa384x_t *priv);
103int prism2mgmt_get_grpaddr_index(u32 did); 103int prism2mgmt_get_grpaddr_index(u32 did);
104 104
105void prism2sta_processing_defer(struct work_struct *data); 105void prism2sta_processing_defer(struct work_struct *data);
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
index 2fff0a110bcb..98a5d58c3f55 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -114,7 +114,7 @@ static int prism2mib_flag(mibrec_t *mib,
114 114
115static int prism2mib_wepdefaultkey(mibrec_t *mib, 115static int prism2mib_wepdefaultkey(mibrec_t *mib,
116 int isget, 116 int isget,
117 wlandevice_t * wlandev, 117 wlandevice_t *wlandev,
118 hfa384x_t *hw, 118 hfa384x_t *hw,
119 p80211msg_dot11req_mibset_t *msg, 119 p80211msg_dot11req_mibset_t *msg,
120 void *data); 120 void *data);
@@ -726,7 +726,7 @@ static int prism2mib_priv(mibrec_t *mib,
726 if (isget) { 726 if (isget) {
727 hfa384x_drvr_getconfig(hw, 727 hfa384x_drvr_getconfig(hw,
728 HFA384x_RID_CNFWPADATA, 728 HFA384x_RID_CNFWPADATA,
729 (u8 *) & wpa, 729 (u8 *) &wpa,
730 sizeof(wpa)); 730 sizeof(wpa));
731 pstr->len = le16_to_cpu(wpa.datalen); 731 pstr->len = le16_to_cpu(wpa.datalen);
732 memcpy(pstr->data, wpa.data, pstr->len); 732 memcpy(pstr->data, wpa.data, pstr->len);
@@ -736,9 +736,9 @@ static int prism2mib_priv(mibrec_t *mib,
736 736
737 result = 737 result =
738 hfa384x_drvr_setconfig(hw, 738 hfa384x_drvr_setconfig(hw,
739 HFA384x_RID_CNFWPADATA, 739 HFA384x_RID_CNFWPADATA,
740 (u8 *) & wpa, 740 (u8 *) &wpa,
741 sizeof(wpa)); 741 sizeof(wpa));
742 } 742 }
743 break; 743 break;
744 } 744 }
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index 50f301d65212..31ac8da39c81 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -64,7 +64,7 @@
64#include <linux/byteorder/generic.h> 64#include <linux/byteorder/generic.h>
65#include <linux/ctype.h> 65#include <linux/ctype.h>
66 66
67#include <asm/io.h> 67#include <linux/io.h>
68#include <linux/delay.h> 68#include <linux/delay.h>
69#include <asm/byteorder.h> 69#include <asm/byteorder.h>
70#include <linux/if_arp.h> 70#include <linux/if_arp.h>
@@ -1023,13 +1023,13 @@ static void prism2sta_inf_tallies(wlandevice_t *wlandev,
1023 1023
1024 cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32); 1024 cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32);
1025 if (inf->framelen > 22) { 1025 if (inf->framelen > 22) {
1026 dst = (u32 *) & hw->tallies; 1026 dst = (u32 *) &hw->tallies;
1027 src32 = (u32 *) & inf->info.commtallies32; 1027 src32 = (u32 *) &inf->info.commtallies32;
1028 for (i = 0; i < cnt; i++, dst++, src32++) 1028 for (i = 0; i < cnt; i++, dst++, src32++)
1029 *dst += le32_to_cpu(*src32); 1029 *dst += le32_to_cpu(*src32);
1030 } else { 1030 } else {
1031 dst = (u32 *) & hw->tallies; 1031 dst = (u32 *) &hw->tallies;
1032 src16 = (u16 *) & inf->info.commtallies16; 1032 src16 = (u16 *) &inf->info.commtallies16;
1033 for (i = 0; i < cnt; i++, dst++, src16++) 1033 for (i = 0; i < cnt; i++, dst++, src16++)
1034 *dst += le16_to_cpu(*src16); 1034 *dst += le16_to_cpu(*src16);
1035 } 1035 }
@@ -1280,7 +1280,7 @@ void prism2sta_processing_defer(struct work_struct *data)
1280 HFA384x_RID_CURRENTSSID, result); 1280 HFA384x_RID_CURRENTSSID, result);
1281 goto failed; 1281 goto failed;
1282 } 1282 }
1283 prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid, 1283 prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
1284 (p80211pstrd_t *) & 1284 (p80211pstrd_t *) &
1285 wlandev->ssid); 1285 wlandev->ssid);
1286 1286
@@ -1368,8 +1368,8 @@ void prism2sta_processing_defer(struct work_struct *data)
1368 HFA384x_RID_CURRENTSSID, result); 1368 HFA384x_RID_CURRENTSSID, result);
1369 goto failed; 1369 goto failed;
1370 } 1370 }
1371 prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid, 1371 prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
1372 (p80211pstrd_t *) & wlandev->ssid); 1372 (p80211pstrd_t *) &wlandev->ssid);
1373 1373
1374 hw->link_status = HFA384x_LINK_CONNECTED; 1374 hw->link_status = HFA384x_LINK_CONNECTED;
1375 netif_carrier_on(wlandev->netdev); 1375 netif_carrier_on(wlandev->netdev);
@@ -2028,8 +2028,8 @@ void prism2sta_commsqual_defer(struct work_struct *data)
2028 HFA384x_RID_CURRENTSSID, result); 2028 HFA384x_RID_CURRENTSSID, result);
2029 goto done; 2029 goto done;
2030 } 2030 }
2031 prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) & ssid, 2031 prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *) &ssid,
2032 (p80211pstrd_t *) & wlandev->ssid); 2032 (p80211pstrd_t *) &wlandev->ssid);
2033 2033
2034 /* Reschedule timer */ 2034 /* Reschedule timer */
2035 mod_timer(&hw->commsqual_timer, jiffies + HZ); 2035 mod_timer(&hw->commsqual_timer, jiffies + HZ);
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index 9dde68be8d74..501d27f74c7d 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -24,8 +24,9 @@ static struct usb_device_id usb_prism_tbl[] = {
24 (0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")}, 24 (0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
25 {PRISM_USB_DEVICE 25 {PRISM_USB_DEVICE
26 (0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")}, 26 (0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
27 {PRISM_USB_DEVICE(0x049f, 0x0033, 27 {PRISM_USB_DEVICE
28 "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")}, 28 (0x049f, 0x0033,
29 "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
29 {PRISM_USB_DEVICE 30 {PRISM_USB_DEVICE
30 (0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")}, 31 (0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
31 {PRISM_USB_DEVICE 32 {PRISM_USB_DEVICE
@@ -55,7 +56,6 @@ static struct usb_device_id usb_prism_tbl[] = {
55 (0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")}, 56 (0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
56 {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")}, 57 {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
57 {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")}, 58 {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
58/* {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, */
59 {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")}, 59 {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
60 {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")}, 60 {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
61 {PRISM_USB_DEVICE 61 {PRISM_USB_DEVICE
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index c83c975152a6..d41811bfef2a 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -117,13 +117,20 @@ static const char *format_endpt =
117 * However, these will come from functions that return ptrs to each of them. 117 * However, these will come from functions that return ptrs to each of them.
118 */ 118 */
119 119
120static DECLARE_WAIT_QUEUE_HEAD(deviceconndiscwq); 120/*
121/* guarded by usbfs_mutex */ 121 * Wait for an connect/disconnect event to happen. We initialize
122static unsigned int conndiscevcnt; 122 * the event counter with an odd number, and each event will increment
123 123 * the event counter by two, so it will always _stay_ odd. That means
124/* this struct stores the poll state for <mountpoint>/devices pollers */ 124 * that it will never be zero, so "event 0" will never match a current
125struct usb_device_status { 125 * event, and thus 'poll' will always trigger as readable for the first
126 unsigned int lastev; 126 * time it gets called.
127 */
128static struct device_connect_event {
129 atomic_t count;
130 wait_queue_head_t wait;
131} device_event = {
132 .count = ATOMIC_INIT(1),
133 .wait = __WAIT_QUEUE_HEAD_INITIALIZER(device_event.wait)
127}; 134};
128 135
129struct class_info { 136struct class_info {
@@ -157,10 +164,8 @@ static const struct class_info clas_info[] =
157 164
158void usbfs_conn_disc_event(void) 165void usbfs_conn_disc_event(void)
159{ 166{
160 mutex_lock(&usbfs_mutex); 167 atomic_add(2, &device_event.count);
161 conndiscevcnt++; 168 wake_up(&device_event.wait);
162 mutex_unlock(&usbfs_mutex);
163 wake_up(&deviceconndiscwq);
164} 169}
165 170
166static const char *class_decode(const int class) 171static const char *class_decode(const int class)
@@ -632,42 +637,16 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
632static unsigned int usb_device_poll(struct file *file, 637static unsigned int usb_device_poll(struct file *file,
633 struct poll_table_struct *wait) 638 struct poll_table_struct *wait)
634{ 639{
635 struct usb_device_status *st; 640 unsigned int event_count;
636 unsigned int mask = 0;
637
638 mutex_lock(&usbfs_mutex);
639 st = file->private_data;
640 if (!st) {
641 st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
642 if (!st) {
643 mutex_unlock(&usbfs_mutex);
644 return POLLIN;
645 }
646
647 st->lastev = conndiscevcnt;
648 file->private_data = st;
649 mask = POLLIN;
650 }
651 641
652 if (file->f_mode & FMODE_READ) 642 poll_wait(file, &device_event.wait, wait);
653 poll_wait(file, &deviceconndiscwq, wait);
654 if (st->lastev != conndiscevcnt)
655 mask |= POLLIN;
656 st->lastev = conndiscevcnt;
657 mutex_unlock(&usbfs_mutex);
658 return mask;
659}
660 643
661static int usb_device_open(struct inode *inode, struct file *file) 644 event_count = atomic_read(&device_event.count);
662{ 645 if (file->f_version != event_count) {
663 file->private_data = NULL; 646 file->f_version = event_count;
664 return 0; 647 return POLLIN | POLLRDNORM;
665} 648 }
666 649
667static int usb_device_release(struct inode *inode, struct file *file)
668{
669 kfree(file->private_data);
670 file->private_data = NULL;
671 return 0; 650 return 0;
672} 651}
673 652
@@ -699,6 +678,4 @@ const struct file_operations usbfs_devices_fops = {
699 .llseek = usb_device_lseek, 678 .llseek = usb_device_lseek,
700 .read = usb_device_read, 679 .read = usb_device_read,
701 .poll = usb_device_poll, 680 .poll = usb_device_poll,
702 .open = usb_device_open,
703 .release = usb_device_release,
704}; 681};
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
new file mode 100644
index 000000000000..b8f705cca438
--- /dev/null
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -0,0 +1,304 @@
1/*
2 * Backlight driver for Marvell Semiconductor 88PM8606
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/fb.h>
16#include <linux/i2c.h>
17#include <linux/backlight.h>
18#include <linux/mfd/88pm860x.h>
19
20#define MAX_BRIGHTNESS (0xFF)
21#define MIN_BRIGHTNESS (0)
22
23#define CURRENT_MASK (0x1F << 1)
24
25struct pm860x_backlight_data {
26 struct pm860x_chip *chip;
27 struct i2c_client *i2c;
28 int current_brightness;
29 int port;
30 int pwm;
31 int iset;
32};
33
34static inline int wled_a(int port)
35{
36 int ret;
37
38 ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
39 return ret;
40}
41
42static inline int wled_b(int port)
43{
44 int ret;
45
46 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
47 return ret;
48}
49
50/* WLED2 & WLED3 share the same IDC */
51static inline int wled_idc(int port)
52{
53 int ret;
54
55 switch (port) {
56 case PM8606_BACKLIGHT1:
57 case PM8606_BACKLIGHT2:
58 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
59 break;
60 case PM8606_BACKLIGHT3:
61 default:
62 ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
63 break;
64 }
65 return ret;
66}
67
68static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
69{
70 struct pm860x_backlight_data *data = bl_get_data(bl);
71 struct pm860x_chip *chip = data->chip;
72 unsigned char value;
73 int ret;
74
75 if (brightness > MAX_BRIGHTNESS)
76 value = MAX_BRIGHTNESS;
77 else
78 value = brightness;
79
80 ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
81 if (ret < 0)
82 goto out;
83
84 if ((data->current_brightness == 0) && brightness) {
85 if (data->iset) {
86 ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
87 CURRENT_MASK, data->iset);
88 if (ret < 0)
89 goto out;
90 }
91 if (data->pwm) {
92 ret = pm860x_set_bits(data->i2c, PM8606_PWM,
93 PM8606_PWM_FREQ_MASK, data->pwm);
94 if (ret < 0)
95 goto out;
96 }
97 if (brightness == MAX_BRIGHTNESS) {
98 /* set WLED_ON bit as 100% */
99 ret = pm860x_set_bits(data->i2c, wled_b(data->port),
100 PM8606_WLED_ON, PM8606_WLED_ON);
101 }
102 } else {
103 if (brightness == MAX_BRIGHTNESS) {
104 /* set WLED_ON bit as 100% */
105 ret = pm860x_set_bits(data->i2c, wled_b(data->port),
106 PM8606_WLED_ON, PM8606_WLED_ON);
107 } else {
108 /* clear WLED_ON bit since it's not 100% */
109 ret = pm860x_set_bits(data->i2c, wled_b(data->port),
110 PM8606_WLED_ON, 0);
111 }
112 }
113 if (ret < 0)
114 goto out;
115
116 dev_dbg(chip->dev, "set brightness %d\n", value);
117 data->current_brightness = value;
118 return 0;
119out:
120 dev_dbg(chip->dev, "set brightness %d failure with return "
121 "value:%d\n", value, ret);
122 return ret;
123}
124
125static int pm860x_backlight_update_status(struct backlight_device *bl)
126{
127 int brightness = bl->props.brightness;
128
129 if (bl->props.power != FB_BLANK_UNBLANK)
130 brightness = 0;
131
132 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
133 brightness = 0;
134
135 if (bl->props.state & BL_CORE_SUSPENDED)
136 brightness = 0;
137
138 return pm860x_backlight_set(bl, brightness);
139}
140
141static int pm860x_backlight_get_brightness(struct backlight_device *bl)
142{
143 struct pm860x_backlight_data *data = bl_get_data(bl);
144 struct pm860x_chip *chip = data->chip;
145 int ret;
146
147 ret = pm860x_reg_read(data->i2c, wled_a(data->port));
148 if (ret < 0)
149 goto out;
150 data->current_brightness = ret;
151 dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
152 return data->current_brightness;
153out:
154 return -EINVAL;
155}
156
157static struct backlight_ops pm860x_backlight_ops = {
158 .options = BL_CORE_SUSPENDRESUME,
159 .update_status = pm860x_backlight_update_status,
160 .get_brightness = pm860x_backlight_get_brightness,
161};
162
163static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
164{
165 struct pm860x_backlight_pdata *p = pdata;
166 int ret = -EINVAL;
167
168 while (p && p->id) {
169 if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
170 break;
171
172 if (!strncmp(name, pm860x_backlight_name[p->flags],
173 MFD_NAME_SIZE)) {
174 ret = (int)p->flags;
175 break;
176 }
177 p++;
178 }
179 return ret;
180}
181
182static int pm860x_backlight_probe(struct platform_device *pdev)
183{
184 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
185 struct pm860x_platform_data *pm860x_pdata;
186 struct pm860x_backlight_pdata *pdata = NULL;
187 struct pm860x_backlight_data *data;
188 struct backlight_device *bl;
189 struct resource *res;
190 unsigned char value;
191 char name[MFD_NAME_SIZE];
192 int ret;
193
194 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
195 if (res == NULL) {
196 dev_err(&pdev->dev, "No I/O resource!\n");
197 return -EINVAL;
198 }
199
200 if (pdev->dev.parent->platform_data) {
201 pm860x_pdata = pdev->dev.parent->platform_data;
202 pdata = pm860x_pdata->backlight;
203 }
204 if (pdata == NULL) {
205 dev_err(&pdev->dev, "platform data isn't assigned to "
206 "backlight\n");
207 return -EINVAL;
208 }
209
210 data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL);
211 if (data == NULL)
212 return -ENOMEM;
213 strncpy(name, res->name, MFD_NAME_SIZE);
214 data->chip = chip;
215 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
216 : chip->companion;
217 data->current_brightness = MAX_BRIGHTNESS;
218 data->pwm = pdata->pwm;
219 data->iset = pdata->iset;
220 data->port = __check_device(pdata, name);
221 if (data->port < 0) {
222 dev_err(&pdev->dev, "wrong platform data is assigned");
223 return -EINVAL;
224 }
225
226 bl = backlight_device_register(name, &pdev->dev, data,
227 &pm860x_backlight_ops);
228 if (IS_ERR(bl)) {
229 dev_err(&pdev->dev, "failed to register backlight\n");
230 kfree(data);
231 return PTR_ERR(bl);
232 }
233 bl->props.max_brightness = MAX_BRIGHTNESS;
234 bl->props.brightness = MAX_BRIGHTNESS;
235
236 platform_set_drvdata(pdev, bl);
237
238 /* Enable reference VSYS */
239 ret = pm860x_reg_read(data->i2c, PM8606_VSYS);
240 if (ret < 0)
241 goto out;
242 if ((ret & PM8606_VSYS_EN) == 0) {
243 value = ret | PM8606_VSYS_EN;
244 ret = pm860x_reg_write(data->i2c, PM8606_VSYS, value);
245 if (ret < 0)
246 goto out;
247 }
248 /* Enable reference OSC */
249 ret = pm860x_reg_read(data->i2c, PM8606_MISC);
250 if (ret < 0)
251 goto out;
252 if ((ret & PM8606_MISC_OSC_EN) == 0) {
253 value = ret | PM8606_MISC_OSC_EN;
254 ret = pm860x_reg_write(data->i2c, PM8606_MISC, value);
255 if (ret < 0)
256 goto out;
257 }
258 /* read current backlight */
259 ret = pm860x_backlight_get_brightness(bl);
260 if (ret < 0)
261 goto out;
262
263 backlight_update_status(bl);
264 return 0;
265out:
266 kfree(data);
267 return ret;
268}
269
270static int pm860x_backlight_remove(struct platform_device *pdev)
271{
272 struct backlight_device *bl = platform_get_drvdata(pdev);
273 struct pm860x_backlight_data *data = bl_get_data(bl);
274
275 backlight_device_unregister(bl);
276 kfree(data);
277 return 0;
278}
279
280static struct platform_driver pm860x_backlight_driver = {
281 .driver = {
282 .name = "88pm860x-backlight",
283 .owner = THIS_MODULE,
284 },
285 .probe = pm860x_backlight_probe,
286 .remove = pm860x_backlight_remove,
287};
288
289static int __init pm860x_backlight_init(void)
290{
291 return platform_driver_register(&pm860x_backlight_driver);
292}
293module_init(pm860x_backlight_init);
294
295static void __exit pm860x_backlight_exit(void)
296{
297 platform_driver_unregister(&pm860x_backlight_driver);
298}
299module_exit(pm860x_backlight_exit);
300
301MODULE_DESCRIPTION("Backlight Driver for Marvell Semiconductor 88PM8606");
302MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
303MODULE_LICENSE("GPL");
304MODULE_ALIAS("platform:88pm860x-backlight");
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 09bfa9662e4d..0c77fc610212 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -212,6 +212,13 @@ config BACKLIGHT_DA903X
212 If you have a LCD backlight connected to the WLED output of DA9030 212 If you have a LCD backlight connected to the WLED output of DA9030
213 or DA9034 WLED output, say Y here to enable this driver. 213 or DA9034 WLED output, say Y here to enable this driver.
214 214
215config BACKLIGHT_MAX8925
216 tristate "Backlight driver for MAX8925"
217 depends on BACKLIGHT_CLASS_DEVICE && MFD_MAX8925
218 help
219 If you have a LCD backlight connected to the WLED output of MAX8925
220 WLED output, say Y here to enable this driver.
221
215config BACKLIGHT_MBP_NVIDIA 222config BACKLIGHT_MBP_NVIDIA
216 tristate "MacBook Pro Nvidia Backlight Driver" 223 tristate "MacBook Pro Nvidia Backlight Driver"
217 depends on BACKLIGHT_CLASS_DEVICE && X86 224 depends on BACKLIGHT_CLASS_DEVICE && X86
@@ -262,3 +269,9 @@ config BACKLIGHT_ADP5520
262 To compile this driver as a module, choose M here: the module will 269 To compile this driver as a module, choose M here: the module will
263 be called adp5520_bl. 270 be called adp5520_bl.
264 271
272config BACKLIGHT_88PM860X
273 tristate "Backlight Driver for 88PM8606 using WLED"
274 depends on BACKLIGHT_CLASS_DEVICE && MFD_88PM860X
275 help
276 Say Y to enable the backlight driver for Marvell 88PM8606.
277
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 9a405548874c..6c704d41462d 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -22,10 +22,12 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
22obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 22obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
23obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 23obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
24obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o 24obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
25obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o
25obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o 26obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
26obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 27obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
27obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o 28obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
28obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o 29obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
29obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o 30obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o
30obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o 31obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o
32obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
31 33
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
new file mode 100644
index 000000000000..c267069a52a3
--- /dev/null
+++ b/drivers/video/backlight/max8925_bl.c
@@ -0,0 +1,200 @@
1/*
2 * Backlight driver for Maxim MAX8925
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/platform_device.h>
15#include <linux/fb.h>
16#include <linux/i2c.h>
17#include <linux/backlight.h>
18#include <linux/mfd/max8925.h>
19
20#define MAX_BRIGHTNESS (0xff)
21#define MIN_BRIGHTNESS (0)
22
23#define LWX_FREQ(x) (((x - 601) / 100) & 0x7)
24
25struct max8925_backlight_data {
26 struct max8925_chip *chip;
27
28 int current_brightness;
29};
30
31static int max8925_backlight_set(struct backlight_device *bl, int brightness)
32{
33 struct max8925_backlight_data *data = bl_get_data(bl);
34 struct max8925_chip *chip = data->chip;
35 unsigned char value;
36 int ret;
37
38 if (brightness > MAX_BRIGHTNESS)
39 value = MAX_BRIGHTNESS;
40 else
41 value = brightness;
42
43 ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
44 if (ret < 0)
45 goto out;
46
47 if (!data->current_brightness && brightness)
48 /* enable WLED output */
49 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
50 else if (!brightness)
51 /* disable WLED output */
52 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
53 if (ret < 0)
54 goto out;
55 dev_dbg(chip->dev, "set brightness %d\n", value);
56 data->current_brightness = value;
57 return 0;
58out:
59 dev_dbg(chip->dev, "set brightness %d failure with return value:%d\n",
60 value, ret);
61 return ret;
62}
63
64static int max8925_backlight_update_status(struct backlight_device *bl)
65{
66 int brightness = bl->props.brightness;
67
68 if (bl->props.power != FB_BLANK_UNBLANK)
69 brightness = 0;
70
71 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
72 brightness = 0;
73
74 if (bl->props.state & BL_CORE_SUSPENDED)
75 brightness = 0;
76
77 return max8925_backlight_set(bl, brightness);
78}
79
80static int max8925_backlight_get_brightness(struct backlight_device *bl)
81{
82 struct max8925_backlight_data *data = bl_get_data(bl);
83 struct max8925_chip *chip = data->chip;
84 int ret;
85
86 ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
87 if (ret < 0)
88 return -EINVAL;
89 data->current_brightness = ret;
90 dev_dbg(chip->dev, "get brightness %d\n", data->current_brightness);
91 return ret;
92}
93
94static struct backlight_ops max8925_backlight_ops = {
95 .options = BL_CORE_SUSPENDRESUME,
96 .update_status = max8925_backlight_update_status,
97 .get_brightness = max8925_backlight_get_brightness,
98};
99
100static int __devinit max8925_backlight_probe(struct platform_device *pdev)
101{
102 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
103 struct max8925_platform_data *max8925_pdata;
104 struct max8925_backlight_pdata *pdata = NULL;
105 struct max8925_backlight_data *data;
106 struct backlight_device *bl;
107 struct resource *res;
108 char name[MAX8925_NAME_SIZE];
109 unsigned char value;
110 int ret;
111
112 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
113 if (res == NULL) {
114 dev_err(&pdev->dev, "No I/O resource!\n");
115 return -EINVAL;
116 }
117
118 if (pdev->dev.parent->platform_data) {
119 max8925_pdata = pdev->dev.parent->platform_data;
120 pdata = max8925_pdata->backlight;
121 }
122
123 if (!pdata) {
124 dev_err(&pdev->dev, "platform data isn't assigned to "
125 "backlight\n");
126 return -EINVAL;
127 }
128
129 data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
130 if (data == NULL)
131 return -ENOMEM;
132 strncpy(name, res->name, MAX8925_NAME_SIZE);
133 data->chip = chip;
134 data->current_brightness = 0;
135
136 bl = backlight_device_register(name, &pdev->dev, data,
137 &max8925_backlight_ops);
138 if (IS_ERR(bl)) {
139 dev_err(&pdev->dev, "failed to register backlight\n");
140 kfree(data);
141 return PTR_ERR(bl);
142 }
143 bl->props.max_brightness = MAX_BRIGHTNESS;
144 bl->props.brightness = MAX_BRIGHTNESS;
145
146 platform_set_drvdata(pdev, bl);
147
148 value = 0;
149 if (pdata->lxw_scl)
150 value |= (1 << 7);
151 if (pdata->lxw_freq)
152 value |= (LWX_FREQ(pdata->lxw_freq) << 4);
153 if (pdata->dual_string)
154 value |= (1 << 1);
155 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
156 if (ret < 0)
157 goto out;
158
159 backlight_update_status(bl);
160 return 0;
161out:
162 kfree(data);
163 return ret;
164}
165
166static int __devexit max8925_backlight_remove(struct platform_device *pdev)
167{
168 struct backlight_device *bl = platform_get_drvdata(pdev);
169 struct max8925_backlight_data *data = bl_get_data(bl);
170
171 backlight_device_unregister(bl);
172 kfree(data);
173 return 0;
174}
175
176static struct platform_driver max8925_backlight_driver = {
177 .driver = {
178 .name = "max8925-backlight",
179 .owner = THIS_MODULE,
180 },
181 .probe = max8925_backlight_probe,
182 .remove = __devexit_p(max8925_backlight_remove),
183};
184
185static int __init max8925_backlight_init(void)
186{
187 return platform_driver_register(&max8925_backlight_driver);
188}
189module_init(max8925_backlight_init);
190
191static void __exit max8925_backlight_exit(void)
192{
193 platform_driver_unregister(&max8925_backlight_driver);
194};
195module_exit(max8925_backlight_exit);
196
197MODULE_DESCRIPTION("Backlight Driver for Maxim MAX8925");
198MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
199MODULE_LICENSE("GPL");
200MODULE_ALIAS("platform:max8925-backlight");
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fc7d9bbb548c..8e8f18d29d7a 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -37,6 +37,7 @@ config VGACON_SOFT_SCROLLBACK
37config VGACON_SOFT_SCROLLBACK_SIZE 37config VGACON_SOFT_SCROLLBACK_SIZE
38 int "Scrollback Buffer Size (in KB)" 38 int "Scrollback Buffer Size (in KB)"
39 depends on VGACON_SOFT_SCROLLBACK 39 depends on VGACON_SOFT_SCROLLBACK
40 range 1 1024
40 default "64" 41 default "64"
41 help 42 help
42 Enter the amount of System RAM to allocate for the scrollback 43 Enter the amount of System RAM to allocate for the scrollback
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index cc4bbbe44aca..182dd6f8aadd 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -112,7 +112,7 @@ static int vga_video_font_height;
112static int vga_scan_lines __read_mostly; 112static int vga_scan_lines __read_mostly;
113static unsigned int vga_rolled_over; 113static unsigned int vga_rolled_over;
114 114
115int vgacon_text_mode_force = 0; 115static int vgacon_text_mode_force;
116 116
117bool vgacon_text_force(void) 117bool vgacon_text_force(void)
118{ 118{
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 1b6573216998..625447f645d9 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -649,6 +649,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
649 goto out_req_regions; 649 goto out_req_regions;
650 650
651 pci_set_drvdata(pci_dev, vp_dev); 651 pci_set_drvdata(pci_dev, vp_dev);
652 pci_set_master(pci_dev);
652 653
653 /* we use the subsystem vendor/device id as the virtio vendor/device 654 /* we use the subsystem vendor/device id as the virtio vendor/device
654 * id. this allows us to use the same PCI vendor/device id for all 655 * id. this allows us to use the same PCI vendor/device id for all
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index cab100acf983..fad3df2c1276 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -1,6 +1,8 @@
1menu "Xen driver support"
2 depends on XEN
3
1config XEN_BALLOON 4config XEN_BALLOON
2 bool "Xen memory balloon driver" 5 bool "Xen memory balloon driver"
3 depends on XEN
4 default y 6 default y
5 help 7 help
6 The balloon driver allows the Xen domain to request more memory from 8 The balloon driver allows the Xen domain to request more memory from
@@ -20,7 +22,6 @@ config XEN_SCRUB_PAGES
20 22
21config XEN_DEV_EVTCHN 23config XEN_DEV_EVTCHN
22 tristate "Xen /dev/xen/evtchn device" 24 tristate "Xen /dev/xen/evtchn device"
23 depends on XEN
24 default y 25 default y
25 help 26 help
26 The evtchn driver allows a userspace process to triger event 27 The evtchn driver allows a userspace process to triger event
@@ -30,7 +31,6 @@ config XEN_DEV_EVTCHN
30 31
31config XENFS 32config XENFS
32 tristate "Xen filesystem" 33 tristate "Xen filesystem"
33 depends on XEN
34 default y 34 default y
35 help 35 help
36 The xen filesystem provides a way for domains to share 36 The xen filesystem provides a way for domains to share
@@ -53,11 +53,13 @@ config XEN_COMPAT_XENFS
53 53
54config XEN_SYS_HYPERVISOR 54config XEN_SYS_HYPERVISOR
55 bool "Create xen entries under /sys/hypervisor" 55 bool "Create xen entries under /sys/hypervisor"
56 depends on XEN && SYSFS 56 depends on SYSFS
57 select SYS_HYPERVISOR 57 select SYS_HYPERVISOR
58 default y 58 default y
59 help 59 help
60 Create entries under /sys/hypervisor describing the Xen 60 Create entries under /sys/hypervisor describing the Xen
61 hypervisor environment. When running native or in another 61 hypervisor environment. When running native or in another
62 virtual environment, /sys/hypervisor will still be present, 62 virtual environment, /sys/hypervisor will still be present,
63 but will have no xen contents. \ No newline at end of file 63 but will have no xen contents.
64
65endmenu
diff --git a/fs/Kconfig b/fs/Kconfig
index 64d44efad7a5..7405f071be67 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -177,6 +177,7 @@ source "fs/efs/Kconfig"
177source "fs/jffs2/Kconfig" 177source "fs/jffs2/Kconfig"
178# UBIFS File system configuration 178# UBIFS File system configuration
179source "fs/ubifs/Kconfig" 179source "fs/ubifs/Kconfig"
180source "fs/logfs/Kconfig"
180source "fs/cramfs/Kconfig" 181source "fs/cramfs/Kconfig"
181source "fs/squashfs/Kconfig" 182source "fs/squashfs/Kconfig"
182source "fs/freevxfs/Kconfig" 183source "fs/freevxfs/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index af6d04700d9c..c3633aa46911 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_NTFS_FS) += ntfs/
99obj-$(CONFIG_UFS_FS) += ufs/ 99obj-$(CONFIG_UFS_FS) += ufs/
100obj-$(CONFIG_EFS_FS) += efs/ 100obj-$(CONFIG_EFS_FS) += efs/
101obj-$(CONFIG_JFFS2_FS) += jffs2/ 101obj-$(CONFIG_JFFS2_FS) += jffs2/
102obj-$(CONFIG_LOGFS) += logfs/
102obj-$(CONFIG_UBIFS_FS) += ubifs/ 103obj-$(CONFIG_UBIFS_FS) += ubifs/
103obj-$(CONFIG_AFFS_FS) += affs/ 104obj-$(CONFIG_AFFS_FS) += affs/
104obj-$(CONFIG_ROMFS_FS) += romfs/ 105obj-$(CONFIG_ROMFS_FS) += romfs/
diff --git a/fs/attr.c b/fs/attr.c
index 0a6ea54cde7d..0815e93bb487 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -81,7 +81,7 @@ int inode_newsize_ok(const struct inode *inode, loff_t offset)
81 if (inode->i_size < offset) { 81 if (inode->i_size < offset) {
82 unsigned long limit; 82 unsigned long limit;
83 83
84 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; 84 limit = rlimit(RLIMIT_FSIZE);
85 if (limit != RLIM_INFINITY && offset > limit) 85 if (limit != RLIM_INFINITY && offset > limit)
86 goto out_sig; 86 goto out_sig;
87 if (offset > inode->i_sb->s_maxbytes) 87 if (offset > inode->i_sb->s_maxbytes)
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index fdd397099172..15d80bb35d6f 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -24,6 +24,7 @@
24#include <linux/binfmts.h> 24#include <linux/binfmts.h>
25#include <linux/personality.h> 25#include <linux/personality.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/coredump.h>
27 28
28#include <asm/system.h> 29#include <asm/system.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
@@ -60,26 +61,6 @@ static int set_brk(unsigned long start, unsigned long end)
60} 61}
61 62
62/* 63/*
63 * These are the only things you should do on a core-file: use only these
64 * macros to write out all the necessary info.
65 */
66
67static int dump_write(struct file *file, const void *addr, int nr)
68{
69 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
70}
71
72#define DUMP_WRITE(addr, nr) \
73 if (!dump_write(file, (void *)(addr), (nr))) \
74 goto end_coredump;
75
76#define DUMP_SEEK(offset) \
77if (file->f_op->llseek) { \
78 if (file->f_op->llseek(file,(offset),0) != (offset)) \
79 goto end_coredump; \
80} else file->f_pos = (offset)
81
82/*
83 * Routine writes a core dump image in the current directory. 64 * Routine writes a core dump image in the current directory.
84 * Currently only a stub-function. 65 * Currently only a stub-function.
85 * 66 *
@@ -130,26 +111,31 @@ static int aout_core_dump(struct coredump_params *cprm)
130 111
131 set_fs(KERNEL_DS); 112 set_fs(KERNEL_DS);
132/* struct user */ 113/* struct user */
133 DUMP_WRITE(&dump,sizeof(dump)); 114 if (!dump_write(file, &dump, sizeof(dump)))
115 goto end_coredump;
134/* Now dump all of the user data. Include malloced stuff as well */ 116/* Now dump all of the user data. Include malloced stuff as well */
135 DUMP_SEEK(PAGE_SIZE); 117 if (!dump_seek(cprm->file, PAGE_SIZE - sizeof(dump)))
118 goto end_coredump;
136/* now we start writing out the user space info */ 119/* now we start writing out the user space info */
137 set_fs(USER_DS); 120 set_fs(USER_DS);
138/* Dump the data area */ 121/* Dump the data area */
139 if (dump.u_dsize != 0) { 122 if (dump.u_dsize != 0) {
140 dump_start = START_DATA(dump); 123 dump_start = START_DATA(dump);
141 dump_size = dump.u_dsize << PAGE_SHIFT; 124 dump_size = dump.u_dsize << PAGE_SHIFT;
142 DUMP_WRITE(dump_start,dump_size); 125 if (!dump_write(file, dump_start, dump_size))
126 goto end_coredump;
143 } 127 }
144/* Now prepare to dump the stack area */ 128/* Now prepare to dump the stack area */
145 if (dump.u_ssize != 0) { 129 if (dump.u_ssize != 0) {
146 dump_start = START_STACK(dump); 130 dump_start = START_STACK(dump);
147 dump_size = dump.u_ssize << PAGE_SHIFT; 131 dump_size = dump.u_ssize << PAGE_SHIFT;
148 DUMP_WRITE(dump_start,dump_size); 132 if (!dump_write(file, dump_start, dump_size))
133 goto end_coredump;
149 } 134 }
150/* Finally dump the task struct. Not be used by gdb, but could be useful */ 135/* Finally dump the task struct. Not be used by gdb, but could be useful */
151 set_fs(KERNEL_DS); 136 set_fs(KERNEL_DS);
152 DUMP_WRITE(current,sizeof(*current)); 137 if (!dump_write(file, current, sizeof(*current)))
138 goto end_coredump;
153end_coredump: 139end_coredump:
154 set_fs(fs); 140 set_fs(fs);
155 return has_dumped; 141 return has_dumped;
@@ -247,7 +233,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
247 * size limits imposed on them by creating programs with large 233 * size limits imposed on them by creating programs with large
248 * arrays in the data or bss. 234 * arrays in the data or bss.
249 */ 235 */
250 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 236 rlim = rlimit(RLIMIT_DATA);
251 if (rlim >= RLIM_INFINITY) 237 if (rlim >= RLIM_INFINITY)
252 rlim = ~0; 238 rlim = ~0;
253 if (ex.a_data + ex.a_bss > rlim) 239 if (ex.a_data + ex.a_bss > rlim)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index fd5b2ea5d299..535e763ab1a6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -31,6 +31,7 @@
31#include <linux/random.h> 31#include <linux/random.h>
32#include <linux/elf.h> 32#include <linux/elf.h>
33#include <linux/utsname.h> 33#include <linux/utsname.h>
34#include <linux/coredump.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35#include <asm/param.h> 36#include <asm/param.h>
36#include <asm/page.h> 37#include <asm/page.h>
@@ -1085,36 +1086,6 @@ out:
1085 * Modelled on fs/exec.c:aout_core_dump() 1086 * Modelled on fs/exec.c:aout_core_dump()
1086 * Jeremy Fitzhardinge <jeremy@sw.oz.au> 1087 * Jeremy Fitzhardinge <jeremy@sw.oz.au>
1087 */ 1088 */
1088/*
1089 * These are the only things you should do on a core-file: use only these
1090 * functions to write out all the necessary info.
1091 */
1092static int dump_write(struct file *file, const void *addr, int nr)
1093{
1094 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1095}
1096
1097static int dump_seek(struct file *file, loff_t off)
1098{
1099 if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
1100 if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
1101 return 0;
1102 } else {
1103 char *buf = (char *)get_zeroed_page(GFP_KERNEL);
1104 if (!buf)
1105 return 0;
1106 while (off > 0) {
1107 unsigned long n = off;
1108 if (n > PAGE_SIZE)
1109 n = PAGE_SIZE;
1110 if (!dump_write(file, buf, n))
1111 return 0;
1112 off -= n;
1113 }
1114 free_page((unsigned long)buf);
1115 }
1116 return 1;
1117}
1118 1089
1119/* 1090/*
1120 * Decide what to dump of a segment, part, all or none. 1091 * Decide what to dump of a segment, part, all or none.
@@ -1249,11 +1220,6 @@ static int writenote(struct memelfnote *men, struct file *file,
1249} 1220}
1250#undef DUMP_WRITE 1221#undef DUMP_WRITE
1251 1222
1252#define DUMP_WRITE(addr, nr) \
1253 if ((size += (nr)) > cprm->limit || \
1254 !dump_write(cprm->file, (addr), (nr))) \
1255 goto end_coredump;
1256
1257static void fill_elf_header(struct elfhdr *elf, int segs, 1223static void fill_elf_header(struct elfhdr *elf, int segs,
1258 u16 machine, u32 flags, u8 osabi) 1224 u16 machine, u32 flags, u8 osabi)
1259{ 1225{
@@ -1872,6 +1838,34 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
1872 return gate_vma; 1838 return gate_vma;
1873} 1839}
1874 1840
1841static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
1842 elf_addr_t e_shoff, int segs)
1843{
1844 elf->e_shoff = e_shoff;
1845 elf->e_shentsize = sizeof(*shdr4extnum);
1846 elf->e_shnum = 1;
1847 elf->e_shstrndx = SHN_UNDEF;
1848
1849 memset(shdr4extnum, 0, sizeof(*shdr4extnum));
1850
1851 shdr4extnum->sh_type = SHT_NULL;
1852 shdr4extnum->sh_size = elf->e_shnum;
1853 shdr4extnum->sh_link = elf->e_shstrndx;
1854 shdr4extnum->sh_info = segs;
1855}
1856
1857static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
1858 unsigned long mm_flags)
1859{
1860 struct vm_area_struct *vma;
1861 size_t size = 0;
1862
1863 for (vma = first_vma(current, gate_vma); vma != NULL;
1864 vma = next_vma(vma, gate_vma))
1865 size += vma_dump_size(vma, mm_flags);
1866 return size;
1867}
1868
1875/* 1869/*
1876 * Actual dumper 1870 * Actual dumper
1877 * 1871 *
@@ -1888,8 +1882,11 @@ static int elf_core_dump(struct coredump_params *cprm)
1888 struct vm_area_struct *vma, *gate_vma; 1882 struct vm_area_struct *vma, *gate_vma;
1889 struct elfhdr *elf = NULL; 1883 struct elfhdr *elf = NULL;
1890 loff_t offset = 0, dataoff, foffset; 1884 loff_t offset = 0, dataoff, foffset;
1891 unsigned long mm_flags;
1892 struct elf_note_info info; 1885 struct elf_note_info info;
1886 struct elf_phdr *phdr4note = NULL;
1887 struct elf_shdr *shdr4extnum = NULL;
1888 Elf_Half e_phnum;
1889 elf_addr_t e_shoff;
1893 1890
1894 /* 1891 /*
1895 * We no longer stop all VM operations. 1892 * We no longer stop all VM operations.
@@ -1912,20 +1909,25 @@ static int elf_core_dump(struct coredump_params *cprm)
1912 * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here. 1909 * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
1913 */ 1910 */
1914 segs = current->mm->map_count; 1911 segs = current->mm->map_count;
1915#ifdef ELF_CORE_EXTRA_PHDRS 1912 segs += elf_core_extra_phdrs();
1916 segs += ELF_CORE_EXTRA_PHDRS;
1917#endif
1918 1913
1919 gate_vma = get_gate_vma(current); 1914 gate_vma = get_gate_vma(current);
1920 if (gate_vma != NULL) 1915 if (gate_vma != NULL)
1921 segs++; 1916 segs++;
1922 1917
1918 /* for notes section */
1919 segs++;
1920
1921 /* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
1922 * this, kernel supports extended numbering. Have a look at
1923 * include/linux/elf.h for further information. */
1924 e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
1925
1923 /* 1926 /*
1924 * Collect all the non-memory information about the process for the 1927 * Collect all the non-memory information about the process for the
1925 * notes. This also sets up the file header. 1928 * notes. This also sets up the file header.
1926 */ 1929 */
1927 if (!fill_note_info(elf, segs + 1, /* including notes section */ 1930 if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs))
1928 &info, cprm->signr, cprm->regs))
1929 goto cleanup; 1931 goto cleanup;
1930 1932
1931 has_dumped = 1; 1933 has_dumped = 1;
@@ -1934,31 +1936,47 @@ static int elf_core_dump(struct coredump_params *cprm)
1934 fs = get_fs(); 1936 fs = get_fs();
1935 set_fs(KERNEL_DS); 1937 set_fs(KERNEL_DS);
1936 1938
1937 DUMP_WRITE(elf, sizeof(*elf));
1938 offset += sizeof(*elf); /* Elf header */ 1939 offset += sizeof(*elf); /* Elf header */
1939 offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */ 1940 offset += segs * sizeof(struct elf_phdr); /* Program headers */
1940 foffset = offset; 1941 foffset = offset;
1941 1942
1942 /* Write notes phdr entry */ 1943 /* Write notes phdr entry */
1943 { 1944 {
1944 struct elf_phdr phdr;
1945 size_t sz = get_note_info_size(&info); 1945 size_t sz = get_note_info_size(&info);
1946 1946
1947 sz += elf_coredump_extra_notes_size(); 1947 sz += elf_coredump_extra_notes_size();
1948 1948
1949 fill_elf_note_phdr(&phdr, sz, offset); 1949 phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
1950 if (!phdr4note)
1951 goto end_coredump;
1952
1953 fill_elf_note_phdr(phdr4note, sz, offset);
1950 offset += sz; 1954 offset += sz;
1951 DUMP_WRITE(&phdr, sizeof(phdr));
1952 } 1955 }
1953 1956
1954 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1957 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1955 1958
1956 /* 1959 offset += elf_core_vma_data_size(gate_vma, cprm->mm_flags);
1957 * We must use the same mm->flags while dumping core to avoid 1960 offset += elf_core_extra_data_size();
1958 * inconsistency between the program headers and bodies, otherwise an 1961 e_shoff = offset;
1959 * unusable core file can be generated. 1962
1960 */ 1963 if (e_phnum == PN_XNUM) {
1961 mm_flags = current->mm->flags; 1964 shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
1965 if (!shdr4extnum)
1966 goto end_coredump;
1967 fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
1968 }
1969
1970 offset = dataoff;
1971
1972 size += sizeof(*elf);
1973 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
1974 goto end_coredump;
1975
1976 size += sizeof(*phdr4note);
1977 if (size > cprm->limit
1978 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
1979 goto end_coredump;
1962 1980
1963 /* Write program headers for segments dump */ 1981 /* Write program headers for segments dump */
1964 for (vma = first_vma(current, gate_vma); vma != NULL; 1982 for (vma = first_vma(current, gate_vma); vma != NULL;
@@ -1969,7 +1987,7 @@ static int elf_core_dump(struct coredump_params *cprm)
1969 phdr.p_offset = offset; 1987 phdr.p_offset = offset;
1970 phdr.p_vaddr = vma->vm_start; 1988 phdr.p_vaddr = vma->vm_start;
1971 phdr.p_paddr = 0; 1989 phdr.p_paddr = 0;
1972 phdr.p_filesz = vma_dump_size(vma, mm_flags); 1990 phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags);
1973 phdr.p_memsz = vma->vm_end - vma->vm_start; 1991 phdr.p_memsz = vma->vm_end - vma->vm_start;
1974 offset += phdr.p_filesz; 1992 offset += phdr.p_filesz;
1975 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1993 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1979,12 +1997,14 @@ static int elf_core_dump(struct coredump_params *cprm)
1979 phdr.p_flags |= PF_X; 1997 phdr.p_flags |= PF_X;
1980 phdr.p_align = ELF_EXEC_PAGESIZE; 1998 phdr.p_align = ELF_EXEC_PAGESIZE;
1981 1999
1982 DUMP_WRITE(&phdr, sizeof(phdr)); 2000 size += sizeof(phdr);
2001 if (size > cprm->limit
2002 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
2003 goto end_coredump;
1983 } 2004 }
1984 2005
1985#ifdef ELF_CORE_WRITE_EXTRA_PHDRS 2006 if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
1986 ELF_CORE_WRITE_EXTRA_PHDRS; 2007 goto end_coredump;
1987#endif
1988 2008
1989 /* write out the notes section */ 2009 /* write out the notes section */
1990 if (!write_note_info(&info, cprm->file, &foffset)) 2010 if (!write_note_info(&info, cprm->file, &foffset))
@@ -2002,7 +2022,7 @@ static int elf_core_dump(struct coredump_params *cprm)
2002 unsigned long addr; 2022 unsigned long addr;
2003 unsigned long end; 2023 unsigned long end;
2004 2024
2005 end = vma->vm_start + vma_dump_size(vma, mm_flags); 2025 end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
2006 2026
2007 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { 2027 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
2008 struct page *page; 2028 struct page *page;
@@ -2023,15 +2043,24 @@ static int elf_core_dump(struct coredump_params *cprm)
2023 } 2043 }
2024 } 2044 }
2025 2045
2026#ifdef ELF_CORE_WRITE_EXTRA_DATA 2046 if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
2027 ELF_CORE_WRITE_EXTRA_DATA; 2047 goto end_coredump;
2028#endif 2048
2049 if (e_phnum == PN_XNUM) {
2050 size += sizeof(*shdr4extnum);
2051 if (size > cprm->limit
2052 || !dump_write(cprm->file, shdr4extnum,
2053 sizeof(*shdr4extnum)))
2054 goto end_coredump;
2055 }
2029 2056
2030end_coredump: 2057end_coredump:
2031 set_fs(fs); 2058 set_fs(fs);
2032 2059
2033cleanup: 2060cleanup:
2034 free_note_info(&info); 2061 free_note_info(&info);
2062 kfree(shdr4extnum);
2063 kfree(phdr4note);
2035 kfree(elf); 2064 kfree(elf);
2036out: 2065out:
2037 return has_dumped; 2066 return has_dumped;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 18d77297ccc8..6d6a16c5e9bb 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -34,6 +34,7 @@
34#include <linux/elf.h> 34#include <linux/elf.h>
35#include <linux/elf-fdpic.h> 35#include <linux/elf-fdpic.h>
36#include <linux/elfcore.h> 36#include <linux/elfcore.h>
37#include <linux/coredump.h>
37 38
38#include <asm/uaccess.h> 39#include <asm/uaccess.h>
39#include <asm/param.h> 40#include <asm/param.h>
@@ -1216,26 +1217,6 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1216#ifdef CONFIG_ELF_CORE 1217#ifdef CONFIG_ELF_CORE
1217 1218
1218/* 1219/*
1219 * These are the only things you should do on a core-file: use only these
1220 * functions to write out all the necessary info.
1221 */
1222static int dump_write(struct file *file, const void *addr, int nr)
1223{
1224 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1225}
1226
1227static int dump_seek(struct file *file, loff_t off)
1228{
1229 if (file->f_op->llseek) {
1230 if (file->f_op->llseek(file, off, SEEK_SET) != off)
1231 return 0;
1232 } else {
1233 file->f_pos = off;
1234 }
1235 return 1;
1236}
1237
1238/*
1239 * Decide whether a segment is worth dumping; default is yes to be 1220 * Decide whether a segment is worth dumping; default is yes to be
1240 * sure (missing info is worse than too much; etc). 1221 * sure (missing info is worse than too much; etc).
1241 * Personally I'd include everything, and use the coredump limit... 1222 * Personally I'd include everything, and use the coredump limit...
@@ -1313,35 +1294,35 @@ static int notesize(struct memelfnote *en)
1313 1294
1314/* #define DEBUG */ 1295/* #define DEBUG */
1315 1296
1316#define DUMP_WRITE(addr, nr) \ 1297#define DUMP_WRITE(addr, nr, foffset) \
1317 do { if (!dump_write(file, (addr), (nr))) return 0; } while(0) 1298 do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
1318#define DUMP_SEEK(off) \
1319 do { if (!dump_seek(file, (off))) return 0; } while(0)
1320 1299
1321static int writenote(struct memelfnote *men, struct file *file) 1300static int alignfile(struct file *file, loff_t *foffset)
1322{ 1301{
1323 struct elf_note en; 1302 static const char buf[4] = { 0, };
1303 DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
1304 return 1;
1305}
1324 1306
1307static int writenote(struct memelfnote *men, struct file *file,
1308 loff_t *foffset)
1309{
1310 struct elf_note en;
1325 en.n_namesz = strlen(men->name) + 1; 1311 en.n_namesz = strlen(men->name) + 1;
1326 en.n_descsz = men->datasz; 1312 en.n_descsz = men->datasz;
1327 en.n_type = men->type; 1313 en.n_type = men->type;
1328 1314
1329 DUMP_WRITE(&en, sizeof(en)); 1315 DUMP_WRITE(&en, sizeof(en), foffset);
1330 DUMP_WRITE(men->name, en.n_namesz); 1316 DUMP_WRITE(men->name, en.n_namesz, foffset);
1331 /* XXX - cast from long long to long to avoid need for libgcc.a */ 1317 if (!alignfile(file, foffset))
1332 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ 1318 return 0;
1333 DUMP_WRITE(men->data, men->datasz); 1319 DUMP_WRITE(men->data, men->datasz, foffset);
1334 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ 1320 if (!alignfile(file, foffset))
1321 return 0;
1335 1322
1336 return 1; 1323 return 1;
1337} 1324}
1338#undef DUMP_WRITE 1325#undef DUMP_WRITE
1339#undef DUMP_SEEK
1340
1341#define DUMP_WRITE(addr, nr) \
1342 if ((size += (nr)) > cprm->limit || \
1343 !dump_write(cprm->file, (addr), (nr))) \
1344 goto end_coredump;
1345 1326
1346static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) 1327static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs)
1347{ 1328{
@@ -1524,6 +1505,22 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1524 return sz; 1505 return sz;
1525} 1506}
1526 1507
1508static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
1509 elf_addr_t e_shoff, int segs)
1510{
1511 elf->e_shoff = e_shoff;
1512 elf->e_shentsize = sizeof(*shdr4extnum);
1513 elf->e_shnum = 1;
1514 elf->e_shstrndx = SHN_UNDEF;
1515
1516 memset(shdr4extnum, 0, sizeof(*shdr4extnum));
1517
1518 shdr4extnum->sh_type = SHT_NULL;
1519 shdr4extnum->sh_size = elf->e_shnum;
1520 shdr4extnum->sh_link = elf->e_shstrndx;
1521 shdr4extnum->sh_info = segs;
1522}
1523
1527/* 1524/*
1528 * dump the segments for an MMU process 1525 * dump the segments for an MMU process
1529 */ 1526 */
@@ -1552,7 +1549,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1552 err = -EIO; 1549 err = -EIO;
1553 kunmap(page); 1550 kunmap(page);
1554 page_cache_release(page); 1551 page_cache_release(page);
1555 } else if (!dump_seek(file, file->f_pos + PAGE_SIZE)) 1552 } else if (!dump_seek(file, PAGE_SIZE))
1556 err = -EFBIG; 1553 err = -EFBIG;
1557 if (err) 1554 if (err)
1558 goto out; 1555 goto out;
@@ -1588,6 +1585,17 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1588} 1585}
1589#endif 1586#endif
1590 1587
1588static size_t elf_core_vma_data_size(unsigned long mm_flags)
1589{
1590 struct vm_area_struct *vma;
1591 size_t size = 0;
1592
1593 for (vma = current->mm->mmap; vma; vma->vm_next)
1594 if (maydump(vma, mm_flags))
1595 size += vma->vm_end - vma->vm_start;
1596 return size;
1597}
1598
1591/* 1599/*
1592 * Actual dumper 1600 * Actual dumper
1593 * 1601 *
@@ -1605,7 +1613,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1605 int i; 1613 int i;
1606 struct vm_area_struct *vma; 1614 struct vm_area_struct *vma;
1607 struct elfhdr *elf = NULL; 1615 struct elfhdr *elf = NULL;
1608 loff_t offset = 0, dataoff; 1616 loff_t offset = 0, dataoff, foffset;
1609 int numnote; 1617 int numnote;
1610 struct memelfnote *notes = NULL; 1618 struct memelfnote *notes = NULL;
1611 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */ 1619 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
@@ -1618,7 +1626,10 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1618#endif 1626#endif
1619 int thread_status_size = 0; 1627 int thread_status_size = 0;
1620 elf_addr_t *auxv; 1628 elf_addr_t *auxv;
1621 unsigned long mm_flags; 1629 struct elf_phdr *phdr4note = NULL;
1630 struct elf_shdr *shdr4extnum = NULL;
1631 Elf_Half e_phnum;
1632 elf_addr_t e_shoff;
1622 1633
1623 /* 1634 /*
1624 * We no longer stop all VM operations. 1635 * We no longer stop all VM operations.
@@ -1683,12 +1694,18 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1683 elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); 1694 elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
1684 1695
1685 segs = current->mm->map_count; 1696 segs = current->mm->map_count;
1686#ifdef ELF_CORE_EXTRA_PHDRS 1697 segs += elf_core_extra_phdrs();
1687 segs += ELF_CORE_EXTRA_PHDRS; 1698
1688#endif 1699 /* for notes section */
1700 segs++;
1701
1702 /* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
1703 * this, kernel supports extended numbering. Have a look at
1704 * include/linux/elf.h for further information. */
1705 e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
1689 1706
1690 /* Set up header */ 1707 /* Set up header */
1691 fill_elf_fdpic_header(elf, segs + 1); /* including notes section */ 1708 fill_elf_fdpic_header(elf, e_phnum);
1692 1709
1693 has_dumped = 1; 1710 has_dumped = 1;
1694 current->flags |= PF_DUMPCORE; 1711 current->flags |= PF_DUMPCORE;
@@ -1727,13 +1744,12 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1727 fs = get_fs(); 1744 fs = get_fs();
1728 set_fs(KERNEL_DS); 1745 set_fs(KERNEL_DS);
1729 1746
1730 DUMP_WRITE(elf, sizeof(*elf));
1731 offset += sizeof(*elf); /* Elf header */ 1747 offset += sizeof(*elf); /* Elf header */
1732 offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */ 1748 offset += segs * sizeof(struct elf_phdr); /* Program headers */
1749 foffset = offset;
1733 1750
1734 /* Write notes phdr entry */ 1751 /* Write notes phdr entry */
1735 { 1752 {
1736 struct elf_phdr phdr;
1737 int sz = 0; 1753 int sz = 0;
1738 1754
1739 for (i = 0; i < numnote; i++) 1755 for (i = 0; i < numnote; i++)
@@ -1741,20 +1757,38 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1741 1757
1742 sz += thread_status_size; 1758 sz += thread_status_size;
1743 1759
1744 fill_elf_note_phdr(&phdr, sz, offset); 1760 phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
1761 if (!phdr4note)
1762 goto end_coredump;
1763
1764 fill_elf_note_phdr(phdr4note, sz, offset);
1745 offset += sz; 1765 offset += sz;
1746 DUMP_WRITE(&phdr, sizeof(phdr));
1747 } 1766 }
1748 1767
1749 /* Page-align dumped data */ 1768 /* Page-align dumped data */
1750 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1769 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1751 1770
1752 /* 1771 offset += elf_core_vma_data_size(cprm->mm_flags);
1753 * We must use the same mm->flags while dumping core to avoid 1772 offset += elf_core_extra_data_size();
1754 * inconsistency between the program headers and bodies, otherwise an 1773 e_shoff = offset;
1755 * unusable core file can be generated. 1774
1756 */ 1775 if (e_phnum == PN_XNUM) {
1757 mm_flags = current->mm->flags; 1776 shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
1777 if (!shdr4extnum)
1778 goto end_coredump;
1779 fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
1780 }
1781
1782 offset = dataoff;
1783
1784 size += sizeof(*elf);
1785 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
1786 goto end_coredump;
1787
1788 size += sizeof(*phdr4note);
1789 if (size > cprm->limit
1790 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
1791 goto end_coredump;
1758 1792
1759 /* write program headers for segments dump */ 1793 /* write program headers for segments dump */
1760 for (vma = current->mm->mmap; vma; vma = vma->vm_next) { 1794 for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
@@ -1767,7 +1801,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1767 phdr.p_offset = offset; 1801 phdr.p_offset = offset;
1768 phdr.p_vaddr = vma->vm_start; 1802 phdr.p_vaddr = vma->vm_start;
1769 phdr.p_paddr = 0; 1803 phdr.p_paddr = 0;
1770 phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0; 1804 phdr.p_filesz = maydump(vma, cprm->mm_flags) ? sz : 0;
1771 phdr.p_memsz = sz; 1805 phdr.p_memsz = sz;
1772 offset += phdr.p_filesz; 1806 offset += phdr.p_filesz;
1773 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1807 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1777,16 +1811,18 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1777 phdr.p_flags |= PF_X; 1811 phdr.p_flags |= PF_X;
1778 phdr.p_align = ELF_EXEC_PAGESIZE; 1812 phdr.p_align = ELF_EXEC_PAGESIZE;
1779 1813
1780 DUMP_WRITE(&phdr, sizeof(phdr)); 1814 size += sizeof(phdr);
1815 if (size > cprm->limit
1816 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
1817 goto end_coredump;
1781 } 1818 }
1782 1819
1783#ifdef ELF_CORE_WRITE_EXTRA_PHDRS 1820 if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
1784 ELF_CORE_WRITE_EXTRA_PHDRS; 1821 goto end_coredump;
1785#endif
1786 1822
1787 /* write out the notes section */ 1823 /* write out the notes section */
1788 for (i = 0; i < numnote; i++) 1824 for (i = 0; i < numnote; i++)
1789 if (!writenote(notes + i, cprm->file)) 1825 if (!writenote(notes + i, cprm->file, &foffset))
1790 goto end_coredump; 1826 goto end_coredump;
1791 1827
1792 /* write out the thread status notes section */ 1828 /* write out the thread status notes section */
@@ -1795,20 +1831,27 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
1795 list_entry(t, struct elf_thread_status, list); 1831 list_entry(t, struct elf_thread_status, list);
1796 1832
1797 for (i = 0; i < tmp->num_notes; i++) 1833 for (i = 0; i < tmp->num_notes; i++)
1798 if (!writenote(&tmp->notes[i], cprm->file)) 1834 if (!writenote(&tmp->notes[i], cprm->file, &foffset))
1799 goto end_coredump; 1835 goto end_coredump;
1800 } 1836 }
1801 1837
1802 if (!dump_seek(cprm->file, dataoff)) 1838 if (!dump_seek(cprm->file, dataoff - foffset))
1803 goto end_coredump; 1839 goto end_coredump;
1804 1840
1805 if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit, 1841 if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit,
1806 mm_flags) < 0) 1842 cprm->mm_flags) < 0)
1807 goto end_coredump; 1843 goto end_coredump;
1808 1844
1809#ifdef ELF_CORE_WRITE_EXTRA_DATA 1845 if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
1810 ELF_CORE_WRITE_EXTRA_DATA; 1846 goto end_coredump;
1811#endif 1847
1848 if (e_phnum == PN_XNUM) {
1849 size += sizeof(*shdr4extnum);
1850 if (size > cprm->limit
1851 || !dump_write(cprm->file, shdr4extnum,
1852 sizeof(*shdr4extnum)))
1853 goto end_coredump;
1854 }
1812 1855
1813 if (cprm->file->f_pos != offset) { 1856 if (cprm->file->f_pos != offset) {
1814 /* Sanity check */ 1857 /* Sanity check */
@@ -1826,7 +1869,7 @@ cleanup:
1826 list_del(tmp); 1869 list_del(tmp);
1827 kfree(list_entry(tmp, struct elf_thread_status, list)); 1870 kfree(list_entry(tmp, struct elf_thread_status, list));
1828 } 1871 }
1829 1872 kfree(phdr4note);
1830 kfree(elf); 1873 kfree(elf);
1831 kfree(prstatus); 1874 kfree(prstatus);
1832 kfree(psinfo); 1875 kfree(psinfo);
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 42c6b4a54445..e0e769bdca59 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -501,7 +501,7 @@ static int load_flat_file(struct linux_binprm * bprm,
501 * size limits imposed on them by creating programs with large 501 * size limits imposed on them by creating programs with large
502 * arrays in the data or bss. 502 * arrays in the data or bss.
503 */ 503 */
504 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 504 rlim = rlimit(RLIMIT_DATA);
505 if (rlim >= RLIM_INFINITY) 505 if (rlim >= RLIM_INFINITY)
506 rlim = ~0; 506 rlim = ~0;
507 if (data_len + bss_len > rlim) { 507 if (data_len + bss_len > rlim) {
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c
index 0adced2f296f..112e45a17e99 100644
--- a/fs/compat_binfmt_elf.c
+++ b/fs/compat_binfmt_elf.c
@@ -28,10 +28,12 @@
28 28
29#undef elfhdr 29#undef elfhdr
30#undef elf_phdr 30#undef elf_phdr
31#undef elf_shdr
31#undef elf_note 32#undef elf_note
32#undef elf_addr_t 33#undef elf_addr_t
33#define elfhdr elf32_hdr 34#define elfhdr elf32_hdr
34#define elf_phdr elf32_phdr 35#define elf_phdr elf32_phdr
36#define elf_shdr elf32_shdr
35#define elf_note elf32_note 37#define elf_note elf32_note
36#define elf_addr_t Elf32_Addr 38#define elf_addr_t Elf32_Addr
37 39
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 0ca9ec4a79c3..6d55b61bfa79 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -545,7 +545,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp)
545 kcmd = MTIOCPOS; 545 kcmd = MTIOCPOS;
546 karg = &pos; 546 karg = &pos;
547 break; 547 break;
548 case MTIOCGET32: 548 default: /* MTIOCGET32 */
549 kcmd = MTIOCGET; 549 kcmd = MTIOCGET;
550 karg = &get; 550 karg = &get;
551 break; 551 break;
@@ -663,7 +663,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd,
663 663
664 switch (cmd) { 664 switch (cmd) {
665 case RAW_SETBIND: 665 case RAW_SETBIND:
666 case RAW_GETBIND: { 666 default: { /* RAW_GETBIND */
667 struct raw_config_request req; 667 struct raw_config_request req;
668 mm_segment_t oldfs = get_fs(); 668 mm_segment_t oldfs = get_fs();
669 669
diff --git a/fs/exec.c b/fs/exec.c
index cce6bbdbdbb1..49cdaa19e5b9 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -195,7 +195,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
195 * to work from. 195 * to work from.
196 */ 196 */
197 rlim = current->signal->rlim; 197 rlim = current->signal->rlim;
198 if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { 198 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
199 put_page(page); 199 put_page(page);
200 return NULL; 200 return NULL;
201 } 201 }
@@ -246,6 +246,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
246 vma->vm_start = vma->vm_end - PAGE_SIZE; 246 vma->vm_start = vma->vm_end - PAGE_SIZE;
247 vma->vm_flags = VM_STACK_FLAGS; 247 vma->vm_flags = VM_STACK_FLAGS;
248 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 248 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
249 INIT_LIST_HEAD(&vma->anon_vma_chain);
249 err = insert_vm_struct(mm, vma); 250 err = insert_vm_struct(mm, vma);
250 if (err) 251 if (err)
251 goto err; 252 goto err;
@@ -516,7 +517,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
516 /* 517 /*
517 * cover the whole range: [new_start, old_end) 518 * cover the whole range: [new_start, old_end)
518 */ 519 */
519 vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL); 520 if (vma_adjust(vma, new_start, old_end, vma->vm_pgoff, NULL))
521 return -ENOMEM;
520 522
521 /* 523 /*
522 * move the page tables downwards, on failure we rely on 524 * move the page tables downwards, on failure we rely on
@@ -547,15 +549,13 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
547 tlb_finish_mmu(tlb, new_end, old_end); 549 tlb_finish_mmu(tlb, new_end, old_end);
548 550
549 /* 551 /*
550 * shrink the vma to just the new range. 552 * Shrink the vma to just the new range. Always succeeds.
551 */ 553 */
552 vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL); 554 vma_adjust(vma, new_start, new_end, vma->vm_pgoff, NULL);
553 555
554 return 0; 556 return 0;
555} 557}
556 558
557#define EXTRA_STACK_VM_PAGES 20 /* random */
558
559/* 559/*
560 * Finalizes the stack vm_area_struct. The flags and permissions are updated, 560 * Finalizes the stack vm_area_struct. The flags and permissions are updated,
561 * the stack is optionally relocated, and some extra space is added. 561 * the stack is optionally relocated, and some extra space is added.
@@ -577,7 +577,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
577 577
578#ifdef CONFIG_STACK_GROWSUP 578#ifdef CONFIG_STACK_GROWSUP
579 /* Limit stack size to 1GB */ 579 /* Limit stack size to 1GB */
580 stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max; 580 stack_base = rlimit_max(RLIMIT_STACK);
581 if (stack_base > (1 << 30)) 581 if (stack_base > (1 << 30))
582 stack_base = 1 << 30; 582 stack_base = 1 << 30;
583 583
@@ -630,7 +630,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
630 goto out_unlock; 630 goto out_unlock;
631 } 631 }
632 632
633 stack_expand = EXTRA_STACK_VM_PAGES * PAGE_SIZE; 633 stack_expand = 131072UL; /* randomly 32*4k (or 2*64k) pages */
634 stack_size = vma->vm_end - vma->vm_start; 634 stack_size = vma->vm_end - vma->vm_start;
635 /* 635 /*
636 * Align this down to a page boundary as expand_stack 636 * Align this down to a page boundary as expand_stack
@@ -718,6 +718,7 @@ static int exec_mmap(struct mm_struct *mm)
718 /* Notify parent that we're no longer interested in the old VM */ 718 /* Notify parent that we're no longer interested in the old VM */
719 tsk = current; 719 tsk = current;
720 old_mm = current->mm; 720 old_mm = current->mm;
721 sync_mm_rss(tsk, old_mm);
721 mm_release(tsk, old_mm); 722 mm_release(tsk, old_mm);
722 723
723 if (old_mm) { 724 if (old_mm) {
@@ -1532,7 +1533,7 @@ static int format_corename(char *corename, long signr)
1532 /* core limit size */ 1533 /* core limit size */
1533 case 'c': 1534 case 'c':
1534 rc = snprintf(out_ptr, out_end - out_ptr, 1535 rc = snprintf(out_ptr, out_end - out_ptr,
1535 "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur); 1536 "%lu", rlimit(RLIMIT_CORE));
1536 if (rc > out_end - out_ptr) 1537 if (rc > out_end - out_ptr)
1537 goto out; 1538 goto out;
1538 out_ptr += rc; 1539 out_ptr += rc;
@@ -1560,12 +1561,13 @@ out:
1560 return ispipe; 1561 return ispipe;
1561} 1562}
1562 1563
1563static int zap_process(struct task_struct *start) 1564static int zap_process(struct task_struct *start, int exit_code)
1564{ 1565{
1565 struct task_struct *t; 1566 struct task_struct *t;
1566 int nr = 0; 1567 int nr = 0;
1567 1568
1568 start->signal->flags = SIGNAL_GROUP_EXIT; 1569 start->signal->flags = SIGNAL_GROUP_EXIT;
1570 start->signal->group_exit_code = exit_code;
1569 start->signal->group_stop_count = 0; 1571 start->signal->group_stop_count = 0;
1570 1572
1571 t = start; 1573 t = start;
@@ -1590,8 +1592,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
1590 spin_lock_irq(&tsk->sighand->siglock); 1592 spin_lock_irq(&tsk->sighand->siglock);
1591 if (!signal_group_exit(tsk->signal)) { 1593 if (!signal_group_exit(tsk->signal)) {
1592 mm->core_state = core_state; 1594 mm->core_state = core_state;
1593 tsk->signal->group_exit_code = exit_code; 1595 nr = zap_process(tsk, exit_code);
1594 nr = zap_process(tsk);
1595 } 1596 }
1596 spin_unlock_irq(&tsk->sighand->siglock); 1597 spin_unlock_irq(&tsk->sighand->siglock);
1597 if (unlikely(nr < 0)) 1598 if (unlikely(nr < 0))
@@ -1640,7 +1641,7 @@ static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm,
1640 if (p->mm) { 1641 if (p->mm) {
1641 if (unlikely(p->mm == mm)) { 1642 if (unlikely(p->mm == mm)) {
1642 lock_task_sighand(p, &flags); 1643 lock_task_sighand(p, &flags);
1643 nr += zap_process(p); 1644 nr += zap_process(p, exit_code);
1644 unlock_task_sighand(p, &flags); 1645 unlock_task_sighand(p, &flags);
1645 } 1646 }
1646 break; 1647 break;
@@ -1747,14 +1748,19 @@ void set_dumpable(struct mm_struct *mm, int value)
1747 } 1748 }
1748} 1749}
1749 1750
1750int get_dumpable(struct mm_struct *mm) 1751static int __get_dumpable(unsigned long mm_flags)
1751{ 1752{
1752 int ret; 1753 int ret;
1753 1754
1754 ret = mm->flags & 0x3; 1755 ret = mm_flags & MMF_DUMPABLE_MASK;
1755 return (ret >= 2) ? 2 : ret; 1756 return (ret >= 2) ? 2 : ret;
1756} 1757}
1757 1758
1759int get_dumpable(struct mm_struct *mm)
1760{
1761 return __get_dumpable(mm->flags);
1762}
1763
1758static void wait_for_dump_helpers(struct file *file) 1764static void wait_for_dump_helpers(struct file *file)
1759{ 1765{
1760 struct pipe_inode_info *pipe; 1766 struct pipe_inode_info *pipe;
@@ -1797,7 +1803,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1797 struct coredump_params cprm = { 1803 struct coredump_params cprm = {
1798 .signr = signr, 1804 .signr = signr,
1799 .regs = regs, 1805 .regs = regs,
1800 .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur, 1806 .limit = rlimit(RLIMIT_CORE),
1807 /*
1808 * We must use the same mm->flags while dumping core to avoid
1809 * inconsistency of bit flags, since this flag is not protected
1810 * by any locks.
1811 */
1812 .mm_flags = mm->flags,
1801 }; 1813 };
1802 1814
1803 audit_core_dumps(signr); 1815 audit_core_dumps(signr);
@@ -1816,7 +1828,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1816 /* 1828 /*
1817 * If another thread got here first, or we are not dumpable, bail out. 1829 * If another thread got here first, or we are not dumpable, bail out.
1818 */ 1830 */
1819 if (mm->core_state || !get_dumpable(mm)) { 1831 if (mm->core_state || !__get_dumpable(cprm.mm_flags)) {
1820 up_write(&mm->mmap_sem); 1832 up_write(&mm->mmap_sem);
1821 put_cred(cred); 1833 put_cred(cred);
1822 goto fail; 1834 goto fail;
@@ -1827,7 +1839,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1827 * process nor do we know its entire history. We only know it 1839 * process nor do we know its entire history. We only know it
1828 * was tainted so we dump it as root in mode 2. 1840 * was tainted so we dump it as root in mode 2.
1829 */ 1841 */
1830 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ 1842 if (__get_dumpable(cprm.mm_flags) == 2) {
1843 /* Setuid core dump mode */
1831 flag = O_EXCL; /* Stop rewrite attacks */ 1844 flag = O_EXCL; /* Stop rewrite attacks */
1832 cred->fsuid = 0; /* Dump root private */ 1845 cred->fsuid = 0; /* Dump root private */
1833 } 1846 }
@@ -1923,8 +1936,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1923 /* 1936 /*
1924 * Dont allow local users get cute and trick others to coredump 1937 * Dont allow local users get cute and trick others to coredump
1925 * into their pre-created files: 1938 * into their pre-created files:
1939 * Note, this is not relevant for pipes
1926 */ 1940 */
1927 if (inode->i_uid != current_fsuid()) 1941 if (!ispipe && (inode->i_uid != current_fsuid()))
1928 goto close_fail; 1942 goto close_fail;
1929 if (!cprm.file->f_op) 1943 if (!cprm.file->f_op)
1930 goto close_fail; 1944 goto close_fail;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 97e01dc0d95f..452d02f9075e 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -344,7 +344,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
344 switch (cmd) { 344 switch (cmd) {
345 case F_DUPFD: 345 case F_DUPFD:
346 case F_DUPFD_CLOEXEC: 346 case F_DUPFD_CLOEXEC:
347 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) 347 if (arg >= rlimit(RLIMIT_NOFILE))
348 break; 348 break;
349 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0); 349 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
350 if (err >= 0) { 350 if (err >= 0) {
diff --git a/fs/file.c b/fs/file.c
index 38039af67663..34bb7f71d994 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -257,7 +257,7 @@ int expand_files(struct files_struct *files, int nr)
257 * N.B. For clone tasks sharing a files structure, this test 257 * N.B. For clone tasks sharing a files structure, this test
258 * will limit the total number of files that can be opened. 258 * will limit the total number of files that can be opened.
259 */ 259 */
260 if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) 260 if (nr >= rlimit(RLIMIT_NOFILE))
261 return -EMFILE; 261 return -EMFILE;
262 262
263 /* Do we need to expand? */ 263 /* Do we need to expand? */
diff --git a/fs/file_table.c b/fs/file_table.c
index b98404b54383..32d12b78bac8 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -393,7 +393,9 @@ retry:
393 continue; 393 continue;
394 if (!(f->f_mode & FMODE_WRITE)) 394 if (!(f->f_mode & FMODE_WRITE))
395 continue; 395 continue;
396 spin_lock(&f->f_lock);
396 f->f_mode &= ~FMODE_WRITE; 397 f->f_mode &= ~FMODE_WRITE;
398 spin_unlock(&f->f_lock);
397 if (file_check_writeable(f) != 0) 399 if (file_check_writeable(f) != 0)
398 continue; 400 continue;
399 file_release_write(f); 401 file_release_write(f);
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig
index 864dac20a242..cc94bb9563f2 100644
--- a/fs/fscache/Kconfig
+++ b/fs/fscache/Kconfig
@@ -1,7 +1,6 @@
1 1
2config FSCACHE 2config FSCACHE
3 tristate "General filesystem local caching manager" 3 tristate "General filesystem local caching manager"
4 depends on EXPERIMENTAL
5 select SLOW_WORK 4 select SLOW_WORK
6 help 5 help
7 This option enables a generic filesystem caching manager that can be 6 This option enables a generic filesystem caching manager that can be
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 4600c2037b8b..bb464d12104c 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -479,8 +479,8 @@ again: mutex_lock(&nlm_host_mutex);
479 } 479 }
480 } 480 }
481 } 481 }
482
483 mutex_unlock(&nlm_host_mutex); 482 mutex_unlock(&nlm_host_mutex);
483 nsm_release(nsm);
484} 484}
485 485
486/* 486/*
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index f956651d0f65..fefa4df3f005 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -349,9 +349,9 @@ retry:
349 * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle 349 * nsm_reboot_lookup - match NLMPROC_SM_NOTIFY arguments to an nsm_handle
350 * @info: pointer to NLMPROC_SM_NOTIFY arguments 350 * @info: pointer to NLMPROC_SM_NOTIFY arguments
351 * 351 *
352 * Returns a matching nsm_handle if found in the nsm cache; the returned 352 * Returns a matching nsm_handle if found in the nsm cache. The returned
353 * nsm_handle's reference count is bumped and sm_monitored is cleared. 353 * nsm_handle's reference count is bumped. Otherwise returns NULL if some
354 * Otherwise returns NULL if some error occurred. 354 * error occurred.
355 */ 355 */
356struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info) 356struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
357{ 357{
@@ -370,12 +370,6 @@ struct nsm_handle *nsm_reboot_lookup(const struct nlm_reboot *info)
370 atomic_inc(&cached->sm_count); 370 atomic_inc(&cached->sm_count);
371 spin_unlock(&nsm_lock); 371 spin_unlock(&nsm_lock);
372 372
373 /*
374 * During subsequent lock activity, force a fresh
375 * notification to be set up for this host.
376 */
377 cached->sm_monitored = 0;
378
379 dprintk("lockd: host %s (%s) rebooted, cnt %d\n", 373 dprintk("lockd: host %s (%s) rebooted, cnt %d\n",
380 cached->sm_name, cached->sm_addrbuf, 374 cached->sm_name, cached->sm_addrbuf,
381 atomic_read(&cached->sm_count)); 375 atomic_read(&cached->sm_count));
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index e50cfa3d9654..7d150517ddf0 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -243,11 +243,9 @@ static int make_socks(struct svc_serv *serv)
243 if (err < 0) 243 if (err < 0)
244 goto out_err; 244 goto out_err;
245 245
246#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
247 err = create_lockd_family(serv, PF_INET6); 246 err = create_lockd_family(serv, PF_INET6);
248 if (err < 0 && err != -EAFNOSUPPORT) 247 if (err < 0 && err != -EAFNOSUPPORT)
249 goto out_err; 248 goto out_err;
250#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
251 249
252 warned = 0; 250 warned = 0;
253 return 0; 251 return 0;
diff --git a/fs/logfs/Kconfig b/fs/logfs/Kconfig
new file mode 100644
index 000000000000..daf9a9b32dd3
--- /dev/null
+++ b/fs/logfs/Kconfig
@@ -0,0 +1,17 @@
1config LOGFS
2 tristate "LogFS file system (EXPERIMENTAL)"
3 depends on (MTD || BLOCK) && EXPERIMENTAL
4 select ZLIB_INFLATE
5 select ZLIB_DEFLATE
6 select CRC32
7 select BTREE
8 help
9 Flash filesystem aimed to scale efficiently to large devices.
10 In comparison to JFFS2 it offers significantly faster mount
11 times and potentially less RAM usage, although the latter has
12 not been measured yet.
13
14 In its current state it is still very experimental and should
15 not be used for other than testing purposes.
16
17 If unsure, say N.
diff --git a/fs/logfs/Makefile b/fs/logfs/Makefile
new file mode 100644
index 000000000000..4820027787ee
--- /dev/null
+++ b/fs/logfs/Makefile
@@ -0,0 +1,13 @@
1obj-$(CONFIG_LOGFS) += logfs.o
2
3logfs-y += compr.o
4logfs-y += dir.o
5logfs-y += file.o
6logfs-y += gc.o
7logfs-y += inode.o
8logfs-y += journal.o
9logfs-y += readwrite.o
10logfs-y += segment.o
11logfs-y += super.o
12logfs-$(CONFIG_BLOCK) += dev_bdev.o
13logfs-$(CONFIG_MTD) += dev_mtd.o
diff --git a/fs/logfs/compr.c b/fs/logfs/compr.c
new file mode 100644
index 000000000000..44bbfd249abc
--- /dev/null
+++ b/fs/logfs/compr.c
@@ -0,0 +1,95 @@
1/*
2 * fs/logfs/compr.c - compression routines
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9#include <linux/vmalloc.h>
10#include <linux/zlib.h>
11
12#define COMPR_LEVEL 3
13
14static DEFINE_MUTEX(compr_mutex);
15static struct z_stream_s stream;
16
17int logfs_compress(void *in, void *out, size_t inlen, size_t outlen)
18{
19 int err, ret;
20
21 ret = -EIO;
22 mutex_lock(&compr_mutex);
23 err = zlib_deflateInit(&stream, COMPR_LEVEL);
24 if (err != Z_OK)
25 goto error;
26
27 stream.next_in = in;
28 stream.avail_in = inlen;
29 stream.total_in = 0;
30 stream.next_out = out;
31 stream.avail_out = outlen;
32 stream.total_out = 0;
33
34 err = zlib_deflate(&stream, Z_FINISH);
35 if (err != Z_STREAM_END)
36 goto error;
37
38 err = zlib_deflateEnd(&stream);
39 if (err != Z_OK)
40 goto error;
41
42 if (stream.total_out >= stream.total_in)
43 goto error;
44
45 ret = stream.total_out;
46error:
47 mutex_unlock(&compr_mutex);
48 return ret;
49}
50
51int logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen)
52{
53 int err, ret;
54
55 ret = -EIO;
56 mutex_lock(&compr_mutex);
57 err = zlib_inflateInit(&stream);
58 if (err != Z_OK)
59 goto error;
60
61 stream.next_in = in;
62 stream.avail_in = inlen;
63 stream.total_in = 0;
64 stream.next_out = out;
65 stream.avail_out = outlen;
66 stream.total_out = 0;
67
68 err = zlib_inflate(&stream, Z_FINISH);
69 if (err != Z_STREAM_END)
70 goto error;
71
72 err = zlib_inflateEnd(&stream);
73 if (err != Z_OK)
74 goto error;
75
76 ret = 0;
77error:
78 mutex_unlock(&compr_mutex);
79 return ret;
80}
81
82int __init logfs_compr_init(void)
83{
84 size_t size = max(zlib_deflate_workspacesize(),
85 zlib_inflate_workspacesize());
86 stream.workspace = vmalloc(size);
87 if (!stream.workspace)
88 return -ENOMEM;
89 return 0;
90}
91
92void logfs_compr_exit(void)
93{
94 vfree(stream.workspace);
95}
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c
new file mode 100644
index 000000000000..9718c22f186d
--- /dev/null
+++ b/fs/logfs/dev_bdev.c
@@ -0,0 +1,327 @@
1/*
2 * fs/logfs/dev_bdev.c - Device access methods for block devices
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9#include <linux/bio.h>
10#include <linux/blkdev.h>
11#include <linux/buffer_head.h>
12
13#define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
14
15static void request_complete(struct bio *bio, int err)
16{
17 complete((struct completion *)bio->bi_private);
18}
19
20static int sync_request(struct page *page, struct block_device *bdev, int rw)
21{
22 struct bio bio;
23 struct bio_vec bio_vec;
24 struct completion complete;
25
26 bio_init(&bio);
27 bio.bi_io_vec = &bio_vec;
28 bio_vec.bv_page = page;
29 bio_vec.bv_len = PAGE_SIZE;
30 bio_vec.bv_offset = 0;
31 bio.bi_vcnt = 1;
32 bio.bi_idx = 0;
33 bio.bi_size = PAGE_SIZE;
34 bio.bi_bdev = bdev;
35 bio.bi_sector = page->index * (PAGE_SIZE >> 9);
36 init_completion(&complete);
37 bio.bi_private = &complete;
38 bio.bi_end_io = request_complete;
39
40 submit_bio(rw, &bio);
41 generic_unplug_device(bdev_get_queue(bdev));
42 wait_for_completion(&complete);
43 return test_bit(BIO_UPTODATE, &bio.bi_flags) ? 0 : -EIO;
44}
45
46static int bdev_readpage(void *_sb, struct page *page)
47{
48 struct super_block *sb = _sb;
49 struct block_device *bdev = logfs_super(sb)->s_bdev;
50 int err;
51
52 err = sync_request(page, bdev, READ);
53 if (err) {
54 ClearPageUptodate(page);
55 SetPageError(page);
56 } else {
57 SetPageUptodate(page);
58 ClearPageError(page);
59 }
60 unlock_page(page);
61 return err;
62}
63
64static DECLARE_WAIT_QUEUE_HEAD(wq);
65
66static void writeseg_end_io(struct bio *bio, int err)
67{
68 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
69 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
70 struct super_block *sb = bio->bi_private;
71 struct logfs_super *super = logfs_super(sb);
72 struct page *page;
73
74 BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */
75 BUG_ON(err);
76 BUG_ON(bio->bi_vcnt == 0);
77 do {
78 page = bvec->bv_page;
79 if (--bvec >= bio->bi_io_vec)
80 prefetchw(&bvec->bv_page->flags);
81
82 end_page_writeback(page);
83 } while (bvec >= bio->bi_io_vec);
84 bio_put(bio);
85 if (atomic_dec_and_test(&super->s_pending_writes))
86 wake_up(&wq);
87}
88
89static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
90 size_t nr_pages)
91{
92 struct logfs_super *super = logfs_super(sb);
93 struct address_space *mapping = super->s_mapping_inode->i_mapping;
94 struct bio *bio;
95 struct page *page;
96 struct request_queue *q = bdev_get_queue(sb->s_bdev);
97 unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
98 int i;
99
100 bio = bio_alloc(GFP_NOFS, max_pages);
101 BUG_ON(!bio); /* FIXME: handle this */
102
103 for (i = 0; i < nr_pages; i++) {
104 if (i >= max_pages) {
105 /* Block layer cannot split bios :( */
106 bio->bi_vcnt = i;
107 bio->bi_idx = 0;
108 bio->bi_size = i * PAGE_SIZE;
109 bio->bi_bdev = super->s_bdev;
110 bio->bi_sector = ofs >> 9;
111 bio->bi_private = sb;
112 bio->bi_end_io = writeseg_end_io;
113 atomic_inc(&super->s_pending_writes);
114 submit_bio(WRITE, bio);
115
116 ofs += i * PAGE_SIZE;
117 index += i;
118 nr_pages -= i;
119 i = 0;
120
121 bio = bio_alloc(GFP_NOFS, max_pages);
122 BUG_ON(!bio);
123 }
124 page = find_lock_page(mapping, index + i);
125 BUG_ON(!page);
126 bio->bi_io_vec[i].bv_page = page;
127 bio->bi_io_vec[i].bv_len = PAGE_SIZE;
128 bio->bi_io_vec[i].bv_offset = 0;
129
130 BUG_ON(PageWriteback(page));
131 set_page_writeback(page);
132 unlock_page(page);
133 }
134 bio->bi_vcnt = nr_pages;
135 bio->bi_idx = 0;
136 bio->bi_size = nr_pages * PAGE_SIZE;
137 bio->bi_bdev = super->s_bdev;
138 bio->bi_sector = ofs >> 9;
139 bio->bi_private = sb;
140 bio->bi_end_io = writeseg_end_io;
141 atomic_inc(&super->s_pending_writes);
142 submit_bio(WRITE, bio);
143 return 0;
144}
145
146static void bdev_writeseg(struct super_block *sb, u64 ofs, size_t len)
147{
148 struct logfs_super *super = logfs_super(sb);
149 int head;
150
151 BUG_ON(super->s_flags & LOGFS_SB_FLAG_RO);
152
153 if (len == 0) {
154 /* This can happen when the object fit perfectly into a
155 * segment, the segment gets written per sync and subsequently
156 * closed.
157 */
158 return;
159 }
160 head = ofs & (PAGE_SIZE - 1);
161 if (head) {
162 ofs -= head;
163 len += head;
164 }
165 len = PAGE_ALIGN(len);
166 __bdev_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT);
167 generic_unplug_device(bdev_get_queue(logfs_super(sb)->s_bdev));
168}
169
170
171static void erase_end_io(struct bio *bio, int err)
172{
173 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
174 struct super_block *sb = bio->bi_private;
175 struct logfs_super *super = logfs_super(sb);
176
177 BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */
178 BUG_ON(err);
179 BUG_ON(bio->bi_vcnt == 0);
180 bio_put(bio);
181 if (atomic_dec_and_test(&super->s_pending_writes))
182 wake_up(&wq);
183}
184
185static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index,
186 size_t nr_pages)
187{
188 struct logfs_super *super = logfs_super(sb);
189 struct bio *bio;
190 struct request_queue *q = bdev_get_queue(sb->s_bdev);
191 unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9);
192 int i;
193
194 bio = bio_alloc(GFP_NOFS, max_pages);
195 BUG_ON(!bio); /* FIXME: handle this */
196
197 for (i = 0; i < nr_pages; i++) {
198 if (i >= max_pages) {
199 /* Block layer cannot split bios :( */
200 bio->bi_vcnt = i;
201 bio->bi_idx = 0;
202 bio->bi_size = i * PAGE_SIZE;
203 bio->bi_bdev = super->s_bdev;
204 bio->bi_sector = ofs >> 9;
205 bio->bi_private = sb;
206 bio->bi_end_io = erase_end_io;
207 atomic_inc(&super->s_pending_writes);
208 submit_bio(WRITE, bio);
209
210 ofs += i * PAGE_SIZE;
211 index += i;
212 nr_pages -= i;
213 i = 0;
214
215 bio = bio_alloc(GFP_NOFS, max_pages);
216 BUG_ON(!bio);
217 }
218 bio->bi_io_vec[i].bv_page = super->s_erase_page;
219 bio->bi_io_vec[i].bv_len = PAGE_SIZE;
220 bio->bi_io_vec[i].bv_offset = 0;
221 }
222 bio->bi_vcnt = nr_pages;
223 bio->bi_idx = 0;
224 bio->bi_size = nr_pages * PAGE_SIZE;
225 bio->bi_bdev = super->s_bdev;
226 bio->bi_sector = ofs >> 9;
227 bio->bi_private = sb;
228 bio->bi_end_io = erase_end_io;
229 atomic_inc(&super->s_pending_writes);
230 submit_bio(WRITE, bio);
231 return 0;
232}
233
234static int bdev_erase(struct super_block *sb, loff_t to, size_t len,
235 int ensure_write)
236{
237 struct logfs_super *super = logfs_super(sb);
238
239 BUG_ON(to & (PAGE_SIZE - 1));
240 BUG_ON(len & (PAGE_SIZE - 1));
241
242 if (super->s_flags & LOGFS_SB_FLAG_RO)
243 return -EROFS;
244
245 if (ensure_write) {
246 /*
247 * Object store doesn't care whether erases happen or not.
248 * But for the journal they are required. Otherwise a scan
249 * can find an old commit entry and assume it is the current
250 * one, travelling back in time.
251 */
252 do_erase(sb, to, to >> PAGE_SHIFT, len >> PAGE_SHIFT);
253 }
254
255 return 0;
256}
257
258static void bdev_sync(struct super_block *sb)
259{
260 struct logfs_super *super = logfs_super(sb);
261
262 wait_event(wq, atomic_read(&super->s_pending_writes) == 0);
263}
264
265static struct page *bdev_find_first_sb(struct super_block *sb, u64 *ofs)
266{
267 struct logfs_super *super = logfs_super(sb);
268 struct address_space *mapping = super->s_mapping_inode->i_mapping;
269 filler_t *filler = bdev_readpage;
270
271 *ofs = 0;
272 return read_cache_page(mapping, 0, filler, sb);
273}
274
275static struct page *bdev_find_last_sb(struct super_block *sb, u64 *ofs)
276{
277 struct logfs_super *super = logfs_super(sb);
278 struct address_space *mapping = super->s_mapping_inode->i_mapping;
279 filler_t *filler = bdev_readpage;
280 u64 pos = (super->s_bdev->bd_inode->i_size & ~0xfffULL) - 0x1000;
281 pgoff_t index = pos >> PAGE_SHIFT;
282
283 *ofs = pos;
284 return read_cache_page(mapping, index, filler, sb);
285}
286
287static int bdev_write_sb(struct super_block *sb, struct page *page)
288{
289 struct block_device *bdev = logfs_super(sb)->s_bdev;
290
291 /* Nothing special to do for block devices. */
292 return sync_request(page, bdev, WRITE);
293}
294
295static void bdev_put_device(struct super_block *sb)
296{
297 close_bdev_exclusive(logfs_super(sb)->s_bdev, FMODE_READ|FMODE_WRITE);
298}
299
300static const struct logfs_device_ops bd_devops = {
301 .find_first_sb = bdev_find_first_sb,
302 .find_last_sb = bdev_find_last_sb,
303 .write_sb = bdev_write_sb,
304 .readpage = bdev_readpage,
305 .writeseg = bdev_writeseg,
306 .erase = bdev_erase,
307 .sync = bdev_sync,
308 .put_device = bdev_put_device,
309};
310
311int logfs_get_sb_bdev(struct file_system_type *type, int flags,
312 const char *devname, struct vfsmount *mnt)
313{
314 struct block_device *bdev;
315
316 bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, type);
317 if (IS_ERR(bdev))
318 return PTR_ERR(bdev);
319
320 if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
321 int mtdnr = MINOR(bdev->bd_dev);
322 close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
323 return logfs_get_sb_mtd(type, flags, mtdnr, mnt);
324 }
325
326 return logfs_get_sb_device(type, flags, NULL, bdev, &bd_devops, mnt);
327}
diff --git a/fs/logfs/dev_mtd.c b/fs/logfs/dev_mtd.c
new file mode 100644
index 000000000000..cafb6ef2e05b
--- /dev/null
+++ b/fs/logfs/dev_mtd.c
@@ -0,0 +1,254 @@
1/*
2 * fs/logfs/dev_mtd.c - Device access methods for MTD
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9#include <linux/completion.h>
10#include <linux/mount.h>
11#include <linux/sched.h>
12
13#define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
14
15static int mtd_read(struct super_block *sb, loff_t ofs, size_t len, void *buf)
16{
17 struct mtd_info *mtd = logfs_super(sb)->s_mtd;
18 size_t retlen;
19 int ret;
20
21 ret = mtd->read(mtd, ofs, len, &retlen, buf);
22 BUG_ON(ret == -EINVAL);
23 if (ret)
24 return ret;
25
26 /* Not sure if we should loop instead. */
27 if (retlen != len)
28 return -EIO;
29
30 return 0;
31}
32
33static int mtd_write(struct super_block *sb, loff_t ofs, size_t len, void *buf)
34{
35 struct logfs_super *super = logfs_super(sb);
36 struct mtd_info *mtd = super->s_mtd;
37 size_t retlen;
38 loff_t page_start, page_end;
39 int ret;
40
41 if (super->s_flags & LOGFS_SB_FLAG_RO)
42 return -EROFS;
43
44 BUG_ON((ofs >= mtd->size) || (len > mtd->size - ofs));
45 BUG_ON(ofs != (ofs >> super->s_writeshift) << super->s_writeshift);
46 BUG_ON(len > PAGE_CACHE_SIZE);
47 page_start = ofs & PAGE_CACHE_MASK;
48 page_end = PAGE_CACHE_ALIGN(ofs + len) - 1;
49 ret = mtd->write(mtd, ofs, len, &retlen, buf);
50 if (ret || (retlen != len))
51 return -EIO;
52
53 return 0;
54}
55
56/*
57 * For as long as I can remember (since about 2001) mtd->erase has been an
58 * asynchronous interface lacking the first driver to actually use the
59 * asynchronous properties. So just to prevent the first implementor of such
60 * a thing from breaking logfs in 2350, we do the usual pointless dance to
61 * declare a completion variable and wait for completion before returning
62 * from mtd_erase(). What an excercise in futility!
63 */
64static void logfs_erase_callback(struct erase_info *ei)
65{
66 complete((struct completion *)ei->priv);
67}
68
69static int mtd_erase_mapping(struct super_block *sb, loff_t ofs, size_t len)
70{
71 struct logfs_super *super = logfs_super(sb);
72 struct address_space *mapping = super->s_mapping_inode->i_mapping;
73 struct page *page;
74 pgoff_t index = ofs >> PAGE_SHIFT;
75
76 for (index = ofs >> PAGE_SHIFT; index < (ofs + len) >> PAGE_SHIFT; index++) {
77 page = find_get_page(mapping, index);
78 if (!page)
79 continue;
80 memset(page_address(page), 0xFF, PAGE_SIZE);
81 page_cache_release(page);
82 }
83 return 0;
84}
85
86static int mtd_erase(struct super_block *sb, loff_t ofs, size_t len,
87 int ensure_write)
88{
89 struct mtd_info *mtd = logfs_super(sb)->s_mtd;
90 struct erase_info ei;
91 DECLARE_COMPLETION_ONSTACK(complete);
92 int ret;
93
94 BUG_ON(len % mtd->erasesize);
95 if (logfs_super(sb)->s_flags & LOGFS_SB_FLAG_RO)
96 return -EROFS;
97
98 memset(&ei, 0, sizeof(ei));
99 ei.mtd = mtd;
100 ei.addr = ofs;
101 ei.len = len;
102 ei.callback = logfs_erase_callback;
103 ei.priv = (long)&complete;
104 ret = mtd->erase(mtd, &ei);
105 if (ret)
106 return -EIO;
107
108 wait_for_completion(&complete);
109 if (ei.state != MTD_ERASE_DONE)
110 return -EIO;
111 return mtd_erase_mapping(sb, ofs, len);
112}
113
114static void mtd_sync(struct super_block *sb)
115{
116 struct mtd_info *mtd = logfs_super(sb)->s_mtd;
117
118 if (mtd->sync)
119 mtd->sync(mtd);
120}
121
122static int mtd_readpage(void *_sb, struct page *page)
123{
124 struct super_block *sb = _sb;
125 int err;
126
127 err = mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
128 page_address(page));
129 if (err == -EUCLEAN) {
130 err = 0;
131 /* FIXME: force GC this segment */
132 }
133 if (err) {
134 ClearPageUptodate(page);
135 SetPageError(page);
136 } else {
137 SetPageUptodate(page);
138 ClearPageError(page);
139 }
140 unlock_page(page);
141 return err;
142}
143
144static struct page *mtd_find_first_sb(struct super_block *sb, u64 *ofs)
145{
146 struct logfs_super *super = logfs_super(sb);
147 struct address_space *mapping = super->s_mapping_inode->i_mapping;
148 filler_t *filler = mtd_readpage;
149 struct mtd_info *mtd = super->s_mtd;
150
151 if (!mtd->block_isbad)
152 return NULL;
153
154 *ofs = 0;
155 while (mtd->block_isbad(mtd, *ofs)) {
156 *ofs += mtd->erasesize;
157 if (*ofs >= mtd->size)
158 return NULL;
159 }
160 BUG_ON(*ofs & ~PAGE_MASK);
161 return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb);
162}
163
164static struct page *mtd_find_last_sb(struct super_block *sb, u64 *ofs)
165{
166 struct logfs_super *super = logfs_super(sb);
167 struct address_space *mapping = super->s_mapping_inode->i_mapping;
168 filler_t *filler = mtd_readpage;
169 struct mtd_info *mtd = super->s_mtd;
170
171 if (!mtd->block_isbad)
172 return NULL;
173
174 *ofs = mtd->size - mtd->erasesize;
175 while (mtd->block_isbad(mtd, *ofs)) {
176 *ofs -= mtd->erasesize;
177 if (*ofs <= 0)
178 return NULL;
179 }
180 *ofs = *ofs + mtd->erasesize - 0x1000;
181 BUG_ON(*ofs & ~PAGE_MASK);
182 return read_cache_page(mapping, *ofs >> PAGE_SHIFT, filler, sb);
183}
184
185static int __mtd_writeseg(struct super_block *sb, u64 ofs, pgoff_t index,
186 size_t nr_pages)
187{
188 struct logfs_super *super = logfs_super(sb);
189 struct address_space *mapping = super->s_mapping_inode->i_mapping;
190 struct page *page;
191 int i, err;
192
193 for (i = 0; i < nr_pages; i++) {
194 page = find_lock_page(mapping, index + i);
195 BUG_ON(!page);
196
197 err = mtd_write(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
198 page_address(page));
199 unlock_page(page);
200 page_cache_release(page);
201 if (err)
202 return err;
203 }
204 return 0;
205}
206
207static void mtd_writeseg(struct super_block *sb, u64 ofs, size_t len)
208{
209 struct logfs_super *super = logfs_super(sb);
210 int head;
211
212 if (super->s_flags & LOGFS_SB_FLAG_RO)
213 return;
214
215 if (len == 0) {
216 /* This can happen when the object fit perfectly into a
217 * segment, the segment gets written per sync and subsequently
218 * closed.
219 */
220 return;
221 }
222 head = ofs & (PAGE_SIZE - 1);
223 if (head) {
224 ofs -= head;
225 len += head;
226 }
227 len = PAGE_ALIGN(len);
228 __mtd_writeseg(sb, ofs, ofs >> PAGE_SHIFT, len >> PAGE_SHIFT);
229}
230
231static void mtd_put_device(struct super_block *sb)
232{
233 put_mtd_device(logfs_super(sb)->s_mtd);
234}
235
236static const struct logfs_device_ops mtd_devops = {
237 .find_first_sb = mtd_find_first_sb,
238 .find_last_sb = mtd_find_last_sb,
239 .readpage = mtd_readpage,
240 .writeseg = mtd_writeseg,
241 .erase = mtd_erase,
242 .sync = mtd_sync,
243 .put_device = mtd_put_device,
244};
245
246int logfs_get_sb_mtd(struct file_system_type *type, int flags,
247 int mtdnr, struct vfsmount *mnt)
248{
249 struct mtd_info *mtd;
250 const struct logfs_device_ops *devops = &mtd_devops;
251
252 mtd = get_mtd_device(NULL, mtdnr);
253 return logfs_get_sb_device(type, flags, mtd, NULL, devops, mnt);
254}
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
new file mode 100644
index 000000000000..56a8bfbb0120
--- /dev/null
+++ b/fs/logfs/dir.c
@@ -0,0 +1,827 @@
1/*
2 * fs/logfs/dir.c - directory-related code
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9
10
11/*
12 * Atomic dir operations
13 *
14 * Directory operations are by default not atomic. Dentries and Inodes are
15 * created/removed/altered in seperate operations. Therefore we need to do
16 * a small amount of journaling.
17 *
18 * Create, link, mkdir, mknod and symlink all share the same function to do
19 * the work: __logfs_create. This function works in two atomic steps:
20 * 1. allocate inode (remember in journal)
21 * 2. allocate dentry (clear journal)
22 *
23 * As we can only get interrupted between the two, when the inode we just
24 * created is simply stored in the anchor. On next mount, if we were
25 * interrupted, we delete the inode. From a users point of view the
26 * operation never happened.
27 *
28 * Unlink and rmdir also share the same function: unlink. Again, this
29 * function works in two atomic steps
30 * 1. remove dentry (remember inode in journal)
31 * 2. unlink inode (clear journal)
32 *
33 * And again, on the next mount, if we were interrupted, we delete the inode.
34 * From a users point of view the operation succeeded.
35 *
36 * Rename is the real pain to deal with, harder than all the other methods
37 * combined. Depending on the circumstances we can run into three cases.
38 * A "target rename" where the target dentry already existed, a "local
39 * rename" where both parent directories are identical or a "cross-directory
40 * rename" in the remaining case.
41 *
42 * Local rename is atomic, as the old dentry is simply rewritten with a new
43 * name.
44 *
45 * Cross-directory rename works in two steps, similar to __logfs_create and
46 * logfs_unlink:
47 * 1. Write new dentry (remember old dentry in journal)
48 * 2. Remove old dentry (clear journal)
49 *
50 * Here we remember a dentry instead of an inode. On next mount, if we were
51 * interrupted, we delete the dentry. From a users point of view, the
52 * operation succeeded.
53 *
54 * Target rename works in three atomic steps:
55 * 1. Attach old inode to new dentry (remember old dentry and new inode)
56 * 2. Remove old dentry (still remember the new inode)
57 * 3. Remove victim inode
58 *
59 * Here we remember both an inode an a dentry. If we get interrupted
60 * between steps 1 and 2, we delete both the dentry and the inode. If
61 * we get interrupted between steps 2 and 3, we delete just the inode.
62 * In either case, the remaining objects are deleted on next mount. From
63 * a users point of view, the operation succeeded.
64 */
65
66static int write_dir(struct inode *dir, struct logfs_disk_dentry *dd,
67 loff_t pos)
68{
69 return logfs_inode_write(dir, dd, sizeof(*dd), pos, WF_LOCK, NULL);
70}
71
72static int write_inode(struct inode *inode)
73{
74 return __logfs_write_inode(inode, WF_LOCK);
75}
76
77static s64 dir_seek_data(struct inode *inode, s64 pos)
78{
79 s64 new_pos = logfs_seek_data(inode, pos);
80
81 return max(pos, new_pos - 1);
82}
83
84static int beyond_eof(struct inode *inode, loff_t bix)
85{
86 loff_t pos = bix << inode->i_sb->s_blocksize_bits;
87 return pos >= i_size_read(inode);
88}
89
90/*
91 * Prime value was chosen to be roughly 256 + 26. r5 hash uses 11,
92 * so short names (len <= 9) don't even occupy the complete 32bit name
93 * space. A prime >256 ensures short names quickly spread the 32bit
94 * name space. Add about 26 for the estimated amount of information
95 * of each character and pick a prime nearby, preferrably a bit-sparse
96 * one.
97 */
98static u32 hash_32(const char *s, int len, u32 seed)
99{
100 u32 hash = seed;
101 int i;
102
103 for (i = 0; i < len; i++)
104 hash = hash * 293 + s[i];
105 return hash;
106}
107
108/*
109 * We have to satisfy several conflicting requirements here. Small
110 * directories should stay fairly compact and not require too many
111 * indirect blocks. The number of possible locations for a given hash
112 * should be small to make lookup() fast. And we should try hard not
113 * to overflow the 32bit name space or nfs and 32bit host systems will
114 * be unhappy.
115 *
116 * So we use the following scheme. First we reduce the hash to 0..15
117 * and try a direct block. If that is occupied we reduce the hash to
118 * 16..255 and try an indirect block. Same for 2x and 3x indirect
119 * blocks. Lastly we reduce the hash to 0x800_0000 .. 0xffff_ffff,
120 * but use buckets containing eight entries instead of a single one.
121 *
122 * Using 16 entries should allow for a reasonable amount of hash
123 * collisions, so the 32bit name space can be packed fairly tight
124 * before overflowing. Oh and currently we don't overflow but return
125 * and error.
126 *
127 * How likely are collisions? Doing the appropriate math is beyond me
128 * and the Bronstein textbook. But running a test program to brute
129 * force collisions for a couple of days showed that on average the
130 * first collision occurs after 598M entries, with 290M being the
131 * smallest result. Obviously 21 entries could already cause a
132 * collision if all entries are carefully chosen.
133 */
134static pgoff_t hash_index(u32 hash, int round)
135{
136 u32 i0_blocks = I0_BLOCKS;
137 u32 i1_blocks = I1_BLOCKS;
138 u32 i2_blocks = I2_BLOCKS;
139 u32 i3_blocks = I3_BLOCKS;
140
141 switch (round) {
142 case 0:
143 return hash % i0_blocks;
144 case 1:
145 return i0_blocks + hash % (i1_blocks - i0_blocks);
146 case 2:
147 return i1_blocks + hash % (i2_blocks - i1_blocks);
148 case 3:
149 return i2_blocks + hash % (i3_blocks - i2_blocks);
150 case 4 ... 19:
151 return i3_blocks + 16 * (hash % (((1<<31) - i3_blocks) / 16))
152 + round - 4;
153 }
154 BUG();
155}
156
157static struct page *logfs_get_dd_page(struct inode *dir, struct dentry *dentry)
158{
159 struct qstr *name = &dentry->d_name;
160 struct page *page;
161 struct logfs_disk_dentry *dd;
162 u32 hash = hash_32(name->name, name->len, 0);
163 pgoff_t index;
164 int round;
165
166 if (name->len > LOGFS_MAX_NAMELEN)
167 return ERR_PTR(-ENAMETOOLONG);
168
169 for (round = 0; round < 20; round++) {
170 index = hash_index(hash, round);
171
172 if (beyond_eof(dir, index))
173 return NULL;
174 if (!logfs_exist_block(dir, index))
175 continue;
176 page = read_cache_page(dir->i_mapping, index,
177 (filler_t *)logfs_readpage, NULL);
178 if (IS_ERR(page))
179 return page;
180 dd = kmap_atomic(page, KM_USER0);
181 BUG_ON(dd->namelen == 0);
182
183 if (name->len != be16_to_cpu(dd->namelen) ||
184 memcmp(name->name, dd->name, name->len)) {
185 kunmap_atomic(dd, KM_USER0);
186 page_cache_release(page);
187 continue;
188 }
189
190 kunmap_atomic(dd, KM_USER0);
191 return page;
192 }
193 return NULL;
194}
195
196static int logfs_remove_inode(struct inode *inode)
197{
198 int ret;
199
200 inode->i_nlink--;
201 ret = write_inode(inode);
202 LOGFS_BUG_ON(ret, inode->i_sb);
203 return ret;
204}
205
206static void abort_transaction(struct inode *inode, struct logfs_transaction *ta)
207{
208 if (logfs_inode(inode)->li_block)
209 logfs_inode(inode)->li_block->ta = NULL;
210 kfree(ta);
211}
212
213static int logfs_unlink(struct inode *dir, struct dentry *dentry)
214{
215 struct logfs_super *super = logfs_super(dir->i_sb);
216 struct inode *inode = dentry->d_inode;
217 struct logfs_transaction *ta;
218 struct page *page;
219 pgoff_t index;
220 int ret;
221
222 ta = kzalloc(sizeof(*ta), GFP_KERNEL);
223 if (!ta)
224 return -ENOMEM;
225
226 ta->state = UNLINK_1;
227 ta->ino = inode->i_ino;
228
229 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
230
231 page = logfs_get_dd_page(dir, dentry);
232 if (!page) {
233 kfree(ta);
234 return -ENOENT;
235 }
236 if (IS_ERR(page)) {
237 kfree(ta);
238 return PTR_ERR(page);
239 }
240 index = page->index;
241 page_cache_release(page);
242
243 mutex_lock(&super->s_dirop_mutex);
244 logfs_add_transaction(dir, ta);
245
246 ret = logfs_delete(dir, index, NULL);
247 if (!ret)
248 ret = write_inode(dir);
249
250 if (ret) {
251 abort_transaction(dir, ta);
252 printk(KERN_ERR"LOGFS: unable to delete inode\n");
253 goto out;
254 }
255
256 ta->state = UNLINK_2;
257 logfs_add_transaction(inode, ta);
258 ret = logfs_remove_inode(inode);
259out:
260 mutex_unlock(&super->s_dirop_mutex);
261 return ret;
262}
263
264static inline int logfs_empty_dir(struct inode *dir)
265{
266 u64 data;
267
268 data = logfs_seek_data(dir, 0) << dir->i_sb->s_blocksize_bits;
269 return data >= i_size_read(dir);
270}
271
272static int logfs_rmdir(struct inode *dir, struct dentry *dentry)
273{
274 struct inode *inode = dentry->d_inode;
275
276 if (!logfs_empty_dir(inode))
277 return -ENOTEMPTY;
278
279 return logfs_unlink(dir, dentry);
280}
281
282/* FIXME: readdir currently has it's own dir_walk code. I don't see a good
283 * way to combine the two copies */
284#define IMPLICIT_NODES 2
285static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir)
286{
287 struct inode *dir = file->f_dentry->d_inode;
288 loff_t pos = file->f_pos - IMPLICIT_NODES;
289 struct page *page;
290 struct logfs_disk_dentry *dd;
291 int full;
292
293 BUG_ON(pos < 0);
294 for (;; pos++) {
295 if (beyond_eof(dir, pos))
296 break;
297 if (!logfs_exist_block(dir, pos)) {
298 /* deleted dentry */
299 pos = dir_seek_data(dir, pos);
300 continue;
301 }
302 page = read_cache_page(dir->i_mapping, pos,
303 (filler_t *)logfs_readpage, NULL);
304 if (IS_ERR(page))
305 return PTR_ERR(page);
306 dd = kmap_atomic(page, KM_USER0);
307 BUG_ON(dd->namelen == 0);
308
309 full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen),
310 pos, be64_to_cpu(dd->ino), dd->type);
311 kunmap_atomic(dd, KM_USER0);
312 page_cache_release(page);
313 if (full)
314 break;
315 }
316
317 file->f_pos = pos + IMPLICIT_NODES;
318 return 0;
319}
320
321static int logfs_readdir(struct file *file, void *buf, filldir_t filldir)
322{
323 struct inode *inode = file->f_dentry->d_inode;
324 ino_t pino = parent_ino(file->f_dentry);
325 int err;
326
327 if (file->f_pos < 0)
328 return -EINVAL;
329
330 if (file->f_pos == 0) {
331 if (filldir(buf, ".", 1, 1, inode->i_ino, DT_DIR) < 0)
332 return 0;
333 file->f_pos++;
334 }
335 if (file->f_pos == 1) {
336 if (filldir(buf, "..", 2, 2, pino, DT_DIR) < 0)
337 return 0;
338 file->f_pos++;
339 }
340
341 err = __logfs_readdir(file, buf, filldir);
342 return err;
343}
344
345static void logfs_set_name(struct logfs_disk_dentry *dd, struct qstr *name)
346{
347 dd->namelen = cpu_to_be16(name->len);
348 memcpy(dd->name, name->name, name->len);
349}
350
351static struct dentry *logfs_lookup(struct inode *dir, struct dentry *dentry,
352 struct nameidata *nd)
353{
354 struct page *page;
355 struct logfs_disk_dentry *dd;
356 pgoff_t index;
357 u64 ino = 0;
358 struct inode *inode;
359
360 page = logfs_get_dd_page(dir, dentry);
361 if (IS_ERR(page))
362 return ERR_CAST(page);
363 if (!page) {
364 d_add(dentry, NULL);
365 return NULL;
366 }
367 index = page->index;
368 dd = kmap_atomic(page, KM_USER0);
369 ino = be64_to_cpu(dd->ino);
370 kunmap_atomic(dd, KM_USER0);
371 page_cache_release(page);
372
373 inode = logfs_iget(dir->i_sb, ino);
374 if (IS_ERR(inode)) {
375 printk(KERN_ERR"LogFS: Cannot read inode #%llx for dentry (%lx, %lx)n",
376 ino, dir->i_ino, index);
377 return ERR_CAST(inode);
378 }
379 return d_splice_alias(inode, dentry);
380}
381
382static void grow_dir(struct inode *dir, loff_t index)
383{
384 index = (index + 1) << dir->i_sb->s_blocksize_bits;
385 if (i_size_read(dir) < index)
386 i_size_write(dir, index);
387}
388
389static int logfs_write_dir(struct inode *dir, struct dentry *dentry,
390 struct inode *inode)
391{
392 struct page *page;
393 struct logfs_disk_dentry *dd;
394 u32 hash = hash_32(dentry->d_name.name, dentry->d_name.len, 0);
395 pgoff_t index;
396 int round, err;
397
398 for (round = 0; round < 20; round++) {
399 index = hash_index(hash, round);
400
401 if (logfs_exist_block(dir, index))
402 continue;
403 page = find_or_create_page(dir->i_mapping, index, GFP_KERNEL);
404 if (!page)
405 return -ENOMEM;
406
407 dd = kmap_atomic(page, KM_USER0);
408 memset(dd, 0, sizeof(*dd));
409 dd->ino = cpu_to_be64(inode->i_ino);
410 dd->type = logfs_type(inode);
411 logfs_set_name(dd, &dentry->d_name);
412 kunmap_atomic(dd, KM_USER0);
413
414 err = logfs_write_buf(dir, page, WF_LOCK);
415 unlock_page(page);
416 page_cache_release(page);
417 if (!err)
418 grow_dir(dir, index);
419 return err;
420 }
421 /* FIXME: Is there a better return value? In most cases neither
422 * the filesystem nor the directory are full. But we have had
423 * too many collisions for this particular hash and no fallback.
424 */
425 return -ENOSPC;
426}
427
428static int __logfs_create(struct inode *dir, struct dentry *dentry,
429 struct inode *inode, const char *dest, long destlen)
430{
431 struct logfs_super *super = logfs_super(dir->i_sb);
432 struct logfs_inode *li = logfs_inode(inode);
433 struct logfs_transaction *ta;
434 int ret;
435
436 ta = kzalloc(sizeof(*ta), GFP_KERNEL);
437 if (!ta)
438 return -ENOMEM;
439
440 ta->state = CREATE_1;
441 ta->ino = inode->i_ino;
442 mutex_lock(&super->s_dirop_mutex);
443 logfs_add_transaction(inode, ta);
444
445 if (dest) {
446 /* symlink */
447 ret = logfs_inode_write(inode, dest, destlen, 0, WF_LOCK, NULL);
448 if (!ret)
449 ret = write_inode(inode);
450 } else {
451 /* creat/mkdir/mknod */
452 ret = write_inode(inode);
453 }
454 if (ret) {
455 abort_transaction(inode, ta);
456 li->li_flags |= LOGFS_IF_STILLBORN;
457 /* FIXME: truncate symlink */
458 inode->i_nlink--;
459 iput(inode);
460 goto out;
461 }
462
463 ta->state = CREATE_2;
464 logfs_add_transaction(dir, ta);
465 ret = logfs_write_dir(dir, dentry, inode);
466 /* sync directory */
467 if (!ret)
468 ret = write_inode(dir);
469
470 if (ret) {
471 logfs_del_transaction(dir, ta);
472 ta->state = CREATE_2;
473 logfs_add_transaction(inode, ta);
474 logfs_remove_inode(inode);
475 iput(inode);
476 goto out;
477 }
478 d_instantiate(dentry, inode);
479out:
480 mutex_unlock(&super->s_dirop_mutex);
481 return ret;
482}
483
484static int logfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
485{
486 struct inode *inode;
487
488 /*
489 * FIXME: why do we have to fill in S_IFDIR, while the mode is
490 * correct for mknod, creat, etc.? Smells like the vfs *should*
491 * do it for us but for some reason fails to do so.
492 */
493 inode = logfs_new_inode(dir, S_IFDIR | mode);
494 if (IS_ERR(inode))
495 return PTR_ERR(inode);
496
497 inode->i_op = &logfs_dir_iops;
498 inode->i_fop = &logfs_dir_fops;
499
500 return __logfs_create(dir, dentry, inode, NULL, 0);
501}
502
503static int logfs_create(struct inode *dir, struct dentry *dentry, int mode,
504 struct nameidata *nd)
505{
506 struct inode *inode;
507
508 inode = logfs_new_inode(dir, mode);
509 if (IS_ERR(inode))
510 return PTR_ERR(inode);
511
512 inode->i_op = &logfs_reg_iops;
513 inode->i_fop = &logfs_reg_fops;
514 inode->i_mapping->a_ops = &logfs_reg_aops;
515
516 return __logfs_create(dir, dentry, inode, NULL, 0);
517}
518
519static int logfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
520 dev_t rdev)
521{
522 struct inode *inode;
523
524 if (dentry->d_name.len > LOGFS_MAX_NAMELEN)
525 return -ENAMETOOLONG;
526
527 inode = logfs_new_inode(dir, mode);
528 if (IS_ERR(inode))
529 return PTR_ERR(inode);
530
531 init_special_inode(inode, mode, rdev);
532
533 return __logfs_create(dir, dentry, inode, NULL, 0);
534}
535
536static int logfs_symlink(struct inode *dir, struct dentry *dentry,
537 const char *target)
538{
539 struct inode *inode;
540 size_t destlen = strlen(target) + 1;
541
542 if (destlen > dir->i_sb->s_blocksize)
543 return -ENAMETOOLONG;
544
545 inode = logfs_new_inode(dir, S_IFLNK | 0777);
546 if (IS_ERR(inode))
547 return PTR_ERR(inode);
548
549 inode->i_op = &logfs_symlink_iops;
550 inode->i_mapping->a_ops = &logfs_reg_aops;
551
552 return __logfs_create(dir, dentry, inode, target, destlen);
553}
554
555static int logfs_permission(struct inode *inode, int mask)
556{
557 return generic_permission(inode, mask, NULL);
558}
559
560static int logfs_link(struct dentry *old_dentry, struct inode *dir,
561 struct dentry *dentry)
562{
563 struct inode *inode = old_dentry->d_inode;
564
565 if (inode->i_nlink >= LOGFS_LINK_MAX)
566 return -EMLINK;
567
568 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
569 atomic_inc(&inode->i_count);
570 inode->i_nlink++;
571 mark_inode_dirty_sync(inode);
572
573 return __logfs_create(dir, dentry, inode, NULL, 0);
574}
575
576static int logfs_get_dd(struct inode *dir, struct dentry *dentry,
577 struct logfs_disk_dentry *dd, loff_t *pos)
578{
579 struct page *page;
580 void *map;
581
582 page = logfs_get_dd_page(dir, dentry);
583 if (IS_ERR(page))
584 return PTR_ERR(page);
585 *pos = page->index;
586 map = kmap_atomic(page, KM_USER0);
587 memcpy(dd, map, sizeof(*dd));
588 kunmap_atomic(map, KM_USER0);
589 page_cache_release(page);
590 return 0;
591}
592
593static int logfs_delete_dd(struct inode *dir, loff_t pos)
594{
595 /*
596 * Getting called with pos somewhere beyond eof is either a goofup
597 * within this file or means someone maliciously edited the
598 * (crc-protected) journal.
599 */
600 BUG_ON(beyond_eof(dir, pos));
601 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
602 log_dir(" Delete dentry (%lx, %llx)\n", dir->i_ino, pos);
603 return logfs_delete(dir, pos, NULL);
604}
605
606/*
607 * Cross-directory rename, target does not exist. Just a little nasty.
608 * Create a new dentry in the target dir, then remove the old dentry,
609 * all the while taking care to remember our operation in the journal.
610 */
611static int logfs_rename_cross(struct inode *old_dir, struct dentry *old_dentry,
612 struct inode *new_dir, struct dentry *new_dentry)
613{
614 struct logfs_super *super = logfs_super(old_dir->i_sb);
615 struct logfs_disk_dentry dd;
616 struct logfs_transaction *ta;
617 loff_t pos;
618 int err;
619
620 /* 1. locate source dd */
621 err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
622 if (err)
623 return err;
624
625 ta = kzalloc(sizeof(*ta), GFP_KERNEL);
626 if (!ta)
627 return -ENOMEM;
628
629 ta->state = CROSS_RENAME_1;
630 ta->dir = old_dir->i_ino;
631 ta->pos = pos;
632
633 /* 2. write target dd */
634 mutex_lock(&super->s_dirop_mutex);
635 logfs_add_transaction(new_dir, ta);
636 err = logfs_write_dir(new_dir, new_dentry, old_dentry->d_inode);
637 if (!err)
638 err = write_inode(new_dir);
639
640 if (err) {
641 super->s_rename_dir = 0;
642 super->s_rename_pos = 0;
643 abort_transaction(new_dir, ta);
644 goto out;
645 }
646
647 /* 3. remove source dd */
648 ta->state = CROSS_RENAME_2;
649 logfs_add_transaction(old_dir, ta);
650 err = logfs_delete_dd(old_dir, pos);
651 if (!err)
652 err = write_inode(old_dir);
653 LOGFS_BUG_ON(err, old_dir->i_sb);
654out:
655 mutex_unlock(&super->s_dirop_mutex);
656 return err;
657}
658
659static int logfs_replace_inode(struct inode *dir, struct dentry *dentry,
660 struct logfs_disk_dentry *dd, struct inode *inode)
661{
662 loff_t pos;
663 int err;
664
665 err = logfs_get_dd(dir, dentry, dd, &pos);
666 if (err)
667 return err;
668 dd->ino = cpu_to_be64(inode->i_ino);
669 dd->type = logfs_type(inode);
670
671 err = write_dir(dir, dd, pos);
672 if (err)
673 return err;
674 log_dir("Replace dentry (%lx, %llx) %s -> %llx\n", dir->i_ino, pos,
675 dd->name, be64_to_cpu(dd->ino));
676 return write_inode(dir);
677}
678
679/* Target dentry exists - the worst case. We need to attach the source
680 * inode to the target dentry, then remove the orphaned target inode and
681 * source dentry.
682 */
683static int logfs_rename_target(struct inode *old_dir, struct dentry *old_dentry,
684 struct inode *new_dir, struct dentry *new_dentry)
685{
686 struct logfs_super *super = logfs_super(old_dir->i_sb);
687 struct inode *old_inode = old_dentry->d_inode;
688 struct inode *new_inode = new_dentry->d_inode;
689 int isdir = S_ISDIR(old_inode->i_mode);
690 struct logfs_disk_dentry dd;
691 struct logfs_transaction *ta;
692 loff_t pos;
693 int err;
694
695 BUG_ON(isdir != S_ISDIR(new_inode->i_mode));
696 if (isdir) {
697 if (!logfs_empty_dir(new_inode))
698 return -ENOTEMPTY;
699 }
700
701 /* 1. locate source dd */
702 err = logfs_get_dd(old_dir, old_dentry, &dd, &pos);
703 if (err)
704 return err;
705
706 ta = kzalloc(sizeof(*ta), GFP_KERNEL);
707 if (!ta)
708 return -ENOMEM;
709
710 ta->state = TARGET_RENAME_1;
711 ta->dir = old_dir->i_ino;
712 ta->pos = pos;
713 ta->ino = new_inode->i_ino;
714
715 /* 2. attach source inode to target dd */
716 mutex_lock(&super->s_dirop_mutex);
717 logfs_add_transaction(new_dir, ta);
718 err = logfs_replace_inode(new_dir, new_dentry, &dd, old_inode);
719 if (err) {
720 super->s_rename_dir = 0;
721 super->s_rename_pos = 0;
722 super->s_victim_ino = 0;
723 abort_transaction(new_dir, ta);
724 goto out;
725 }
726
727 /* 3. remove source dd */
728 ta->state = TARGET_RENAME_2;
729 logfs_add_transaction(old_dir, ta);
730 err = logfs_delete_dd(old_dir, pos);
731 if (!err)
732 err = write_inode(old_dir);
733 LOGFS_BUG_ON(err, old_dir->i_sb);
734
735 /* 4. remove target inode */
736 ta->state = TARGET_RENAME_3;
737 logfs_add_transaction(new_inode, ta);
738 err = logfs_remove_inode(new_inode);
739
740out:
741 mutex_unlock(&super->s_dirop_mutex);
742 return err;
743}
744
745static int logfs_rename(struct inode *old_dir, struct dentry *old_dentry,
746 struct inode *new_dir, struct dentry *new_dentry)
747{
748 if (new_dentry->d_inode)
749 return logfs_rename_target(old_dir, old_dentry,
750 new_dir, new_dentry);
751 return logfs_rename_cross(old_dir, old_dentry, new_dir, new_dentry);
752}
753
754/* No locking done here, as this is called before .get_sb() returns. */
755int logfs_replay_journal(struct super_block *sb)
756{
757 struct logfs_super *super = logfs_super(sb);
758 struct inode *inode;
759 u64 ino, pos;
760 int err;
761
762 if (super->s_victim_ino) {
763 /* delete victim inode */
764 ino = super->s_victim_ino;
765 printk(KERN_INFO"LogFS: delete unmapped inode #%llx\n", ino);
766 inode = logfs_iget(sb, ino);
767 if (IS_ERR(inode))
768 goto fail;
769
770 LOGFS_BUG_ON(i_size_read(inode) > 0, sb);
771 super->s_victim_ino = 0;
772 err = logfs_remove_inode(inode);
773 iput(inode);
774 if (err) {
775 super->s_victim_ino = ino;
776 goto fail;
777 }
778 }
779 if (super->s_rename_dir) {
780 /* delete old dd from rename */
781 ino = super->s_rename_dir;
782 pos = super->s_rename_pos;
783 printk(KERN_INFO"LogFS: delete unbacked dentry (%llx, %llx)\n",
784 ino, pos);
785 inode = logfs_iget(sb, ino);
786 if (IS_ERR(inode))
787 goto fail;
788
789 super->s_rename_dir = 0;
790 super->s_rename_pos = 0;
791 err = logfs_delete_dd(inode, pos);
792 iput(inode);
793 if (err) {
794 super->s_rename_dir = ino;
795 super->s_rename_pos = pos;
796 goto fail;
797 }
798 }
799 return 0;
800fail:
801 LOGFS_BUG(sb);
802 return -EIO;
803}
804
805const struct inode_operations logfs_symlink_iops = {
806 .readlink = generic_readlink,
807 .follow_link = page_follow_link_light,
808};
809
810const struct inode_operations logfs_dir_iops = {
811 .create = logfs_create,
812 .link = logfs_link,
813 .lookup = logfs_lookup,
814 .mkdir = logfs_mkdir,
815 .mknod = logfs_mknod,
816 .rename = logfs_rename,
817 .rmdir = logfs_rmdir,
818 .permission = logfs_permission,
819 .symlink = logfs_symlink,
820 .unlink = logfs_unlink,
821};
822const struct file_operations logfs_dir_fops = {
823 .fsync = logfs_fsync,
824 .ioctl = logfs_ioctl,
825 .readdir = logfs_readdir,
826 .read = generic_read_dir,
827};
diff --git a/fs/logfs/file.c b/fs/logfs/file.c
new file mode 100644
index 000000000000..370f367a933e
--- /dev/null
+++ b/fs/logfs/file.c
@@ -0,0 +1,263 @@
1/*
2 * fs/logfs/file.c - prepare_write, commit_write and friends
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9#include <linux/sched.h>
10#include <linux/writeback.h>
11
12static int logfs_write_begin(struct file *file, struct address_space *mapping,
13 loff_t pos, unsigned len, unsigned flags,
14 struct page **pagep, void **fsdata)
15{
16 struct inode *inode = mapping->host;
17 struct page *page;
18 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
19
20 page = grab_cache_page_write_begin(mapping, index, flags);
21 if (!page)
22 return -ENOMEM;
23 *pagep = page;
24
25 if ((len == PAGE_CACHE_SIZE) || PageUptodate(page))
26 return 0;
27 if ((pos & PAGE_CACHE_MASK) >= i_size_read(inode)) {
28 unsigned start = pos & (PAGE_CACHE_SIZE - 1);
29 unsigned end = start + len;
30
31 /* Reading beyond i_size is simple: memset to zero */
32 zero_user_segments(page, 0, start, end, PAGE_CACHE_SIZE);
33 return 0;
34 }
35 return logfs_readpage_nolock(page);
36}
37
38static int logfs_write_end(struct file *file, struct address_space *mapping,
39 loff_t pos, unsigned len, unsigned copied, struct page *page,
40 void *fsdata)
41{
42 struct inode *inode = mapping->host;
43 pgoff_t index = page->index;
44 unsigned start = pos & (PAGE_CACHE_SIZE - 1);
45 unsigned end = start + copied;
46 int ret = 0;
47
48 BUG_ON(PAGE_CACHE_SIZE != inode->i_sb->s_blocksize);
49 BUG_ON(page->index > I3_BLOCKS);
50
51 if (copied < len) {
52 /*
53 * Short write of a non-initialized paged. Just tell userspace
54 * to retry the entire page.
55 */
56 if (!PageUptodate(page)) {
57 copied = 0;
58 goto out;
59 }
60 }
61 if (copied == 0)
62 goto out; /* FIXME: do we need to update inode? */
63
64 if (i_size_read(inode) < (index << PAGE_CACHE_SHIFT) + end) {
65 i_size_write(inode, (index << PAGE_CACHE_SHIFT) + end);
66 mark_inode_dirty_sync(inode);
67 }
68
69 SetPageUptodate(page);
70 if (!PageDirty(page)) {
71 if (!get_page_reserve(inode, page))
72 __set_page_dirty_nobuffers(page);
73 else
74 ret = logfs_write_buf(inode, page, WF_LOCK);
75 }
76out:
77 unlock_page(page);
78 page_cache_release(page);
79 return ret ? ret : copied;
80}
81
82int logfs_readpage(struct file *file, struct page *page)
83{
84 int ret;
85
86 ret = logfs_readpage_nolock(page);
87 unlock_page(page);
88 return ret;
89}
90
91/* Clear the page's dirty flag in the radix tree. */
92/* TODO: mucking with PageWriteback is silly. Add a generic function to clear
93 * the dirty bit from the radix tree for filesystems that don't have to wait
94 * for page writeback to finish (i.e. any compressing filesystem).
95 */
96static void clear_radix_tree_dirty(struct page *page)
97{
98 BUG_ON(PagePrivate(page) || page->private);
99 set_page_writeback(page);
100 end_page_writeback(page);
101}
102
103static int __logfs_writepage(struct page *page)
104{
105 struct inode *inode = page->mapping->host;
106 int err;
107
108 err = logfs_write_buf(inode, page, WF_LOCK);
109 if (err)
110 set_page_dirty(page);
111 else
112 clear_radix_tree_dirty(page);
113 unlock_page(page);
114 return err;
115}
116
117static int logfs_writepage(struct page *page, struct writeback_control *wbc)
118{
119 struct inode *inode = page->mapping->host;
120 loff_t i_size = i_size_read(inode);
121 pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
122 unsigned offset;
123 u64 bix;
124 level_t level;
125
126 log_file("logfs_writepage(%lx, %lx, %p)\n", inode->i_ino, page->index,
127 page);
128
129 logfs_unpack_index(page->index, &bix, &level);
130
131 /* Indirect blocks are never truncated */
132 if (level != 0)
133 return __logfs_writepage(page);
134
135 /*
136 * TODO: everything below is a near-verbatim copy of nobh_writepage().
137 * The relevant bits should be factored out after logfs is merged.
138 */
139
140 /* Is the page fully inside i_size? */
141 if (bix < end_index)
142 return __logfs_writepage(page);
143
144 /* Is the page fully outside i_size? (truncate in progress) */
145 offset = i_size & (PAGE_CACHE_SIZE-1);
146 if (bix > end_index || offset == 0) {
147 unlock_page(page);
148 return 0; /* don't care */
149 }
150
151 /*
152 * The page straddles i_size. It must be zeroed out on each and every
153 * writepage invokation because it may be mmapped. "A file is mapped
154 * in multiples of the page size. For a file that is not a multiple of
155 * the page size, the remaining memory is zeroed when mapped, and
156 * writes to that region are not written out to the file."
157 */
158 zero_user_segment(page, offset, PAGE_CACHE_SIZE);
159 return __logfs_writepage(page);
160}
161
162static void logfs_invalidatepage(struct page *page, unsigned long offset)
163{
164 move_page_to_btree(page);
165 BUG_ON(PagePrivate(page) || page->private);
166}
167
168static int logfs_releasepage(struct page *page, gfp_t only_xfs_uses_this)
169{
170 return 0; /* None of these are easy to release */
171}
172
173
174int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
175 unsigned long arg)
176{
177 struct logfs_inode *li = logfs_inode(inode);
178 unsigned int oldflags, flags;
179 int err;
180
181 switch (cmd) {
182 case FS_IOC_GETFLAGS:
183 flags = li->li_flags & LOGFS_FL_USER_VISIBLE;
184 return put_user(flags, (int __user *)arg);
185 case FS_IOC_SETFLAGS:
186 if (IS_RDONLY(inode))
187 return -EROFS;
188
189 if (!is_owner_or_cap(inode))
190 return -EACCES;
191
192 err = get_user(flags, (int __user *)arg);
193 if (err)
194 return err;
195
196 mutex_lock(&inode->i_mutex);
197 oldflags = li->li_flags;
198 flags &= LOGFS_FL_USER_MODIFIABLE;
199 flags |= oldflags & ~LOGFS_FL_USER_MODIFIABLE;
200 li->li_flags = flags;
201 mutex_unlock(&inode->i_mutex);
202
203 inode->i_ctime = CURRENT_TIME;
204 mark_inode_dirty_sync(inode);
205 return 0;
206
207 default:
208 return -ENOTTY;
209 }
210}
211
212int logfs_fsync(struct file *file, struct dentry *dentry, int datasync)
213{
214 struct super_block *sb = dentry->d_inode->i_sb;
215 struct logfs_super *super = logfs_super(sb);
216
217 /* FIXME: write anchor */
218 super->s_devops->sync(sb);
219 return 0;
220}
221
222static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
223{
224 struct inode *inode = dentry->d_inode;
225 int err = 0;
226
227 if (attr->ia_valid & ATTR_SIZE)
228 err = logfs_truncate(inode, attr->ia_size);
229 attr->ia_valid &= ~ATTR_SIZE;
230
231 if (!err)
232 err = inode_change_ok(inode, attr);
233 if (!err)
234 err = inode_setattr(inode, attr);
235 return err;
236}
237
238const struct inode_operations logfs_reg_iops = {
239 .setattr = logfs_setattr,
240};
241
242const struct file_operations logfs_reg_fops = {
243 .aio_read = generic_file_aio_read,
244 .aio_write = generic_file_aio_write,
245 .fsync = logfs_fsync,
246 .ioctl = logfs_ioctl,
247 .llseek = generic_file_llseek,
248 .mmap = generic_file_readonly_mmap,
249 .open = generic_file_open,
250 .read = do_sync_read,
251 .write = do_sync_write,
252};
253
254const struct address_space_operations logfs_reg_aops = {
255 .invalidatepage = logfs_invalidatepage,
256 .readpage = logfs_readpage,
257 .releasepage = logfs_releasepage,
258 .set_page_dirty = __set_page_dirty_nobuffers,
259 .writepage = logfs_writepage,
260 .writepages = generic_writepages,
261 .write_begin = logfs_write_begin,
262 .write_end = logfs_write_end,
263};
diff --git a/fs/logfs/gc.c b/fs/logfs/gc.c
new file mode 100644
index 000000000000..92949f95a901
--- /dev/null
+++ b/fs/logfs/gc.c
@@ -0,0 +1,730 @@
1/*
2 * fs/logfs/gc.c - garbage collection code
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9#include <linux/sched.h>
10
11/*
12 * Wear leveling needs to kick in when the difference between low erase
13 * counts and high erase counts gets too big. A good value for "too big"
14 * may be somewhat below 10% of maximum erase count for the device.
15 * Why not 397, to pick a nice round number with no specific meaning? :)
16 *
17 * WL_RATELIMIT is the minimum time between two wear level events. A huge
18 * number of segments may fulfil the requirements for wear leveling at the
19 * same time. If that happens we don't want to cause a latency from hell,
20 * but just gently pick one segment every so often and minimize overhead.
21 */
22#define WL_DELTA 397
23#define WL_RATELIMIT 100
24#define MAX_OBJ_ALIASES 2600
25#define SCAN_RATIO 512 /* number of scanned segments per gc'd segment */
26#define LIST_SIZE 64 /* base size of candidate lists */
27#define SCAN_ROUNDS 128 /* maximum number of complete medium scans */
28#define SCAN_ROUNDS_HIGH 4 /* maximum number of higher-level scans */
29
30static int no_free_segments(struct super_block *sb)
31{
32 struct logfs_super *super = logfs_super(sb);
33
34 return super->s_free_list.count;
35}
36
37/* journal has distance -1, top-most ifile layer distance 0 */
38static u8 root_distance(struct super_block *sb, gc_level_t __gc_level)
39{
40 struct logfs_super *super = logfs_super(sb);
41 u8 gc_level = (__force u8)__gc_level;
42
43 switch (gc_level) {
44 case 0: /* fall through */
45 case 1: /* fall through */
46 case 2: /* fall through */
47 case 3:
48 /* file data or indirect blocks */
49 return super->s_ifile_levels + super->s_iblock_levels - gc_level;
50 case 6: /* fall through */
51 case 7: /* fall through */
52 case 8: /* fall through */
53 case 9:
54 /* inode file data or indirect blocks */
55 return super->s_ifile_levels - (gc_level - 6);
56 default:
57 printk(KERN_ERR"LOGFS: segment of unknown level %x found\n",
58 gc_level);
59 WARN_ON(1);
60 return super->s_ifile_levels + super->s_iblock_levels;
61 }
62}
63
64static int segment_is_reserved(struct super_block *sb, u32 segno)
65{
66 struct logfs_super *super = logfs_super(sb);
67 struct logfs_area *area;
68 void *reserved;
69 int i;
70
71 /* Some segments are reserved. Just pretend they were all valid */
72 reserved = btree_lookup32(&super->s_reserved_segments, segno);
73 if (reserved)
74 return 1;
75
76 /* Currently open segments */
77 for_each_area(i) {
78 area = super->s_area[i];
79 if (area->a_is_open && area->a_segno == segno)
80 return 1;
81 }
82
83 return 0;
84}
85
86static void logfs_mark_segment_bad(struct super_block *sb, u32 segno)
87{
88 BUG();
89}
90
91/*
92 * Returns the bytes consumed by valid objects in this segment. Object headers
93 * are counted, the segment header is not.
94 */
95static u32 logfs_valid_bytes(struct super_block *sb, u32 segno, u32 *ec,
96 gc_level_t *gc_level)
97{
98 struct logfs_segment_entry se;
99 u32 ec_level;
100
101 logfs_get_segment_entry(sb, segno, &se);
102 if (se.ec_level == cpu_to_be32(BADSEG) ||
103 se.valid == cpu_to_be32(RESERVED))
104 return RESERVED;
105
106 ec_level = be32_to_cpu(se.ec_level);
107 *ec = ec_level >> 4;
108 *gc_level = GC_LEVEL(ec_level & 0xf);
109 return be32_to_cpu(se.valid);
110}
111
112static void logfs_cleanse_block(struct super_block *sb, u64 ofs, u64 ino,
113 u64 bix, gc_level_t gc_level)
114{
115 struct inode *inode;
116 int err, cookie;
117
118 inode = logfs_safe_iget(sb, ino, &cookie);
119 err = logfs_rewrite_block(inode, bix, ofs, gc_level, 0);
120 BUG_ON(err);
121 logfs_safe_iput(inode, cookie);
122}
123
124static u32 logfs_gc_segment(struct super_block *sb, u32 segno, u8 dist)
125{
126 struct logfs_super *super = logfs_super(sb);
127 struct logfs_segment_header sh;
128 struct logfs_object_header oh;
129 u64 ofs, ino, bix;
130 u32 seg_ofs, logical_segno, cleaned = 0;
131 int err, len, valid;
132 gc_level_t gc_level;
133
134 LOGFS_BUG_ON(segment_is_reserved(sb, segno), sb);
135
136 btree_insert32(&super->s_reserved_segments, segno, (void *)1, GFP_NOFS);
137 err = wbuf_read(sb, dev_ofs(sb, segno, 0), sizeof(sh), &sh);
138 BUG_ON(err);
139 gc_level = GC_LEVEL(sh.level);
140 logical_segno = be32_to_cpu(sh.segno);
141 if (sh.crc != logfs_crc32(&sh, sizeof(sh), 4)) {
142 logfs_mark_segment_bad(sb, segno);
143 cleaned = -1;
144 goto out;
145 }
146
147 for (seg_ofs = LOGFS_SEGMENT_HEADERSIZE;
148 seg_ofs + sizeof(oh) < super->s_segsize; ) {
149 ofs = dev_ofs(sb, logical_segno, seg_ofs);
150 err = wbuf_read(sb, dev_ofs(sb, segno, seg_ofs), sizeof(oh),
151 &oh);
152 BUG_ON(err);
153
154 if (!memchr_inv(&oh, 0xff, sizeof(oh)))
155 break;
156
157 if (oh.crc != logfs_crc32(&oh, sizeof(oh) - 4, 4)) {
158 logfs_mark_segment_bad(sb, segno);
159 cleaned = super->s_segsize - 1;
160 goto out;
161 }
162
163 ino = be64_to_cpu(oh.ino);
164 bix = be64_to_cpu(oh.bix);
165 len = sizeof(oh) + be16_to_cpu(oh.len);
166 valid = logfs_is_valid_block(sb, ofs, ino, bix, gc_level);
167 if (valid == 1) {
168 logfs_cleanse_block(sb, ofs, ino, bix, gc_level);
169 cleaned += len;
170 } else if (valid == 2) {
171 /* Will be invalid upon journal commit */
172 cleaned += len;
173 }
174 seg_ofs += len;
175 }
176out:
177 btree_remove32(&super->s_reserved_segments, segno);
178 return cleaned;
179}
180
181static struct gc_candidate *add_list(struct gc_candidate *cand,
182 struct candidate_list *list)
183{
184 struct rb_node **p = &list->rb_tree.rb_node;
185 struct rb_node *parent = NULL;
186 struct gc_candidate *cur;
187 int comp;
188
189 cand->list = list;
190 while (*p) {
191 parent = *p;
192 cur = rb_entry(parent, struct gc_candidate, rb_node);
193
194 if (list->sort_by_ec)
195 comp = cand->erase_count < cur->erase_count;
196 else
197 comp = cand->valid < cur->valid;
198
199 if (comp)
200 p = &parent->rb_left;
201 else
202 p = &parent->rb_right;
203 }
204 rb_link_node(&cand->rb_node, parent, p);
205 rb_insert_color(&cand->rb_node, &list->rb_tree);
206
207 if (list->count <= list->maxcount) {
208 list->count++;
209 return NULL;
210 }
211 cand = rb_entry(rb_last(&list->rb_tree), struct gc_candidate, rb_node);
212 rb_erase(&cand->rb_node, &list->rb_tree);
213 cand->list = NULL;
214 return cand;
215}
216
217static void remove_from_list(struct gc_candidate *cand)
218{
219 struct candidate_list *list = cand->list;
220
221 rb_erase(&cand->rb_node, &list->rb_tree);
222 list->count--;
223}
224
225static void free_candidate(struct super_block *sb, struct gc_candidate *cand)
226{
227 struct logfs_super *super = logfs_super(sb);
228
229 btree_remove32(&super->s_cand_tree, cand->segno);
230 kfree(cand);
231}
232
233u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec)
234{
235 struct gc_candidate *cand;
236 u32 segno;
237
238 BUG_ON(list->count == 0);
239
240 cand = rb_entry(rb_first(&list->rb_tree), struct gc_candidate, rb_node);
241 remove_from_list(cand);
242 segno = cand->segno;
243 if (ec)
244 *ec = cand->erase_count;
245 free_candidate(sb, cand);
246 return segno;
247}
248
249/*
250 * We have several lists to manage segments with. The reserve_list is used to
251 * deal with bad blocks. We try to keep the best (lowest ec) segments on this
252 * list.
253 * The free_list contains free segments for normal usage. It usually gets the
254 * second pick after the reserve_list. But when the free_list is running short
255 * it is more important to keep the free_list full than to keep a reserve.
256 *
257 * Segments that are not free are put onto a per-level low_list. If we have
258 * to run garbage collection, we pick a candidate from there. All segments on
259 * those lists should have at least some free space so GC will make progress.
260 *
261 * And last we have the ec_list, which is used to pick segments for wear
262 * leveling.
263 *
264 * If all appropriate lists are full, we simply free the candidate and forget
265 * about that segment for a while. We have better candidates for each purpose.
266 */
267static void __add_candidate(struct super_block *sb, struct gc_candidate *cand)
268{
269 struct logfs_super *super = logfs_super(sb);
270 u32 full = super->s_segsize - LOGFS_SEGMENT_RESERVE;
271
272 if (cand->valid == 0) {
273 /* 100% free segments */
274 log_gc_noisy("add reserve segment %x (ec %x) at %llx\n",
275 cand->segno, cand->erase_count,
276 dev_ofs(sb, cand->segno, 0));
277 cand = add_list(cand, &super->s_reserve_list);
278 if (cand) {
279 log_gc_noisy("add free segment %x (ec %x) at %llx\n",
280 cand->segno, cand->erase_count,
281 dev_ofs(sb, cand->segno, 0));
282 cand = add_list(cand, &super->s_free_list);
283 }
284 } else {
285 /* good candidates for Garbage Collection */
286 if (cand->valid < full)
287 cand = add_list(cand, &super->s_low_list[cand->dist]);
288 /* good candidates for wear leveling,
289 * segments that were recently written get ignored */
290 if (cand)
291 cand = add_list(cand, &super->s_ec_list);
292 }
293 if (cand)
294 free_candidate(sb, cand);
295}
296
297static int add_candidate(struct super_block *sb, u32 segno, u32 valid, u32 ec,
298 u8 dist)
299{
300 struct logfs_super *super = logfs_super(sb);
301 struct gc_candidate *cand;
302
303 cand = kmalloc(sizeof(*cand), GFP_NOFS);
304 if (!cand)
305 return -ENOMEM;
306
307 cand->segno = segno;
308 cand->valid = valid;
309 cand->erase_count = ec;
310 cand->dist = dist;
311
312 btree_insert32(&super->s_cand_tree, segno, cand, GFP_NOFS);
313 __add_candidate(sb, cand);
314 return 0;
315}
316
317static void remove_segment_from_lists(struct super_block *sb, u32 segno)
318{
319 struct logfs_super *super = logfs_super(sb);
320 struct gc_candidate *cand;
321
322 cand = btree_lookup32(&super->s_cand_tree, segno);
323 if (cand) {
324 remove_from_list(cand);
325 free_candidate(sb, cand);
326 }
327}
328
329static void scan_segment(struct super_block *sb, u32 segno)
330{
331 u32 valid, ec = 0;
332 gc_level_t gc_level = 0;
333 u8 dist;
334
335 if (segment_is_reserved(sb, segno))
336 return;
337
338 remove_segment_from_lists(sb, segno);
339 valid = logfs_valid_bytes(sb, segno, &ec, &gc_level);
340 if (valid == RESERVED)
341 return;
342
343 dist = root_distance(sb, gc_level);
344 add_candidate(sb, segno, valid, ec, dist);
345}
346
347static struct gc_candidate *first_in_list(struct candidate_list *list)
348{
349 if (list->count == 0)
350 return NULL;
351 return rb_entry(rb_first(&list->rb_tree), struct gc_candidate, rb_node);
352}
353
354/*
355 * Find the best segment for garbage collection. Main criterion is
356 * the segment requiring the least effort to clean. Secondary
357 * criterion is to GC on the lowest level available.
358 *
359 * So we search the least effort segment on the lowest level first,
360 * then move up and pick another segment iff is requires significantly
361 * less effort. Hence the LOGFS_MAX_OBJECTSIZE in the comparison.
362 */
363static struct gc_candidate *get_candidate(struct super_block *sb)
364{
365 struct logfs_super *super = logfs_super(sb);
366 int i, max_dist;
367 struct gc_candidate *cand = NULL, *this;
368
369 max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS);
370
371 for (i = max_dist; i >= 0; i--) {
372 this = first_in_list(&super->s_low_list[i]);
373 if (!this)
374 continue;
375 if (!cand)
376 cand = this;
377 if (this->valid + LOGFS_MAX_OBJECTSIZE <= cand->valid)
378 cand = this;
379 }
380 return cand;
381}
382
383static int __logfs_gc_once(struct super_block *sb, struct gc_candidate *cand)
384{
385 struct logfs_super *super = logfs_super(sb);
386 gc_level_t gc_level;
387 u32 cleaned, valid, segno, ec;
388 u8 dist;
389
390 if (!cand) {
391 log_gc("GC attempted, but no candidate found\n");
392 return 0;
393 }
394
395 segno = cand->segno;
396 dist = cand->dist;
397 valid = logfs_valid_bytes(sb, segno, &ec, &gc_level);
398 free_candidate(sb, cand);
399 log_gc("GC segment #%02x at %llx, %x required, %x free, %x valid, %llx free\n",
400 segno, (u64)segno << super->s_segshift,
401 dist, no_free_segments(sb), valid,
402 super->s_free_bytes);
403 cleaned = logfs_gc_segment(sb, segno, dist);
404 log_gc("GC segment #%02x complete - now %x valid\n", segno,
405 valid - cleaned);
406 BUG_ON(cleaned != valid);
407 return 1;
408}
409
410static int logfs_gc_once(struct super_block *sb)
411{
412 struct gc_candidate *cand;
413
414 cand = get_candidate(sb);
415 if (cand)
416 remove_from_list(cand);
417 return __logfs_gc_once(sb, cand);
418}
419
420/* returns 1 if a wrap occurs, 0 otherwise */
421static int logfs_scan_some(struct super_block *sb)
422{
423 struct logfs_super *super = logfs_super(sb);
424 u32 segno;
425 int i, ret = 0;
426
427 segno = super->s_sweeper;
428 for (i = SCAN_RATIO; i > 0; i--) {
429 segno++;
430 if (segno >= super->s_no_segs) {
431 segno = 0;
432 ret = 1;
433 /* Break out of the loop. We want to read a single
434 * block from the segment size on next invocation if
435 * SCAN_RATIO is set to match block size
436 */
437 break;
438 }
439
440 scan_segment(sb, segno);
441 }
442 super->s_sweeper = segno;
443 return ret;
444}
445
446/*
447 * In principle, this function should loop forever, looking for GC candidates
448 * and moving data. LogFS is designed in such a way that this loop is
449 * guaranteed to terminate.
450 *
451 * Limiting the loop to some iterations serves purely to catch cases when
452 * these guarantees have failed. An actual endless loop is an obvious bug
453 * and should be reported as such.
454 */
455static void __logfs_gc_pass(struct super_block *sb, int target)
456{
457 struct logfs_super *super = logfs_super(sb);
458 struct logfs_block *block;
459 int round, progress, last_progress = 0;
460
461 if (no_free_segments(sb) >= target &&
462 super->s_no_object_aliases < MAX_OBJ_ALIASES)
463 return;
464
465 log_gc("__logfs_gc_pass(%x)\n", target);
466 for (round = 0; round < SCAN_ROUNDS; ) {
467 if (no_free_segments(sb) >= target)
468 goto write_alias;
469
470 /* Sync in-memory state with on-medium state in case they
471 * diverged */
472 logfs_write_anchor(sb);
473 round += logfs_scan_some(sb);
474 if (no_free_segments(sb) >= target)
475 goto write_alias;
476 progress = logfs_gc_once(sb);
477 if (progress)
478 last_progress = round;
479 else if (round - last_progress > 2)
480 break;
481 continue;
482
483 /*
484 * The goto logic is nasty, I just don't know a better way to
485 * code it. GC is supposed to ensure two things:
486 * 1. Enough free segments are available.
487 * 2. The number of aliases is bounded.
488 * When 1. is achieved, we take a look at 2. and write back
489 * some alias-containing blocks, if necessary. However, after
490 * each such write we need to go back to 1., as writes can
491 * consume free segments.
492 */
493write_alias:
494 if (super->s_no_object_aliases < MAX_OBJ_ALIASES)
495 return;
496 if (list_empty(&super->s_object_alias)) {
497 /* All aliases are still in btree */
498 return;
499 }
500 log_gc("Write back one alias\n");
501 block = list_entry(super->s_object_alias.next,
502 struct logfs_block, alias_list);
503 block->ops->write_block(block);
504 /*
505 * To round off the nasty goto logic, we reset round here. It
506 * is a safety-net for GC not making any progress and limited
507 * to something reasonably small. If incremented it for every
508 * single alias, the loop could terminate rather quickly.
509 */
510 round = 0;
511 }
512 LOGFS_BUG(sb);
513}
514
515static int wl_ratelimit(struct super_block *sb, u64 *next_event)
516{
517 struct logfs_super *super = logfs_super(sb);
518
519 if (*next_event < super->s_gec) {
520 *next_event = super->s_gec + WL_RATELIMIT;
521 return 0;
522 }
523 return 1;
524}
525
526static void logfs_wl_pass(struct super_block *sb)
527{
528 struct logfs_super *super = logfs_super(sb);
529 struct gc_candidate *wl_cand, *free_cand;
530
531 if (wl_ratelimit(sb, &super->s_wl_gec_ostore))
532 return;
533
534 wl_cand = first_in_list(&super->s_ec_list);
535 if (!wl_cand)
536 return;
537 free_cand = first_in_list(&super->s_free_list);
538 if (!free_cand)
539 return;
540
541 if (wl_cand->erase_count < free_cand->erase_count + WL_DELTA) {
542 remove_from_list(wl_cand);
543 __logfs_gc_once(sb, wl_cand);
544 }
545}
546
547/*
548 * The journal needs wear leveling as well. But moving the journal is an
549 * expensive operation so we try to avoid it as much as possible. And if we
550 * have to do it, we move the whole journal, not individual segments.
551 *
552 * Ratelimiting is not strictly necessary here, it mainly serves to avoid the
553 * calculations. First we check whether moving the journal would be a
554 * significant improvement. That means that a) the current journal segments
555 * have more wear than the future journal segments and b) the current journal
556 * segments have more wear than normal ostore segments.
557 * Rationale for b) is that we don't have to move the journal if it is aging
558 * less than the ostore, even if the reserve segments age even less (they are
559 * excluded from wear leveling, after all).
560 * Next we check that the superblocks have less wear than the journal. Since
561 * moving the journal requires writing the superblocks, we have to protect the
562 * superblocks even more than the journal.
563 *
564 * Also we double the acceptable wear difference, compared to ostore wear
565 * leveling. Journal data is read and rewritten rapidly, comparatively. So
566 * soft errors have much less time to accumulate and we allow the journal to
567 * be a bit worse than the ostore.
568 */
569static void logfs_journal_wl_pass(struct super_block *sb)
570{
571 struct logfs_super *super = logfs_super(sb);
572 struct gc_candidate *cand;
573 u32 min_journal_ec = -1, max_reserve_ec = 0;
574 int i;
575
576 if (wl_ratelimit(sb, &super->s_wl_gec_journal))
577 return;
578
579 if (super->s_reserve_list.count < super->s_no_journal_segs) {
580 /* Reserve is not full enough to move complete journal */
581 return;
582 }
583
584 journal_for_each(i)
585 if (super->s_journal_seg[i])
586 min_journal_ec = min(min_journal_ec,
587 super->s_journal_ec[i]);
588 cand = rb_entry(rb_first(&super->s_free_list.rb_tree),
589 struct gc_candidate, rb_node);
590 max_reserve_ec = cand->erase_count;
591 for (i = 0; i < 2; i++) {
592 struct logfs_segment_entry se;
593 u32 segno = seg_no(sb, super->s_sb_ofs[i]);
594 u32 ec;
595
596 logfs_get_segment_entry(sb, segno, &se);
597 ec = be32_to_cpu(se.ec_level) >> 4;
598 max_reserve_ec = max(max_reserve_ec, ec);
599 }
600
601 if (min_journal_ec > max_reserve_ec + 2 * WL_DELTA) {
602 do_logfs_journal_wl_pass(sb);
603 }
604}
605
606void logfs_gc_pass(struct super_block *sb)
607{
608 struct logfs_super *super = logfs_super(sb);
609
610 //BUG_ON(mutex_trylock(&logfs_super(sb)->s_w_mutex));
611 /* Write journal before free space is getting saturated with dirty
612 * objects.
613 */
614 if (super->s_dirty_used_bytes + super->s_dirty_free_bytes
615 + LOGFS_MAX_OBJECTSIZE >= super->s_free_bytes)
616 logfs_write_anchor(sb);
617 __logfs_gc_pass(sb, super->s_total_levels);
618 logfs_wl_pass(sb);
619 logfs_journal_wl_pass(sb);
620}
621
622static int check_area(struct super_block *sb, int i)
623{
624 struct logfs_super *super = logfs_super(sb);
625 struct logfs_area *area = super->s_area[i];
626 struct logfs_object_header oh;
627 u32 segno = area->a_segno;
628 u32 ofs = area->a_used_bytes;
629 __be32 crc;
630 int err;
631
632 if (!area->a_is_open)
633 return 0;
634
635 for (ofs = area->a_used_bytes;
636 ofs <= super->s_segsize - sizeof(oh);
637 ofs += (u32)be16_to_cpu(oh.len) + sizeof(oh)) {
638 err = wbuf_read(sb, dev_ofs(sb, segno, ofs), sizeof(oh), &oh);
639 if (err)
640 return err;
641
642 if (!memchr_inv(&oh, 0xff, sizeof(oh)))
643 break;
644
645 crc = logfs_crc32(&oh, sizeof(oh) - 4, 4);
646 if (crc != oh.crc) {
647 printk(KERN_INFO "interrupted header at %llx\n",
648 dev_ofs(sb, segno, ofs));
649 return 0;
650 }
651 }
652 if (ofs != area->a_used_bytes) {
653 printk(KERN_INFO "%x bytes unaccounted data found at %llx\n",
654 ofs - area->a_used_bytes,
655 dev_ofs(sb, segno, area->a_used_bytes));
656 area->a_used_bytes = ofs;
657 }
658 return 0;
659}
660
661int logfs_check_areas(struct super_block *sb)
662{
663 int i, err;
664
665 for_each_area(i) {
666 err = check_area(sb, i);
667 if (err)
668 return err;
669 }
670 return 0;
671}
672
673static void logfs_init_candlist(struct candidate_list *list, int maxcount,
674 int sort_by_ec)
675{
676 list->count = 0;
677 list->maxcount = maxcount;
678 list->sort_by_ec = sort_by_ec;
679 list->rb_tree = RB_ROOT;
680}
681
682int logfs_init_gc(struct super_block *sb)
683{
684 struct logfs_super *super = logfs_super(sb);
685 int i;
686
687 btree_init_mempool32(&super->s_cand_tree, super->s_btree_pool);
688 logfs_init_candlist(&super->s_free_list, LIST_SIZE + SCAN_RATIO, 1);
689 logfs_init_candlist(&super->s_reserve_list,
690 super->s_bad_seg_reserve, 1);
691 for_each_area(i)
692 logfs_init_candlist(&super->s_low_list[i], LIST_SIZE, 0);
693 logfs_init_candlist(&super->s_ec_list, LIST_SIZE, 1);
694 return 0;
695}
696
697static void logfs_cleanup_list(struct super_block *sb,
698 struct candidate_list *list)
699{
700 struct gc_candidate *cand;
701
702 while (list->count) {
703 cand = rb_entry(list->rb_tree.rb_node, struct gc_candidate,
704 rb_node);
705 remove_from_list(cand);
706 free_candidate(sb, cand);
707 }
708 BUG_ON(list->rb_tree.rb_node);
709}
710
711void logfs_cleanup_gc(struct super_block *sb)
712{
713 struct logfs_super *super = logfs_super(sb);
714 int i;
715
716 if (!super->s_free_list.count)
717 return;
718
719 /*
720 * FIXME: The btree may still contain a single empty node. So we
721 * call the grim visitor to clean up that mess. Btree code should
722 * do it for us, really.
723 */
724 btree_grim_visitor32(&super->s_cand_tree, 0, NULL);
725 logfs_cleanup_list(sb, &super->s_free_list);
726 logfs_cleanup_list(sb, &super->s_reserve_list);
727 for_each_area(i)
728 logfs_cleanup_list(sb, &super->s_low_list[i]);
729 logfs_cleanup_list(sb, &super->s_ec_list);
730}
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c
new file mode 100644
index 000000000000..33ec1aeaeec4
--- /dev/null
+++ b/fs/logfs/inode.c
@@ -0,0 +1,417 @@
1/*
2 * fs/logfs/inode.c - inode handling code
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9#include <linux/writeback.h>
10#include <linux/backing-dev.h>
11
12/*
13 * How soon to reuse old inode numbers? LogFS doesn't store deleted inodes
14 * on the medium. It therefore also lacks a method to store the previous
15 * generation number for deleted inodes. Instead a single generation number
16 * is stored which will be used for new inodes. Being just a 32bit counter,
17 * this can obvious wrap relatively quickly. So we only reuse inodes if we
18 * know that a fair number of inodes can be created before we have to increment
19 * the generation again - effectively adding some bits to the counter.
20 * But being too aggressive here means we keep a very large and very sparse
21 * inode file, wasting space on indirect blocks.
22 * So what is a good value? Beats me. 64k seems moderately bad on both
23 * fronts, so let's use that for now...
24 *
25 * NFS sucks, as everyone already knows.
26 */
27#define INOS_PER_WRAP (0x10000)
28
29/*
30 * Logfs' requirement to read inodes for garbage collection makes life a bit
31 * harder. GC may have to read inodes that are in I_FREEING state, when they
32 * are being written out - and waiting for GC to make progress, naturally.
33 *
34 * So we cannot just call iget() or some variant of it, but first have to check
35 * wether the inode in question might be in I_FREEING state. Therefore we
36 * maintain our own per-sb list of "almost deleted" inodes and check against
37 * that list first. Normally this should be at most 1-2 entries long.
38 *
39 * Also, inodes have logfs-specific reference counting on top of what the vfs
40 * does. When .destroy_inode is called, normally the reference count will drop
41 * to zero and the inode gets deleted. But if GC accessed the inode, its
42 * refcount will remain nonzero and final deletion will have to wait.
43 *
44 * As a result we have two sets of functions to get/put inodes:
45 * logfs_safe_iget/logfs_safe_iput - safe to call from GC context
46 * logfs_iget/iput - normal version
47 */
48static struct kmem_cache *logfs_inode_cache;
49
50static DEFINE_SPINLOCK(logfs_inode_lock);
51
52static void logfs_inode_setops(struct inode *inode)
53{
54 switch (inode->i_mode & S_IFMT) {
55 case S_IFDIR:
56 inode->i_op = &logfs_dir_iops;
57 inode->i_fop = &logfs_dir_fops;
58 inode->i_mapping->a_ops = &logfs_reg_aops;
59 break;
60 case S_IFREG:
61 inode->i_op = &logfs_reg_iops;
62 inode->i_fop = &logfs_reg_fops;
63 inode->i_mapping->a_ops = &logfs_reg_aops;
64 break;
65 case S_IFLNK:
66 inode->i_op = &logfs_symlink_iops;
67 inode->i_mapping->a_ops = &logfs_reg_aops;
68 break;
69 case S_IFSOCK: /* fall through */
70 case S_IFBLK: /* fall through */
71 case S_IFCHR: /* fall through */
72 case S_IFIFO:
73 init_special_inode(inode, inode->i_mode, inode->i_rdev);
74 break;
75 default:
76 BUG();
77 }
78}
79
80static struct inode *__logfs_iget(struct super_block *sb, ino_t ino)
81{
82 struct inode *inode = iget_locked(sb, ino);
83 int err;
84
85 if (!inode)
86 return ERR_PTR(-ENOMEM);
87 if (!(inode->i_state & I_NEW))
88 return inode;
89
90 err = logfs_read_inode(inode);
91 if (err || inode->i_nlink == 0) {
92 /* inode->i_nlink == 0 can be true when called from
93 * block validator */
94 /* set i_nlink to 0 to prevent caching */
95 inode->i_nlink = 0;
96 logfs_inode(inode)->li_flags |= LOGFS_IF_ZOMBIE;
97 iget_failed(inode);
98 if (!err)
99 err = -ENOENT;
100 return ERR_PTR(err);
101 }
102
103 logfs_inode_setops(inode);
104 unlock_new_inode(inode);
105 return inode;
106}
107
108struct inode *logfs_iget(struct super_block *sb, ino_t ino)
109{
110 BUG_ON(ino == LOGFS_INO_MASTER);
111 BUG_ON(ino == LOGFS_INO_SEGFILE);
112 return __logfs_iget(sb, ino);
113}
114
115/*
116 * is_cached is set to 1 if we hand out a cached inode, 0 otherwise.
117 * this allows logfs_iput to do the right thing later
118 */
119struct inode *logfs_safe_iget(struct super_block *sb, ino_t ino, int *is_cached)
120{
121 struct logfs_super *super = logfs_super(sb);
122 struct logfs_inode *li;
123
124 if (ino == LOGFS_INO_MASTER)
125 return super->s_master_inode;
126 if (ino == LOGFS_INO_SEGFILE)
127 return super->s_segfile_inode;
128
129 spin_lock(&logfs_inode_lock);
130 list_for_each_entry(li, &super->s_freeing_list, li_freeing_list)
131 if (li->vfs_inode.i_ino == ino) {
132 li->li_refcount++;
133 spin_unlock(&logfs_inode_lock);
134 *is_cached = 1;
135 return &li->vfs_inode;
136 }
137 spin_unlock(&logfs_inode_lock);
138
139 *is_cached = 0;
140 return __logfs_iget(sb, ino);
141}
142
143static void __logfs_destroy_inode(struct inode *inode)
144{
145 struct logfs_inode *li = logfs_inode(inode);
146
147 BUG_ON(li->li_block);
148 list_del(&li->li_freeing_list);
149 kmem_cache_free(logfs_inode_cache, li);
150}
151
152static void logfs_destroy_inode(struct inode *inode)
153{
154 struct logfs_inode *li = logfs_inode(inode);
155
156 BUG_ON(list_empty(&li->li_freeing_list));
157 spin_lock(&logfs_inode_lock);
158 li->li_refcount--;
159 if (li->li_refcount == 0)
160 __logfs_destroy_inode(inode);
161 spin_unlock(&logfs_inode_lock);
162}
163
164void logfs_safe_iput(struct inode *inode, int is_cached)
165{
166 if (inode->i_ino == LOGFS_INO_MASTER)
167 return;
168 if (inode->i_ino == LOGFS_INO_SEGFILE)
169 return;
170
171 if (is_cached) {
172 logfs_destroy_inode(inode);
173 return;
174 }
175
176 iput(inode);
177}
178
179static void logfs_init_inode(struct super_block *sb, struct inode *inode)
180{
181 struct logfs_inode *li = logfs_inode(inode);
182 int i;
183
184 li->li_flags = 0;
185 li->li_height = 0;
186 li->li_used_bytes = 0;
187 li->li_block = NULL;
188 inode->i_uid = 0;
189 inode->i_gid = 0;
190 inode->i_size = 0;
191 inode->i_blocks = 0;
192 inode->i_ctime = CURRENT_TIME;
193 inode->i_mtime = CURRENT_TIME;
194 inode->i_nlink = 1;
195 INIT_LIST_HEAD(&li->li_freeing_list);
196
197 for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
198 li->li_data[i] = 0;
199
200 return;
201}
202
203static struct inode *logfs_alloc_inode(struct super_block *sb)
204{
205 struct logfs_inode *li;
206
207 li = kmem_cache_alloc(logfs_inode_cache, GFP_NOFS);
208 if (!li)
209 return NULL;
210 logfs_init_inode(sb, &li->vfs_inode);
211 return &li->vfs_inode;
212}
213
214/*
215 * In logfs inodes are written to an inode file. The inode file, like any
216 * other file, is managed with a inode. The inode file's inode, aka master
217 * inode, requires special handling in several respects. First, it cannot be
218 * written to the inode file, so it is stored in the journal instead.
219 *
220 * Secondly, this inode cannot be written back and destroyed before all other
221 * inodes have been written. The ordering is important. Linux' VFS is happily
222 * unaware of the ordering constraint and would ordinarily destroy the master
223 * inode at umount time while other inodes are still in use and dirty. Not
224 * good.
225 *
226 * So logfs makes sure the master inode is not written until all other inodes
227 * have been destroyed. Sadly, this method has another side-effect. The VFS
228 * will notice one remaining inode and print a frightening warning message.
229 * Worse, it is impossible to judge whether such a warning was caused by the
230 * master inode or any other inodes have leaked as well.
231 *
232 * Our attempt of solving this is with logfs_new_meta_inode() below. Its
233 * purpose is to create a new inode that will not trigger the warning if such
234 * an inode is still in use. An ugly hack, no doubt. Suggections for
235 * improvement are welcome.
236 */
237struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino)
238{
239 struct inode *inode;
240
241 inode = logfs_alloc_inode(sb);
242 if (!inode)
243 return ERR_PTR(-ENOMEM);
244
245 inode->i_mode = S_IFREG;
246 inode->i_ino = ino;
247 inode->i_sb = sb;
248
249 /* This is a blatant copy of alloc_inode code. We'd need alloc_inode
250 * to be nonstatic, alas. */
251 {
252 struct address_space * const mapping = &inode->i_data;
253
254 mapping->a_ops = &logfs_reg_aops;
255 mapping->host = inode;
256 mapping->flags = 0;
257 mapping_set_gfp_mask(mapping, GFP_NOFS);
258 mapping->assoc_mapping = NULL;
259 mapping->backing_dev_info = &default_backing_dev_info;
260 inode->i_mapping = mapping;
261 inode->i_nlink = 1;
262 }
263
264 return inode;
265}
266
267struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino)
268{
269 struct inode *inode;
270 int err;
271
272 inode = logfs_new_meta_inode(sb, ino);
273 if (IS_ERR(inode))
274 return inode;
275
276 err = logfs_read_inode(inode);
277 if (err) {
278 destroy_meta_inode(inode);
279 return ERR_PTR(err);
280 }
281 logfs_inode_setops(inode);
282 return inode;
283}
284
285static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc)
286{
287 int ret;
288 long flags = WF_LOCK;
289
290 /* Can only happen if creat() failed. Safe to skip. */
291 if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN)
292 return 0;
293
294 ret = __logfs_write_inode(inode, flags);
295 LOGFS_BUG_ON(ret, inode->i_sb);
296 return ret;
297}
298
299void destroy_meta_inode(struct inode *inode)
300{
301 if (inode) {
302 if (inode->i_data.nrpages)
303 truncate_inode_pages(&inode->i_data, 0);
304 logfs_clear_inode(inode);
305 kmem_cache_free(logfs_inode_cache, logfs_inode(inode));
306 }
307}
308
309/* called with inode_lock held */
310static void logfs_drop_inode(struct inode *inode)
311{
312 struct logfs_super *super = logfs_super(inode->i_sb);
313 struct logfs_inode *li = logfs_inode(inode);
314
315 spin_lock(&logfs_inode_lock);
316 list_move(&li->li_freeing_list, &super->s_freeing_list);
317 spin_unlock(&logfs_inode_lock);
318 generic_drop_inode(inode);
319}
320
321static void logfs_set_ino_generation(struct super_block *sb,
322 struct inode *inode)
323{
324 struct logfs_super *super = logfs_super(sb);
325 u64 ino;
326
327 mutex_lock(&super->s_journal_mutex);
328 ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino);
329 super->s_last_ino = ino;
330 super->s_inos_till_wrap--;
331 if (super->s_inos_till_wrap < 0) {
332 super->s_last_ino = LOGFS_RESERVED_INOS;
333 super->s_generation++;
334 super->s_inos_till_wrap = INOS_PER_WRAP;
335 }
336 inode->i_ino = ino;
337 inode->i_generation = super->s_generation;
338 mutex_unlock(&super->s_journal_mutex);
339}
340
341struct inode *logfs_new_inode(struct inode *dir, int mode)
342{
343 struct super_block *sb = dir->i_sb;
344 struct inode *inode;
345
346 inode = new_inode(sb);
347 if (!inode)
348 return ERR_PTR(-ENOMEM);
349
350 logfs_init_inode(sb, inode);
351
352 /* inherit parent flags */
353 logfs_inode(inode)->li_flags |=
354 logfs_inode(dir)->li_flags & LOGFS_FL_INHERITED;
355
356 inode->i_mode = mode;
357 logfs_set_ino_generation(sb, inode);
358
359 inode->i_uid = current_fsuid();
360 inode->i_gid = current_fsgid();
361 if (dir->i_mode & S_ISGID) {
362 inode->i_gid = dir->i_gid;
363 if (S_ISDIR(mode))
364 inode->i_mode |= S_ISGID;
365 }
366
367 logfs_inode_setops(inode);
368 insert_inode_hash(inode);
369
370 return inode;
371}
372
373static void logfs_init_once(void *_li)
374{
375 struct logfs_inode *li = _li;
376 int i;
377
378 li->li_flags = 0;
379 li->li_used_bytes = 0;
380 li->li_refcount = 1;
381 for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
382 li->li_data[i] = 0;
383 inode_init_once(&li->vfs_inode);
384}
385
386static int logfs_sync_fs(struct super_block *sb, int wait)
387{
388 /* FIXME: write anchor */
389 logfs_super(sb)->s_devops->sync(sb);
390 return 0;
391}
392
393const struct super_operations logfs_super_operations = {
394 .alloc_inode = logfs_alloc_inode,
395 .clear_inode = logfs_clear_inode,
396 .delete_inode = logfs_delete_inode,
397 .destroy_inode = logfs_destroy_inode,
398 .drop_inode = logfs_drop_inode,
399 .write_inode = logfs_write_inode,
400 .statfs = logfs_statfs,
401 .sync_fs = logfs_sync_fs,
402};
403
404int logfs_init_inode_cache(void)
405{
406 logfs_inode_cache = kmem_cache_create("logfs_inode_cache",
407 sizeof(struct logfs_inode), 0, SLAB_RECLAIM_ACCOUNT,
408 logfs_init_once);
409 if (!logfs_inode_cache)
410 return -ENOMEM;
411 return 0;
412}
413
414void logfs_destroy_inode_cache(void)
415{
416 kmem_cache_destroy(logfs_inode_cache);
417}
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c
new file mode 100644
index 000000000000..6ad30a4c9052
--- /dev/null
+++ b/fs/logfs/journal.c
@@ -0,0 +1,883 @@
1/*
2 * fs/logfs/journal.c - journal handling code
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 */
8#include "logfs.h"
9
10static void logfs_calc_free(struct super_block *sb)
11{
12 struct logfs_super *super = logfs_super(sb);
13 u64 reserve, no_segs = super->s_no_segs;
14 s64 free;
15 int i;
16
17 /* superblock segments */
18 no_segs -= 2;
19 super->s_no_journal_segs = 0;
20 /* journal */
21 journal_for_each(i)
22 if (super->s_journal_seg[i]) {
23 no_segs--;
24 super->s_no_journal_segs++;
25 }
26
27 /* open segments plus one extra per level for GC */
28 no_segs -= 2 * super->s_total_levels;
29
30 free = no_segs * (super->s_segsize - LOGFS_SEGMENT_RESERVE);
31 free -= super->s_used_bytes;
32 /* just a bit extra */
33 free -= super->s_total_levels * 4096;
34
35 /* Bad blocks are 'paid' for with speed reserve - the filesystem
36 * simply gets slower as bad blocks accumulate. Until the bad blocks
37 * exceed the speed reserve - then the filesystem gets smaller.
38 */
39 reserve = super->s_bad_segments + super->s_bad_seg_reserve;
40 reserve *= super->s_segsize - LOGFS_SEGMENT_RESERVE;
41 reserve = max(reserve, super->s_speed_reserve);
42 free -= reserve;
43 if (free < 0)
44 free = 0;
45
46 super->s_free_bytes = free;
47}
48
49static void reserve_sb_and_journal(struct super_block *sb)
50{
51 struct logfs_super *super = logfs_super(sb);
52 struct btree_head32 *head = &super->s_reserved_segments;
53 int i, err;
54
55 err = btree_insert32(head, seg_no(sb, super->s_sb_ofs[0]), (void *)1,
56 GFP_KERNEL);
57 BUG_ON(err);
58
59 err = btree_insert32(head, seg_no(sb, super->s_sb_ofs[1]), (void *)1,
60 GFP_KERNEL);
61 BUG_ON(err);
62
63 journal_for_each(i) {
64 if (!super->s_journal_seg[i])
65 continue;
66 err = btree_insert32(head, super->s_journal_seg[i], (void *)1,
67 GFP_KERNEL);
68 BUG_ON(err);
69 }
70}
71
72static void read_dynsb(struct super_block *sb,
73 struct logfs_je_dynsb *dynsb)
74{
75 struct logfs_super *super = logfs_super(sb);
76
77 super->s_gec = be64_to_cpu(dynsb->ds_gec);
78 super->s_sweeper = be64_to_cpu(dynsb->ds_sweeper);
79 super->s_victim_ino = be64_to_cpu(dynsb->ds_victim_ino);
80 super->s_rename_dir = be64_to_cpu(dynsb->ds_rename_dir);
81 super->s_rename_pos = be64_to_cpu(dynsb->ds_rename_pos);
82 super->s_used_bytes = be64_to_cpu(dynsb->ds_used_bytes);
83 super->s_generation = be32_to_cpu(dynsb->ds_generation);
84}
85
86static void read_anchor(struct super_block *sb,
87 struct logfs_je_anchor *da)
88{
89 struct logfs_super *super = logfs_super(sb);
90 struct inode *inode = super->s_master_inode;
91 struct logfs_inode *li = logfs_inode(inode);
92 int i;
93
94 super->s_last_ino = be64_to_cpu(da->da_last_ino);
95 li->li_flags = 0;
96 li->li_height = da->da_height;
97 i_size_write(inode, be64_to_cpu(da->da_size));
98 li->li_used_bytes = be64_to_cpu(da->da_used_bytes);
99
100 for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
101 li->li_data[i] = be64_to_cpu(da->da_data[i]);
102}
103
104static void read_erasecount(struct super_block *sb,
105 struct logfs_je_journal_ec *ec)
106{
107 struct logfs_super *super = logfs_super(sb);
108 int i;
109
110 journal_for_each(i)
111 super->s_journal_ec[i] = be32_to_cpu(ec->ec[i]);
112}
113
114static int read_area(struct super_block *sb, struct logfs_je_area *a)
115{
116 struct logfs_super *super = logfs_super(sb);
117 struct logfs_area *area = super->s_area[a->gc_level];
118 u64 ofs;
119 u32 writemask = ~(super->s_writesize - 1);
120
121 if (a->gc_level >= LOGFS_NO_AREAS)
122 return -EIO;
123 if (a->vim != VIM_DEFAULT)
124 return -EIO; /* TODO: close area and continue */
125
126 area->a_used_bytes = be32_to_cpu(a->used_bytes);
127 area->a_written_bytes = area->a_used_bytes & writemask;
128 area->a_segno = be32_to_cpu(a->segno);
129 if (area->a_segno)
130 area->a_is_open = 1;
131
132 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
133 if (super->s_writesize > 1)
134 logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
135 else
136 logfs_buf_recover(area, ofs, NULL, 0);
137 return 0;
138}
139
140static void *unpack(void *from, void *to)
141{
142 struct logfs_journal_header *jh = from;
143 void *data = from + sizeof(struct logfs_journal_header);
144 int err;
145 size_t inlen, outlen;
146
147 inlen = be16_to_cpu(jh->h_len);
148 outlen = be16_to_cpu(jh->h_datalen);
149
150 if (jh->h_compr == COMPR_NONE)
151 memcpy(to, data, inlen);
152 else {
153 err = logfs_uncompress(data, to, inlen, outlen);
154 BUG_ON(err);
155 }
156 return to;
157}
158
159static int __read_je_header(struct super_block *sb, u64 ofs,
160 struct logfs_journal_header *jh)
161{
162 struct logfs_super *super = logfs_super(sb);
163 size_t bufsize = max_t(size_t, sb->s_blocksize, super->s_writesize)
164 + MAX_JOURNAL_HEADER;
165 u16 type, len, datalen;
166 int err;
167
168 /* read header only */
169 err = wbuf_read(sb, ofs, sizeof(*jh), jh);
170 if (err)
171 return err;
172 type = be16_to_cpu(jh->h_type);
173 len = be16_to_cpu(jh->h_len);
174 datalen = be16_to_cpu(jh->h_datalen);
175 if (len > sb->s_blocksize)
176 return -EIO;
177 if ((type < JE_FIRST) || (type > JE_LAST))
178 return -EIO;
179 if (datalen > bufsize)
180 return -EIO;
181 return 0;
182}
183
184static int __read_je_payload(struct super_block *sb, u64 ofs,
185 struct logfs_journal_header *jh)
186{
187 u16 len;
188 int err;
189
190 len = be16_to_cpu(jh->h_len);
191 err = wbuf_read(sb, ofs + sizeof(*jh), len, jh + 1);
192 if (err)
193 return err;
194 if (jh->h_crc != logfs_crc32(jh, len + sizeof(*jh), 4)) {
195 /* Old code was confused. It forgot about the header length
196 * and stopped calculating the crc 16 bytes before the end
197 * of data - ick!
198 * FIXME: Remove this hack once the old code is fixed.
199 */
200 if (jh->h_crc == logfs_crc32(jh, len, 4))
201 WARN_ON_ONCE(1);
202 else
203 return -EIO;
204 }
205 return 0;
206}
207
208/*
209 * jh needs to be large enough to hold the complete entry, not just the header
210 */
211static int __read_je(struct super_block *sb, u64 ofs,
212 struct logfs_journal_header *jh)
213{
214 int err;
215
216 err = __read_je_header(sb, ofs, jh);
217 if (err)
218 return err;
219 return __read_je_payload(sb, ofs, jh);
220}
221
222static int read_je(struct super_block *sb, u64 ofs)
223{
224 struct logfs_super *super = logfs_super(sb);
225 struct logfs_journal_header *jh = super->s_compressed_je;
226 void *scratch = super->s_je;
227 u16 type, datalen;
228 int err;
229
230 err = __read_je(sb, ofs, jh);
231 if (err)
232 return err;
233 type = be16_to_cpu(jh->h_type);
234 datalen = be16_to_cpu(jh->h_datalen);
235
236 switch (type) {
237 case JE_DYNSB:
238 read_dynsb(sb, unpack(jh, scratch));
239 break;
240 case JE_ANCHOR:
241 read_anchor(sb, unpack(jh, scratch));
242 break;
243 case JE_ERASECOUNT:
244 read_erasecount(sb, unpack(jh, scratch));
245 break;
246 case JE_AREA:
247 read_area(sb, unpack(jh, scratch));
248 break;
249 case JE_OBJ_ALIAS:
250 err = logfs_load_object_aliases(sb, unpack(jh, scratch),
251 datalen);
252 break;
253 default:
254 WARN_ON_ONCE(1);
255 return -EIO;
256 }
257 return err;
258}
259
260static int logfs_read_segment(struct super_block *sb, u32 segno)
261{
262 struct logfs_super *super = logfs_super(sb);
263 struct logfs_journal_header *jh = super->s_compressed_je;
264 u64 ofs, seg_ofs = dev_ofs(sb, segno, 0);
265 u32 h_ofs, last_ofs = 0;
266 u16 len, datalen, last_len = 0;
267 int i, err;
268
269 /* search for most recent commit */
270 for (h_ofs = 0; h_ofs < super->s_segsize; h_ofs += sizeof(*jh)) {
271 ofs = seg_ofs + h_ofs;
272 err = __read_je_header(sb, ofs, jh);
273 if (err)
274 continue;
275 if (jh->h_type != cpu_to_be16(JE_COMMIT))
276 continue;
277 err = __read_je_payload(sb, ofs, jh);
278 if (err)
279 continue;
280 len = be16_to_cpu(jh->h_len);
281 datalen = be16_to_cpu(jh->h_datalen);
282 if ((datalen > sizeof(super->s_je_array)) ||
283 (datalen % sizeof(__be64)))
284 continue;
285 last_ofs = h_ofs;
286 last_len = datalen;
287 h_ofs += ALIGN(len, sizeof(*jh)) - sizeof(*jh);
288 }
289 /* read commit */
290 if (last_ofs == 0)
291 return -ENOENT;
292 ofs = seg_ofs + last_ofs;
293 log_journal("Read commit from %llx\n", ofs);
294 err = __read_je(sb, ofs, jh);
295 BUG_ON(err); /* We should have caught it in the scan loop already */
296 if (err)
297 return err;
298 /* uncompress */
299 unpack(jh, super->s_je_array);
300 super->s_no_je = last_len / sizeof(__be64);
301 /* iterate over array */
302 for (i = 0; i < super->s_no_je; i++) {
303 err = read_je(sb, be64_to_cpu(super->s_je_array[i]));
304 if (err)
305 return err;
306 }
307 super->s_journal_area->a_segno = segno;
308 return 0;
309}
310
311static u64 read_gec(struct super_block *sb, u32 segno)
312{
313 struct logfs_segment_header sh;
314 __be32 crc;
315 int err;
316
317 if (!segno)
318 return 0;
319 err = wbuf_read(sb, dev_ofs(sb, segno, 0), sizeof(sh), &sh);
320 if (err)
321 return 0;
322 crc = logfs_crc32(&sh, sizeof(sh), 4);
323 if (crc != sh.crc) {
324 WARN_ON(sh.gec != cpu_to_be64(0xffffffffffffffffull));
325 /* Most likely it was just erased */
326 return 0;
327 }
328 return be64_to_cpu(sh.gec);
329}
330
331static int logfs_read_journal(struct super_block *sb)
332{
333 struct logfs_super *super = logfs_super(sb);
334 u64 gec[LOGFS_JOURNAL_SEGS], max;
335 u32 segno;
336 int i, max_i;
337
338 max = 0;
339 max_i = -1;
340 journal_for_each(i) {
341 segno = super->s_journal_seg[i];
342 gec[i] = read_gec(sb, super->s_journal_seg[i]);
343 if (gec[i] > max) {
344 max = gec[i];
345 max_i = i;
346 }
347 }
348 if (max_i == -1)
349 return -EIO;
350 /* FIXME: Try older segments in case of error */
351 return logfs_read_segment(sb, super->s_journal_seg[max_i]);
352}
353
354/*
355 * First search the current segment (outer loop), then pick the next segment
356 * in the array, skipping any zero entries (inner loop).
357 */
358static void journal_get_free_segment(struct logfs_area *area)
359{
360 struct logfs_super *super = logfs_super(area->a_sb);
361 int i;
362
363 journal_for_each(i) {
364 if (area->a_segno != super->s_journal_seg[i])
365 continue;
366
367 do {
368 i++;
369 if (i == LOGFS_JOURNAL_SEGS)
370 i = 0;
371 } while (!super->s_journal_seg[i]);
372
373 area->a_segno = super->s_journal_seg[i];
374 area->a_erase_count = ++(super->s_journal_ec[i]);
375 log_journal("Journal now at %x (ec %x)\n", area->a_segno,
376 area->a_erase_count);
377 return;
378 }
379 BUG();
380}
381
382static void journal_get_erase_count(struct logfs_area *area)
383{
384 /* erase count is stored globally and incremented in
385 * journal_get_free_segment() - nothing to do here */
386}
387
388static int journal_erase_segment(struct logfs_area *area)
389{
390 struct super_block *sb = area->a_sb;
391 struct logfs_segment_header sh;
392 u64 ofs;
393 int err;
394
395 err = logfs_erase_segment(sb, area->a_segno, 1);
396 if (err)
397 return err;
398
399 sh.pad = 0;
400 sh.type = SEG_JOURNAL;
401 sh.level = 0;
402 sh.segno = cpu_to_be32(area->a_segno);
403 sh.ec = cpu_to_be32(area->a_erase_count);
404 sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
405 sh.crc = logfs_crc32(&sh, sizeof(sh), 4);
406
407 /* This causes a bug in segment.c. Not yet. */
408 //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0);
409
410 ofs = dev_ofs(sb, area->a_segno, 0);
411 area->a_used_bytes = ALIGN(sizeof(sh), 16);
412 logfs_buf_write(area, ofs, &sh, sizeof(sh));
413 return 0;
414}
415
416static size_t __logfs_write_header(struct logfs_super *super,
417 struct logfs_journal_header *jh, size_t len, size_t datalen,
418 u16 type, u8 compr)
419{
420 jh->h_len = cpu_to_be16(len);
421 jh->h_type = cpu_to_be16(type);
422 jh->h_datalen = cpu_to_be16(datalen);
423 jh->h_compr = compr;
424 jh->h_pad[0] = 'H';
425 jh->h_pad[1] = 'E';
426 jh->h_pad[2] = 'A';
427 jh->h_pad[3] = 'D';
428 jh->h_pad[4] = 'R';
429 jh->h_crc = logfs_crc32(jh, len + sizeof(*jh), 4);
430 return ALIGN(len, 16) + sizeof(*jh);
431}
432
433static size_t logfs_write_header(struct logfs_super *super,
434 struct logfs_journal_header *jh, size_t datalen, u16 type)
435{
436 size_t len = datalen;
437
438 return __logfs_write_header(super, jh, len, datalen, type, COMPR_NONE);
439}
440
441static inline size_t logfs_journal_erasecount_size(struct logfs_super *super)
442{
443 return LOGFS_JOURNAL_SEGS * sizeof(__be32);
444}
445
446static void *logfs_write_erasecount(struct super_block *sb, void *_ec,
447 u16 *type, size_t *len)
448{
449 struct logfs_super *super = logfs_super(sb);
450 struct logfs_je_journal_ec *ec = _ec;
451 int i;
452
453 journal_for_each(i)
454 ec->ec[i] = cpu_to_be32(super->s_journal_ec[i]);
455 *type = JE_ERASECOUNT;
456 *len = logfs_journal_erasecount_size(super);
457 return ec;
458}
459
460static void account_shadow(void *_shadow, unsigned long _sb, u64 ignore,
461 size_t ignore2)
462{
463 struct logfs_shadow *shadow = _shadow;
464 struct super_block *sb = (void *)_sb;
465 struct logfs_super *super = logfs_super(sb);
466
467 /* consume new space */
468 super->s_free_bytes -= shadow->new_len;
469 super->s_used_bytes += shadow->new_len;
470 super->s_dirty_used_bytes -= shadow->new_len;
471
472 /* free up old space */
473 super->s_free_bytes += shadow->old_len;
474 super->s_used_bytes -= shadow->old_len;
475 super->s_dirty_free_bytes -= shadow->old_len;
476
477 logfs_set_segment_used(sb, shadow->old_ofs, -shadow->old_len);
478 logfs_set_segment_used(sb, shadow->new_ofs, shadow->new_len);
479
480 log_journal("account_shadow(%llx, %llx, %x) %llx->%llx %x->%x\n",
481 shadow->ino, shadow->bix, shadow->gc_level,
482 shadow->old_ofs, shadow->new_ofs,
483 shadow->old_len, shadow->new_len);
484 mempool_free(shadow, super->s_shadow_pool);
485}
486
487static void account_shadows(struct super_block *sb)
488{
489 struct logfs_super *super = logfs_super(sb);
490 struct inode *inode = super->s_master_inode;
491 struct logfs_inode *li = logfs_inode(inode);
492 struct shadow_tree *tree = &super->s_shadow_tree;
493
494 btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
495 btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);
496
497 if (li->li_block) {
498 /*
499 * We never actually use the structure, when attached to the
500 * master inode. But it is easier to always free it here than
501 * to have checks in several places elsewhere when allocating
502 * it.
503 */
504 li->li_block->ops->free_block(sb, li->li_block);
505 }
506 BUG_ON((s64)li->li_used_bytes < 0);
507}
508
509static void *__logfs_write_anchor(struct super_block *sb, void *_da,
510 u16 *type, size_t *len)
511{
512 struct logfs_super *super = logfs_super(sb);
513 struct logfs_je_anchor *da = _da;
514 struct inode *inode = super->s_master_inode;
515 struct logfs_inode *li = logfs_inode(inode);
516 int i;
517
518 da->da_height = li->li_height;
519 da->da_last_ino = cpu_to_be64(super->s_last_ino);
520 da->da_size = cpu_to_be64(i_size_read(inode));
521 da->da_used_bytes = cpu_to_be64(li->li_used_bytes);
522 for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
523 da->da_data[i] = cpu_to_be64(li->li_data[i]);
524 *type = JE_ANCHOR;
525 *len = sizeof(*da);
526 return da;
527}
528
529static void *logfs_write_dynsb(struct super_block *sb, void *_dynsb,
530 u16 *type, size_t *len)
531{
532 struct logfs_super *super = logfs_super(sb);
533 struct logfs_je_dynsb *dynsb = _dynsb;
534
535 dynsb->ds_gec = cpu_to_be64(super->s_gec);
536 dynsb->ds_sweeper = cpu_to_be64(super->s_sweeper);
537 dynsb->ds_victim_ino = cpu_to_be64(super->s_victim_ino);
538 dynsb->ds_rename_dir = cpu_to_be64(super->s_rename_dir);
539 dynsb->ds_rename_pos = cpu_to_be64(super->s_rename_pos);
540 dynsb->ds_used_bytes = cpu_to_be64(super->s_used_bytes);
541 dynsb->ds_generation = cpu_to_be32(super->s_generation);
542 *type = JE_DYNSB;
543 *len = sizeof(*dynsb);
544 return dynsb;
545}
546
547static void write_wbuf(struct super_block *sb, struct logfs_area *area,
548 void *wbuf)
549{
550 struct logfs_super *super = logfs_super(sb);
551 struct address_space *mapping = super->s_mapping_inode->i_mapping;
552 u64 ofs;
553 pgoff_t index;
554 int page_ofs;
555 struct page *page;
556
557 ofs = dev_ofs(sb, area->a_segno,
558 area->a_used_bytes & ~(super->s_writesize - 1));
559 index = ofs >> PAGE_SHIFT;
560 page_ofs = ofs & (PAGE_SIZE - 1);
561
562 page = find_lock_page(mapping, index);
563 BUG_ON(!page);
564 memcpy(wbuf, page_address(page) + page_ofs, super->s_writesize);
565 unlock_page(page);
566}
567
568static void *logfs_write_area(struct super_block *sb, void *_a,
569 u16 *type, size_t *len)
570{
571 struct logfs_super *super = logfs_super(sb);
572 struct logfs_area *area = super->s_area[super->s_sum_index];
573 struct logfs_je_area *a = _a;
574
575 a->vim = VIM_DEFAULT;
576 a->gc_level = super->s_sum_index;
577 a->used_bytes = cpu_to_be32(area->a_used_bytes);
578 a->segno = cpu_to_be32(area->a_segno);
579 if (super->s_writesize > 1)
580 write_wbuf(sb, area, a + 1);
581
582 *type = JE_AREA;
583 *len = sizeof(*a) + super->s_writesize;
584 return a;
585}
586
587static void *logfs_write_commit(struct super_block *sb, void *h,
588 u16 *type, size_t *len)
589{
590 struct logfs_super *super = logfs_super(sb);
591
592 *type = JE_COMMIT;
593 *len = super->s_no_je * sizeof(__be64);
594 return super->s_je_array;
595}
596
597static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type,
598 size_t len)
599{
600 struct logfs_super *super = logfs_super(sb);
601 void *header = super->s_compressed_je;
602 void *data = header + sizeof(struct logfs_journal_header);
603 ssize_t compr_len, pad_len;
604 u8 compr = COMPR_ZLIB;
605
606 if (len == 0)
607 return logfs_write_header(super, header, 0, type);
608
609 compr_len = logfs_compress(buf, data, len, sb->s_blocksize);
610 if (compr_len < 0 || type == JE_ANCHOR) {
611 BUG_ON(len > sb->s_blocksize);
612 memcpy(data, buf, len);
613 compr_len = len;
614 compr = COMPR_NONE;
615 }
616
617 pad_len = ALIGN(compr_len, 16);
618 memset(data + compr_len, 0, pad_len - compr_len);
619
620 return __logfs_write_header(super, header, compr_len, len, type, compr);
621}
622
623static s64 logfs_get_free_bytes(struct logfs_area *area, size_t *bytes,
624 int must_pad)
625{
626 u32 writesize = logfs_super(area->a_sb)->s_writesize;
627 s32 ofs;
628 int ret;
629
630 ret = logfs_open_area(area, *bytes);
631 if (ret)
632 return -EAGAIN;
633
634 ofs = area->a_used_bytes;
635 area->a_used_bytes += *bytes;
636
637 if (must_pad) {
638 area->a_used_bytes = ALIGN(area->a_used_bytes, writesize);
639 *bytes = area->a_used_bytes - ofs;
640 }
641
642 return dev_ofs(area->a_sb, area->a_segno, ofs);
643}
644
645static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type,
646 size_t buf_len)
647{
648 struct logfs_super *super = logfs_super(sb);
649 struct logfs_area *area = super->s_journal_area;
650 struct logfs_journal_header *jh = super->s_compressed_je;
651 size_t len;
652 int must_pad = 0;
653 s64 ofs;
654
655 len = __logfs_write_je(sb, buf, type, buf_len);
656 if (jh->h_type == cpu_to_be16(JE_COMMIT))
657 must_pad = 1;
658
659 ofs = logfs_get_free_bytes(area, &len, must_pad);
660 if (ofs < 0)
661 return ofs;
662 logfs_buf_write(area, ofs, super->s_compressed_je, len);
663 super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs);
664 return 0;
665}
666
667static int logfs_write_je(struct super_block *sb,
668 void* (*write)(struct super_block *sb, void *scratch,
669 u16 *type, size_t *len))
670{
671 void *buf;
672 size_t len;
673 u16 type;
674
675 buf = write(sb, logfs_super(sb)->s_je, &type, &len);
676 return logfs_write_je_buf(sb, buf, type, len);
677}
678
679int write_alias_journal(struct super_block *sb, u64 ino, u64 bix,
680 level_t level, int child_no, __be64 val)
681{
682 struct logfs_super *super = logfs_super(sb);
683 struct logfs_obj_alias *oa = super->s_je;
684 int err = 0, fill = super->s_je_fill;
685
686 log_aliases("logfs_write_obj_aliases #%x(%llx, %llx, %x, %x) %llx\n",
687 fill, ino, bix, level, child_no, be64_to_cpu(val));
688 oa[fill].ino = cpu_to_be64(ino);
689 oa[fill].bix = cpu_to_be64(bix);
690 oa[fill].val = val;
691 oa[fill].level = (__force u8)level;
692 oa[fill].child_no = cpu_to_be16(child_no);
693 fill++;
694 if (fill >= sb->s_blocksize / sizeof(*oa)) {
695 err = logfs_write_je_buf(sb, oa, JE_OBJ_ALIAS, sb->s_blocksize);
696 fill = 0;
697 }
698
699 super->s_je_fill = fill;
700 return err;
701}
702
703static int logfs_write_obj_aliases(struct super_block *sb)
704{
705 struct logfs_super *super = logfs_super(sb);
706 int err;
707
708 log_journal("logfs_write_obj_aliases: %d aliases to write\n",
709 super->s_no_object_aliases);
710 super->s_je_fill = 0;
711 err = logfs_write_obj_aliases_pagecache(sb);
712 if (err)
713 return err;
714
715 if (super->s_je_fill)
716 err = logfs_write_je_buf(sb, super->s_je, JE_OBJ_ALIAS,
717 super->s_je_fill
718 * sizeof(struct logfs_obj_alias));
719 return err;
720}
721
722/*
723 * Write all journal entries. The goto logic ensures that all journal entries
724 * are written whenever a new segment is used. It is ugly and potentially a
725 * bit wasteful, but robustness is more important. With this we can *always*
726 * erase all journal segments except the one containing the most recent commit.
727 */
728void logfs_write_anchor(struct super_block *sb)
729{
730 struct logfs_super *super = logfs_super(sb);
731 struct logfs_area *area = super->s_journal_area;
732 int i, err;
733
734 if (!(super->s_flags & LOGFS_SB_FLAG_DIRTY))
735 return;
736 super->s_flags &= ~LOGFS_SB_FLAG_DIRTY;
737
738 BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
739 mutex_lock(&super->s_journal_mutex);
740
741 /* Do this first or suffer corruption */
742 logfs_sync_segments(sb);
743 account_shadows(sb);
744
745again:
746 super->s_no_je = 0;
747 for_each_area(i) {
748 if (!super->s_area[i]->a_is_open)
749 continue;
750 super->s_sum_index = i;
751 err = logfs_write_je(sb, logfs_write_area);
752 if (err)
753 goto again;
754 }
755 err = logfs_write_obj_aliases(sb);
756 if (err)
757 goto again;
758 err = logfs_write_je(sb, logfs_write_erasecount);
759 if (err)
760 goto again;
761 err = logfs_write_je(sb, __logfs_write_anchor);
762 if (err)
763 goto again;
764 err = logfs_write_je(sb, logfs_write_dynsb);
765 if (err)
766 goto again;
767 /*
768 * Order is imperative. First we sync all writes, including the
769 * non-committed journal writes. Then we write the final commit and
770 * sync the current journal segment.
771 * There is a theoretical bug here. Syncing the journal segment will
772 * write a number of journal entries and the final commit. All these
773 * are written in a single operation. If the device layer writes the
774 * data back-to-front, the commit will precede the other journal
775 * entries, leaving a race window.
776 * Two fixes are possible. Preferred is to fix the device layer to
777 * ensure writes happen front-to-back. Alternatively we can insert
778 * another logfs_sync_area() super->s_devops->sync() combo before
779 * writing the commit.
780 */
781 /*
782 * On another subject, super->s_devops->sync is usually not necessary.
783 * Unless called from sys_sync or friends, a barrier would suffice.
784 */
785 super->s_devops->sync(sb);
786 err = logfs_write_je(sb, logfs_write_commit);
787 if (err)
788 goto again;
789 log_journal("Write commit to %llx\n",
790 be64_to_cpu(super->s_je_array[super->s_no_je - 1]));
791 logfs_sync_area(area);
792 BUG_ON(area->a_used_bytes != area->a_written_bytes);
793 super->s_devops->sync(sb);
794
795 mutex_unlock(&super->s_journal_mutex);
796 return;
797}
798
799void do_logfs_journal_wl_pass(struct super_block *sb)
800{
801 struct logfs_super *super = logfs_super(sb);
802 struct logfs_area *area = super->s_journal_area;
803 u32 segno, ec;
804 int i, err;
805
806 log_journal("Journal requires wear-leveling.\n");
807 /* Drop old segments */
808 journal_for_each(i)
809 if (super->s_journal_seg[i]) {
810 logfs_set_segment_unreserved(sb,
811 super->s_journal_seg[i],
812 super->s_journal_ec[i]);
813 super->s_journal_seg[i] = 0;
814 super->s_journal_ec[i] = 0;
815 }
816 /* Get new segments */
817 for (i = 0; i < super->s_no_journal_segs; i++) {
818 segno = get_best_cand(sb, &super->s_reserve_list, &ec);
819 super->s_journal_seg[i] = segno;
820 super->s_journal_ec[i] = ec;
821 logfs_set_segment_reserved(sb, segno);
822 }
823 /* Manually move journal_area */
824 area->a_segno = super->s_journal_seg[0];
825 area->a_is_open = 0;
826 area->a_used_bytes = 0;
827 /* Write journal */
828 logfs_write_anchor(sb);
829 /* Write superblocks */
830 err = logfs_write_sb(sb);
831 BUG_ON(err);
832}
833
834static const struct logfs_area_ops journal_area_ops = {
835 .get_free_segment = journal_get_free_segment,
836 .get_erase_count = journal_get_erase_count,
837 .erase_segment = journal_erase_segment,
838};
839
840int logfs_init_journal(struct super_block *sb)
841{
842 struct logfs_super *super = logfs_super(sb);
843 size_t bufsize = max_t(size_t, sb->s_blocksize, super->s_writesize)
844 + MAX_JOURNAL_HEADER;
845 int ret = -ENOMEM;
846
847 mutex_init(&super->s_journal_mutex);
848 btree_init_mempool32(&super->s_reserved_segments, super->s_btree_pool);
849
850 super->s_je = kzalloc(bufsize, GFP_KERNEL);
851 if (!super->s_je)
852 return ret;
853
854 super->s_compressed_je = kzalloc(bufsize, GFP_KERNEL);
855 if (!super->s_compressed_je)
856 return ret;
857
858 super->s_master_inode = logfs_new_meta_inode(sb, LOGFS_INO_MASTER);
859 if (IS_ERR(super->s_master_inode))
860 return PTR_ERR(super->s_master_inode);
861
862 ret = logfs_read_journal(sb);
863 if (ret)
864 return -EIO;
865
866 reserve_sb_and_journal(sb);
867 logfs_calc_free(sb);
868
869 super->s_journal_area->a_ops = &journal_area_ops;
870 return 0;
871}
872
873void logfs_cleanup_journal(struct super_block *sb)
874{
875 struct logfs_super *super = logfs_super(sb);
876
877 btree_grim_visitor32(&super->s_reserved_segments, 0, NULL);
878 destroy_meta_inode(super->s_master_inode);
879 super->s_master_inode = NULL;
880
881 kfree(super->s_compressed_je);
882 kfree(super->s_je);
883}
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h
new file mode 100644
index 000000000000..129779431373
--- /dev/null
+++ b/fs/logfs/logfs.h
@@ -0,0 +1,724 @@
1/*
2 * fs/logfs/logfs.h
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 *
8 * Private header for logfs.
9 */
10#ifndef FS_LOGFS_LOGFS_H
11#define FS_LOGFS_LOGFS_H
12
13#undef __CHECK_ENDIAN__
14#define __CHECK_ENDIAN__
15
16#include <linux/btree.h>
17#include <linux/crc32.h>
18#include <linux/fs.h>
19#include <linux/kernel.h>
20#include <linux/mempool.h>
21#include <linux/pagemap.h>
22#include <linux/mtd/mtd.h>
23#include "logfs_abi.h"
24
25#define LOGFS_DEBUG_SUPER (0x0001)
26#define LOGFS_DEBUG_SEGMENT (0x0002)
27#define LOGFS_DEBUG_JOURNAL (0x0004)
28#define LOGFS_DEBUG_DIR (0x0008)
29#define LOGFS_DEBUG_FILE (0x0010)
30#define LOGFS_DEBUG_INODE (0x0020)
31#define LOGFS_DEBUG_READWRITE (0x0040)
32#define LOGFS_DEBUG_GC (0x0080)
33#define LOGFS_DEBUG_GC_NOISY (0x0100)
34#define LOGFS_DEBUG_ALIASES (0x0200)
35#define LOGFS_DEBUG_BLOCKMOVE (0x0400)
36#define LOGFS_DEBUG_ALL (0xffffffff)
37
38#define LOGFS_DEBUG (0x01)
39/*
40 * To enable specific log messages, simply define LOGFS_DEBUG to match any
41 * or all of the above.
42 */
43#ifndef LOGFS_DEBUG
44#define LOGFS_DEBUG (0)
45#endif
46
47#define log_cond(cond, fmt, arg...) do { \
48 if (cond) \
49 printk(KERN_DEBUG fmt, ##arg); \
50} while (0)
51
52#define log_super(fmt, arg...) \
53 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_SUPER, fmt, ##arg)
54#define log_segment(fmt, arg...) \
55 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_SEGMENT, fmt, ##arg)
56#define log_journal(fmt, arg...) \
57 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_JOURNAL, fmt, ##arg)
58#define log_dir(fmt, arg...) \
59 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_DIR, fmt, ##arg)
60#define log_file(fmt, arg...) \
61 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_FILE, fmt, ##arg)
62#define log_inode(fmt, arg...) \
63 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_INODE, fmt, ##arg)
64#define log_readwrite(fmt, arg...) \
65 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_READWRITE, fmt, ##arg)
66#define log_gc(fmt, arg...) \
67 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_GC, fmt, ##arg)
68#define log_gc_noisy(fmt, arg...) \
69 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_GC_NOISY, fmt, ##arg)
70#define log_aliases(fmt, arg...) \
71 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_ALIASES, fmt, ##arg)
72#define log_blockmove(fmt, arg...) \
73 log_cond(LOGFS_DEBUG & LOGFS_DEBUG_BLOCKMOVE, fmt, ##arg)
74
75#define PG_pre_locked PG_owner_priv_1
76#define PagePreLocked(page) test_bit(PG_pre_locked, &(page)->flags)
77#define SetPagePreLocked(page) set_bit(PG_pre_locked, &(page)->flags)
78#define ClearPagePreLocked(page) clear_bit(PG_pre_locked, &(page)->flags)
79
80/* FIXME: This should really be somewhere in the 64bit area. */
81#define LOGFS_LINK_MAX (1<<30)
82
83/* Read-only filesystem */
84#define LOGFS_SB_FLAG_RO 0x0001
85#define LOGFS_SB_FLAG_DIRTY 0x0002
86#define LOGFS_SB_FLAG_OBJ_ALIAS 0x0004
87#define LOGFS_SB_FLAG_SHUTDOWN 0x0008
88
89/* Write Control Flags */
90#define WF_LOCK 0x01 /* take write lock */
91#define WF_WRITE 0x02 /* write block */
92#define WF_DELETE 0x04 /* delete old block */
93
94typedef u8 __bitwise level_t;
95typedef u8 __bitwise gc_level_t;
96
97#define LEVEL(level) ((__force level_t)(level))
98#define GC_LEVEL(gc_level) ((__force gc_level_t)(gc_level))
99
100#define SUBLEVEL(level) ( (void)((level) == LEVEL(1)), \
101 (__force level_t)((__force u8)(level) - 1) )
102
103/**
104 * struct logfs_area - area management information
105 *
106 * @a_sb: the superblock this area belongs to
107 * @a_is_open: 1 if the area is currently open, else 0
108 * @a_segno: segment number of area
109 * @a_written_bytes: number of bytes already written back
110 * @a_used_bytes: number of used bytes
111 * @a_ops: area operations (either journal or ostore)
112 * @a_erase_count: erase count
113 * @a_level: GC level
114 */
115struct logfs_area { /* a segment open for writing */
116 struct super_block *a_sb;
117 int a_is_open;
118 u32 a_segno;
119 u32 a_written_bytes;
120 u32 a_used_bytes;
121 const struct logfs_area_ops *a_ops;
122 u32 a_erase_count;
123 gc_level_t a_level;
124};
125
126/**
127 * struct logfs_area_ops - area operations
128 *
129 * @get_free_segment: fill area->ofs with the offset of a free segment
130 * @get_erase_count: fill area->erase_count (needs area->ofs)
131 * @erase_segment: erase and setup segment
132 */
133struct logfs_area_ops {
134 void (*get_free_segment)(struct logfs_area *area);
135 void (*get_erase_count)(struct logfs_area *area);
136 int (*erase_segment)(struct logfs_area *area);
137};
138
139/**
140 * struct logfs_device_ops - device access operations
141 *
142 * @readpage: read one page (mm page)
143 * @writeseg: write one segment. may be a partial segment
144 * @erase: erase one segment
145 * @read: read from the device
146 * @erase: erase part of the device
147 */
148struct logfs_device_ops {
149 struct page *(*find_first_sb)(struct super_block *sb, u64 *ofs);
150 struct page *(*find_last_sb)(struct super_block *sb, u64 *ofs);
151 int (*write_sb)(struct super_block *sb, struct page *page);
152 int (*readpage)(void *_sb, struct page *page);
153 void (*writeseg)(struct super_block *sb, u64 ofs, size_t len);
154 int (*erase)(struct super_block *sb, loff_t ofs, size_t len,
155 int ensure_write);
156 void (*sync)(struct super_block *sb);
157 void (*put_device)(struct super_block *sb);
158};
159
160/**
161 * struct candidate_list - list of similar candidates
162 */
163struct candidate_list {
164 struct rb_root rb_tree;
165 int count;
166 int maxcount;
167 int sort_by_ec;
168};
169
170/**
171 * struct gc_candidate - "candidate" segment to be garbage collected next
172 *
173 * @list: list (either free of low)
174 * @segno: segment number
175 * @valid: number of valid bytes
176 * @erase_count: erase count of segment
177 * @dist: distance from tree root
178 *
179 * Candidates can be on two lists. The free list contains electees rather
180 * than candidates - segments that no longer contain any valid data. The
181 * low list contains candidates to be picked for GC. It should be kept
182 * short. It is not required to always pick a perfect candidate. In the
183 * worst case GC will have to move more data than absolutely necessary.
184 */
185struct gc_candidate {
186 struct rb_node rb_node;
187 struct candidate_list *list;
188 u32 segno;
189 u32 valid;
190 u32 erase_count;
191 u8 dist;
192};
193
194/**
195 * struct logfs_journal_entry - temporary structure used during journal scan
196 *
197 * @used:
198 * @version: normalized version
199 * @len: length
200 * @offset: offset
201 */
202struct logfs_journal_entry {
203 int used;
204 s16 version;
205 u16 len;
206 u16 datalen;
207 u64 offset;
208};
209
210enum transaction_state {
211 CREATE_1 = 1,
212 CREATE_2,
213 UNLINK_1,
214 UNLINK_2,
215 CROSS_RENAME_1,
216 CROSS_RENAME_2,
217 TARGET_RENAME_1,
218 TARGET_RENAME_2,
219 TARGET_RENAME_3
220};
221
222/**
223 * struct logfs_transaction - essential fields to support atomic dirops
224 *
225 * @ino: target inode
226 * @dir: inode of directory containing dentry
227 * @pos: pos of dentry in directory
228 */
229struct logfs_transaction {
230 enum transaction_state state;
231 u64 ino;
232 u64 dir;
233 u64 pos;
234};
235
236/**
237 * struct logfs_shadow - old block in the shadow of a not-yet-committed new one
238 * @old_ofs: offset of old block on medium
239 * @new_ofs: offset of new block on medium
240 * @ino: inode number
241 * @bix: block index
242 * @old_len: size of old block, including header
243 * @new_len: size of new block, including header
244 * @level: block level
245 */
246struct logfs_shadow {
247 u64 old_ofs;
248 u64 new_ofs;
249 u64 ino;
250 u64 bix;
251 int old_len;
252 int new_len;
253 gc_level_t gc_level;
254};
255
256/**
257 * struct shadow_tree
258 * @new: shadows where old_ofs==0, indexed by new_ofs
259 * @old: shadows where old_ofs!=0, indexed by old_ofs
260 */
261struct shadow_tree {
262 struct btree_head64 new;
263 struct btree_head64 old;
264};
265
266struct object_alias_item {
267 struct list_head list;
268 __be64 val;
269 int child_no;
270};
271
272/**
273 * struct logfs_block - contains any block state
274 * @type: indirect block or inode
275 * @full: number of fully populated children
276 * @partial: number of partially populated children
277 *
278 * Most blocks are directly represented by page cache pages. But when a block
279 * becomes dirty, is part of a transaction, contains aliases or is otherwise
280 * special, a struct logfs_block is allocated to track the additional state.
281 * Inodes are very similar to indirect blocks, so they can also get one of
282 * these structures added when appropriate.
283 */
284#define BLOCK_INDIRECT 1 /* Indirect block */
285#define BLOCK_INODE 2 /* Inode */
286struct logfs_block_ops;
287struct logfs_block {
288 struct list_head alias_list;
289 struct list_head item_list;
290 struct super_block *sb;
291 u64 ino;
292 u64 bix;
293 level_t level;
294 struct page *page;
295 struct inode *inode;
296 struct logfs_transaction *ta;
297 unsigned long alias_map[LOGFS_BLOCK_FACTOR / BITS_PER_LONG];
298 struct logfs_block_ops *ops;
299 int full;
300 int partial;
301 int reserved_bytes;
302};
303
304typedef int write_alias_t(struct super_block *sb, u64 ino, u64 bix,
305 level_t level, int child_no, __be64 val);
306struct logfs_block_ops {
307 void (*write_block)(struct logfs_block *block);
308 gc_level_t (*block_level)(struct logfs_block *block);
309 void (*free_block)(struct super_block *sb, struct logfs_block*block);
310 int (*write_alias)(struct super_block *sb,
311 struct logfs_block *block,
312 write_alias_t *write_one_alias);
313};
314
315struct logfs_super {
316 struct mtd_info *s_mtd; /* underlying device */
317 struct block_device *s_bdev; /* underlying device */
318 const struct logfs_device_ops *s_devops;/* device access */
319 struct inode *s_master_inode; /* inode file */
320 struct inode *s_segfile_inode; /* segment file */
321 struct inode *s_mapping_inode; /* device mapping */
322 atomic_t s_pending_writes; /* outstanting bios */
323 long s_flags;
324 mempool_t *s_btree_pool; /* for btree nodes */
325 mempool_t *s_alias_pool; /* aliases in segment.c */
326 u64 s_feature_incompat;
327 u64 s_feature_ro_compat;
328 u64 s_feature_compat;
329 u64 s_feature_flags;
330 u64 s_sb_ofs[2];
331 struct page *s_erase_page; /* for dev_bdev.c */
332 /* alias.c fields */
333 struct btree_head32 s_segment_alias; /* remapped segments */
334 int s_no_object_aliases;
335 struct list_head s_object_alias; /* remapped objects */
336 struct btree_head128 s_object_alias_tree; /* remapped objects */
337 struct mutex s_object_alias_mutex;
338 /* dir.c fields */
339 struct mutex s_dirop_mutex; /* for creat/unlink/rename */
340 u64 s_victim_ino; /* used for atomic dir-ops */
341 u64 s_rename_dir; /* source directory ino */
342 u64 s_rename_pos; /* position of source dd */
343 /* gc.c fields */
344 long s_segsize; /* size of a segment */
345 int s_segshift; /* log2 of segment size */
346 long s_segmask; /* 1 << s_segshift - 1 */
347 long s_no_segs; /* segments on device */
348 long s_no_journal_segs; /* segments used for journal */
349 long s_no_blocks; /* blocks per segment */
350 long s_writesize; /* minimum write size */
351 int s_writeshift; /* log2 of write size */
352 u64 s_size; /* filesystem size */
353 struct logfs_area *s_area[LOGFS_NO_AREAS]; /* open segment array */
354 u64 s_gec; /* global erase count */
355 u64 s_wl_gec_ostore; /* time of last wl event */
356 u64 s_wl_gec_journal; /* time of last wl event */
357 u64 s_sweeper; /* current sweeper pos */
358 u8 s_ifile_levels; /* max level of ifile */
359 u8 s_iblock_levels; /* max level of regular files */
360 u8 s_data_levels; /* # of segments to leaf block*/
361 u8 s_total_levels; /* sum of above three */
362 struct btree_head32 s_cand_tree; /* all candidates */
363 struct candidate_list s_free_list; /* 100% free segments */
364 struct candidate_list s_reserve_list; /* Bad segment reserve */
365 struct candidate_list s_low_list[LOGFS_NO_AREAS];/* good candidates */
366 struct candidate_list s_ec_list; /* wear level candidates */
367 struct btree_head32 s_reserved_segments;/* sb, journal, bad, etc. */
368 /* inode.c fields */
369 u64 s_last_ino; /* highest ino used */
370 long s_inos_till_wrap;
371 u32 s_generation; /* i_generation for new files */
372 struct list_head s_freeing_list; /* inodes being freed */
373 /* journal.c fields */
374 struct mutex s_journal_mutex;
375 void *s_je; /* journal entry to compress */
376 void *s_compressed_je; /* block to write to journal */
377 u32 s_journal_seg[LOGFS_JOURNAL_SEGS]; /* journal segments */
378 u32 s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */
379 u64 s_last_version;
380 struct logfs_area *s_journal_area; /* open journal segment */
381 __be64 s_je_array[64];
382 int s_no_je;
383
384 int s_sum_index; /* for the 12 summaries */
385 struct shadow_tree s_shadow_tree;
386 int s_je_fill; /* index of current je */
387 /* readwrite.c fields */
388 struct mutex s_write_mutex;
389 int s_lock_count;
390 mempool_t *s_block_pool; /* struct logfs_block pool */
391 mempool_t *s_shadow_pool; /* struct logfs_shadow pool */
392 /*
393 * Space accounting:
394 * - s_used_bytes specifies space used to store valid data objects.
395 * - s_dirty_used_bytes is space used to store non-committed data
396 * objects. Those objects have already been written themselves,
397 * but they don't become valid until all indirect blocks up to the
398 * journal have been written as well.
399 * - s_dirty_free_bytes is space used to store the old copy of a
400 * replaced object, as long as the replacement is non-committed.
401 * In other words, it is the amount of space freed when all dirty
402 * blocks are written back.
403 * - s_free_bytes is the amount of free space available for any
404 * purpose.
405 * - s_root_reserve is the amount of free space available only to
406 * the root user. Non-privileged users can no longer write once
407 * this watermark has been reached.
408 * - s_speed_reserve is space which remains unused to speed up
409 * garbage collection performance.
410 * - s_dirty_pages is the space reserved for currently dirty pages.
411 * It is a pessimistic estimate, so some/most will get freed on
412 * page writeback.
413 *
414 * s_used_bytes + s_free_bytes + s_speed_reserve = total usable size
415 */
416 u64 s_free_bytes;
417 u64 s_used_bytes;
418 u64 s_dirty_free_bytes;
419 u64 s_dirty_used_bytes;
420 u64 s_root_reserve;
421 u64 s_speed_reserve;
422 u64 s_dirty_pages;
423 /* Bad block handling:
424 * - s_bad_seg_reserve is a number of segments usually kept
425 * free. When encountering bad blocks, the affected segment's data
426 * is _temporarily_ moved to a reserved segment.
427 * - s_bad_segments is the number of known bad segments.
428 */
429 u32 s_bad_seg_reserve;
430 u32 s_bad_segments;
431};
432
433/**
434 * struct logfs_inode - in-memory inode
435 *
436 * @vfs_inode: struct inode
437 * @li_data: data pointers
438 * @li_used_bytes: number of used bytes
439 * @li_freeing_list: used to track inodes currently being freed
440 * @li_flags: inode flags
441 * @li_refcount: number of internal (GC-induced) references
442 */
443struct logfs_inode {
444 struct inode vfs_inode;
445 u64 li_data[LOGFS_EMBEDDED_FIELDS];
446 u64 li_used_bytes;
447 struct list_head li_freeing_list;
448 struct logfs_block *li_block;
449 u32 li_flags;
450 u8 li_height;
451 int li_refcount;
452};
453
454#define journal_for_each(__i) for (__i = 0; __i < LOGFS_JOURNAL_SEGS; __i++)
455#define for_each_area(__i) for (__i = 0; __i < LOGFS_NO_AREAS; __i++)
456#define for_each_area_down(__i) for (__i = LOGFS_NO_AREAS - 1; __i >= 0; __i--)
457
458/* compr.c */
459int logfs_compress(void *in, void *out, size_t inlen, size_t outlen);
460int logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen);
461int __init logfs_compr_init(void);
462void logfs_compr_exit(void);
463
464/* dev_bdev.c */
465#ifdef CONFIG_BLOCK
466int logfs_get_sb_bdev(struct file_system_type *type, int flags,
467 const char *devname, struct vfsmount *mnt);
468#else
469static inline int logfs_get_sb_bdev(struct file_system_type *type, int flags,
470 const char *devname, struct vfsmount *mnt)
471{
472 return -ENODEV;
473}
474#endif
475
476/* dev_mtd.c */
477#ifdef CONFIG_MTD
478int logfs_get_sb_mtd(struct file_system_type *type, int flags,
479 int mtdnr, struct vfsmount *mnt);
480#else
481static inline int logfs_get_sb_mtd(struct file_system_type *type, int flags,
482 int mtdnr, struct vfsmount *mnt)
483{
484 return -ENODEV;
485}
486#endif
487
488/* dir.c */
489extern const struct inode_operations logfs_symlink_iops;
490extern const struct inode_operations logfs_dir_iops;
491extern const struct file_operations logfs_dir_fops;
492int logfs_replay_journal(struct super_block *sb);
493
494/* file.c */
495extern const struct inode_operations logfs_reg_iops;
496extern const struct file_operations logfs_reg_fops;
497extern const struct address_space_operations logfs_reg_aops;
498int logfs_readpage(struct file *file, struct page *page);
499int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
500 unsigned long arg);
501int logfs_fsync(struct file *file, struct dentry *dentry, int datasync);
502
503/* gc.c */
504u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec);
505void logfs_gc_pass(struct super_block *sb);
506int logfs_check_areas(struct super_block *sb);
507int logfs_init_gc(struct super_block *sb);
508void logfs_cleanup_gc(struct super_block *sb);
509
510/* inode.c */
511extern const struct super_operations logfs_super_operations;
512struct inode *logfs_iget(struct super_block *sb, ino_t ino);
513struct inode *logfs_safe_iget(struct super_block *sb, ino_t ino, int *cookie);
514void logfs_safe_iput(struct inode *inode, int cookie);
515struct inode *logfs_new_inode(struct inode *dir, int mode);
516struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino);
517struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino);
518int logfs_init_inode_cache(void);
519void logfs_destroy_inode_cache(void);
520void destroy_meta_inode(struct inode *inode);
521void logfs_set_blocks(struct inode *inode, u64 no);
522/* these logically belong into inode.c but actually reside in readwrite.c */
523int logfs_read_inode(struct inode *inode);
524int __logfs_write_inode(struct inode *inode, long flags);
525void logfs_delete_inode(struct inode *inode);
526void logfs_clear_inode(struct inode *inode);
527
528/* journal.c */
529void logfs_write_anchor(struct super_block *sb);
530int logfs_init_journal(struct super_block *sb);
531void logfs_cleanup_journal(struct super_block *sb);
532int write_alias_journal(struct super_block *sb, u64 ino, u64 bix,
533 level_t level, int child_no, __be64 val);
534void do_logfs_journal_wl_pass(struct super_block *sb);
535
536/* readwrite.c */
537pgoff_t logfs_pack_index(u64 bix, level_t level);
538void logfs_unpack_index(pgoff_t index, u64 *bix, level_t *level);
539int logfs_inode_write(struct inode *inode, const void *buf, size_t count,
540 loff_t bix, long flags, struct shadow_tree *shadow_tree);
541int logfs_readpage_nolock(struct page *page);
542int logfs_write_buf(struct inode *inode, struct page *page, long flags);
543int logfs_delete(struct inode *inode, pgoff_t index,
544 struct shadow_tree *shadow_tree);
545int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
546 gc_level_t gc_level, long flags);
547int logfs_is_valid_block(struct super_block *sb, u64 ofs, u64 ino, u64 bix,
548 gc_level_t gc_level);
549int logfs_truncate(struct inode *inode, u64 size);
550u64 logfs_seek_hole(struct inode *inode, u64 bix);
551u64 logfs_seek_data(struct inode *inode, u64 bix);
552int logfs_open_segfile(struct super_block *sb);
553int logfs_init_rw(struct super_block *sb);
554void logfs_cleanup_rw(struct super_block *sb);
555void logfs_add_transaction(struct inode *inode, struct logfs_transaction *ta);
556void logfs_del_transaction(struct inode *inode, struct logfs_transaction *ta);
557void logfs_write_block(struct logfs_block *block, long flags);
558int logfs_write_obj_aliases_pagecache(struct super_block *sb);
559void logfs_get_segment_entry(struct super_block *sb, u32 segno,
560 struct logfs_segment_entry *se);
561void logfs_set_segment_used(struct super_block *sb, u64 ofs, int increment);
562void logfs_set_segment_erased(struct super_block *sb, u32 segno, u32 ec,
563 gc_level_t gc_level);
564void logfs_set_segment_reserved(struct super_block *sb, u32 segno);
565void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec);
566struct logfs_block *__alloc_block(struct super_block *sb,
567 u64 ino, u64 bix, level_t level);
568void __free_block(struct super_block *sb, struct logfs_block *block);
569void btree_write_block(struct logfs_block *block);
570void initialize_block_counters(struct page *page, struct logfs_block *block,
571 __be64 *array, int page_is_empty);
572int logfs_exist_block(struct inode *inode, u64 bix);
573int get_page_reserve(struct inode *inode, struct page *page);
574extern struct logfs_block_ops indirect_block_ops;
575
576/* segment.c */
577int logfs_erase_segment(struct super_block *sb, u32 ofs, int ensure_erase);
578int wbuf_read(struct super_block *sb, u64 ofs, size_t len, void *buf);
579int logfs_segment_read(struct inode *inode, struct page *page, u64 ofs, u64 bix,
580 level_t level);
581int logfs_segment_write(struct inode *inode, struct page *page,
582 struct logfs_shadow *shadow);
583int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow);
584int logfs_load_object_aliases(struct super_block *sb,
585 struct logfs_obj_alias *oa, int count);
586void move_page_to_btree(struct page *page);
587int logfs_init_mapping(struct super_block *sb);
588void logfs_sync_area(struct logfs_area *area);
589void logfs_sync_segments(struct super_block *sb);
590
591/* area handling */
592int logfs_init_areas(struct super_block *sb);
593void logfs_cleanup_areas(struct super_block *sb);
594int logfs_open_area(struct logfs_area *area, size_t bytes);
595void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
596 int use_filler);
597
598static inline void logfs_buf_write(struct logfs_area *area, u64 ofs,
599 void *buf, size_t len)
600{
601 __logfs_buf_write(area, ofs, buf, len, 0);
602}
603
604static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs,
605 void *buf, size_t len)
606{
607 __logfs_buf_write(area, ofs, buf, len, 1);
608}
609
610/* super.c */
611struct page *emergency_read_begin(struct address_space *mapping, pgoff_t index);
612void emergency_read_end(struct page *page);
613void logfs_crash_dump(struct super_block *sb);
614void *memchr_inv(const void *s, int c, size_t n);
615int logfs_statfs(struct dentry *dentry, struct kstatfs *stats);
616int logfs_get_sb_device(struct file_system_type *type, int flags,
617 struct mtd_info *mtd, struct block_device *bdev,
618 const struct logfs_device_ops *devops, struct vfsmount *mnt);
619int logfs_check_ds(struct logfs_disk_super *ds);
620int logfs_write_sb(struct super_block *sb);
621
622static inline struct logfs_super *logfs_super(struct super_block *sb)
623{
624 return sb->s_fs_info;
625}
626
627static inline struct logfs_inode *logfs_inode(struct inode *inode)
628{
629 return container_of(inode, struct logfs_inode, vfs_inode);
630}
631
632static inline void logfs_set_ro(struct super_block *sb)
633{
634 logfs_super(sb)->s_flags |= LOGFS_SB_FLAG_RO;
635}
636
637#define LOGFS_BUG(sb) do { \
638 struct super_block *__sb = sb; \
639 logfs_crash_dump(__sb); \
640 logfs_super(__sb)->s_flags |= LOGFS_SB_FLAG_RO; \
641 BUG(); \
642} while (0)
643
644#define LOGFS_BUG_ON(condition, sb) \
645 do { if (unlikely(condition)) LOGFS_BUG((sb)); } while (0)
646
647static inline __be32 logfs_crc32(void *data, size_t len, size_t skip)
648{
649 return cpu_to_be32(crc32(~0, data+skip, len-skip));
650}
651
652static inline u8 logfs_type(struct inode *inode)
653{
654 return (inode->i_mode >> 12) & 15;
655}
656
657static inline pgoff_t logfs_index(struct super_block *sb, u64 pos)
658{
659 return pos >> sb->s_blocksize_bits;
660}
661
662static inline u64 dev_ofs(struct super_block *sb, u32 segno, u32 ofs)
663{
664 return ((u64)segno << logfs_super(sb)->s_segshift) + ofs;
665}
666
667static inline u32 seg_no(struct super_block *sb, u64 ofs)
668{
669 return ofs >> logfs_super(sb)->s_segshift;
670}
671
672static inline u32 seg_ofs(struct super_block *sb, u64 ofs)
673{
674 return ofs & logfs_super(sb)->s_segmask;
675}
676
677static inline u64 seg_align(struct super_block *sb, u64 ofs)
678{
679 return ofs & ~logfs_super(sb)->s_segmask;
680}
681
682static inline struct logfs_block *logfs_block(struct page *page)
683{
684 return (void *)page->private;
685}
686
687static inline level_t shrink_level(gc_level_t __level)
688{
689 u8 level = (__force u8)__level;
690
691 if (level >= LOGFS_MAX_LEVELS)
692 level -= LOGFS_MAX_LEVELS;
693 return (__force level_t)level;
694}
695
696static inline gc_level_t expand_level(u64 ino, level_t __level)
697{
698 u8 level = (__force u8)__level;
699
700 if (ino == LOGFS_INO_MASTER) {
701 /* ifile has seperate areas */
702 level += LOGFS_MAX_LEVELS;
703 }
704 return (__force gc_level_t)level;
705}
706
707static inline int logfs_block_shift(struct super_block *sb, level_t level)
708{
709 level = shrink_level((__force gc_level_t)level);
710 return (__force int)level * (sb->s_blocksize_bits - 3);
711}
712
713static inline u64 logfs_block_mask(struct super_block *sb, level_t level)
714{
715 return ~0ull << logfs_block_shift(sb, level);
716}
717
718static inline struct logfs_area *get_area(struct super_block *sb,
719 gc_level_t gc_level)
720{
721 return logfs_super(sb)->s_area[(__force u8)gc_level];
722}
723
724#endif
diff --git a/fs/logfs/logfs_abi.h b/fs/logfs/logfs_abi.h
new file mode 100644
index 000000000000..f674725663fe
--- /dev/null
+++ b/fs/logfs/logfs_abi.h
@@ -0,0 +1,629 @@
1/*
2 * fs/logfs/logfs_abi.h
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 *
8 * Public header for logfs.
9 */
10#ifndef FS_LOGFS_LOGFS_ABI_H
11#define FS_LOGFS_LOGFS_ABI_H
12
13/* For out-of-kernel compiles */
14#ifndef BUILD_BUG_ON
15#define BUILD_BUG_ON(condition) /**/
16#endif
17
18#define SIZE_CHECK(type, size) \
19static inline void check_##type(void) \
20{ \
21 BUILD_BUG_ON(sizeof(struct type) != (size)); \
22}
23
24/*
25 * Throughout the logfs code, we're constantly dealing with blocks at
26 * various positions or offsets. To remove confusion, we stricly
27 * distinguish between a "position" - the logical position within a
28 * file and an "offset" - the physical location within the device.
29 *
30 * Any usage of the term offset for a logical location or position for
31 * a physical one is a bug and should get fixed.
32 */
33
34/*
35 * Block are allocated in one of several segments depending on their
36 * level. The following levels are used:
37 * 0 - regular data block
38 * 1 - i1 indirect blocks
39 * 2 - i2 indirect blocks
40 * 3 - i3 indirect blocks
41 * 4 - i4 indirect blocks
42 * 5 - i5 indirect blocks
43 * 6 - ifile data blocks
44 * 7 - ifile i1 indirect blocks
45 * 8 - ifile i2 indirect blocks
46 * 9 - ifile i3 indirect blocks
47 * 10 - ifile i4 indirect blocks
48 * 11 - ifile i5 indirect blocks
49 * Potential levels to be used in the future:
50 * 12 - gc recycled blocks, long-lived data
51 * 13 - replacement blocks, short-lived data
52 *
53 * Levels 1-11 are necessary for robust gc operations and help seperate
54 * short-lived metadata from longer-lived file data. In the future,
55 * file data should get seperated into several segments based on simple
56 * heuristics. Old data recycled during gc operation is expected to be
57 * long-lived. New data is of uncertain life expectancy. New data
58 * used to replace older blocks in existing files is expected to be
59 * short-lived.
60 */
61
62
63/* Magic numbers. 64bit for superblock, 32bit for statfs f_type */
64#define LOGFS_MAGIC 0x7a3a8e5cb9d5bf67ull
65#define LOGFS_MAGIC_U32 0xc97e8168u
66
67/*
68 * Various blocksize related macros. Blocksize is currently fixed at 4KiB.
69 * Sooner or later that should become configurable and the macros replaced
70 * by something superblock-dependent. Pointers in indirect blocks are and
71 * will remain 64bit.
72 *
73 * LOGFS_BLOCKSIZE - self-explaining
74 * LOGFS_BLOCK_FACTOR - number of pointers per indirect block
75 * LOGFS_BLOCK_BITS - log2 of LOGFS_BLOCK_FACTOR, used for shifts
76 */
77#define LOGFS_BLOCKSIZE (4096ull)
78#define LOGFS_BLOCK_FACTOR (LOGFS_BLOCKSIZE / sizeof(u64))
79#define LOGFS_BLOCK_BITS (9)
80
81/*
82 * Number of blocks at various levels of indirection. There are 16 direct
83 * block pointers plus a single indirect pointer.
84 */
85#define I0_BLOCKS (16)
86#define I1_BLOCKS LOGFS_BLOCK_FACTOR
87#define I2_BLOCKS (LOGFS_BLOCK_FACTOR * I1_BLOCKS)
88#define I3_BLOCKS (LOGFS_BLOCK_FACTOR * I2_BLOCKS)
89#define I4_BLOCKS (LOGFS_BLOCK_FACTOR * I3_BLOCKS)
90#define I5_BLOCKS (LOGFS_BLOCK_FACTOR * I4_BLOCKS)
91
92#define INDIRECT_INDEX I0_BLOCKS
93#define LOGFS_EMBEDDED_FIELDS (I0_BLOCKS + 1)
94
95/*
96 * Sizes at which files require another level of indirection. Files smaller
97 * than LOGFS_EMBEDDED_SIZE can be completely stored in the inode itself,
98 * similar like ext2 fast symlinks.
99 *
100 * Data at a position smaller than LOGFS_I0_SIZE is accessed through the
101 * direct pointers, else through the 1x indirect pointer and so forth.
102 */
103#define LOGFS_EMBEDDED_SIZE (LOGFS_EMBEDDED_FIELDS * sizeof(u64))
104#define LOGFS_I0_SIZE (I0_BLOCKS * LOGFS_BLOCKSIZE)
105#define LOGFS_I1_SIZE (I1_BLOCKS * LOGFS_BLOCKSIZE)
106#define LOGFS_I2_SIZE (I2_BLOCKS * LOGFS_BLOCKSIZE)
107#define LOGFS_I3_SIZE (I3_BLOCKS * LOGFS_BLOCKSIZE)
108#define LOGFS_I4_SIZE (I4_BLOCKS * LOGFS_BLOCKSIZE)
109#define LOGFS_I5_SIZE (I5_BLOCKS * LOGFS_BLOCKSIZE)
110
111/*
112 * Each indirect block pointer must have this flag set, if all block pointers
113 * behind it are set, i.e. there is no hole hidden in the shadow of this
114 * indirect block pointer.
115 */
116#define LOGFS_FULLY_POPULATED (1ULL << 63)
117#define pure_ofs(ofs) (ofs & ~LOGFS_FULLY_POPULATED)
118
119/*
120 * LogFS needs to seperate data into levels. Each level is defined as the
121 * maximal possible distance from the master inode (inode of the inode file).
122 * Data blocks reside on level 0, 1x indirect block on level 1, etc.
123 * Inodes reside on level 6, indirect blocks for the inode file on levels 7-11.
124 * This effort is necessary to guarantee garbage collection to always make
125 * progress.
126 *
127 * LOGFS_MAX_INDIRECT is the maximal indirection through indirect blocks,
128 * LOGFS_MAX_LEVELS is one more for the actual data level of a file. It is
129 * the maximal number of levels for one file.
130 * LOGFS_NO_AREAS is twice that, as the inode file and regular files are
131 * effectively stacked on top of each other.
132 */
133#define LOGFS_MAX_INDIRECT (5)
134#define LOGFS_MAX_LEVELS (LOGFS_MAX_INDIRECT + 1)
135#define LOGFS_NO_AREAS (2 * LOGFS_MAX_LEVELS)
136
137/* Maximum size of filenames */
138#define LOGFS_MAX_NAMELEN (255)
139
140/* Number of segments in the primary journal. */
141#define LOGFS_JOURNAL_SEGS (16)
142
143/* Maximum number of free/erased/etc. segments in journal entries */
144#define MAX_CACHED_SEGS (64)
145
146
147/*
148 * LOGFS_OBJECT_HEADERSIZE is the size of a single header in the object store,
149 * LOGFS_MAX_OBJECTSIZE the size of the largest possible object, including
150 * its header,
151 * LOGFS_SEGMENT_RESERVE is the amount of space reserved for each segment for
152 * its segment header and the padded space at the end when no further objects
153 * fit.
154 */
155#define LOGFS_OBJECT_HEADERSIZE (0x1c)
156#define LOGFS_SEGMENT_HEADERSIZE (0x18)
157#define LOGFS_MAX_OBJECTSIZE (LOGFS_OBJECT_HEADERSIZE + LOGFS_BLOCKSIZE)
158#define LOGFS_SEGMENT_RESERVE \
159 (LOGFS_SEGMENT_HEADERSIZE + LOGFS_MAX_OBJECTSIZE - 1)
160
161/*
162 * Segment types:
163 * SEG_SUPER - Data or indirect block
164 * SEG_JOURNAL - Inode
165 * SEG_OSTORE - Dentry
166 */
167enum {
168 SEG_SUPER = 0x01,
169 SEG_JOURNAL = 0x02,
170 SEG_OSTORE = 0x03,
171};
172
173/**
174 * struct logfs_segment_header - per-segment header in the ostore
175 *
176 * @crc: crc32 of header (there is no data)
177 * @pad: unused, must be 0
178 * @type: segment type, see above
179 * @level: GC level for all objects in this segment
180 * @segno: segment number
181 * @ec: erase count for this segment
182 * @gec: global erase count at time of writing
183 */
184struct logfs_segment_header {
185 __be32 crc;
186 __be16 pad;
187 __u8 type;
188 __u8 level;
189 __be32 segno;
190 __be32 ec;
191 __be64 gec;
192};
193
194SIZE_CHECK(logfs_segment_header, LOGFS_SEGMENT_HEADERSIZE);
195
196#define LOGFS_FEATURES_INCOMPAT (0ull)
197#define LOGFS_FEATURES_RO_COMPAT (0ull)
198#define LOGFS_FEATURES_COMPAT (0ull)
199
200/**
201 * struct logfs_disk_super - on-medium superblock
202 *
203 * @ds_magic: magic number, must equal LOGFS_MAGIC
204 * @ds_crc: crc32 of structure starting with the next field
205 * @ds_ifile_levels: maximum number of levels for ifile
206 * @ds_iblock_levels: maximum number of levels for regular files
207 * @ds_data_levels: number of seperate levels for data
208 * @pad0: reserved, must be 0
209 * @ds_feature_incompat: incompatible filesystem features
210 * @ds_feature_ro_compat: read-only compatible filesystem features
211 * @ds_feature_compat: compatible filesystem features
212 * @ds_flags: flags
213 * @ds_segment_shift: log2 of segment size
214 * @ds_block_shift: log2 of block size
215 * @ds_write_shift: log2 of write size
216 * @pad1: reserved, must be 0
217 * @ds_journal_seg: segments used by primary journal
218 * @ds_root_reserve: bytes reserved for the superuser
219 * @ds_speed_reserve: bytes reserved to speed up GC
220 * @ds_bad_seg_reserve: number of segments reserved to handle bad blocks
221 * @pad2: reserved, must be 0
222 * @pad3: reserved, must be 0
223 *
224 * Contains only read-only fields. Read-write fields like the amount of used
225 * space is tracked in the dynamic superblock, which is stored in the journal.
226 */
227struct logfs_disk_super {
228 struct logfs_segment_header ds_sh;
229 __be64 ds_magic;
230
231 __be32 ds_crc;
232 __u8 ds_ifile_levels;
233 __u8 ds_iblock_levels;
234 __u8 ds_data_levels;
235 __u8 ds_segment_shift;
236 __u8 ds_block_shift;
237 __u8 ds_write_shift;
238 __u8 pad0[6];
239
240 __be64 ds_filesystem_size;
241 __be32 ds_segment_size;
242 __be32 ds_bad_seg_reserve;
243
244 __be64 ds_feature_incompat;
245 __be64 ds_feature_ro_compat;
246
247 __be64 ds_feature_compat;
248 __be64 ds_feature_flags;
249
250 __be64 ds_root_reserve;
251 __be64 ds_speed_reserve;
252
253 __be32 ds_journal_seg[LOGFS_JOURNAL_SEGS];
254
255 __be64 ds_super_ofs[2];
256 __be64 pad3[8];
257};
258
259SIZE_CHECK(logfs_disk_super, 256);
260
261/*
262 * Object types:
263 * OBJ_BLOCK - Data or indirect block
264 * OBJ_INODE - Inode
265 * OBJ_DENTRY - Dentry
266 */
267enum {
268 OBJ_BLOCK = 0x04,
269 OBJ_INODE = 0x05,
270 OBJ_DENTRY = 0x06,
271};
272
273/**
274 * struct logfs_object_header - per-object header in the ostore
275 *
276 * @crc: crc32 of header, excluding data_crc
277 * @len: length of data
278 * @type: object type, see above
279 * @compr: compression type
280 * @ino: inode number
281 * @bix: block index
282 * @data_crc: crc32 of payload
283 */
284struct logfs_object_header {
285 __be32 crc;
286 __be16 len;
287 __u8 type;
288 __u8 compr;
289 __be64 ino;
290 __be64 bix;
291 __be32 data_crc;
292} __attribute__((packed));
293
294SIZE_CHECK(logfs_object_header, LOGFS_OBJECT_HEADERSIZE);
295
296/*
297 * Reserved inode numbers:
298 * LOGFS_INO_MASTER - master inode (for inode file)
299 * LOGFS_INO_ROOT - root directory
300 * LOGFS_INO_SEGFILE - per-segment used bytes and erase count
301 */
302enum {
303 LOGFS_INO_MAPPING = 0x00,
304 LOGFS_INO_MASTER = 0x01,
305 LOGFS_INO_ROOT = 0x02,
306 LOGFS_INO_SEGFILE = 0x03,
307 LOGFS_RESERVED_INOS = 0x10,
308};
309
310/*
311 * Inode flags. High bits should never be written to the medium. They are
312 * reserved for in-memory usage.
313 * Low bits should either remain in sync with the corresponding FS_*_FL or
314 * reuse slots that obviously don't make sense for logfs.
315 *
316 * LOGFS_IF_DIRTY Inode must be written back
317 * LOGFS_IF_ZOMBIE Inode has been deleted
318 * LOGFS_IF_STILLBORN -ENOSPC happened when creating inode
319 */
320#define LOGFS_IF_COMPRESSED 0x00000004 /* == FS_COMPR_FL */
321#define LOGFS_IF_DIRTY 0x20000000
322#define LOGFS_IF_ZOMBIE 0x40000000
323#define LOGFS_IF_STILLBORN 0x80000000
324
325/* Flags available to chattr */
326#define LOGFS_FL_USER_VISIBLE (LOGFS_IF_COMPRESSED)
327#define LOGFS_FL_USER_MODIFIABLE (LOGFS_IF_COMPRESSED)
328/* Flags inherited from parent directory on file/directory creation */
329#define LOGFS_FL_INHERITED (LOGFS_IF_COMPRESSED)
330
331/**
332 * struct logfs_disk_inode - on-medium inode
333 *
334 * @di_mode: file mode
335 * @di_pad: reserved, must be 0
336 * @di_flags: inode flags, see above
337 * @di_uid: user id
338 * @di_gid: group id
339 * @di_ctime: change time
340 * @di_mtime: modify time
341 * @di_refcount: reference count (aka nlink or link count)
342 * @di_generation: inode generation, for nfs
343 * @di_used_bytes: number of bytes used
344 * @di_size: file size
345 * @di_data: data pointers
346 */
347struct logfs_disk_inode {
348 __be16 di_mode;
349 __u8 di_height;
350 __u8 di_pad;
351 __be32 di_flags;
352 __be32 di_uid;
353 __be32 di_gid;
354
355 __be64 di_ctime;
356 __be64 di_mtime;
357
358 __be64 di_atime;
359 __be32 di_refcount;
360 __be32 di_generation;
361
362 __be64 di_used_bytes;
363 __be64 di_size;
364
365 __be64 di_data[LOGFS_EMBEDDED_FIELDS];
366};
367
368SIZE_CHECK(logfs_disk_inode, 200);
369
370#define INODE_POINTER_OFS \
371 (offsetof(struct logfs_disk_inode, di_data) / sizeof(__be64))
372#define INODE_USED_OFS \
373 (offsetof(struct logfs_disk_inode, di_used_bytes) / sizeof(__be64))
374#define INODE_SIZE_OFS \
375 (offsetof(struct logfs_disk_inode, di_size) / sizeof(__be64))
376#define INODE_HEIGHT_OFS (0)
377
378/**
379 * struct logfs_disk_dentry - on-medium dentry structure
380 *
381 * @ino: inode number
382 * @namelen: length of file name
383 * @type: file type, identical to bits 12..15 of mode
384 * @name: file name
385 */
386/* FIXME: add 6 bytes of padding to remove the __packed */
387struct logfs_disk_dentry {
388 __be64 ino;
389 __be16 namelen;
390 __u8 type;
391 __u8 name[LOGFS_MAX_NAMELEN];
392} __attribute__((packed));
393
394SIZE_CHECK(logfs_disk_dentry, 266);
395
396#define RESERVED 0xffffffff
397#define BADSEG 0xffffffff
398/**
399 * struct logfs_segment_entry - segment file entry
400 *
401 * @ec_level: erase count and level
402 * @valid: number of valid bytes
403 *
404 * Segment file contains one entry for every segment. ec_level contains the
405 * erasecount in the upper 28 bits and the level in the lower 4 bits. An
406 * ec_level of BADSEG (-1) identifies bad segments. valid contains the number
407 * of valid bytes or RESERVED (-1 again) if the segment is used for either the
408 * superblock or the journal, or when the segment is bad.
409 */
410struct logfs_segment_entry {
411 __be32 ec_level;
412 __be32 valid;
413};
414
415SIZE_CHECK(logfs_segment_entry, 8);
416
417/**
418 * struct logfs_journal_header - header for journal entries (JEs)
419 *
420 * @h_crc: crc32 of journal entry
421 * @h_len: length of compressed journal entry,
422 * not including header
423 * @h_datalen: length of uncompressed data
424 * @h_type: JE type
425 * @h_compr: compression type
426 * @h_pad: reserved
427 */
428struct logfs_journal_header {
429 __be32 h_crc;
430 __be16 h_len;
431 __be16 h_datalen;
432 __be16 h_type;
433 __u8 h_compr;
434 __u8 h_pad[5];
435};
436
437SIZE_CHECK(logfs_journal_header, 16);
438
439/*
440 * Life expectency of data.
441 * VIM_DEFAULT - default vim
442 * VIM_SEGFILE - for segment file only - very short-living
443 * VIM_GC - GC'd data - likely long-living
444 */
445enum logfs_vim {
446 VIM_DEFAULT = 0,
447 VIM_SEGFILE = 1,
448};
449
450/**
451 * struct logfs_je_area - wbuf header
452 *
453 * @segno: segment number of area
454 * @used_bytes: number of bytes already used
455 * @gc_level: GC level
456 * @vim: life expectancy of data
457 *
458 * "Areas" are segments currently being used for writing. There is at least
459 * one area per GC level. Several may be used to seperate long-living from
460 * short-living data. If an area with unknown vim is encountered, it can
461 * simply be closed.
462 * The write buffer immediately follow this header.
463 */
464struct logfs_je_area {
465 __be32 segno;
466 __be32 used_bytes;
467 __u8 gc_level;
468 __u8 vim;
469} __attribute__((packed));
470
471SIZE_CHECK(logfs_je_area, 10);
472
473#define MAX_JOURNAL_HEADER \
474 (sizeof(struct logfs_journal_header) + sizeof(struct logfs_je_area))
475
476/**
477 * struct logfs_je_dynsb - dynamic superblock
478 *
479 * @ds_gec: global erase count
480 * @ds_sweeper: current position of GC "sweeper"
481 * @ds_rename_dir: source directory ino (see dir.c documentation)
482 * @ds_rename_pos: position of source dd (see dir.c documentation)
483 * @ds_victim_ino: victims of incomplete dir operation (see dir.c)
484 * @ds_victim_ino: parent inode of victim (see dir.c)
485 * @ds_used_bytes: number of used bytes
486 */
487struct logfs_je_dynsb {
488 __be64 ds_gec;
489 __be64 ds_sweeper;
490
491 __be64 ds_rename_dir;
492 __be64 ds_rename_pos;
493
494 __be64 ds_victim_ino;
495 __be64 ds_victim_parent; /* XXX */
496
497 __be64 ds_used_bytes;
498 __be32 ds_generation;
499 __be32 pad;
500};
501
502SIZE_CHECK(logfs_je_dynsb, 64);
503
504/**
505 * struct logfs_je_anchor - anchor of filesystem tree, aka master inode
506 *
507 * @da_size: size of inode file
508 * @da_last_ino: last created inode
509 * @da_used_bytes: number of bytes used
510 * @da_data: data pointers
511 */
512struct logfs_je_anchor {
513 __be64 da_size;
514 __be64 da_last_ino;
515
516 __be64 da_used_bytes;
517 u8 da_height;
518 u8 pad[7];
519
520 __be64 da_data[LOGFS_EMBEDDED_FIELDS];
521};
522
523SIZE_CHECK(logfs_je_anchor, 168);
524
525/**
526 * struct logfs_je_spillout - spillout entry (from 1st to 2nd journal)
527 *
528 * @so_segment: segments used for 2nd journal
529 *
530 * Length of the array is given by h_len field in the header.
531 */
532struct logfs_je_spillout {
533 __be64 so_segment[0];
534};
535
536SIZE_CHECK(logfs_je_spillout, 0);
537
538/**
539 * struct logfs_je_journal_ec - erase counts for all journal segments
540 *
541 * @ec: erase count
542 *
543 * Length of the array is given by h_len field in the header.
544 */
545struct logfs_je_journal_ec {
546 __be32 ec[0];
547};
548
549SIZE_CHECK(logfs_je_journal_ec, 0);
550
551/**
552 * struct logfs_je_free_segments - list of free segmetns with erase count
553 */
554struct logfs_je_free_segments {
555 __be32 segno;
556 __be32 ec;
557};
558
559SIZE_CHECK(logfs_je_free_segments, 8);
560
561/**
562 * struct logfs_seg_alias - list of segment aliases
563 */
564struct logfs_seg_alias {
565 __be32 old_segno;
566 __be32 new_segno;
567};
568
569SIZE_CHECK(logfs_seg_alias, 8);
570
571/**
572 * struct logfs_obj_alias - list of object aliases
573 */
574struct logfs_obj_alias {
575 __be64 ino;
576 __be64 bix;
577 __be64 val;
578 u8 level;
579 u8 pad[5];
580 __be16 child_no;
581};
582
583SIZE_CHECK(logfs_obj_alias, 32);
584
585/**
586 * Compression types.
587 *
588 * COMPR_NONE - uncompressed
589 * COMPR_ZLIB - compressed with zlib
590 */
591enum {
592 COMPR_NONE = 0,
593 COMPR_ZLIB = 1,
594};
595
596/*
597 * Journal entries come in groups of 16. First group contains unique
598 * entries, next groups contain one entry per level
599 *
600 * JE_FIRST - smallest possible journal entry number
601 *
602 * JEG_BASE - base group, containing unique entries
603 * JE_COMMIT - commit entry, validates all previous entries
604 * JE_DYNSB - dynamic superblock, anything that ought to be in the
605 * superblock but cannot because it is read-write data
606 * JE_ANCHOR - anchor aka master inode aka inode file's inode
607 * JE_ERASECOUNT erasecounts for all journal segments
608 * JE_SPILLOUT - unused
609 * JE_SEG_ALIAS - aliases segments
610 * JE_AREA - area description
611 *
612 * JE_LAST - largest possible journal entry number
613 */
614enum {
615 JE_FIRST = 0x01,
616
617 JEG_BASE = 0x00,
618 JE_COMMIT = 0x02,
619 JE_DYNSB = 0x03,
620 JE_ANCHOR = 0x04,
621 JE_ERASECOUNT = 0x05,
622 JE_SPILLOUT = 0x06,
623 JE_OBJ_ALIAS = 0x0d,
624 JE_AREA = 0x0e,
625
626 JE_LAST = 0x0e,
627};
628
629#endif
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c
new file mode 100644
index 000000000000..7a23b3e7c0a7
--- /dev/null
+++ b/fs/logfs/readwrite.c
@@ -0,0 +1,2246 @@
1/*
2 * fs/logfs/readwrite.c
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 *
8 *
9 * Actually contains five sets of very similar functions:
10 * read read blocks from a file
11 * seek_hole find next hole
12 * seek_data find next data block
13 * valid check whether a block still belongs to a file
14 * write write blocks to a file
15 * delete delete a block (for directories and ifile)
16 * rewrite move existing blocks of a file to a new location (gc helper)
17 * truncate truncate a file
18 */
19#include "logfs.h"
20#include <linux/sched.h>
21
22static u64 adjust_bix(u64 bix, level_t level)
23{
24 switch (level) {
25 case 0:
26 return bix;
27 case LEVEL(1):
28 return max_t(u64, bix, I0_BLOCKS);
29 case LEVEL(2):
30 return max_t(u64, bix, I1_BLOCKS);
31 case LEVEL(3):
32 return max_t(u64, bix, I2_BLOCKS);
33 case LEVEL(4):
34 return max_t(u64, bix, I3_BLOCKS);
35 case LEVEL(5):
36 return max_t(u64, bix, I4_BLOCKS);
37 default:
38 WARN_ON(1);
39 return bix;
40 }
41}
42
43static inline u64 maxbix(u8 height)
44{
45 return 1ULL << (LOGFS_BLOCK_BITS * height);
46}
47
48/**
49 * The inode address space is cut in two halves. Lower half belongs to data
50 * pages, upper half to indirect blocks. If the high bit (INDIRECT_BIT) is
51 * set, the actual block index (bix) and level can be derived from the page
52 * index.
53 *
54 * The lowest three bits of the block index are set to 0 after packing and
55 * unpacking. Since the lowest n bits (9 for 4KiB blocksize) are ignored
56 * anyway this is harmless.
57 */
58#define ARCH_SHIFT (BITS_PER_LONG - 32)
59#define INDIRECT_BIT (0x80000000UL << ARCH_SHIFT)
60#define LEVEL_SHIFT (28 + ARCH_SHIFT)
61static inline pgoff_t first_indirect_block(void)
62{
63 return INDIRECT_BIT | (1ULL << LEVEL_SHIFT);
64}
65
66pgoff_t logfs_pack_index(u64 bix, level_t level)
67{
68 pgoff_t index;
69
70 BUG_ON(bix >= INDIRECT_BIT);
71 if (level == 0)
72 return bix;
73
74 index = INDIRECT_BIT;
75 index |= (__force long)level << LEVEL_SHIFT;
76 index |= bix >> ((__force u8)level * LOGFS_BLOCK_BITS);
77 return index;
78}
79
80void logfs_unpack_index(pgoff_t index, u64 *bix, level_t *level)
81{
82 u8 __level;
83
84 if (!(index & INDIRECT_BIT)) {
85 *bix = index;
86 *level = 0;
87 return;
88 }
89
90 __level = (index & ~INDIRECT_BIT) >> LEVEL_SHIFT;
91 *level = LEVEL(__level);
92 *bix = (index << (__level * LOGFS_BLOCK_BITS)) & ~INDIRECT_BIT;
93 *bix = adjust_bix(*bix, *level);
94 return;
95}
96#undef ARCH_SHIFT
97#undef INDIRECT_BIT
98#undef LEVEL_SHIFT
99
100/*
101 * Time is stored as nanoseconds since the epoch.
102 */
103static struct timespec be64_to_timespec(__be64 betime)
104{
105 return ns_to_timespec(be64_to_cpu(betime));
106}
107
108static __be64 timespec_to_be64(struct timespec tsp)
109{
110 return cpu_to_be64((u64)tsp.tv_sec * NSEC_PER_SEC + tsp.tv_nsec);
111}
112
113static void logfs_disk_to_inode(struct logfs_disk_inode *di, struct inode*inode)
114{
115 struct logfs_inode *li = logfs_inode(inode);
116 int i;
117
118 inode->i_mode = be16_to_cpu(di->di_mode);
119 li->li_height = di->di_height;
120 li->li_flags = be32_to_cpu(di->di_flags);
121 inode->i_uid = be32_to_cpu(di->di_uid);
122 inode->i_gid = be32_to_cpu(di->di_gid);
123 inode->i_size = be64_to_cpu(di->di_size);
124 logfs_set_blocks(inode, be64_to_cpu(di->di_used_bytes));
125 inode->i_atime = be64_to_timespec(di->di_atime);
126 inode->i_ctime = be64_to_timespec(di->di_ctime);
127 inode->i_mtime = be64_to_timespec(di->di_mtime);
128 inode->i_nlink = be32_to_cpu(di->di_refcount);
129 inode->i_generation = be32_to_cpu(di->di_generation);
130
131 switch (inode->i_mode & S_IFMT) {
132 case S_IFSOCK: /* fall through */
133 case S_IFBLK: /* fall through */
134 case S_IFCHR: /* fall through */
135 case S_IFIFO:
136 inode->i_rdev = be64_to_cpu(di->di_data[0]);
137 break;
138 case S_IFDIR: /* fall through */
139 case S_IFREG: /* fall through */
140 case S_IFLNK:
141 for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
142 li->li_data[i] = be64_to_cpu(di->di_data[i]);
143 break;
144 default:
145 BUG();
146 }
147}
148
149static void logfs_inode_to_disk(struct inode *inode, struct logfs_disk_inode*di)
150{
151 struct logfs_inode *li = logfs_inode(inode);
152 int i;
153
154 di->di_mode = cpu_to_be16(inode->i_mode);
155 di->di_height = li->li_height;
156 di->di_pad = 0;
157 di->di_flags = cpu_to_be32(li->li_flags);
158 di->di_uid = cpu_to_be32(inode->i_uid);
159 di->di_gid = cpu_to_be32(inode->i_gid);
160 di->di_size = cpu_to_be64(i_size_read(inode));
161 di->di_used_bytes = cpu_to_be64(li->li_used_bytes);
162 di->di_atime = timespec_to_be64(inode->i_atime);
163 di->di_ctime = timespec_to_be64(inode->i_ctime);
164 di->di_mtime = timespec_to_be64(inode->i_mtime);
165 di->di_refcount = cpu_to_be32(inode->i_nlink);
166 di->di_generation = cpu_to_be32(inode->i_generation);
167
168 switch (inode->i_mode & S_IFMT) {
169 case S_IFSOCK: /* fall through */
170 case S_IFBLK: /* fall through */
171 case S_IFCHR: /* fall through */
172 case S_IFIFO:
173 di->di_data[0] = cpu_to_be64(inode->i_rdev);
174 break;
175 case S_IFDIR: /* fall through */
176 case S_IFREG: /* fall through */
177 case S_IFLNK:
178 for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
179 di->di_data[i] = cpu_to_be64(li->li_data[i]);
180 break;
181 default:
182 BUG();
183 }
184}
185
186static void __logfs_set_blocks(struct inode *inode)
187{
188 struct super_block *sb = inode->i_sb;
189 struct logfs_inode *li = logfs_inode(inode);
190
191 inode->i_blocks = ULONG_MAX;
192 if (li->li_used_bytes >> sb->s_blocksize_bits < ULONG_MAX)
193 inode->i_blocks = ALIGN(li->li_used_bytes, 512) >> 9;
194}
195
196void logfs_set_blocks(struct inode *inode, u64 bytes)
197{
198 struct logfs_inode *li = logfs_inode(inode);
199
200 li->li_used_bytes = bytes;
201 __logfs_set_blocks(inode);
202}
203
204static void prelock_page(struct super_block *sb, struct page *page, int lock)
205{
206 struct logfs_super *super = logfs_super(sb);
207
208 BUG_ON(!PageLocked(page));
209 if (lock) {
210 BUG_ON(PagePreLocked(page));
211 SetPagePreLocked(page);
212 } else {
213 /* We are in GC path. */
214 if (PagePreLocked(page))
215 super->s_lock_count++;
216 else
217 SetPagePreLocked(page);
218 }
219}
220
221static void preunlock_page(struct super_block *sb, struct page *page, int lock)
222{
223 struct logfs_super *super = logfs_super(sb);
224
225 BUG_ON(!PageLocked(page));
226 if (lock)
227 ClearPagePreLocked(page);
228 else {
229 /* We are in GC path. */
230 BUG_ON(!PagePreLocked(page));
231 if (super->s_lock_count)
232 super->s_lock_count--;
233 else
234 ClearPagePreLocked(page);
235 }
236}
237
238/*
239 * Logfs is prone to an AB-BA deadlock where one task tries to acquire
240 * s_write_mutex with a locked page and GC tries to get that page while holding
241 * s_write_mutex.
242 * To solve this issue logfs will ignore the page lock iff the page in question
243 * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked
244 * in addition to PG_locked.
245 */
246static void logfs_get_wblocks(struct super_block *sb, struct page *page,
247 int lock)
248{
249 struct logfs_super *super = logfs_super(sb);
250
251 if (page)
252 prelock_page(sb, page, lock);
253
254 if (lock) {
255 mutex_lock(&super->s_write_mutex);
256 logfs_gc_pass(sb);
257 /* FIXME: We also have to check for shadowed space
258 * and mempool fill grade */
259 }
260}
261
262static void logfs_put_wblocks(struct super_block *sb, struct page *page,
263 int lock)
264{
265 struct logfs_super *super = logfs_super(sb);
266
267 if (page)
268 preunlock_page(sb, page, lock);
269 /* Order matters - we must clear PG_pre_locked before releasing
270 * s_write_mutex or we could race against another task. */
271 if (lock)
272 mutex_unlock(&super->s_write_mutex);
273}
274
275static struct page *logfs_get_read_page(struct inode *inode, u64 bix,
276 level_t level)
277{
278 return find_or_create_page(inode->i_mapping,
279 logfs_pack_index(bix, level), GFP_NOFS);
280}
281
282static void logfs_put_read_page(struct page *page)
283{
284 unlock_page(page);
285 page_cache_release(page);
286}
287
288static void logfs_lock_write_page(struct page *page)
289{
290 int loop = 0;
291
292 while (unlikely(!trylock_page(page))) {
293 if (loop++ > 0x1000) {
294 /* Has been observed once so far... */
295 printk(KERN_ERR "stack at %p\n", &loop);
296 BUG();
297 }
298 if (PagePreLocked(page)) {
299 /* Holder of page lock is waiting for us, it
300 * is safe to use this page. */
301 break;
302 }
303 /* Some other process has this page locked and has
304 * nothing to do with us. Wait for it to finish.
305 */
306 schedule();
307 }
308 BUG_ON(!PageLocked(page));
309}
310
311static struct page *logfs_get_write_page(struct inode *inode, u64 bix,
312 level_t level)
313{
314 struct address_space *mapping = inode->i_mapping;
315 pgoff_t index = logfs_pack_index(bix, level);
316 struct page *page;
317 int err;
318
319repeat:
320 page = find_get_page(mapping, index);
321 if (!page) {
322 page = __page_cache_alloc(GFP_NOFS);
323 if (!page)
324 return NULL;
325 err = add_to_page_cache_lru(page, mapping, index, GFP_NOFS);
326 if (unlikely(err)) {
327 page_cache_release(page);
328 if (err == -EEXIST)
329 goto repeat;
330 return NULL;
331 }
332 } else logfs_lock_write_page(page);
333 BUG_ON(!PageLocked(page));
334 return page;
335}
336
337static void logfs_unlock_write_page(struct page *page)
338{
339 if (!PagePreLocked(page))
340 unlock_page(page);
341}
342
343static void logfs_put_write_page(struct page *page)
344{
345 logfs_unlock_write_page(page);
346 page_cache_release(page);
347}
348
349static struct page *logfs_get_page(struct inode *inode, u64 bix, level_t level,
350 int rw)
351{
352 if (rw == READ)
353 return logfs_get_read_page(inode, bix, level);
354 else
355 return logfs_get_write_page(inode, bix, level);
356}
357
358static void logfs_put_page(struct page *page, int rw)
359{
360 if (rw == READ)
361 logfs_put_read_page(page);
362 else
363 logfs_put_write_page(page);
364}
365
366static unsigned long __get_bits(u64 val, int skip, int no)
367{
368 u64 ret = val;
369
370 ret >>= skip * no;
371 ret <<= 64 - no;
372 ret >>= 64 - no;
373 return ret;
374}
375
376static unsigned long get_bits(u64 val, level_t skip)
377{
378 return __get_bits(val, (__force int)skip, LOGFS_BLOCK_BITS);
379}
380
381static inline void init_shadow_tree(struct super_block *sb,
382 struct shadow_tree *tree)
383{
384 struct logfs_super *super = logfs_super(sb);
385
386 btree_init_mempool64(&tree->new, super->s_btree_pool);
387 btree_init_mempool64(&tree->old, super->s_btree_pool);
388}
389
390static void indirect_write_block(struct logfs_block *block)
391{
392 struct page *page;
393 struct inode *inode;
394 int ret;
395
396 page = block->page;
397 inode = page->mapping->host;
398 logfs_lock_write_page(page);
399 ret = logfs_write_buf(inode, page, 0);
400 logfs_unlock_write_page(page);
401 /*
402 * This needs some rework. Unless you want your filesystem to run
403 * completely synchronously (you don't), the filesystem will always
404 * report writes as 'successful' before the actual work has been
405 * done. The actual work gets done here and this is where any errors
406 * will show up. And there isn't much we can do about it, really.
407 *
408 * Some attempts to fix the errors (move from bad blocks, retry io,...)
409 * have already been done, so anything left should be either a broken
410 * device or a bug somewhere in logfs itself. Being relatively new,
411 * the odds currently favor a bug, so for now the line below isn't
412 * entirely tasteles.
413 */
414 BUG_ON(ret);
415}
416
417static void inode_write_block(struct logfs_block *block)
418{
419 struct inode *inode;
420 int ret;
421
422 inode = block->inode;
423 if (inode->i_ino == LOGFS_INO_MASTER)
424 logfs_write_anchor(inode->i_sb);
425 else {
426 ret = __logfs_write_inode(inode, 0);
427 /* see indirect_write_block comment */
428 BUG_ON(ret);
429 }
430}
431
432static gc_level_t inode_block_level(struct logfs_block *block)
433{
434 BUG_ON(block->inode->i_ino == LOGFS_INO_MASTER);
435 return GC_LEVEL(LOGFS_MAX_LEVELS);
436}
437
438static gc_level_t indirect_block_level(struct logfs_block *block)
439{
440 struct page *page;
441 struct inode *inode;
442 u64 bix;
443 level_t level;
444
445 page = block->page;
446 inode = page->mapping->host;
447 logfs_unpack_index(page->index, &bix, &level);
448 return expand_level(inode->i_ino, level);
449}
450
451/*
452 * This silences a false, yet annoying gcc warning. I hate it when my editor
453 * jumps into bitops.h each time I recompile this file.
454 * TODO: Complain to gcc folks about this and upgrade compiler.
455 */
456static unsigned long fnb(const unsigned long *addr,
457 unsigned long size, unsigned long offset)
458{
459 return find_next_bit(addr, size, offset);
460}
461
462static __be64 inode_val0(struct inode *inode)
463{
464 struct logfs_inode *li = logfs_inode(inode);
465 u64 val;
466
467 /*
468 * Explicit shifting generates good code, but must match the format
469 * of the structure. Add some paranoia just in case.
470 */
471 BUILD_BUG_ON(offsetof(struct logfs_disk_inode, di_mode) != 0);
472 BUILD_BUG_ON(offsetof(struct logfs_disk_inode, di_height) != 2);
473 BUILD_BUG_ON(offsetof(struct logfs_disk_inode, di_flags) != 4);
474
475 val = (u64)inode->i_mode << 48 |
476 (u64)li->li_height << 40 |
477 (u64)li->li_flags;
478 return cpu_to_be64(val);
479}
480
481static int inode_write_alias(struct super_block *sb,
482 struct logfs_block *block, write_alias_t *write_one_alias)
483{
484 struct inode *inode = block->inode;
485 struct logfs_inode *li = logfs_inode(inode);
486 unsigned long pos;
487 u64 ino , bix;
488 __be64 val;
489 level_t level;
490 int err;
491
492 for (pos = 0; ; pos++) {
493 pos = fnb(block->alias_map, LOGFS_BLOCK_FACTOR, pos);
494 if (pos >= LOGFS_EMBEDDED_FIELDS + INODE_POINTER_OFS)
495 return 0;
496
497 switch (pos) {
498 case INODE_HEIGHT_OFS:
499 val = inode_val0(inode);
500 break;
501 case INODE_USED_OFS:
502 val = cpu_to_be64(li->li_used_bytes);;
503 break;
504 case INODE_SIZE_OFS:
505 val = cpu_to_be64(i_size_read(inode));
506 break;
507 case INODE_POINTER_OFS ... INODE_POINTER_OFS + LOGFS_EMBEDDED_FIELDS - 1:
508 val = cpu_to_be64(li->li_data[pos - INODE_POINTER_OFS]);
509 break;
510 default:
511 BUG();
512 }
513
514 ino = LOGFS_INO_MASTER;
515 bix = inode->i_ino;
516 level = LEVEL(0);
517 err = write_one_alias(sb, ino, bix, level, pos, val);
518 if (err)
519 return err;
520 }
521}
522
523static int indirect_write_alias(struct super_block *sb,
524 struct logfs_block *block, write_alias_t *write_one_alias)
525{
526 unsigned long pos;
527 struct page *page = block->page;
528 u64 ino , bix;
529 __be64 *child, val;
530 level_t level;
531 int err;
532
533 for (pos = 0; ; pos++) {
534 pos = fnb(block->alias_map, LOGFS_BLOCK_FACTOR, pos);
535 if (pos >= LOGFS_BLOCK_FACTOR)
536 return 0;
537
538 ino = page->mapping->host->i_ino;
539 logfs_unpack_index(page->index, &bix, &level);
540 child = kmap_atomic(page, KM_USER0);
541 val = child[pos];
542 kunmap_atomic(child, KM_USER0);
543 err = write_one_alias(sb, ino, bix, level, pos, val);
544 if (err)
545 return err;
546 }
547}
548
549int logfs_write_obj_aliases_pagecache(struct super_block *sb)
550{
551 struct logfs_super *super = logfs_super(sb);
552 struct logfs_block *block;
553 int err;
554
555 list_for_each_entry(block, &super->s_object_alias, alias_list) {
556 err = block->ops->write_alias(sb, block, write_alias_journal);
557 if (err)
558 return err;
559 }
560 return 0;
561}
562
563void __free_block(struct super_block *sb, struct logfs_block *block)
564{
565 BUG_ON(!list_empty(&block->item_list));
566 list_del(&block->alias_list);
567 mempool_free(block, logfs_super(sb)->s_block_pool);
568}
569
570static void inode_free_block(struct super_block *sb, struct logfs_block *block)
571{
572 struct inode *inode = block->inode;
573
574 logfs_inode(inode)->li_block = NULL;
575 __free_block(sb, block);
576}
577
578static void indirect_free_block(struct super_block *sb,
579 struct logfs_block *block)
580{
581 ClearPagePrivate(block->page);
582 block->page->private = 0;
583 __free_block(sb, block);
584}
585
586
587static struct logfs_block_ops inode_block_ops = {
588 .write_block = inode_write_block,
589 .block_level = inode_block_level,
590 .free_block = inode_free_block,
591 .write_alias = inode_write_alias,
592};
593
594struct logfs_block_ops indirect_block_ops = {
595 .write_block = indirect_write_block,
596 .block_level = indirect_block_level,
597 .free_block = indirect_free_block,
598 .write_alias = indirect_write_alias,
599};
600
601struct logfs_block *__alloc_block(struct super_block *sb,
602 u64 ino, u64 bix, level_t level)
603{
604 struct logfs_super *super = logfs_super(sb);
605 struct logfs_block *block;
606
607 block = mempool_alloc(super->s_block_pool, GFP_NOFS);
608 memset(block, 0, sizeof(*block));
609 INIT_LIST_HEAD(&block->alias_list);
610 INIT_LIST_HEAD(&block->item_list);
611 block->sb = sb;
612 block->ino = ino;
613 block->bix = bix;
614 block->level = level;
615 return block;
616}
617
618static void alloc_inode_block(struct inode *inode)
619{
620 struct logfs_inode *li = logfs_inode(inode);
621 struct logfs_block *block;
622
623 if (li->li_block)
624 return;
625
626 block = __alloc_block(inode->i_sb, LOGFS_INO_MASTER, inode->i_ino, 0);
627 block->inode = inode;
628 li->li_block = block;
629 block->ops = &inode_block_ops;
630}
631
632void initialize_block_counters(struct page *page, struct logfs_block *block,
633 __be64 *array, int page_is_empty)
634{
635 u64 ptr;
636 int i, start;
637
638 block->partial = 0;
639 block->full = 0;
640 start = 0;
641 if (page->index < first_indirect_block()) {
642 /* Counters are pointless on level 0 */
643 return;
644 }
645 if (page->index == first_indirect_block()) {
646 /* Skip unused pointers */
647 start = I0_BLOCKS;
648 block->full = I0_BLOCKS;
649 }
650 if (!page_is_empty) {
651 for (i = start; i < LOGFS_BLOCK_FACTOR; i++) {
652 ptr = be64_to_cpu(array[i]);
653 if (ptr)
654 block->partial++;
655 if (ptr & LOGFS_FULLY_POPULATED)
656 block->full++;
657 }
658 }
659}
660
661static void alloc_data_block(struct inode *inode, struct page *page)
662{
663 struct logfs_block *block;
664 u64 bix;
665 level_t level;
666
667 if (PagePrivate(page))
668 return;
669
670 logfs_unpack_index(page->index, &bix, &level);
671 block = __alloc_block(inode->i_sb, inode->i_ino, bix, level);
672 block->page = page;
673 SetPagePrivate(page);
674 page->private = (unsigned long)block;
675 block->ops = &indirect_block_ops;
676}
677
678static void alloc_indirect_block(struct inode *inode, struct page *page,
679 int page_is_empty)
680{
681 struct logfs_block *block;
682 __be64 *array;
683
684 if (PagePrivate(page))
685 return;
686
687 alloc_data_block(inode, page);
688
689 block = logfs_block(page);
690 array = kmap_atomic(page, KM_USER0);
691 initialize_block_counters(page, block, array, page_is_empty);
692 kunmap_atomic(array, KM_USER0);
693}
694
695static void block_set_pointer(struct page *page, int index, u64 ptr)
696{
697 struct logfs_block *block = logfs_block(page);
698 __be64 *array;
699 u64 oldptr;
700
701 BUG_ON(!block);
702 array = kmap_atomic(page, KM_USER0);
703 oldptr = be64_to_cpu(array[index]);
704 array[index] = cpu_to_be64(ptr);
705 kunmap_atomic(array, KM_USER0);
706 SetPageUptodate(page);
707
708 block->full += !!(ptr & LOGFS_FULLY_POPULATED)
709 - !!(oldptr & LOGFS_FULLY_POPULATED);
710 block->partial += !!ptr - !!oldptr;
711}
712
713static u64 block_get_pointer(struct page *page, int index)
714{
715 __be64 *block;
716 u64 ptr;
717
718 block = kmap_atomic(page, KM_USER0);
719 ptr = be64_to_cpu(block[index]);
720 kunmap_atomic(block, KM_USER0);
721 return ptr;
722}
723
724static int logfs_read_empty(struct page *page)
725{
726 zero_user_segment(page, 0, PAGE_CACHE_SIZE);
727 return 0;
728}
729
730static int logfs_read_direct(struct inode *inode, struct page *page)
731{
732 struct logfs_inode *li = logfs_inode(inode);
733 pgoff_t index = page->index;
734 u64 block;
735
736 block = li->li_data[index];
737 if (!block)
738 return logfs_read_empty(page);
739
740 return logfs_segment_read(inode, page, block, index, 0);
741}
742
743static int logfs_read_loop(struct inode *inode, struct page *page,
744 int rw_context)
745{
746 struct logfs_inode *li = logfs_inode(inode);
747 u64 bix, bofs = li->li_data[INDIRECT_INDEX];
748 level_t level, target_level;
749 int ret;
750 struct page *ipage;
751
752 logfs_unpack_index(page->index, &bix, &target_level);
753 if (!bofs)
754 return logfs_read_empty(page);
755
756 if (bix >= maxbix(li->li_height))
757 return logfs_read_empty(page);
758
759 for (level = LEVEL(li->li_height);
760 (__force u8)level > (__force u8)target_level;
761 level = SUBLEVEL(level)){
762 ipage = logfs_get_page(inode, bix, level, rw_context);
763 if (!ipage)
764 return -ENOMEM;
765
766 ret = logfs_segment_read(inode, ipage, bofs, bix, level);
767 if (ret) {
768 logfs_put_read_page(ipage);
769 return ret;
770 }
771
772 bofs = block_get_pointer(ipage, get_bits(bix, SUBLEVEL(level)));
773 logfs_put_page(ipage, rw_context);
774 if (!bofs)
775 return logfs_read_empty(page);
776 }
777
778 return logfs_segment_read(inode, page, bofs, bix, 0);
779}
780
781static int logfs_read_block(struct inode *inode, struct page *page,
782 int rw_context)
783{
784 pgoff_t index = page->index;
785
786 if (index < I0_BLOCKS)
787 return logfs_read_direct(inode, page);
788 return logfs_read_loop(inode, page, rw_context);
789}
790
791static int logfs_exist_loop(struct inode *inode, u64 bix)
792{
793 struct logfs_inode *li = logfs_inode(inode);
794 u64 bofs = li->li_data[INDIRECT_INDEX];
795 level_t level;
796 int ret;
797 struct page *ipage;
798
799 if (!bofs)
800 return 0;
801 if (bix >= maxbix(li->li_height))
802 return 0;
803
804 for (level = LEVEL(li->li_height); level != 0; level = SUBLEVEL(level)) {
805 ipage = logfs_get_read_page(inode, bix, level);
806 if (!ipage)
807 return -ENOMEM;
808
809 ret = logfs_segment_read(inode, ipage, bofs, bix, level);
810 if (ret) {
811 logfs_put_read_page(ipage);
812 return ret;
813 }
814
815 bofs = block_get_pointer(ipage, get_bits(bix, SUBLEVEL(level)));
816 logfs_put_read_page(ipage);
817 if (!bofs)
818 return 0;
819 }
820
821 return 1;
822}
823
824int logfs_exist_block(struct inode *inode, u64 bix)
825{
826 struct logfs_inode *li = logfs_inode(inode);
827
828 if (bix < I0_BLOCKS)
829 return !!li->li_data[bix];
830 return logfs_exist_loop(inode, bix);
831}
832
833static u64 seek_holedata_direct(struct inode *inode, u64 bix, int data)
834{
835 struct logfs_inode *li = logfs_inode(inode);
836
837 for (; bix < I0_BLOCKS; bix++)
838 if (data ^ (li->li_data[bix] == 0))
839 return bix;
840 return I0_BLOCKS;
841}
842
843static u64 seek_holedata_loop(struct inode *inode, u64 bix, int data)
844{
845 struct logfs_inode *li = logfs_inode(inode);
846 __be64 *rblock;
847 u64 increment, bofs = li->li_data[INDIRECT_INDEX];
848 level_t level;
849 int ret, slot;
850 struct page *page;
851
852 BUG_ON(!bofs);
853
854 for (level = LEVEL(li->li_height); level != 0; level = SUBLEVEL(level)) {
855 increment = 1 << (LOGFS_BLOCK_BITS * ((__force u8)level-1));
856 page = logfs_get_read_page(inode, bix, level);
857 if (!page)
858 return bix;
859
860 ret = logfs_segment_read(inode, page, bofs, bix, level);
861 if (ret) {
862 logfs_put_read_page(page);
863 return bix;
864 }
865
866 slot = get_bits(bix, SUBLEVEL(level));
867 rblock = kmap_atomic(page, KM_USER0);
868 while (slot < LOGFS_BLOCK_FACTOR) {
869 if (data && (rblock[slot] != 0))
870 break;
871 if (!data && !(be64_to_cpu(rblock[slot]) & LOGFS_FULLY_POPULATED))
872 break;
873 slot++;
874 bix += increment;
875 bix &= ~(increment - 1);
876 }
877 if (slot >= LOGFS_BLOCK_FACTOR) {
878 kunmap_atomic(rblock, KM_USER0);
879 logfs_put_read_page(page);
880 return bix;
881 }
882 bofs = be64_to_cpu(rblock[slot]);
883 kunmap_atomic(rblock, KM_USER0);
884 logfs_put_read_page(page);
885 if (!bofs) {
886 BUG_ON(data);
887 return bix;
888 }
889 }
890 return bix;
891}
892
893/**
894 * logfs_seek_hole - find next hole starting at a given block index
895 * @inode: inode to search in
896 * @bix: block index to start searching
897 *
898 * Returns next hole. If the file doesn't contain any further holes, the
899 * block address next to eof is returned instead.
900 */
901u64 logfs_seek_hole(struct inode *inode, u64 bix)
902{
903 struct logfs_inode *li = logfs_inode(inode);
904
905 if (bix < I0_BLOCKS) {
906 bix = seek_holedata_direct(inode, bix, 0);
907 if (bix < I0_BLOCKS)
908 return bix;
909 }
910
911 if (!li->li_data[INDIRECT_INDEX])
912 return bix;
913 else if (li->li_data[INDIRECT_INDEX] & LOGFS_FULLY_POPULATED)
914 bix = maxbix(li->li_height);
915 else {
916 bix = seek_holedata_loop(inode, bix, 0);
917 if (bix < maxbix(li->li_height))
918 return bix;
919 /* Should not happen anymore. But if some port writes semi-
920 * corrupt images (as this one used to) we might run into it.
921 */
922 WARN_ON_ONCE(bix == maxbix(li->li_height));
923 }
924
925 return bix;
926}
927
928static u64 __logfs_seek_data(struct inode *inode, u64 bix)
929{
930 struct logfs_inode *li = logfs_inode(inode);
931
932 if (bix < I0_BLOCKS) {
933 bix = seek_holedata_direct(inode, bix, 1);
934 if (bix < I0_BLOCKS)
935 return bix;
936 }
937
938 if (bix < maxbix(li->li_height)) {
939 if (!li->li_data[INDIRECT_INDEX])
940 bix = maxbix(li->li_height);
941 else
942 return seek_holedata_loop(inode, bix, 1);
943 }
944
945 return bix;
946}
947
948/**
949 * logfs_seek_data - find next data block after a given block index
950 * @inode: inode to search in
951 * @bix: block index to start searching
952 *
953 * Returns next data block. If the file doesn't contain any further data
954 * blocks, the last block in the file is returned instead.
955 */
956u64 logfs_seek_data(struct inode *inode, u64 bix)
957{
958 struct super_block *sb = inode->i_sb;
959 u64 ret, end;
960
961 ret = __logfs_seek_data(inode, bix);
962 end = i_size_read(inode) >> sb->s_blocksize_bits;
963 if (ret >= end)
964 ret = max(bix, end);
965 return ret;
966}
967
968static int logfs_is_valid_direct(struct logfs_inode *li, u64 bix, u64 ofs)
969{
970 return pure_ofs(li->li_data[bix]) == ofs;
971}
972
973static int __logfs_is_valid_loop(struct inode *inode, u64 bix,
974 u64 ofs, u64 bofs)
975{
976 struct logfs_inode *li = logfs_inode(inode);
977 level_t level;
978 int ret;
979 struct page *page;
980
981 for (level = LEVEL(li->li_height); level != 0; level = SUBLEVEL(level)){
982 page = logfs_get_write_page(inode, bix, level);
983 BUG_ON(!page);
984
985 ret = logfs_segment_read(inode, page, bofs, bix, level);
986 if (ret) {
987 logfs_put_write_page(page);
988 return 0;
989 }
990
991 bofs = block_get_pointer(page, get_bits(bix, SUBLEVEL(level)));
992 logfs_put_write_page(page);
993 if (!bofs)
994 return 0;
995
996 if (pure_ofs(bofs) == ofs)
997 return 1;
998 }
999 return 0;
1000}
1001
1002static int logfs_is_valid_loop(struct inode *inode, u64 bix, u64 ofs)
1003{
1004 struct logfs_inode *li = logfs_inode(inode);
1005 u64 bofs = li->li_data[INDIRECT_INDEX];
1006
1007 if (!bofs)
1008 return 0;
1009
1010 if (bix >= maxbix(li->li_height))
1011 return 0;
1012
1013 if (pure_ofs(bofs) == ofs)
1014 return 1;
1015
1016 return __logfs_is_valid_loop(inode, bix, ofs, bofs);
1017}
1018
1019static int __logfs_is_valid_block(struct inode *inode, u64 bix, u64 ofs)
1020{
1021 struct logfs_inode *li = logfs_inode(inode);
1022
1023 if ((inode->i_nlink == 0) && atomic_read(&inode->i_count) == 1)
1024 return 0;
1025
1026 if (bix < I0_BLOCKS)
1027 return logfs_is_valid_direct(li, bix, ofs);
1028 return logfs_is_valid_loop(inode, bix, ofs);
1029}
1030
1031/**
1032 * logfs_is_valid_block - check whether this block is still valid
1033 *
1034 * @sb - superblock
1035 * @ofs - block physical offset
1036 * @ino - block inode number
1037 * @bix - block index
1038 * @level - block level
1039 *
1040 * Returns 0 if the block is invalid, 1 if it is valid and 2 if it will
1041 * become invalid once the journal is written.
1042 */
1043int logfs_is_valid_block(struct super_block *sb, u64 ofs, u64 ino, u64 bix,
1044 gc_level_t gc_level)
1045{
1046 struct logfs_super *super = logfs_super(sb);
1047 struct inode *inode;
1048 int ret, cookie;
1049
1050 /* Umount closes a segment with free blocks remaining. Those
1051 * blocks are by definition invalid. */
1052 if (ino == -1)
1053 return 0;
1054
1055 LOGFS_BUG_ON((u64)(u_long)ino != ino, sb);
1056
1057 inode = logfs_safe_iget(sb, ino, &cookie);
1058 if (IS_ERR(inode))
1059 goto invalid;
1060
1061 ret = __logfs_is_valid_block(inode, bix, ofs);
1062 logfs_safe_iput(inode, cookie);
1063 if (ret)
1064 return ret;
1065
1066invalid:
1067 /* Block is nominally invalid, but may still sit in the shadow tree,
1068 * waiting for a journal commit.
1069 */
1070 if (btree_lookup64(&super->s_shadow_tree.old, ofs))
1071 return 2;
1072 return 0;
1073}
1074
1075int logfs_readpage_nolock(struct page *page)
1076{
1077 struct inode *inode = page->mapping->host;
1078 int ret = -EIO;
1079
1080 ret = logfs_read_block(inode, page, READ);
1081
1082 if (ret) {
1083 ClearPageUptodate(page);
1084 SetPageError(page);
1085 } else {
1086 SetPageUptodate(page);
1087 ClearPageError(page);
1088 }
1089 flush_dcache_page(page);
1090
1091 return ret;
1092}
1093
1094static int logfs_reserve_bytes(struct inode *inode, int bytes)
1095{
1096 struct logfs_super *super = logfs_super(inode->i_sb);
1097 u64 available = super->s_free_bytes + super->s_dirty_free_bytes
1098 - super->s_dirty_used_bytes - super->s_dirty_pages;
1099
1100 if (!bytes)
1101 return 0;
1102
1103 if (available < bytes)
1104 return -ENOSPC;
1105
1106 if (available < bytes + super->s_root_reserve &&
1107 !capable(CAP_SYS_RESOURCE))
1108 return -ENOSPC;
1109
1110 return 0;
1111}
1112
1113int get_page_reserve(struct inode *inode, struct page *page)
1114{
1115 struct logfs_super *super = logfs_super(inode->i_sb);
1116 int ret;
1117
1118 if (logfs_block(page) && logfs_block(page)->reserved_bytes)
1119 return 0;
1120
1121 logfs_get_wblocks(inode->i_sb, page, WF_LOCK);
1122 ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE);
1123 if (!ret) {
1124 alloc_data_block(inode, page);
1125 logfs_block(page)->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE;
1126 super->s_dirty_pages += 6 * LOGFS_MAX_OBJECTSIZE;
1127 }
1128 logfs_put_wblocks(inode->i_sb, page, WF_LOCK);
1129 return ret;
1130}
1131
1132/*
1133 * We are protected by write lock. Push victims up to superblock level
1134 * and release transaction when appropriate.
1135 */
1136/* FIXME: This is currently called from the wrong spots. */
1137static void logfs_handle_transaction(struct inode *inode,
1138 struct logfs_transaction *ta)
1139{
1140 struct logfs_super *super = logfs_super(inode->i_sb);
1141
1142 if (!ta)
1143 return;
1144 logfs_inode(inode)->li_block->ta = NULL;
1145
1146 if (inode->i_ino != LOGFS_INO_MASTER) {
1147 BUG(); /* FIXME: Yes, this needs more thought */
1148 /* just remember the transaction until inode is written */
1149 //BUG_ON(logfs_inode(inode)->li_transaction);
1150 //logfs_inode(inode)->li_transaction = ta;
1151 return;
1152 }
1153
1154 switch (ta->state) {
1155 case CREATE_1: /* fall through */
1156 case UNLINK_1:
1157 BUG_ON(super->s_victim_ino);
1158 super->s_victim_ino = ta->ino;
1159 break;
1160 case CREATE_2: /* fall through */
1161 case UNLINK_2:
1162 BUG_ON(super->s_victim_ino != ta->ino);
1163 super->s_victim_ino = 0;
1164 /* transaction ends here - free it */
1165 kfree(ta);
1166 break;
1167 case CROSS_RENAME_1:
1168 BUG_ON(super->s_rename_dir);
1169 BUG_ON(super->s_rename_pos);
1170 super->s_rename_dir = ta->dir;
1171 super->s_rename_pos = ta->pos;
1172 break;
1173 case CROSS_RENAME_2:
1174 BUG_ON(super->s_rename_dir != ta->dir);
1175 BUG_ON(super->s_rename_pos != ta->pos);
1176 super->s_rename_dir = 0;
1177 super->s_rename_pos = 0;
1178 kfree(ta);
1179 break;
1180 case TARGET_RENAME_1:
1181 BUG_ON(super->s_rename_dir);
1182 BUG_ON(super->s_rename_pos);
1183 BUG_ON(super->s_victim_ino);
1184 super->s_rename_dir = ta->dir;
1185 super->s_rename_pos = ta->pos;
1186 super->s_victim_ino = ta->ino;
1187 break;
1188 case TARGET_RENAME_2:
1189 BUG_ON(super->s_rename_dir != ta->dir);
1190 BUG_ON(super->s_rename_pos != ta->pos);
1191 BUG_ON(super->s_victim_ino != ta->ino);
1192 super->s_rename_dir = 0;
1193 super->s_rename_pos = 0;
1194 break;
1195 case TARGET_RENAME_3:
1196 BUG_ON(super->s_rename_dir);
1197 BUG_ON(super->s_rename_pos);
1198 BUG_ON(super->s_victim_ino != ta->ino);
1199 super->s_victim_ino = 0;
1200 kfree(ta);
1201 break;
1202 default:
1203 BUG();
1204 }
1205}
1206
1207/*
1208 * Not strictly a reservation, but rather a check that we still have enough
1209 * space to satisfy the write.
1210 */
1211static int logfs_reserve_blocks(struct inode *inode, int blocks)
1212{
1213 return logfs_reserve_bytes(inode, blocks * LOGFS_MAX_OBJECTSIZE);
1214}
1215
1216struct write_control {
1217 u64 ofs;
1218 long flags;
1219};
1220
1221static struct logfs_shadow *alloc_shadow(struct inode *inode, u64 bix,
1222 level_t level, u64 old_ofs)
1223{
1224 struct logfs_super *super = logfs_super(inode->i_sb);
1225 struct logfs_shadow *shadow;
1226
1227 shadow = mempool_alloc(super->s_shadow_pool, GFP_NOFS);
1228 memset(shadow, 0, sizeof(*shadow));
1229 shadow->ino = inode->i_ino;
1230 shadow->bix = bix;
1231 shadow->gc_level = expand_level(inode->i_ino, level);
1232 shadow->old_ofs = old_ofs & ~LOGFS_FULLY_POPULATED;
1233 return shadow;
1234}
1235
1236static void free_shadow(struct inode *inode, struct logfs_shadow *shadow)
1237{
1238 struct logfs_super *super = logfs_super(inode->i_sb);
1239
1240 mempool_free(shadow, super->s_shadow_pool);
1241}
1242
1243/**
1244 * fill_shadow_tree - Propagate shadow tree changes due to a write
1245 * @inode: Inode owning the page
1246 * @page: Struct page that was written
1247 * @shadow: Shadow for the current write
1248 *
1249 * Writes in logfs can result in two semi-valid objects. The old object
1250 * is still valid as long as it can be reached by following pointers on
1251 * the medium. Only when writes propagate all the way up to the journal
1252 * has the new object safely replaced the old one.
1253 *
1254 * To handle this problem, a struct logfs_shadow is used to represent
1255 * every single write. It is attached to the indirect block, which is
1256 * marked dirty. When the indirect block is written, its shadows are
1257 * handed up to the next indirect block (or inode). Untimately they
1258 * will reach the master inode and be freed upon journal commit.
1259 *
1260 * This function handles a single step in the propagation. It adds the
1261 * shadow for the current write to the tree, along with any shadows in
1262 * the page's tree, in case it was an indirect block. If a page is
1263 * written, the inode parameter is left NULL, if an inode is written,
1264 * the page parameter is left NULL.
1265 */
1266static void fill_shadow_tree(struct inode *inode, struct page *page,
1267 struct logfs_shadow *shadow)
1268{
1269 struct logfs_super *super = logfs_super(inode->i_sb);
1270 struct logfs_block *block = logfs_block(page);
1271 struct shadow_tree *tree = &super->s_shadow_tree;
1272
1273 if (PagePrivate(page)) {
1274 if (block->alias_map)
1275 super->s_no_object_aliases -= bitmap_weight(
1276 block->alias_map, LOGFS_BLOCK_FACTOR);
1277 logfs_handle_transaction(inode, block->ta);
1278 block->ops->free_block(inode->i_sb, block);
1279 }
1280 if (shadow) {
1281 if (shadow->old_ofs)
1282 btree_insert64(&tree->old, shadow->old_ofs, shadow,
1283 GFP_NOFS);
1284 else
1285 btree_insert64(&tree->new, shadow->new_ofs, shadow,
1286 GFP_NOFS);
1287
1288 super->s_dirty_used_bytes += shadow->new_len;
1289 super->s_dirty_free_bytes += shadow->old_len;
1290 }
1291}
1292
1293static void logfs_set_alias(struct super_block *sb, struct logfs_block *block,
1294 long child_no)
1295{
1296 struct logfs_super *super = logfs_super(sb);
1297
1298 if (block->inode && block->inode->i_ino == LOGFS_INO_MASTER) {
1299 /* Aliases in the master inode are pointless. */
1300 return;
1301 }
1302
1303 if (!test_bit(child_no, block->alias_map)) {
1304 set_bit(child_no, block->alias_map);
1305 super->s_no_object_aliases++;
1306 }
1307 list_move_tail(&block->alias_list, &super->s_object_alias);
1308}
1309
1310/*
1311 * Object aliases can and often do change the size and occupied space of a
1312 * file. So not only do we have to change the pointers, we also have to
1313 * change inode->i_size and li->li_used_bytes. Which is done by setting
1314 * another two object aliases for the inode itself.
1315 */
1316static void set_iused(struct inode *inode, struct logfs_shadow *shadow)
1317{
1318 struct logfs_inode *li = logfs_inode(inode);
1319
1320 if (shadow->new_len == shadow->old_len)
1321 return;
1322
1323 alloc_inode_block(inode);
1324 li->li_used_bytes += shadow->new_len - shadow->old_len;
1325 __logfs_set_blocks(inode);
1326 logfs_set_alias(inode->i_sb, li->li_block, INODE_USED_OFS);
1327 logfs_set_alias(inode->i_sb, li->li_block, INODE_SIZE_OFS);
1328}
1329
1330static int logfs_write_i0(struct inode *inode, struct page *page,
1331 struct write_control *wc)
1332{
1333 struct logfs_shadow *shadow;
1334 u64 bix;
1335 level_t level;
1336 int full, err = 0;
1337
1338 logfs_unpack_index(page->index, &bix, &level);
1339 if (wc->ofs == 0)
1340 if (logfs_reserve_blocks(inode, 1))
1341 return -ENOSPC;
1342
1343 shadow = alloc_shadow(inode, bix, level, wc->ofs);
1344 if (wc->flags & WF_WRITE)
1345 err = logfs_segment_write(inode, page, shadow);
1346 if (wc->flags & WF_DELETE)
1347 logfs_segment_delete(inode, shadow);
1348 if (err) {
1349 free_shadow(inode, shadow);
1350 return err;
1351 }
1352
1353 set_iused(inode, shadow);
1354 full = 1;
1355 if (level != 0) {
1356 alloc_indirect_block(inode, page, 0);
1357 full = logfs_block(page)->full == LOGFS_BLOCK_FACTOR;
1358 }
1359 fill_shadow_tree(inode, page, shadow);
1360 wc->ofs = shadow->new_ofs;
1361 if (wc->ofs && full)
1362 wc->ofs |= LOGFS_FULLY_POPULATED;
1363 return 0;
1364}
1365
1366static int logfs_write_direct(struct inode *inode, struct page *page,
1367 long flags)
1368{
1369 struct logfs_inode *li = logfs_inode(inode);
1370 struct write_control wc = {
1371 .ofs = li->li_data[page->index],
1372 .flags = flags,
1373 };
1374 int err;
1375
1376 alloc_inode_block(inode);
1377
1378 err = logfs_write_i0(inode, page, &wc);
1379 if (err)
1380 return err;
1381
1382 li->li_data[page->index] = wc.ofs;
1383 logfs_set_alias(inode->i_sb, li->li_block,
1384 page->index + INODE_POINTER_OFS);
1385 return 0;
1386}
1387
1388static int ptr_change(u64 ofs, struct page *page)
1389{
1390 struct logfs_block *block = logfs_block(page);
1391 int empty0, empty1, full0, full1;
1392
1393 empty0 = ofs == 0;
1394 empty1 = block->partial == 0;
1395 if (empty0 != empty1)
1396 return 1;
1397
1398 /* The !! is necessary to shrink result to int */
1399 full0 = !!(ofs & LOGFS_FULLY_POPULATED);
1400 full1 = block->full == LOGFS_BLOCK_FACTOR;
1401 if (full0 != full1)
1402 return 1;
1403 return 0;
1404}
1405
1406static int __logfs_write_rec(struct inode *inode, struct page *page,
1407 struct write_control *this_wc,
1408 pgoff_t bix, level_t target_level, level_t level)
1409{
1410 int ret, page_empty = 0;
1411 int child_no = get_bits(bix, SUBLEVEL(level));
1412 struct page *ipage;
1413 struct write_control child_wc = {
1414 .flags = this_wc->flags,
1415 };
1416
1417 ipage = logfs_get_write_page(inode, bix, level);
1418 if (!ipage)
1419 return -ENOMEM;
1420
1421 if (this_wc->ofs) {
1422 ret = logfs_segment_read(inode, ipage, this_wc->ofs, bix, level);
1423 if (ret)
1424 goto out;
1425 } else if (!PageUptodate(ipage)) {
1426 page_empty = 1;
1427 logfs_read_empty(ipage);
1428 }
1429
1430 child_wc.ofs = block_get_pointer(ipage, child_no);
1431
1432 if ((__force u8)level-1 > (__force u8)target_level)
1433 ret = __logfs_write_rec(inode, page, &child_wc, bix,
1434 target_level, SUBLEVEL(level));
1435 else
1436 ret = logfs_write_i0(inode, page, &child_wc);
1437
1438 if (ret)
1439 goto out;
1440
1441 alloc_indirect_block(inode, ipage, page_empty);
1442 block_set_pointer(ipage, child_no, child_wc.ofs);
1443 /* FIXME: first condition seems superfluous */
1444 if (child_wc.ofs || logfs_block(ipage)->partial)
1445 this_wc->flags |= WF_WRITE;
1446 /* the condition on this_wc->ofs ensures that we won't consume extra
1447 * space for indirect blocks in the future, which we cannot reserve */
1448 if (!this_wc->ofs || ptr_change(this_wc->ofs, ipage))
1449 ret = logfs_write_i0(inode, ipage, this_wc);
1450 else
1451 logfs_set_alias(inode->i_sb, logfs_block(ipage), child_no);
1452out:
1453 logfs_put_write_page(ipage);
1454 return ret;
1455}
1456
1457static int logfs_write_rec(struct inode *inode, struct page *page,
1458 pgoff_t bix, level_t target_level, long flags)
1459{
1460 struct logfs_inode *li = logfs_inode(inode);
1461 struct write_control wc = {
1462 .ofs = li->li_data[INDIRECT_INDEX],
1463 .flags = flags,
1464 };
1465 int ret;
1466
1467 alloc_inode_block(inode);
1468
1469 if (li->li_height > (__force u8)target_level)
1470 ret = __logfs_write_rec(inode, page, &wc, bix, target_level,
1471 LEVEL(li->li_height));
1472 else
1473 ret = logfs_write_i0(inode, page, &wc);
1474 if (ret)
1475 return ret;
1476
1477 if (li->li_data[INDIRECT_INDEX] != wc.ofs) {
1478 li->li_data[INDIRECT_INDEX] = wc.ofs;
1479 logfs_set_alias(inode->i_sb, li->li_block,
1480 INDIRECT_INDEX + INODE_POINTER_OFS);
1481 }
1482 return ret;
1483}
1484
1485void logfs_add_transaction(struct inode *inode, struct logfs_transaction *ta)
1486{
1487 alloc_inode_block(inode);
1488 logfs_inode(inode)->li_block->ta = ta;
1489}
1490
1491void logfs_del_transaction(struct inode *inode, struct logfs_transaction *ta)
1492{
1493 struct logfs_block *block = logfs_inode(inode)->li_block;
1494
1495 if (block && block->ta)
1496 block->ta = NULL;
1497}
1498
1499static int grow_inode(struct inode *inode, u64 bix, level_t level)
1500{
1501 struct logfs_inode *li = logfs_inode(inode);
1502 u8 height = (__force u8)level;
1503 struct page *page;
1504 struct write_control wc = {
1505 .flags = WF_WRITE,
1506 };
1507 int err;
1508
1509 BUG_ON(height > 5 || li->li_height > 5);
1510 while (height > li->li_height || bix >= maxbix(li->li_height)) {
1511 page = logfs_get_write_page(inode, I0_BLOCKS + 1,
1512 LEVEL(li->li_height + 1));
1513 if (!page)
1514 return -ENOMEM;
1515 logfs_read_empty(page);
1516 alloc_indirect_block(inode, page, 1);
1517 block_set_pointer(page, 0, li->li_data[INDIRECT_INDEX]);
1518 err = logfs_write_i0(inode, page, &wc);
1519 logfs_put_write_page(page);
1520 if (err)
1521 return err;
1522 li->li_data[INDIRECT_INDEX] = wc.ofs;
1523 wc.ofs = 0;
1524 li->li_height++;
1525 logfs_set_alias(inode->i_sb, li->li_block, INODE_HEIGHT_OFS);
1526 }
1527 return 0;
1528}
1529
1530static int __logfs_write_buf(struct inode *inode, struct page *page, long flags)
1531{
1532 struct logfs_super *super = logfs_super(inode->i_sb);
1533 pgoff_t index = page->index;
1534 u64 bix;
1535 level_t level;
1536 int err;
1537
1538 flags |= WF_WRITE | WF_DELETE;
1539 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
1540
1541 logfs_unpack_index(index, &bix, &level);
1542 if (logfs_block(page) && logfs_block(page)->reserved_bytes)
1543 super->s_dirty_pages -= logfs_block(page)->reserved_bytes;
1544
1545 if (index < I0_BLOCKS)
1546 return logfs_write_direct(inode, page, flags);
1547
1548 bix = adjust_bix(bix, level);
1549 err = grow_inode(inode, bix, level);
1550 if (err)
1551 return err;
1552 return logfs_write_rec(inode, page, bix, level, flags);
1553}
1554
1555int logfs_write_buf(struct inode *inode, struct page *page, long flags)
1556{
1557 struct super_block *sb = inode->i_sb;
1558 int ret;
1559
1560 logfs_get_wblocks(sb, page, flags & WF_LOCK);
1561 ret = __logfs_write_buf(inode, page, flags);
1562 logfs_put_wblocks(sb, page, flags & WF_LOCK);
1563 return ret;
1564}
1565
1566static int __logfs_delete(struct inode *inode, struct page *page)
1567{
1568 long flags = WF_DELETE;
1569
1570 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
1571
1572 if (page->index < I0_BLOCKS)
1573 return logfs_write_direct(inode, page, flags);
1574 return logfs_write_rec(inode, page, page->index, 0, flags);
1575}
1576
1577int logfs_delete(struct inode *inode, pgoff_t index,
1578 struct shadow_tree *shadow_tree)
1579{
1580 struct super_block *sb = inode->i_sb;
1581 struct page *page;
1582 int ret;
1583
1584 page = logfs_get_read_page(inode, index, 0);
1585 if (!page)
1586 return -ENOMEM;
1587
1588 logfs_get_wblocks(sb, page, 1);
1589 ret = __logfs_delete(inode, page);
1590 logfs_put_wblocks(sb, page, 1);
1591
1592 logfs_put_read_page(page);
1593
1594 return ret;
1595}
1596
1597/* Rewrite cannot mark the inode dirty but has to write it immediatly. */
1598int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs,
1599 gc_level_t gc_level, long flags)
1600{
1601 level_t level = shrink_level(gc_level);
1602 struct page *page;
1603 int err;
1604
1605 page = logfs_get_write_page(inode, bix, level);
1606 if (!page)
1607 return -ENOMEM;
1608
1609 err = logfs_segment_read(inode, page, ofs, bix, level);
1610 if (!err) {
1611 if (level != 0)
1612 alloc_indirect_block(inode, page, 0);
1613 err = logfs_write_buf(inode, page, flags);
1614 }
1615 logfs_put_write_page(page);
1616 return err;
1617}
1618
1619static int truncate_data_block(struct inode *inode, struct page *page,
1620 u64 ofs, struct logfs_shadow *shadow, u64 size)
1621{
1622 loff_t pageofs = page->index << inode->i_sb->s_blocksize_bits;
1623 u64 bix;
1624 level_t level;
1625 int err;
1626
1627 /* Does truncation happen within this page? */
1628 if (size <= pageofs || size - pageofs >= PAGE_SIZE)
1629 return 0;
1630
1631 logfs_unpack_index(page->index, &bix, &level);
1632 BUG_ON(level != 0);
1633
1634 err = logfs_segment_read(inode, page, ofs, bix, level);
1635 if (err)
1636 return err;
1637
1638 zero_user_segment(page, size - pageofs, PAGE_CACHE_SIZE);
1639 return logfs_segment_write(inode, page, shadow);
1640}
1641
1642static int logfs_truncate_i0(struct inode *inode, struct page *page,
1643 struct write_control *wc, u64 size)
1644{
1645 struct logfs_shadow *shadow;
1646 u64 bix;
1647 level_t level;
1648 int err = 0;
1649
1650 logfs_unpack_index(page->index, &bix, &level);
1651 BUG_ON(level != 0);
1652 shadow = alloc_shadow(inode, bix, level, wc->ofs);
1653
1654 err = truncate_data_block(inode, page, wc->ofs, shadow, size);
1655 if (err) {
1656 free_shadow(inode, shadow);
1657 return err;
1658 }
1659
1660 logfs_segment_delete(inode, shadow);
1661 set_iused(inode, shadow);
1662 fill_shadow_tree(inode, page, shadow);
1663 wc->ofs = shadow->new_ofs;
1664 return 0;
1665}
1666
1667static int logfs_truncate_direct(struct inode *inode, u64 size)
1668{
1669 struct logfs_inode *li = logfs_inode(inode);
1670 struct write_control wc;
1671 struct page *page;
1672 int e;
1673 int err;
1674
1675 alloc_inode_block(inode);
1676
1677 for (e = I0_BLOCKS - 1; e >= 0; e--) {
1678 if (size > (e+1) * LOGFS_BLOCKSIZE)
1679 break;
1680
1681 wc.ofs = li->li_data[e];
1682 if (!wc.ofs)
1683 continue;
1684
1685 page = logfs_get_write_page(inode, e, 0);
1686 if (!page)
1687 return -ENOMEM;
1688 err = logfs_segment_read(inode, page, wc.ofs, e, 0);
1689 if (err) {
1690 logfs_put_write_page(page);
1691 return err;
1692 }
1693 err = logfs_truncate_i0(inode, page, &wc, size);
1694 logfs_put_write_page(page);
1695 if (err)
1696 return err;
1697
1698 li->li_data[e] = wc.ofs;
1699 }
1700 return 0;
1701}
1702
1703/* FIXME: these need to become per-sb once we support different blocksizes */
1704static u64 __logfs_step[] = {
1705 1,
1706 I1_BLOCKS,
1707 I2_BLOCKS,
1708 I3_BLOCKS,
1709};
1710
1711static u64 __logfs_start_index[] = {
1712 I0_BLOCKS,
1713 I1_BLOCKS,
1714 I2_BLOCKS,
1715 I3_BLOCKS
1716};
1717
1718static inline u64 logfs_step(level_t level)
1719{
1720 return __logfs_step[(__force u8)level];
1721}
1722
1723static inline u64 logfs_factor(u8 level)
1724{
1725 return __logfs_step[level] * LOGFS_BLOCKSIZE;
1726}
1727
1728static inline u64 logfs_start_index(level_t level)
1729{
1730 return __logfs_start_index[(__force u8)level];
1731}
1732
1733static void logfs_unpack_raw_index(pgoff_t index, u64 *bix, level_t *level)
1734{
1735 logfs_unpack_index(index, bix, level);
1736 if (*bix <= logfs_start_index(SUBLEVEL(*level)))
1737 *bix = 0;
1738}
1739
1740static int __logfs_truncate_rec(struct inode *inode, struct page *ipage,
1741 struct write_control *this_wc, u64 size)
1742{
1743 int truncate_happened = 0;
1744 int e, err = 0;
1745 u64 bix, child_bix, next_bix;
1746 level_t level;
1747 struct page *page;
1748 struct write_control child_wc = { /* FIXME: flags */ };
1749
1750 logfs_unpack_raw_index(ipage->index, &bix, &level);
1751 err = logfs_segment_read(inode, ipage, this_wc->ofs, bix, level);
1752 if (err)
1753 return err;
1754
1755 for (e = LOGFS_BLOCK_FACTOR - 1; e >= 0; e--) {
1756 child_bix = bix + e * logfs_step(SUBLEVEL(level));
1757 next_bix = child_bix + logfs_step(SUBLEVEL(level));
1758 if (size > next_bix * LOGFS_BLOCKSIZE)
1759 break;
1760
1761 child_wc.ofs = pure_ofs(block_get_pointer(ipage, e));
1762 if (!child_wc.ofs)
1763 continue;
1764
1765 page = logfs_get_write_page(inode, child_bix, SUBLEVEL(level));
1766 if (!page)
1767 return -ENOMEM;
1768
1769 if ((__force u8)level > 1)
1770 err = __logfs_truncate_rec(inode, page, &child_wc, size);
1771 else
1772 err = logfs_truncate_i0(inode, page, &child_wc, size);
1773 logfs_put_write_page(page);
1774 if (err)
1775 return err;
1776
1777 truncate_happened = 1;
1778 alloc_indirect_block(inode, ipage, 0);
1779 block_set_pointer(ipage, e, child_wc.ofs);
1780 }
1781
1782 if (!truncate_happened) {
1783 printk("ineffectual truncate (%lx, %lx, %llx)\n", inode->i_ino, ipage->index, size);
1784 return 0;
1785 }
1786
1787 this_wc->flags = WF_DELETE;
1788 if (logfs_block(ipage)->partial)
1789 this_wc->flags |= WF_WRITE;
1790
1791 return logfs_write_i0(inode, ipage, this_wc);
1792}
1793
1794static int logfs_truncate_rec(struct inode *inode, u64 size)
1795{
1796 struct logfs_inode *li = logfs_inode(inode);
1797 struct write_control wc = {
1798 .ofs = li->li_data[INDIRECT_INDEX],
1799 };
1800 struct page *page;
1801 int err;
1802
1803 alloc_inode_block(inode);
1804
1805 if (!wc.ofs)
1806 return 0;
1807
1808 page = logfs_get_write_page(inode, 0, LEVEL(li->li_height));
1809 if (!page)
1810 return -ENOMEM;
1811
1812 err = __logfs_truncate_rec(inode, page, &wc, size);
1813 logfs_put_write_page(page);
1814 if (err)
1815 return err;
1816
1817 if (li->li_data[INDIRECT_INDEX] != wc.ofs)
1818 li->li_data[INDIRECT_INDEX] = wc.ofs;
1819 return 0;
1820}
1821
1822static int __logfs_truncate(struct inode *inode, u64 size)
1823{
1824 int ret;
1825
1826 if (size >= logfs_factor(logfs_inode(inode)->li_height))
1827 return 0;
1828
1829 ret = logfs_truncate_rec(inode, size);
1830 if (ret)
1831 return ret;
1832
1833 return logfs_truncate_direct(inode, size);
1834}
1835
1836int logfs_truncate(struct inode *inode, u64 size)
1837{
1838 struct super_block *sb = inode->i_sb;
1839 int err;
1840
1841 logfs_get_wblocks(sb, NULL, 1);
1842 err = __logfs_truncate(inode, size);
1843 if (!err)
1844 err = __logfs_write_inode(inode, 0);
1845 logfs_put_wblocks(sb, NULL, 1);
1846
1847 if (!err)
1848 err = vmtruncate(inode, size);
1849
1850 /* I don't trust error recovery yet. */
1851 WARN_ON(err);
1852 return err;
1853}
1854
1855static void move_page_to_inode(struct inode *inode, struct page *page)
1856{
1857 struct logfs_inode *li = logfs_inode(inode);
1858 struct logfs_block *block = logfs_block(page);
1859
1860 if (!block)
1861 return;
1862
1863 log_blockmove("move_page_to_inode(%llx, %llx, %x)\n",
1864 block->ino, block->bix, block->level);
1865 BUG_ON(li->li_block);
1866 block->ops = &inode_block_ops;
1867 block->inode = inode;
1868 li->li_block = block;
1869
1870 block->page = NULL;
1871 page->private = 0;
1872 ClearPagePrivate(page);
1873}
1874
1875static void move_inode_to_page(struct page *page, struct inode *inode)
1876{
1877 struct logfs_inode *li = logfs_inode(inode);
1878 struct logfs_block *block = li->li_block;
1879
1880 if (!block)
1881 return;
1882
1883 log_blockmove("move_inode_to_page(%llx, %llx, %x)\n",
1884 block->ino, block->bix, block->level);
1885 BUG_ON(PagePrivate(page));
1886 block->ops = &indirect_block_ops;
1887 block->page = page;
1888 page->private = (unsigned long)block;
1889 SetPagePrivate(page);
1890
1891 block->inode = NULL;
1892 li->li_block = NULL;
1893}
1894
1895int logfs_read_inode(struct inode *inode)
1896{
1897 struct super_block *sb = inode->i_sb;
1898 struct logfs_super *super = logfs_super(sb);
1899 struct inode *master_inode = super->s_master_inode;
1900 struct page *page;
1901 struct logfs_disk_inode *di;
1902 u64 ino = inode->i_ino;
1903
1904 if (ino << sb->s_blocksize_bits > i_size_read(master_inode))
1905 return -ENODATA;
1906 if (!logfs_exist_block(master_inode, ino))
1907 return -ENODATA;
1908
1909 page = read_cache_page(master_inode->i_mapping, ino,
1910 (filler_t *)logfs_readpage, NULL);
1911 if (IS_ERR(page))
1912 return PTR_ERR(page);
1913
1914 di = kmap_atomic(page, KM_USER0);
1915 logfs_disk_to_inode(di, inode);
1916 kunmap_atomic(di, KM_USER0);
1917 move_page_to_inode(inode, page);
1918 page_cache_release(page);
1919 return 0;
1920}
1921
1922/* Caller must logfs_put_write_page(page); */
1923static struct page *inode_to_page(struct inode *inode)
1924{
1925 struct inode *master_inode = logfs_super(inode->i_sb)->s_master_inode;
1926 struct logfs_disk_inode *di;
1927 struct page *page;
1928
1929 BUG_ON(inode->i_ino == LOGFS_INO_MASTER);
1930
1931 page = logfs_get_write_page(master_inode, inode->i_ino, 0);
1932 if (!page)
1933 return NULL;
1934
1935 di = kmap_atomic(page, KM_USER0);
1936 logfs_inode_to_disk(inode, di);
1937 kunmap_atomic(di, KM_USER0);
1938 move_inode_to_page(page, inode);
1939 return page;
1940}
1941
1942/* Cheaper version of write_inode. All changes are concealed in
1943 * aliases, which are moved back. No write to the medium happens.
1944 */
1945void logfs_clear_inode(struct inode *inode)
1946{
1947 struct super_block *sb = inode->i_sb;
1948 struct logfs_inode *li = logfs_inode(inode);
1949 struct logfs_block *block = li->li_block;
1950 struct page *page;
1951
1952 /* Only deleted files may be dirty at this point */
1953 BUG_ON(inode->i_state & I_DIRTY && inode->i_nlink);
1954 if (!block)
1955 return;
1956 if ((logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN)) {
1957 block->ops->free_block(inode->i_sb, block);
1958 return;
1959 }
1960
1961 BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS);
1962 page = inode_to_page(inode);
1963 BUG_ON(!page); /* FIXME: Use emergency page */
1964 logfs_put_write_page(page);
1965}
1966
1967static int do_write_inode(struct inode *inode)
1968{
1969 struct super_block *sb = inode->i_sb;
1970 struct inode *master_inode = logfs_super(sb)->s_master_inode;
1971 loff_t size = (inode->i_ino + 1) << inode->i_sb->s_blocksize_bits;
1972 struct page *page;
1973 int err;
1974
1975 BUG_ON(inode->i_ino == LOGFS_INO_MASTER);
1976 /* FIXME: lock inode */
1977
1978 if (i_size_read(master_inode) < size)
1979 i_size_write(master_inode, size);
1980
1981 /* TODO: Tell vfs this inode is clean now */
1982
1983 page = inode_to_page(inode);
1984 if (!page)
1985 return -ENOMEM;
1986
1987 /* FIXME: transaction is part of logfs_block now. Is that enough? */
1988 err = logfs_write_buf(master_inode, page, 0);
1989 logfs_put_write_page(page);
1990 return err;
1991}
1992
1993static void logfs_mod_segment_entry(struct super_block *sb, u32 segno,
1994 int write,
1995 void (*change_se)(struct logfs_segment_entry *, long),
1996 long arg)
1997{
1998 struct logfs_super *super = logfs_super(sb);
1999 struct inode *inode;
2000 struct page *page;
2001 struct logfs_segment_entry *se;
2002 pgoff_t page_no;
2003 int child_no;
2004
2005 page_no = segno >> (sb->s_blocksize_bits - 3);
2006 child_no = segno & ((sb->s_blocksize >> 3) - 1);
2007
2008 inode = super->s_segfile_inode;
2009 page = logfs_get_write_page(inode, page_no, 0);
2010 BUG_ON(!page); /* FIXME: We need some reserve page for this case */
2011 if (!PageUptodate(page))
2012 logfs_read_block(inode, page, WRITE);
2013
2014 if (write)
2015 alloc_indirect_block(inode, page, 0);
2016 se = kmap_atomic(page, KM_USER0);
2017 change_se(se + child_no, arg);
2018 if (write) {
2019 logfs_set_alias(sb, logfs_block(page), child_no);
2020 BUG_ON((int)be32_to_cpu(se[child_no].valid) > super->s_segsize);
2021 }
2022 kunmap_atomic(se, KM_USER0);
2023
2024 logfs_put_write_page(page);
2025}
2026
2027static void __get_segment_entry(struct logfs_segment_entry *se, long _target)
2028{
2029 struct logfs_segment_entry *target = (void *)_target;
2030
2031 *target = *se;
2032}
2033
2034void logfs_get_segment_entry(struct super_block *sb, u32 segno,
2035 struct logfs_segment_entry *se)
2036{
2037 logfs_mod_segment_entry(sb, segno, 0, __get_segment_entry, (long)se);
2038}
2039
2040static void __set_segment_used(struct logfs_segment_entry *se, long increment)
2041{
2042 u32 valid;
2043
2044 valid = be32_to_cpu(se->valid);
2045 valid += increment;
2046 se->valid = cpu_to_be32(valid);
2047}
2048
2049void logfs_set_segment_used(struct super_block *sb, u64 ofs, int increment)
2050{
2051 struct logfs_super *super = logfs_super(sb);
2052 u32 segno = ofs >> super->s_segshift;
2053
2054 if (!increment)
2055 return;
2056
2057 logfs_mod_segment_entry(sb, segno, 1, __set_segment_used, increment);
2058}
2059
2060static void __set_segment_erased(struct logfs_segment_entry *se, long ec_level)
2061{
2062 se->ec_level = cpu_to_be32(ec_level);
2063}
2064
2065void logfs_set_segment_erased(struct super_block *sb, u32 segno, u32 ec,
2066 gc_level_t gc_level)
2067{
2068 u32 ec_level = ec << 4 | (__force u8)gc_level;
2069
2070 logfs_mod_segment_entry(sb, segno, 1, __set_segment_erased, ec_level);
2071}
2072
2073static void __set_segment_reserved(struct logfs_segment_entry *se, long ignore)
2074{
2075 se->valid = cpu_to_be32(RESERVED);
2076}
2077
2078void logfs_set_segment_reserved(struct super_block *sb, u32 segno)
2079{
2080 logfs_mod_segment_entry(sb, segno, 1, __set_segment_reserved, 0);
2081}
2082
2083static void __set_segment_unreserved(struct logfs_segment_entry *se,
2084 long ec_level)
2085{
2086 se->valid = 0;
2087 se->ec_level = cpu_to_be32(ec_level);
2088}
2089
2090void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec)
2091{
2092 u32 ec_level = ec << 4;
2093
2094 logfs_mod_segment_entry(sb, segno, 1, __set_segment_unreserved,
2095 ec_level);
2096}
2097
2098int __logfs_write_inode(struct inode *inode, long flags)
2099{
2100 struct super_block *sb = inode->i_sb;
2101 int ret;
2102
2103 logfs_get_wblocks(sb, NULL, flags & WF_LOCK);
2104 ret = do_write_inode(inode);
2105 logfs_put_wblocks(sb, NULL, flags & WF_LOCK);
2106 return ret;
2107}
2108
2109static int do_delete_inode(struct inode *inode)
2110{
2111 struct super_block *sb = inode->i_sb;
2112 struct inode *master_inode = logfs_super(sb)->s_master_inode;
2113 struct page *page;
2114 int ret;
2115
2116 page = logfs_get_write_page(master_inode, inode->i_ino, 0);
2117 if (!page)
2118 return -ENOMEM;
2119
2120 move_inode_to_page(page, inode);
2121
2122 logfs_get_wblocks(sb, page, 1);
2123 ret = __logfs_delete(master_inode, page);
2124 logfs_put_wblocks(sb, page, 1);
2125
2126 logfs_put_write_page(page);
2127 return ret;
2128}
2129
2130/*
2131 * ZOMBIE inodes have already been deleted before and should remain dead,
2132 * if it weren't for valid checking. No need to kill them again here.
2133 */
2134void logfs_delete_inode(struct inode *inode)
2135{
2136 struct logfs_inode *li = logfs_inode(inode);
2137
2138 if (!(li->li_flags & LOGFS_IF_ZOMBIE)) {
2139 li->li_flags |= LOGFS_IF_ZOMBIE;
2140 if (i_size_read(inode) > 0)
2141 logfs_truncate(inode, 0);
2142 do_delete_inode(inode);
2143 }
2144 truncate_inode_pages(&inode->i_data, 0);
2145 clear_inode(inode);
2146}
2147
2148void btree_write_block(struct logfs_block *block)
2149{
2150 struct inode *inode;
2151 struct page *page;
2152 int err, cookie;
2153
2154 inode = logfs_safe_iget(block->sb, block->ino, &cookie);
2155 page = logfs_get_write_page(inode, block->bix, block->level);
2156
2157 err = logfs_readpage_nolock(page);
2158 BUG_ON(err);
2159 BUG_ON(!PagePrivate(page));
2160 BUG_ON(logfs_block(page) != block);
2161 err = __logfs_write_buf(inode, page, 0);
2162 BUG_ON(err);
2163 BUG_ON(PagePrivate(page) || page->private);
2164
2165 logfs_put_write_page(page);
2166 logfs_safe_iput(inode, cookie);
2167}
2168
2169/**
2170 * logfs_inode_write - write inode or dentry objects
2171 *
2172 * @inode: parent inode (ifile or directory)
2173 * @buf: object to write (inode or dentry)
2174 * @n: object size
2175 * @_pos: object number (file position in blocks/objects)
2176 * @flags: write flags
2177 * @lock: 0 if write lock is already taken, 1 otherwise
2178 * @shadow_tree: shadow below this inode
2179 *
2180 * FIXME: All caller of this put a 200-300 byte variable on the stack,
2181 * only to call here and do a memcpy from that stack variable. A good
2182 * example of wasted performance and stack space.
2183 */
2184int logfs_inode_write(struct inode *inode, const void *buf, size_t count,
2185 loff_t bix, long flags, struct shadow_tree *shadow_tree)
2186{
2187 loff_t pos = bix << inode->i_sb->s_blocksize_bits;
2188 int err;
2189 struct page *page;
2190 void *pagebuf;
2191
2192 BUG_ON(pos & (LOGFS_BLOCKSIZE-1));
2193 BUG_ON(count > LOGFS_BLOCKSIZE);
2194 page = logfs_get_write_page(inode, bix, 0);
2195 if (!page)
2196 return -ENOMEM;
2197
2198 pagebuf = kmap_atomic(page, KM_USER0);
2199 memcpy(pagebuf, buf, count);
2200 flush_dcache_page(page);
2201 kunmap_atomic(pagebuf, KM_USER0);
2202
2203 if (i_size_read(inode) < pos + LOGFS_BLOCKSIZE)
2204 i_size_write(inode, pos + LOGFS_BLOCKSIZE);
2205
2206 err = logfs_write_buf(inode, page, flags);
2207 logfs_put_write_page(page);
2208 return err;
2209}
2210
2211int logfs_open_segfile(struct super_block *sb)
2212{
2213 struct logfs_super *super = logfs_super(sb);
2214 struct inode *inode;
2215
2216 inode = logfs_read_meta_inode(sb, LOGFS_INO_SEGFILE);
2217 if (IS_ERR(inode))
2218 return PTR_ERR(inode);
2219 super->s_segfile_inode = inode;
2220 return 0;
2221}
2222
2223int logfs_init_rw(struct super_block *sb)
2224{
2225 struct logfs_super *super = logfs_super(sb);
2226 int min_fill = 3 * super->s_no_blocks;
2227
2228 INIT_LIST_HEAD(&super->s_object_alias);
2229 mutex_init(&super->s_write_mutex);
2230 super->s_block_pool = mempool_create_kmalloc_pool(min_fill,
2231 sizeof(struct logfs_block));
2232 super->s_shadow_pool = mempool_create_kmalloc_pool(min_fill,
2233 sizeof(struct logfs_shadow));
2234 return 0;
2235}
2236
2237void logfs_cleanup_rw(struct super_block *sb)
2238{
2239 struct logfs_super *super = logfs_super(sb);
2240
2241 destroy_meta_inode(super->s_segfile_inode);
2242 if (super->s_block_pool)
2243 mempool_destroy(super->s_block_pool);
2244 if (super->s_shadow_pool)
2245 mempool_destroy(super->s_shadow_pool);
2246}
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c
new file mode 100644
index 000000000000..1a14f9910d55
--- /dev/null
+++ b/fs/logfs/segment.c
@@ -0,0 +1,927 @@
1/*
2 * fs/logfs/segment.c - Handling the Object Store
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 *
8 * Object store or ostore makes up the complete device with exception of
9 * the superblock and journal areas. Apart from its own metadata it stores
10 * three kinds of objects: inodes, dentries and blocks, both data and indirect.
11 */
12#include "logfs.h"
13
14static int logfs_mark_segment_bad(struct super_block *sb, u32 segno)
15{
16 struct logfs_super *super = logfs_super(sb);
17 struct btree_head32 *head = &super->s_reserved_segments;
18 int err;
19
20 err = btree_insert32(head, segno, (void *)1, GFP_NOFS);
21 if (err)
22 return err;
23 logfs_super(sb)->s_bad_segments++;
24 /* FIXME: write to journal */
25 return 0;
26}
27
28int logfs_erase_segment(struct super_block *sb, u32 segno, int ensure_erase)
29{
30 struct logfs_super *super = logfs_super(sb);
31
32 super->s_gec++;
33
34 return super->s_devops->erase(sb, (u64)segno << super->s_segshift,
35 super->s_segsize, ensure_erase);
36}
37
38static s64 logfs_get_free_bytes(struct logfs_area *area, size_t bytes)
39{
40 s32 ofs;
41
42 logfs_open_area(area, bytes);
43
44 ofs = area->a_used_bytes;
45 area->a_used_bytes += bytes;
46 BUG_ON(area->a_used_bytes >= logfs_super(area->a_sb)->s_segsize);
47
48 return dev_ofs(area->a_sb, area->a_segno, ofs);
49}
50
51static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
52 int use_filler)
53{
54 struct logfs_super *super = logfs_super(sb);
55 struct address_space *mapping = super->s_mapping_inode->i_mapping;
56 filler_t *filler = super->s_devops->readpage;
57 struct page *page;
58
59 BUG_ON(mapping_gfp_mask(mapping) & __GFP_FS);
60 if (use_filler)
61 page = read_cache_page(mapping, index, filler, sb);
62 else {
63 page = find_or_create_page(mapping, index, GFP_NOFS);
64 unlock_page(page);
65 }
66 return page;
67}
68
69void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
70 int use_filler)
71{
72 pgoff_t index = ofs >> PAGE_SHIFT;
73 struct page *page;
74 long offset = ofs & (PAGE_SIZE-1);
75 long copylen;
76
77 /* Only logfs_wbuf_recover may use len==0 */
78 BUG_ON(!len && !use_filler);
79 do {
80 copylen = min((ulong)len, PAGE_SIZE - offset);
81
82 page = get_mapping_page(area->a_sb, index, use_filler);
83 SetPageUptodate(page);
84 BUG_ON(!page); /* FIXME: reserve a pool */
85 memcpy(page_address(page) + offset, buf, copylen);
86 SetPagePrivate(page);
87 page_cache_release(page);
88
89 buf += copylen;
90 len -= copylen;
91 offset = 0;
92 index++;
93 } while (len);
94}
95
96/*
97 * bdev_writeseg will write full pages. Memset the tail to prevent data leaks.
98 */
99static void pad_wbuf(struct logfs_area *area, int final)
100{
101 struct super_block *sb = area->a_sb;
102 struct logfs_super *super = logfs_super(sb);
103 struct page *page;
104 u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes);
105 pgoff_t index = ofs >> PAGE_SHIFT;
106 long offset = ofs & (PAGE_SIZE-1);
107 u32 len = PAGE_SIZE - offset;
108
109 if (len == PAGE_SIZE) {
110 /* The math in this function can surely use some love */
111 len = 0;
112 }
113 if (len) {
114 BUG_ON(area->a_used_bytes >= super->s_segsize);
115
116 page = get_mapping_page(area->a_sb, index, 0);
117 BUG_ON(!page); /* FIXME: reserve a pool */
118 memset(page_address(page) + offset, 0xff, len);
119 SetPagePrivate(page);
120 page_cache_release(page);
121 }
122
123 if (!final)
124 return;
125
126 area->a_used_bytes += len;
127 for ( ; area->a_used_bytes < super->s_segsize;
128 area->a_used_bytes += PAGE_SIZE) {
129 /* Memset another page */
130 index++;
131 page = get_mapping_page(area->a_sb, index, 0);
132 BUG_ON(!page); /* FIXME: reserve a pool */
133 memset(page_address(page), 0xff, PAGE_SIZE);
134 SetPagePrivate(page);
135 page_cache_release(page);
136 }
137}
138
139/*
140 * We have to be careful with the alias tree. Since lookup is done by bix,
141 * it needs to be normalized, so 14, 15, 16, etc. all match when dealing with
142 * indirect blocks. So always use it through accessor functions.
143 */
144static void *alias_tree_lookup(struct super_block *sb, u64 ino, u64 bix,
145 level_t level)
146{
147 struct btree_head128 *head = &logfs_super(sb)->s_object_alias_tree;
148 pgoff_t index = logfs_pack_index(bix, level);
149
150 return btree_lookup128(head, ino, index);
151}
152
153static int alias_tree_insert(struct super_block *sb, u64 ino, u64 bix,
154 level_t level, void *val)
155{
156 struct btree_head128 *head = &logfs_super(sb)->s_object_alias_tree;
157 pgoff_t index = logfs_pack_index(bix, level);
158
159 return btree_insert128(head, ino, index, val, GFP_NOFS);
160}
161
162static int btree_write_alias(struct super_block *sb, struct logfs_block *block,
163 write_alias_t *write_one_alias)
164{
165 struct object_alias_item *item;
166 int err;
167
168 list_for_each_entry(item, &block->item_list, list) {
169 err = write_alias_journal(sb, block->ino, block->bix,
170 block->level, item->child_no, item->val);
171 if (err)
172 return err;
173 }
174 return 0;
175}
176
177static gc_level_t btree_block_level(struct logfs_block *block)
178{
179 return expand_level(block->ino, block->level);
180}
181
182static struct logfs_block_ops btree_block_ops = {
183 .write_block = btree_write_block,
184 .block_level = btree_block_level,
185 .free_block = __free_block,
186 .write_alias = btree_write_alias,
187};
188
189int logfs_load_object_aliases(struct super_block *sb,
190 struct logfs_obj_alias *oa, int count)
191{
192 struct logfs_super *super = logfs_super(sb);
193 struct logfs_block *block;
194 struct object_alias_item *item;
195 u64 ino, bix;
196 level_t level;
197 int i, err;
198
199 super->s_flags |= LOGFS_SB_FLAG_OBJ_ALIAS;
200 count /= sizeof(*oa);
201 for (i = 0; i < count; i++) {
202 item = mempool_alloc(super->s_alias_pool, GFP_NOFS);
203 if (!item)
204 return -ENOMEM;
205 memset(item, 0, sizeof(*item));
206
207 super->s_no_object_aliases++;
208 item->val = oa[i].val;
209 item->child_no = be16_to_cpu(oa[i].child_no);
210
211 ino = be64_to_cpu(oa[i].ino);
212 bix = be64_to_cpu(oa[i].bix);
213 level = LEVEL(oa[i].level);
214
215 log_aliases("logfs_load_object_aliases(%llx, %llx, %x, %x) %llx\n",
216 ino, bix, level, item->child_no,
217 be64_to_cpu(item->val));
218 block = alias_tree_lookup(sb, ino, bix, level);
219 if (!block) {
220 block = __alloc_block(sb, ino, bix, level);
221 block->ops = &btree_block_ops;
222 err = alias_tree_insert(sb, ino, bix, level, block);
223 BUG_ON(err); /* mempool empty */
224 }
225 if (test_and_set_bit(item->child_no, block->alias_map)) {
226 printk(KERN_ERR"LogFS: Alias collision detected\n");
227 return -EIO;
228 }
229 list_move_tail(&block->alias_list, &super->s_object_alias);
230 list_add(&item->list, &block->item_list);
231 }
232 return 0;
233}
234
235static void kill_alias(void *_block, unsigned long ignore0,
236 u64 ignore1, u64 ignore2, size_t ignore3)
237{
238 struct logfs_block *block = _block;
239 struct super_block *sb = block->sb;
240 struct logfs_super *super = logfs_super(sb);
241 struct object_alias_item *item;
242
243 while (!list_empty(&block->item_list)) {
244 item = list_entry(block->item_list.next, typeof(*item), list);
245 list_del(&item->list);
246 mempool_free(item, super->s_alias_pool);
247 }
248 block->ops->free_block(sb, block);
249}
250
251static int obj_type(struct inode *inode, level_t level)
252{
253 if (level == 0) {
254 if (S_ISDIR(inode->i_mode))
255 return OBJ_DENTRY;
256 if (inode->i_ino == LOGFS_INO_MASTER)
257 return OBJ_INODE;
258 }
259 return OBJ_BLOCK;
260}
261
262static int obj_len(struct super_block *sb, int obj_type)
263{
264 switch (obj_type) {
265 case OBJ_DENTRY:
266 return sizeof(struct logfs_disk_dentry);
267 case OBJ_INODE:
268 return sizeof(struct logfs_disk_inode);
269 case OBJ_BLOCK:
270 return sb->s_blocksize;
271 default:
272 BUG();
273 }
274}
275
276static int __logfs_segment_write(struct inode *inode, void *buf,
277 struct logfs_shadow *shadow, int type, int len, int compr)
278{
279 struct logfs_area *area;
280 struct super_block *sb = inode->i_sb;
281 s64 ofs;
282 struct logfs_object_header h;
283 int acc_len;
284
285 if (shadow->gc_level == 0)
286 acc_len = len;
287 else
288 acc_len = obj_len(sb, type);
289
290 area = get_area(sb, shadow->gc_level);
291 ofs = logfs_get_free_bytes(area, len + LOGFS_OBJECT_HEADERSIZE);
292 LOGFS_BUG_ON(ofs <= 0, sb);
293 /*
294 * Order is important. logfs_get_free_bytes(), by modifying the
295 * segment file, may modify the content of the very page we're about
296 * to write now. Which is fine, as long as the calculated crc and
297 * written data still match. So do the modifications _before_
298 * calculating the crc.
299 */
300
301 h.len = cpu_to_be16(len);
302 h.type = type;
303 h.compr = compr;
304 h.ino = cpu_to_be64(inode->i_ino);
305 h.bix = cpu_to_be64(shadow->bix);
306 h.crc = logfs_crc32(&h, sizeof(h) - 4, 4);
307 h.data_crc = logfs_crc32(buf, len, 0);
308
309 logfs_buf_write(area, ofs, &h, sizeof(h));
310 logfs_buf_write(area, ofs + LOGFS_OBJECT_HEADERSIZE, buf, len);
311
312 shadow->new_ofs = ofs;
313 shadow->new_len = acc_len + LOGFS_OBJECT_HEADERSIZE;
314
315 return 0;
316}
317
318static s64 logfs_segment_write_compress(struct inode *inode, void *buf,
319 struct logfs_shadow *shadow, int type, int len)
320{
321 struct super_block *sb = inode->i_sb;
322 void *compressor_buf = logfs_super(sb)->s_compressed_je;
323 ssize_t compr_len;
324 int ret;
325
326 mutex_lock(&logfs_super(sb)->s_journal_mutex);
327 compr_len = logfs_compress(buf, compressor_buf, len, len);
328
329 if (compr_len >= 0) {
330 ret = __logfs_segment_write(inode, compressor_buf, shadow,
331 type, compr_len, COMPR_ZLIB);
332 } else {
333 ret = __logfs_segment_write(inode, buf, shadow, type, len,
334 COMPR_NONE);
335 }
336 mutex_unlock(&logfs_super(sb)->s_journal_mutex);
337 return ret;
338}
339
340/**
341 * logfs_segment_write - write data block to object store
342 * @inode: inode containing data
343 *
344 * Returns an errno or zero.
345 */
346int logfs_segment_write(struct inode *inode, struct page *page,
347 struct logfs_shadow *shadow)
348{
349 struct super_block *sb = inode->i_sb;
350 struct logfs_super *super = logfs_super(sb);
351 int do_compress, type, len;
352 int ret;
353 void *buf;
354
355 super->s_flags |= LOGFS_SB_FLAG_DIRTY;
356 BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
357 do_compress = logfs_inode(inode)->li_flags & LOGFS_IF_COMPRESSED;
358 if (shadow->gc_level != 0) {
359 /* temporarily disable compression for indirect blocks */
360 do_compress = 0;
361 }
362
363 type = obj_type(inode, shrink_level(shadow->gc_level));
364 len = obj_len(sb, type);
365 buf = kmap(page);
366 if (do_compress)
367 ret = logfs_segment_write_compress(inode, buf, shadow, type,
368 len);
369 else
370 ret = __logfs_segment_write(inode, buf, shadow, type, len,
371 COMPR_NONE);
372 kunmap(page);
373
374 log_segment("logfs_segment_write(%llx, %llx, %x) %llx->%llx %x->%x\n",
375 shadow->ino, shadow->bix, shadow->gc_level,
376 shadow->old_ofs, shadow->new_ofs,
377 shadow->old_len, shadow->new_len);
378 /* this BUG_ON did catch a locking bug. useful */
379 BUG_ON(!(shadow->new_ofs & (super->s_segsize - 1)));
380 return ret;
381}
382
383int wbuf_read(struct super_block *sb, u64 ofs, size_t len, void *buf)
384{
385 pgoff_t index = ofs >> PAGE_SHIFT;
386 struct page *page;
387 long offset = ofs & (PAGE_SIZE-1);
388 long copylen;
389
390 while (len) {
391 copylen = min((ulong)len, PAGE_SIZE - offset);
392
393 page = get_mapping_page(sb, index, 1);
394 if (IS_ERR(page))
395 return PTR_ERR(page);
396 memcpy(buf, page_address(page) + offset, copylen);
397 page_cache_release(page);
398
399 buf += copylen;
400 len -= copylen;
401 offset = 0;
402 index++;
403 }
404 return 0;
405}
406
407/*
408 * The "position" of indirect blocks is ambiguous. It can be the position
409 * of any data block somewhere behind this indirect block. So we need to
410 * normalize the positions through logfs_block_mask() before comparing.
411 */
412static int check_pos(struct super_block *sb, u64 pos1, u64 pos2, level_t level)
413{
414 return (pos1 & logfs_block_mask(sb, level)) !=
415 (pos2 & logfs_block_mask(sb, level));
416}
417
418#if 0
419static int read_seg_header(struct super_block *sb, u64 ofs,
420 struct logfs_segment_header *sh)
421{
422 __be32 crc;
423 int err;
424
425 err = wbuf_read(sb, ofs, sizeof(*sh), sh);
426 if (err)
427 return err;
428 crc = logfs_crc32(sh, sizeof(*sh), 4);
429 if (crc != sh->crc) {
430 printk(KERN_ERR"LOGFS: header crc error at %llx: expected %x, "
431 "got %x\n", ofs, be32_to_cpu(sh->crc),
432 be32_to_cpu(crc));
433 return -EIO;
434 }
435 return 0;
436}
437#endif
438
439static int read_obj_header(struct super_block *sb, u64 ofs,
440 struct logfs_object_header *oh)
441{
442 __be32 crc;
443 int err;
444
445 err = wbuf_read(sb, ofs, sizeof(*oh), oh);
446 if (err)
447 return err;
448 crc = logfs_crc32(oh, sizeof(*oh) - 4, 4);
449 if (crc != oh->crc) {
450 printk(KERN_ERR"LOGFS: header crc error at %llx: expected %x, "
451 "got %x\n", ofs, be32_to_cpu(oh->crc),
452 be32_to_cpu(crc));
453 return -EIO;
454 }
455 return 0;
456}
457
458static void move_btree_to_page(struct inode *inode, struct page *page,
459 __be64 *data)
460{
461 struct super_block *sb = inode->i_sb;
462 struct logfs_super *super = logfs_super(sb);
463 struct btree_head128 *head = &super->s_object_alias_tree;
464 struct logfs_block *block;
465 struct object_alias_item *item, *next;
466
467 if (!(super->s_flags & LOGFS_SB_FLAG_OBJ_ALIAS))
468 return;
469
470 block = btree_remove128(head, inode->i_ino, page->index);
471 if (!block)
472 return;
473
474 log_blockmove("move_btree_to_page(%llx, %llx, %x)\n",
475 block->ino, block->bix, block->level);
476 list_for_each_entry_safe(item, next, &block->item_list, list) {
477 data[item->child_no] = item->val;
478 list_del(&item->list);
479 mempool_free(item, super->s_alias_pool);
480 }
481 block->page = page;
482 SetPagePrivate(page);
483 page->private = (unsigned long)block;
484 block->ops = &indirect_block_ops;
485 initialize_block_counters(page, block, data, 0);
486}
487
488/*
489 * This silences a false, yet annoying gcc warning. I hate it when my editor
490 * jumps into bitops.h each time I recompile this file.
491 * TODO: Complain to gcc folks about this and upgrade compiler.
492 */
493static unsigned long fnb(const unsigned long *addr,
494 unsigned long size, unsigned long offset)
495{
496 return find_next_bit(addr, size, offset);
497}
498
499void move_page_to_btree(struct page *page)
500{
501 struct logfs_block *block = logfs_block(page);
502 struct super_block *sb = block->sb;
503 struct logfs_super *super = logfs_super(sb);
504 struct object_alias_item *item;
505 unsigned long pos;
506 __be64 *child;
507 int err;
508
509 if (super->s_flags & LOGFS_SB_FLAG_SHUTDOWN) {
510 block->ops->free_block(sb, block);
511 return;
512 }
513 log_blockmove("move_page_to_btree(%llx, %llx, %x)\n",
514 block->ino, block->bix, block->level);
515 super->s_flags |= LOGFS_SB_FLAG_OBJ_ALIAS;
516
517 for (pos = 0; ; pos++) {
518 pos = fnb(block->alias_map, LOGFS_BLOCK_FACTOR, pos);
519 if (pos >= LOGFS_BLOCK_FACTOR)
520 break;
521
522 item = mempool_alloc(super->s_alias_pool, GFP_NOFS);
523 BUG_ON(!item); /* mempool empty */
524 memset(item, 0, sizeof(*item));
525
526 child = kmap_atomic(page, KM_USER0);
527 item->val = child[pos];
528 kunmap_atomic(child, KM_USER0);
529 item->child_no = pos;
530 list_add(&item->list, &block->item_list);
531 }
532 block->page = NULL;
533 ClearPagePrivate(page);
534 page->private = 0;
535 block->ops = &btree_block_ops;
536 err = alias_tree_insert(block->sb, block->ino, block->bix, block->level,
537 block);
538 BUG_ON(err); /* mempool empty */
539 ClearPageUptodate(page);
540}
541
542static int __logfs_segment_read(struct inode *inode, void *buf,
543 u64 ofs, u64 bix, level_t level)
544{
545 struct super_block *sb = inode->i_sb;
546 void *compressor_buf = logfs_super(sb)->s_compressed_je;
547 struct logfs_object_header oh;
548 __be32 crc;
549 u16 len;
550 int err, block_len;
551
552 block_len = obj_len(sb, obj_type(inode, level));
553 err = read_obj_header(sb, ofs, &oh);
554 if (err)
555 goto out_err;
556
557 err = -EIO;
558 if (be64_to_cpu(oh.ino) != inode->i_ino
559 || check_pos(sb, be64_to_cpu(oh.bix), bix, level)) {
560 printk(KERN_ERR"LOGFS: (ino, bix) don't match at %llx: "
561 "expected (%lx, %llx), got (%llx, %llx)\n",
562 ofs, inode->i_ino, bix,
563 be64_to_cpu(oh.ino), be64_to_cpu(oh.bix));
564 goto out_err;
565 }
566
567 len = be16_to_cpu(oh.len);
568
569 switch (oh.compr) {
570 case COMPR_NONE:
571 err = wbuf_read(sb, ofs + LOGFS_OBJECT_HEADERSIZE, len, buf);
572 if (err)
573 goto out_err;
574 crc = logfs_crc32(buf, len, 0);
575 if (crc != oh.data_crc) {
576 printk(KERN_ERR"LOGFS: uncompressed data crc error at "
577 "%llx: expected %x, got %x\n", ofs,
578 be32_to_cpu(oh.data_crc),
579 be32_to_cpu(crc));
580 goto out_err;
581 }
582 break;
583 case COMPR_ZLIB:
584 mutex_lock(&logfs_super(sb)->s_journal_mutex);
585 err = wbuf_read(sb, ofs + LOGFS_OBJECT_HEADERSIZE, len,
586 compressor_buf);
587 if (err) {
588 mutex_unlock(&logfs_super(sb)->s_journal_mutex);
589 goto out_err;
590 }
591 crc = logfs_crc32(compressor_buf, len, 0);
592 if (crc != oh.data_crc) {
593 printk(KERN_ERR"LOGFS: compressed data crc error at "
594 "%llx: expected %x, got %x\n", ofs,
595 be32_to_cpu(oh.data_crc),
596 be32_to_cpu(crc));
597 mutex_unlock(&logfs_super(sb)->s_journal_mutex);
598 goto out_err;
599 }
600 err = logfs_uncompress(compressor_buf, buf, len, block_len);
601 mutex_unlock(&logfs_super(sb)->s_journal_mutex);
602 if (err) {
603 printk(KERN_ERR"LOGFS: uncompress error at %llx\n", ofs);
604 goto out_err;
605 }
606 break;
607 default:
608 LOGFS_BUG(sb);
609 err = -EIO;
610 goto out_err;
611 }
612 return 0;
613
614out_err:
615 logfs_set_ro(sb);
616 printk(KERN_ERR"LOGFS: device is read-only now\n");
617 LOGFS_BUG(sb);
618 return err;
619}
620
621/**
622 * logfs_segment_read - read data block from object store
623 * @inode: inode containing data
624 * @buf: data buffer
625 * @ofs: physical data offset
626 * @bix: block index
627 * @level: block level
628 *
629 * Returns 0 on success or a negative errno.
630 */
631int logfs_segment_read(struct inode *inode, struct page *page,
632 u64 ofs, u64 bix, level_t level)
633{
634 int err;
635 void *buf;
636
637 if (PageUptodate(page))
638 return 0;
639
640 ofs &= ~LOGFS_FULLY_POPULATED;
641
642 buf = kmap(page);
643 err = __logfs_segment_read(inode, buf, ofs, bix, level);
644 if (!err) {
645 move_btree_to_page(inode, page, buf);
646 SetPageUptodate(page);
647 }
648 kunmap(page);
649 log_segment("logfs_segment_read(%lx, %llx, %x) %llx (%d)\n",
650 inode->i_ino, bix, level, ofs, err);
651 return err;
652}
653
654int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
655{
656 struct super_block *sb = inode->i_sb;
657 struct logfs_super *super = logfs_super(sb);
658 struct logfs_object_header h;
659 u16 len;
660 int err;
661
662 super->s_flags |= LOGFS_SB_FLAG_DIRTY;
663 BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
664 BUG_ON(shadow->old_ofs & LOGFS_FULLY_POPULATED);
665 if (!shadow->old_ofs)
666 return 0;
667
668 log_segment("logfs_segment_delete(%llx, %llx, %x) %llx->%llx %x->%x\n",
669 shadow->ino, shadow->bix, shadow->gc_level,
670 shadow->old_ofs, shadow->new_ofs,
671 shadow->old_len, shadow->new_len);
672 err = read_obj_header(sb, shadow->old_ofs, &h);
673 LOGFS_BUG_ON(err, sb);
674 LOGFS_BUG_ON(be64_to_cpu(h.ino) != inode->i_ino, sb);
675 LOGFS_BUG_ON(check_pos(sb, shadow->bix, be64_to_cpu(h.bix),
676 shrink_level(shadow->gc_level)), sb);
677
678 if (shadow->gc_level == 0)
679 len = be16_to_cpu(h.len);
680 else
681 len = obj_len(sb, h.type);
682 shadow->old_len = len + sizeof(h);
683 return 0;
684}
685
686static void freeseg(struct super_block *sb, u32 segno)
687{
688 struct logfs_super *super = logfs_super(sb);
689 struct address_space *mapping = super->s_mapping_inode->i_mapping;
690 struct page *page;
691 u64 ofs, start, end;
692
693 start = dev_ofs(sb, segno, 0);
694 end = dev_ofs(sb, segno + 1, 0);
695 for (ofs = start; ofs < end; ofs += PAGE_SIZE) {
696 page = find_get_page(mapping, ofs >> PAGE_SHIFT);
697 if (!page)
698 continue;
699 ClearPagePrivate(page);
700 page_cache_release(page);
701 }
702}
703
704int logfs_open_area(struct logfs_area *area, size_t bytes)
705{
706 struct super_block *sb = area->a_sb;
707 struct logfs_super *super = logfs_super(sb);
708 int err, closed = 0;
709
710 if (area->a_is_open && area->a_used_bytes + bytes <= super->s_segsize)
711 return 0;
712
713 if (area->a_is_open) {
714 u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
715 u32 len = super->s_segsize - area->a_written_bytes;
716
717 log_gc("logfs_close_area(%x)\n", area->a_segno);
718 pad_wbuf(area, 1);
719 super->s_devops->writeseg(area->a_sb, ofs, len);
720 freeseg(sb, area->a_segno);
721 closed = 1;
722 }
723
724 area->a_used_bytes = 0;
725 area->a_written_bytes = 0;
726again:
727 area->a_ops->get_free_segment(area);
728 area->a_ops->get_erase_count(area);
729
730 log_gc("logfs_open_area(%x, %x)\n", area->a_segno, area->a_level);
731 err = area->a_ops->erase_segment(area);
732 if (err) {
733 printk(KERN_WARNING "LogFS: Error erasing segment %x\n",
734 area->a_segno);
735 logfs_mark_segment_bad(sb, area->a_segno);
736 goto again;
737 }
738 area->a_is_open = 1;
739 return closed;
740}
741
742void logfs_sync_area(struct logfs_area *area)
743{
744 struct super_block *sb = area->a_sb;
745 struct logfs_super *super = logfs_super(sb);
746 u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
747 u32 len = (area->a_used_bytes - area->a_written_bytes);
748
749 if (super->s_writesize)
750 len &= ~(super->s_writesize - 1);
751 if (len == 0)
752 return;
753 pad_wbuf(area, 0);
754 super->s_devops->writeseg(sb, ofs, len);
755 area->a_written_bytes += len;
756}
757
758void logfs_sync_segments(struct super_block *sb)
759{
760 struct logfs_super *super = logfs_super(sb);
761 int i;
762
763 for_each_area(i)
764 logfs_sync_area(super->s_area[i]);
765}
766
767/*
768 * Pick a free segment to be used for this area. Effectively takes a
769 * candidate from the free list (not really a candidate anymore).
770 */
771static void ostore_get_free_segment(struct logfs_area *area)
772{
773 struct super_block *sb = area->a_sb;
774 struct logfs_super *super = logfs_super(sb);
775
776 if (super->s_free_list.count == 0) {
777 printk(KERN_ERR"LOGFS: ran out of free segments\n");
778 LOGFS_BUG(sb);
779 }
780
781 area->a_segno = get_best_cand(sb, &super->s_free_list, NULL);
782}
783
784static void ostore_get_erase_count(struct logfs_area *area)
785{
786 struct logfs_segment_entry se;
787 u32 ec_level;
788
789 logfs_get_segment_entry(area->a_sb, area->a_segno, &se);
790 BUG_ON(se.ec_level == cpu_to_be32(BADSEG) ||
791 se.valid == cpu_to_be32(RESERVED));
792
793 ec_level = be32_to_cpu(se.ec_level);
794 area->a_erase_count = (ec_level >> 4) + 1;
795}
796
797static int ostore_erase_segment(struct logfs_area *area)
798{
799 struct super_block *sb = area->a_sb;
800 struct logfs_segment_header sh;
801 u64 ofs;
802 int err;
803
804 err = logfs_erase_segment(sb, area->a_segno, 0);
805 if (err)
806 return err;
807
808 sh.pad = 0;
809 sh.type = SEG_OSTORE;
810 sh.level = (__force u8)area->a_level;
811 sh.segno = cpu_to_be32(area->a_segno);
812 sh.ec = cpu_to_be32(area->a_erase_count);
813 sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
814 sh.crc = logfs_crc32(&sh, sizeof(sh), 4);
815
816 logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count,
817 area->a_level);
818
819 ofs = dev_ofs(sb, area->a_segno, 0);
820 area->a_used_bytes = sizeof(sh);
821 logfs_buf_write(area, ofs, &sh, sizeof(sh));
822 return 0;
823}
824
825static const struct logfs_area_ops ostore_area_ops = {
826 .get_free_segment = ostore_get_free_segment,
827 .get_erase_count = ostore_get_erase_count,
828 .erase_segment = ostore_erase_segment,
829};
830
831static void free_area(struct logfs_area *area)
832{
833 if (area)
834 freeseg(area->a_sb, area->a_segno);
835 kfree(area);
836}
837
838static struct logfs_area *alloc_area(struct super_block *sb)
839{
840 struct logfs_area *area;
841
842 area = kzalloc(sizeof(*area), GFP_KERNEL);
843 if (!area)
844 return NULL;
845
846 area->a_sb = sb;
847 return area;
848}
849
850static void map_invalidatepage(struct page *page, unsigned long l)
851{
852 BUG();
853}
854
855static int map_releasepage(struct page *page, gfp_t g)
856{
857 /* Don't release these pages */
858 return 0;
859}
860
861static const struct address_space_operations mapping_aops = {
862 .invalidatepage = map_invalidatepage,
863 .releasepage = map_releasepage,
864 .set_page_dirty = __set_page_dirty_nobuffers,
865};
866
867int logfs_init_mapping(struct super_block *sb)
868{
869 struct logfs_super *super = logfs_super(sb);
870 struct address_space *mapping;
871 struct inode *inode;
872
873 inode = logfs_new_meta_inode(sb, LOGFS_INO_MAPPING);
874 if (IS_ERR(inode))
875 return PTR_ERR(inode);
876 super->s_mapping_inode = inode;
877 mapping = inode->i_mapping;
878 mapping->a_ops = &mapping_aops;
879 /* Would it be possible to use __GFP_HIGHMEM as well? */
880 mapping_set_gfp_mask(mapping, GFP_NOFS);
881 return 0;
882}
883
884int logfs_init_areas(struct super_block *sb)
885{
886 struct logfs_super *super = logfs_super(sb);
887 int i = -1;
888
889 super->s_alias_pool = mempool_create_kmalloc_pool(600,
890 sizeof(struct object_alias_item));
891 if (!super->s_alias_pool)
892 return -ENOMEM;
893
894 super->s_journal_area = alloc_area(sb);
895 if (!super->s_journal_area)
896 goto err;
897
898 for_each_area(i) {
899 super->s_area[i] = alloc_area(sb);
900 if (!super->s_area[i])
901 goto err;
902 super->s_area[i]->a_level = GC_LEVEL(i);
903 super->s_area[i]->a_ops = &ostore_area_ops;
904 }
905 btree_init_mempool128(&super->s_object_alias_tree,
906 super->s_btree_pool);
907 return 0;
908
909err:
910 for (i--; i >= 0; i--)
911 free_area(super->s_area[i]);
912 free_area(super->s_journal_area);
913 mempool_destroy(super->s_alias_pool);
914 return -ENOMEM;
915}
916
917void logfs_cleanup_areas(struct super_block *sb)
918{
919 struct logfs_super *super = logfs_super(sb);
920 int i;
921
922 btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias);
923 for_each_area(i)
924 free_area(super->s_area[i]);
925 free_area(super->s_journal_area);
926 destroy_meta_inode(super->s_mapping_inode);
927}
diff --git a/fs/logfs/super.c b/fs/logfs/super.c
new file mode 100644
index 000000000000..c66beab78dee
--- /dev/null
+++ b/fs/logfs/super.c
@@ -0,0 +1,650 @@
1/*
2 * fs/logfs/super.c
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
7 *
8 * Generally contains mount/umount code and also serves as a dump area for
9 * any functions that don't fit elsewhere and neither justify a file of their
10 * own.
11 */
12#include "logfs.h"
13#include <linux/bio.h>
14#include <linux/mtd/mtd.h>
15#include <linux/statfs.h>
16#include <linux/buffer_head.h>
17
18static DEFINE_MUTEX(emergency_mutex);
19static struct page *emergency_page;
20
21struct page *emergency_read_begin(struct address_space *mapping, pgoff_t index)
22{
23 filler_t *filler = (filler_t *)mapping->a_ops->readpage;
24 struct page *page;
25 int err;
26
27 page = read_cache_page(mapping, index, filler, NULL);
28 if (page)
29 return page;
30
31 /* No more pages available, switch to emergency page */
32 printk(KERN_INFO"Logfs: Using emergency page\n");
33 mutex_lock(&emergency_mutex);
34 err = filler(NULL, emergency_page);
35 if (err) {
36 mutex_unlock(&emergency_mutex);
37 printk(KERN_EMERG"Logfs: Error reading emergency page\n");
38 return ERR_PTR(err);
39 }
40 return emergency_page;
41}
42
43void emergency_read_end(struct page *page)
44{
45 if (page == emergency_page)
46 mutex_unlock(&emergency_mutex);
47 else
48 page_cache_release(page);
49}
50
51static void dump_segfile(struct super_block *sb)
52{
53 struct logfs_super *super = logfs_super(sb);
54 struct logfs_segment_entry se;
55 u32 segno;
56
57 for (segno = 0; segno < super->s_no_segs; segno++) {
58 logfs_get_segment_entry(sb, segno, &se);
59 printk("%3x: %6x %8x", segno, be32_to_cpu(se.ec_level),
60 be32_to_cpu(se.valid));
61 if (++segno < super->s_no_segs) {
62 logfs_get_segment_entry(sb, segno, &se);
63 printk(" %6x %8x", be32_to_cpu(se.ec_level),
64 be32_to_cpu(se.valid));
65 }
66 if (++segno < super->s_no_segs) {
67 logfs_get_segment_entry(sb, segno, &se);
68 printk(" %6x %8x", be32_to_cpu(se.ec_level),
69 be32_to_cpu(se.valid));
70 }
71 if (++segno < super->s_no_segs) {
72 logfs_get_segment_entry(sb, segno, &se);
73 printk(" %6x %8x", be32_to_cpu(se.ec_level),
74 be32_to_cpu(se.valid));
75 }
76 printk("\n");
77 }
78}
79
80/*
81 * logfs_crash_dump - dump debug information to device
82 *
83 * The LogFS superblock only occupies part of a segment. This function will
84 * write as much debug information as it can gather into the spare space.
85 */
86void logfs_crash_dump(struct super_block *sb)
87{
88 dump_segfile(sb);
89}
90
91/*
92 * TODO: move to lib/string.c
93 */
94/**
95 * memchr_inv - Find a character in an area of memory.
96 * @s: The memory area
97 * @c: The byte to search for
98 * @n: The size of the area.
99 *
100 * returns the address of the first character other than @c, or %NULL
101 * if the whole buffer contains just @c.
102 */
103void *memchr_inv(const void *s, int c, size_t n)
104{
105 const unsigned char *p = s;
106 while (n-- != 0)
107 if ((unsigned char)c != *p++)
108 return (void *)(p - 1);
109
110 return NULL;
111}
112
113/*
114 * FIXME: There should be a reserve for root, similar to ext2.
115 */
116int logfs_statfs(struct dentry *dentry, struct kstatfs *stats)
117{
118 struct super_block *sb = dentry->d_sb;
119 struct logfs_super *super = logfs_super(sb);
120
121 stats->f_type = LOGFS_MAGIC_U32;
122 stats->f_bsize = sb->s_blocksize;
123 stats->f_blocks = super->s_size >> LOGFS_BLOCK_BITS >> 3;
124 stats->f_bfree = super->s_free_bytes >> sb->s_blocksize_bits;
125 stats->f_bavail = super->s_free_bytes >> sb->s_blocksize_bits;
126 stats->f_files = 0;
127 stats->f_ffree = 0;
128 stats->f_namelen = LOGFS_MAX_NAMELEN;
129 return 0;
130}
131
132static int logfs_sb_set(struct super_block *sb, void *_super)
133{
134 struct logfs_super *super = _super;
135
136 sb->s_fs_info = super;
137 sb->s_mtd = super->s_mtd;
138 sb->s_bdev = super->s_bdev;
139 return 0;
140}
141
142static int logfs_sb_test(struct super_block *sb, void *_super)
143{
144 struct logfs_super *super = _super;
145 struct mtd_info *mtd = super->s_mtd;
146
147 if (mtd && sb->s_mtd == mtd)
148 return 1;
149 if (super->s_bdev && sb->s_bdev == super->s_bdev)
150 return 1;
151 return 0;
152}
153
154static void set_segment_header(struct logfs_segment_header *sh, u8 type,
155 u8 level, u32 segno, u32 ec)
156{
157 sh->pad = 0;
158 sh->type = type;
159 sh->level = level;
160 sh->segno = cpu_to_be32(segno);
161 sh->ec = cpu_to_be32(ec);
162 sh->gec = cpu_to_be64(segno);
163 sh->crc = logfs_crc32(sh, LOGFS_SEGMENT_HEADERSIZE, 4);
164}
165
166static void logfs_write_ds(struct super_block *sb, struct logfs_disk_super *ds,
167 u32 segno, u32 ec)
168{
169 struct logfs_super *super = logfs_super(sb);
170 struct logfs_segment_header *sh = &ds->ds_sh;
171 int i;
172
173 memset(ds, 0, sizeof(*ds));
174 set_segment_header(sh, SEG_SUPER, 0, segno, ec);
175
176 ds->ds_ifile_levels = super->s_ifile_levels;
177 ds->ds_iblock_levels = super->s_iblock_levels;
178 ds->ds_data_levels = super->s_data_levels; /* XXX: Remove */
179 ds->ds_segment_shift = super->s_segshift;
180 ds->ds_block_shift = sb->s_blocksize_bits;
181 ds->ds_write_shift = super->s_writeshift;
182 ds->ds_filesystem_size = cpu_to_be64(super->s_size);
183 ds->ds_segment_size = cpu_to_be32(super->s_segsize);
184 ds->ds_bad_seg_reserve = cpu_to_be32(super->s_bad_seg_reserve);
185 ds->ds_feature_incompat = cpu_to_be64(super->s_feature_incompat);
186 ds->ds_feature_ro_compat= cpu_to_be64(super->s_feature_ro_compat);
187 ds->ds_feature_compat = cpu_to_be64(super->s_feature_compat);
188 ds->ds_feature_flags = cpu_to_be64(super->s_feature_flags);
189 ds->ds_root_reserve = cpu_to_be64(super->s_root_reserve);
190 ds->ds_speed_reserve = cpu_to_be64(super->s_speed_reserve);
191 journal_for_each(i)
192 ds->ds_journal_seg[i] = cpu_to_be32(super->s_journal_seg[i]);
193 ds->ds_magic = cpu_to_be64(LOGFS_MAGIC);
194 ds->ds_crc = logfs_crc32(ds, sizeof(*ds),
195 LOGFS_SEGMENT_HEADERSIZE + 12);
196}
197
198static int write_one_sb(struct super_block *sb,
199 struct page *(*find_sb)(struct super_block *sb, u64 *ofs))
200{
201 struct logfs_super *super = logfs_super(sb);
202 struct logfs_disk_super *ds;
203 struct logfs_segment_entry se;
204 struct page *page;
205 u64 ofs;
206 u32 ec, segno;
207 int err;
208
209 page = find_sb(sb, &ofs);
210 if (!page)
211 return -EIO;
212 ds = page_address(page);
213 segno = seg_no(sb, ofs);
214 logfs_get_segment_entry(sb, segno, &se);
215 ec = be32_to_cpu(se.ec_level) >> 4;
216 ec++;
217 logfs_set_segment_erased(sb, segno, ec, 0);
218 logfs_write_ds(sb, ds, segno, ec);
219 err = super->s_devops->write_sb(sb, page);
220 page_cache_release(page);
221 return err;
222}
223
224int logfs_write_sb(struct super_block *sb)
225{
226 struct logfs_super *super = logfs_super(sb);
227 int err;
228
229 /* First superblock */
230 err = write_one_sb(sb, super->s_devops->find_first_sb);
231 if (err)
232 return err;
233
234 /* Last superblock */
235 err = write_one_sb(sb, super->s_devops->find_last_sb);
236 if (err)
237 return err;
238 return 0;
239}
240
241static int ds_cmp(const void *ds0, const void *ds1)
242{
243 size_t len = sizeof(struct logfs_disk_super);
244
245 /* We know the segment headers differ, so ignore them */
246 len -= LOGFS_SEGMENT_HEADERSIZE;
247 ds0 += LOGFS_SEGMENT_HEADERSIZE;
248 ds1 += LOGFS_SEGMENT_HEADERSIZE;
249 return memcmp(ds0, ds1, len);
250}
251
252static int logfs_recover_sb(struct super_block *sb)
253{
254 struct logfs_super *super = logfs_super(sb);
255 struct logfs_disk_super _ds0, *ds0 = &_ds0;
256 struct logfs_disk_super _ds1, *ds1 = &_ds1;
257 int err, valid0, valid1;
258
259 /* read first superblock */
260 err = wbuf_read(sb, super->s_sb_ofs[0], sizeof(*ds0), ds0);
261 if (err)
262 return err;
263 /* read last superblock */
264 err = wbuf_read(sb, super->s_sb_ofs[1], sizeof(*ds1), ds1);
265 if (err)
266 return err;
267 valid0 = logfs_check_ds(ds0) == 0;
268 valid1 = logfs_check_ds(ds1) == 0;
269
270 if (!valid0 && valid1) {
271 printk(KERN_INFO"First superblock is invalid - fixing.\n");
272 return write_one_sb(sb, super->s_devops->find_first_sb);
273 }
274 if (valid0 && !valid1) {
275 printk(KERN_INFO"Last superblock is invalid - fixing.\n");
276 return write_one_sb(sb, super->s_devops->find_last_sb);
277 }
278 if (valid0 && valid1 && ds_cmp(ds0, ds1)) {
279 printk(KERN_INFO"Superblocks don't match - fixing.\n");
280 return write_one_sb(sb, super->s_devops->find_last_sb);
281 }
282 /* If neither is valid now, something's wrong. Didn't we properly
283 * check them before?!? */
284 BUG_ON(!valid0 && !valid1);
285 return 0;
286}
287
288static int logfs_make_writeable(struct super_block *sb)
289{
290 int err;
291
292 /* Repair any broken superblock copies */
293 err = logfs_recover_sb(sb);
294 if (err)
295 return err;
296
297 /* Check areas for trailing unaccounted data */
298 err = logfs_check_areas(sb);
299 if (err)
300 return err;
301
302 err = logfs_open_segfile(sb);
303 if (err)
304 return err;
305
306 /* Do one GC pass before any data gets dirtied */
307 logfs_gc_pass(sb);
308
309 /* after all initializations are done, replay the journal
310 * for rw-mounts, if necessary */
311 err = logfs_replay_journal(sb);
312 if (err)
313 return err;
314
315 return 0;
316}
317
318static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)
319{
320 struct logfs_super *super = logfs_super(sb);
321 struct inode *rootdir;
322 int err;
323
324 /* root dir */
325 rootdir = logfs_iget(sb, LOGFS_INO_ROOT);
326 if (IS_ERR(rootdir))
327 goto fail;
328
329 sb->s_root = d_alloc_root(rootdir);
330 if (!sb->s_root)
331 goto fail;
332
333 super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
334 if (!super->s_erase_page)
335 goto fail2;
336 memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE);
337
338 /* FIXME: check for read-only mounts */
339 err = logfs_make_writeable(sb);
340 if (err)
341 goto fail3;
342
343 log_super("LogFS: Finished mounting\n");
344 simple_set_mnt(mnt, sb);
345 return 0;
346
347fail3:
348 __free_page(super->s_erase_page);
349fail2:
350 iput(rootdir);
351fail:
352 iput(logfs_super(sb)->s_master_inode);
353 return -EIO;
354}
355
356int logfs_check_ds(struct logfs_disk_super *ds)
357{
358 struct logfs_segment_header *sh = &ds->ds_sh;
359
360 if (ds->ds_magic != cpu_to_be64(LOGFS_MAGIC))
361 return -EINVAL;
362 if (sh->crc != logfs_crc32(sh, LOGFS_SEGMENT_HEADERSIZE, 4))
363 return -EINVAL;
364 if (ds->ds_crc != logfs_crc32(ds, sizeof(*ds),
365 LOGFS_SEGMENT_HEADERSIZE + 12))
366 return -EINVAL;
367 return 0;
368}
369
370static struct page *find_super_block(struct super_block *sb)
371{
372 struct logfs_super *super = logfs_super(sb);
373 struct page *first, *last;
374
375 first = super->s_devops->find_first_sb(sb, &super->s_sb_ofs[0]);
376 if (!first || IS_ERR(first))
377 return NULL;
378 last = super->s_devops->find_last_sb(sb, &super->s_sb_ofs[1]);
379 if (!last || IS_ERR(first)) {
380 page_cache_release(first);
381 return NULL;
382 }
383
384 if (!logfs_check_ds(page_address(first))) {
385 page_cache_release(last);
386 return first;
387 }
388
389 /* First one didn't work, try the second superblock */
390 if (!logfs_check_ds(page_address(last))) {
391 page_cache_release(first);
392 return last;
393 }
394
395 /* Neither worked, sorry folks */
396 page_cache_release(first);
397 page_cache_release(last);
398 return NULL;
399}
400
401static int __logfs_read_sb(struct super_block *sb)
402{
403 struct logfs_super *super = logfs_super(sb);
404 struct page *page;
405 struct logfs_disk_super *ds;
406 int i;
407
408 page = find_super_block(sb);
409 if (!page)
410 return -EIO;
411
412 ds = page_address(page);
413 super->s_size = be64_to_cpu(ds->ds_filesystem_size);
414 super->s_root_reserve = be64_to_cpu(ds->ds_root_reserve);
415 super->s_speed_reserve = be64_to_cpu(ds->ds_speed_reserve);
416 super->s_bad_seg_reserve = be32_to_cpu(ds->ds_bad_seg_reserve);
417 super->s_segsize = 1 << ds->ds_segment_shift;
418 super->s_segmask = (1 << ds->ds_segment_shift) - 1;
419 super->s_segshift = ds->ds_segment_shift;
420 sb->s_blocksize = 1 << ds->ds_block_shift;
421 sb->s_blocksize_bits = ds->ds_block_shift;
422 super->s_writesize = 1 << ds->ds_write_shift;
423 super->s_writeshift = ds->ds_write_shift;
424 super->s_no_segs = super->s_size >> super->s_segshift;
425 super->s_no_blocks = super->s_segsize >> sb->s_blocksize_bits;
426 super->s_feature_incompat = be64_to_cpu(ds->ds_feature_incompat);
427 super->s_feature_ro_compat = be64_to_cpu(ds->ds_feature_ro_compat);
428 super->s_feature_compat = be64_to_cpu(ds->ds_feature_compat);
429 super->s_feature_flags = be64_to_cpu(ds->ds_feature_flags);
430
431 journal_for_each(i)
432 super->s_journal_seg[i] = be32_to_cpu(ds->ds_journal_seg[i]);
433
434 super->s_ifile_levels = ds->ds_ifile_levels;
435 super->s_iblock_levels = ds->ds_iblock_levels;
436 super->s_data_levels = ds->ds_data_levels;
437 super->s_total_levels = super->s_ifile_levels + super->s_iblock_levels
438 + super->s_data_levels;
439 page_cache_release(page);
440 return 0;
441}
442
443static int logfs_read_sb(struct super_block *sb, int read_only)
444{
445 struct logfs_super *super = logfs_super(sb);
446 int ret;
447
448 super->s_btree_pool = mempool_create(32, btree_alloc, btree_free, NULL);
449 if (!super->s_btree_pool)
450 return -ENOMEM;
451
452 btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool);
453 btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool);
454
455 ret = logfs_init_mapping(sb);
456 if (ret)
457 return ret;
458
459 ret = __logfs_read_sb(sb);
460 if (ret)
461 return ret;
462
463 if (super->s_feature_incompat & ~LOGFS_FEATURES_INCOMPAT)
464 return -EIO;
465 if ((super->s_feature_ro_compat & ~LOGFS_FEATURES_RO_COMPAT) &&
466 !read_only)
467 return -EIO;
468
469 mutex_init(&super->s_dirop_mutex);
470 mutex_init(&super->s_object_alias_mutex);
471 INIT_LIST_HEAD(&super->s_freeing_list);
472
473 ret = logfs_init_rw(sb);
474 if (ret)
475 return ret;
476
477 ret = logfs_init_areas(sb);
478 if (ret)
479 return ret;
480
481 ret = logfs_init_gc(sb);
482 if (ret)
483 return ret;
484
485 ret = logfs_init_journal(sb);
486 if (ret)
487 return ret;
488
489 return 0;
490}
491
492static void logfs_kill_sb(struct super_block *sb)
493{
494 struct logfs_super *super = logfs_super(sb);
495
496 log_super("LogFS: Start unmounting\n");
497 /* Alias entries slow down mount, so evict as many as possible */
498 sync_filesystem(sb);
499 logfs_write_anchor(sb);
500
501 /*
502 * From this point on alias entries are simply dropped - and any
503 * writes to the object store are considered bugs.
504 */
505 super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN;
506 log_super("LogFS: Now in shutdown\n");
507 generic_shutdown_super(sb);
508
509 BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes);
510
511 logfs_cleanup_gc(sb);
512 logfs_cleanup_journal(sb);
513 logfs_cleanup_areas(sb);
514 logfs_cleanup_rw(sb);
515 if (super->s_erase_page)
516 __free_page(super->s_erase_page);
517 super->s_devops->put_device(sb);
518 mempool_destroy(super->s_btree_pool);
519 mempool_destroy(super->s_alias_pool);
520 kfree(super);
521 log_super("LogFS: Finished unmounting\n");
522}
523
524int logfs_get_sb_device(struct file_system_type *type, int flags,
525 struct mtd_info *mtd, struct block_device *bdev,
526 const struct logfs_device_ops *devops, struct vfsmount *mnt)
527{
528 struct logfs_super *super;
529 struct super_block *sb;
530 int err = -ENOMEM;
531 static int mount_count;
532
533 log_super("LogFS: Start mount %x\n", mount_count++);
534 super = kzalloc(sizeof(*super), GFP_KERNEL);
535 if (!super)
536 goto err0;
537
538 super->s_mtd = mtd;
539 super->s_bdev = bdev;
540 err = -EINVAL;
541 sb = sget(type, logfs_sb_test, logfs_sb_set, super);
542 if (IS_ERR(sb))
543 goto err0;
544
545 if (sb->s_root) {
546 /* Device is already in use */
547 err = 0;
548 simple_set_mnt(mnt, sb);
549 goto err0;
550 }
551
552 super->s_devops = devops;
553
554 /*
555 * sb->s_maxbytes is limited to 8TB. On 32bit systems, the page cache
556 * only covers 16TB and the upper 8TB are used for indirect blocks.
557 * On 64bit system we could bump up the limit, but that would make
558 * the filesystem incompatible with 32bit systems.
559 */
560 sb->s_maxbytes = (1ull << 43) - 1;
561 sb->s_op = &logfs_super_operations;
562 sb->s_flags = flags | MS_NOATIME;
563
564 err = logfs_read_sb(sb, sb->s_flags & MS_RDONLY);
565 if (err)
566 goto err1;
567
568 sb->s_flags |= MS_ACTIVE;
569 err = logfs_get_sb_final(sb, mnt);
570 if (err)
571 goto err1;
572 return 0;
573
574err1:
575 up_write(&sb->s_umount);
576 deactivate_super(sb);
577 return err;
578err0:
579 kfree(super);
580 //devops->put_device(sb);
581 return err;
582}
583
584static int logfs_get_sb(struct file_system_type *type, int flags,
585 const char *devname, void *data, struct vfsmount *mnt)
586{
587 ulong mtdnr;
588
589 if (!devname)
590 return logfs_get_sb_bdev(type, flags, devname, mnt);
591 if (strncmp(devname, "mtd", 3))
592 return logfs_get_sb_bdev(type, flags, devname, mnt);
593
594 {
595 char *garbage;
596 mtdnr = simple_strtoul(devname+3, &garbage, 0);
597 if (*garbage)
598 return -EINVAL;
599 }
600
601 return logfs_get_sb_mtd(type, flags, mtdnr, mnt);
602}
603
604static struct file_system_type logfs_fs_type = {
605 .owner = THIS_MODULE,
606 .name = "logfs",
607 .get_sb = logfs_get_sb,
608 .kill_sb = logfs_kill_sb,
609 .fs_flags = FS_REQUIRES_DEV,
610
611};
612
613static int __init logfs_init(void)
614{
615 int ret;
616
617 emergency_page = alloc_pages(GFP_KERNEL, 0);
618 if (!emergency_page)
619 return -ENOMEM;
620
621 ret = logfs_compr_init();
622 if (ret)
623 goto out1;
624
625 ret = logfs_init_inode_cache();
626 if (ret)
627 goto out2;
628
629 return register_filesystem(&logfs_fs_type);
630out2:
631 logfs_compr_exit();
632out1:
633 __free_pages(emergency_page, 0);
634 return ret;
635}
636
637static void __exit logfs_exit(void)
638{
639 unregister_filesystem(&logfs_fs_type);
640 logfs_destroy_inode_cache();
641 logfs_compr_exit();
642 __free_pages(emergency_page, 0);
643}
644
645module_init(logfs_init);
646module_exit(logfs_exit);
647
648MODULE_LICENSE("GPL v2");
649MODULE_AUTHOR("Joern Engel <joern@logfs.org>");
650MODULE_DESCRIPTION("scalable flash filesystem");
diff --git a/fs/namei.c b/fs/namei.c
index 3d9d2f965f84..48e60a187325 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1656,7 +1656,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
1656 if (path->dentry->d_inode->i_op->follow_link) 1656 if (path->dentry->d_inode->i_op->follow_link)
1657 return NULL; 1657 return NULL;
1658 error = -ENOTDIR; 1658 error = -ENOTDIR;
1659 if (*want_dir & !path->dentry->d_inode->i_op->lookup) 1659 if (*want_dir && !path->dentry->d_inode->i_op->lookup)
1660 goto exit_dput; 1660 goto exit_dput;
1661 path_to_nameidata(path, nd); 1661 path_to_nameidata(path, nd);
1662 audit_inode(pathname, nd->path.dentry); 1662 audit_inode(pathname, nd->path.dentry);
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 73ab220354df..36dfdae95123 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -118,7 +118,6 @@ nfs4_callback_up(struct svc_serv *serv)
118 dprintk("NFS: Callback listener port = %u (af %u)\n", 118 dprintk("NFS: Callback listener port = %u (af %u)\n",
119 nfs_callback_tcpport, PF_INET); 119 nfs_callback_tcpport, PF_INET);
120 120
121#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
122 ret = svc_create_xprt(serv, "tcp", PF_INET6, 121 ret = svc_create_xprt(serv, "tcp", PF_INET6,
123 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); 122 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
124 if (ret > 0) { 123 if (ret > 0) {
@@ -129,7 +128,6 @@ nfs4_callback_up(struct svc_serv *serv)
129 ret = 0; 128 ret = 0;
130 else 129 else
131 goto out_err; 130 goto out_err;
132#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
133 131
134 return svc_prepare_thread(serv, &serv->sv_pools[0]); 132 return svc_prepare_thread(serv, &serv->sv_pools[0]);
135 133
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index c6eed2a3b093..4bc22c763de7 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -525,6 +525,8 @@ static struct rpc_cred *callback_cred;
525 525
526int set_callback_cred(void) 526int set_callback_cred(void)
527{ 527{
528 if (callback_cred)
529 return 0;
528 callback_cred = rpc_lookup_machine_cred(); 530 callback_cred = rpc_lookup_machine_cred();
529 if (!callback_cred) 531 if (!callback_cred)
530 return -ENOMEM; 532 return -ENOMEM;
@@ -542,7 +544,8 @@ void do_probe_callback(struct nfs4_client *clp)
542 }; 544 };
543 int status; 545 int status;
544 546
545 status = rpc_call_async(cb->cb_client, &msg, RPC_TASK_SOFT, 547 status = rpc_call_async(cb->cb_client, &msg,
548 RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
546 &nfsd4_cb_probe_ops, (void *)clp); 549 &nfsd4_cb_probe_ops, (void *)clp);
547 if (status) { 550 if (status) {
548 warn_no_callback_path(clp, status); 551 warn_no_callback_path(clp, status);
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 5a754f7b71ed..98fb98e330b4 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -119,9 +119,7 @@ out_no_tfm:
119static void 119static void
120nfsd4_sync_rec_dir(void) 120nfsd4_sync_rec_dir(void)
121{ 121{
122 mutex_lock(&rec_dir.dentry->d_inode->i_mutex); 122 vfs_fsync(NULL, rec_dir.dentry, 0);
123 nfsd_sync_dir(rec_dir.dentry);
124 mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
125} 123}
126 124
127int 125int
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index f19ed866c95f..c97fddbd17db 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1998,7 +1998,9 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
1998{ 1998{
1999 if (share_access & NFS4_SHARE_ACCESS_WRITE) { 1999 if (share_access & NFS4_SHARE_ACCESS_WRITE) {
2000 drop_file_write_access(filp); 2000 drop_file_write_access(filp);
2001 spin_lock(&filp->f_lock);
2001 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; 2002 filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE;
2003 spin_unlock(&filp->f_lock);
2002 } 2004 }
2003} 2005}
2004 2006
@@ -2480,8 +2482,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
2480 } 2482 }
2481 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t)); 2483 memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
2482 2484
2483 if (nfsd4_has_session(&resp->cstate)) 2485 if (nfsd4_has_session(&resp->cstate)) {
2484 open->op_stateowner->so_confirmed = 1; 2486 open->op_stateowner->so_confirmed = 1;
2487 nfsd4_create_clid_dir(open->op_stateowner->so_client);
2488 }
2485 2489
2486 /* 2490 /*
2487 * Attempt to hand out a delegation. No error return, because the 2491 * Attempt to hand out a delegation. No error return, because the
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bbf72d8f9fc0..78c7e24e5129 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1434,7 +1434,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1434 } 1434 }
1435 op->opnum = ntohl(*argp->p++); 1435 op->opnum = ntohl(*argp->p++);
1436 1436
1437 if (op->opnum >= OP_ACCESS && op->opnum < ops->nops) 1437 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
1438 op->status = ops->decoders[op->opnum](argp, &op->u); 1438 op->status = ops->decoders[op->opnum](argp, &op->u);
1439 else { 1439 else {
1440 op->opnum = OP_ILLEGAL; 1440 op->opnum = OP_ILLEGAL;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 2604c3e70ea5..0f0e77f2012f 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -988,6 +988,7 @@ static ssize_t __write_ports_delfd(char *buf)
988static ssize_t __write_ports_addxprt(char *buf) 988static ssize_t __write_ports_addxprt(char *buf)
989{ 989{
990 char transport[16]; 990 char transport[16];
991 struct svc_xprt *xprt;
991 int port, err; 992 int port, err;
992 993
993 if (sscanf(buf, "%15s %4u", transport, &port) != 2) 994 if (sscanf(buf, "%15s %4u", transport, &port) != 2)
@@ -1002,13 +1003,24 @@ static ssize_t __write_ports_addxprt(char *buf)
1002 1003
1003 err = svc_create_xprt(nfsd_serv, transport, 1004 err = svc_create_xprt(nfsd_serv, transport,
1004 PF_INET, port, SVC_SOCK_ANONYMOUS); 1005 PF_INET, port, SVC_SOCK_ANONYMOUS);
1005 if (err < 0) { 1006 if (err < 0)
1006 /* Give a reasonable perror msg for bad transport string */ 1007 goto out_err;
1007 if (err == -ENOENT) 1008
1008 err = -EPROTONOSUPPORT; 1009 err = svc_create_xprt(nfsd_serv, transport,
1009 return err; 1010 PF_INET6, port, SVC_SOCK_ANONYMOUS);
1010 } 1011 if (err < 0 && err != -EAFNOSUPPORT)
1012 goto out_close;
1011 return 0; 1013 return 0;
1014out_close:
1015 xprt = svc_find_xprt(nfsd_serv, transport, PF_INET, port);
1016 if (xprt != NULL) {
1017 svc_close_xprt(xprt);
1018 svc_xprt_put(xprt);
1019 }
1020out_err:
1021 /* Decrease the count, but don't shut down the service */
1022 nfsd_serv->sv_nrthreads--;
1023 return err;
1012} 1024}
1013 1025
1014/* 1026/*
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 8eca17df4f63..a11b0e8678ee 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -26,6 +26,8 @@
26#include <linux/jhash.h> 26#include <linux/jhash.h>
27#include <linux/ima.h> 27#include <linux/ima.h>
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <linux/exportfs.h>
30#include <linux/writeback.h>
29 31
30#ifdef CONFIG_NFSD_V3 32#ifdef CONFIG_NFSD_V3
31#include "xdr3.h" 33#include "xdr3.h"
@@ -270,6 +272,32 @@ out:
270 return err; 272 return err;
271} 273}
272 274
275/*
276 * Commit metadata changes to stable storage.
277 */
278static int
279commit_metadata(struct svc_fh *fhp)
280{
281 struct inode *inode = fhp->fh_dentry->d_inode;
282 const struct export_operations *export_ops = inode->i_sb->s_export_op;
283 int error = 0;
284
285 if (!EX_ISSYNC(fhp->fh_export))
286 return 0;
287
288 if (export_ops->commit_metadata) {
289 error = export_ops->commit_metadata(inode);
290 } else {
291 struct writeback_control wbc = {
292 .sync_mode = WB_SYNC_ALL,
293 .nr_to_write = 0, /* metadata only */
294 };
295
296 error = sync_inode(inode, &wbc);
297 }
298
299 return error;
300}
273 301
274/* 302/*
275 * Set various file attributes. 303 * Set various file attributes.
@@ -767,43 +795,6 @@ nfsd_close(struct file *filp)
767} 795}
768 796
769/* 797/*
770 * Sync a file
771 * As this calls fsync (not fdatasync) there is no need for a write_inode
772 * after it.
773 */
774static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
775 const struct file_operations *fop)
776{
777 struct inode *inode = dp->d_inode;
778 int (*fsync) (struct file *, struct dentry *, int);
779 int err;
780
781 err = filemap_write_and_wait(inode->i_mapping);
782 if (err == 0 && fop && (fsync = fop->fsync))
783 err = fsync(filp, dp, 0);
784 return err;
785}
786
787static int
788nfsd_sync(struct file *filp)
789{
790 int err;
791 struct inode *inode = filp->f_path.dentry->d_inode;
792 dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name);
793 mutex_lock(&inode->i_mutex);
794 err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op);
795 mutex_unlock(&inode->i_mutex);
796
797 return err;
798}
799
800int
801nfsd_sync_dir(struct dentry *dp)
802{
803 return nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
804}
805
806/*
807 * Obtain the readahead parameters for the file 798 * Obtain the readahead parameters for the file
808 * specified by (dev, ino). 799 * specified by (dev, ino).
809 */ 800 */
@@ -1006,7 +997,7 @@ static int wait_for_concurrent_writes(struct file *file)
1006 997
1007 if (inode->i_state & I_DIRTY) { 998 if (inode->i_state & I_DIRTY) {
1008 dprintk("nfsd: write sync %d\n", task_pid_nr(current)); 999 dprintk("nfsd: write sync %d\n", task_pid_nr(current));
1009 err = nfsd_sync(file); 1000 err = vfs_fsync(file, file->f_path.dentry, 0);
1010 } 1001 }
1011 last_ino = inode->i_ino; 1002 last_ino = inode->i_ino;
1012 last_dev = inode->i_sb->s_dev; 1003 last_dev = inode->i_sb->s_dev;
@@ -1154,8 +1145,9 @@ out:
1154#ifdef CONFIG_NFSD_V3 1145#ifdef CONFIG_NFSD_V3
1155/* 1146/*
1156 * Commit all pending writes to stable storage. 1147 * Commit all pending writes to stable storage.
1157 * Strictly speaking, we could sync just the indicated file region here, 1148 *
1158 * but there's currently no way we can ask the VFS to do so. 1149 * Note: we only guarantee that data that lies within the range specified
1150 * by the 'offset' and 'count' parameters will be synced.
1159 * 1151 *
1160 * Unfortunately we cannot lock the file to make sure we return full WCC 1152 * Unfortunately we cannot lock the file to make sure we return full WCC
1161 * data to the client, as locking happens lower down in the filesystem. 1153 * data to the client, as locking happens lower down in the filesystem.
@@ -1165,23 +1157,32 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1165 loff_t offset, unsigned long count) 1157 loff_t offset, unsigned long count)
1166{ 1158{
1167 struct file *file; 1159 struct file *file;
1168 __be32 err; 1160 loff_t end = LLONG_MAX;
1161 __be32 err = nfserr_inval;
1169 1162
1170 if ((u64)count > ~(u64)offset) 1163 if (offset < 0)
1171 return nfserr_inval; 1164 goto out;
1165 if (count != 0) {
1166 end = offset + (loff_t)count - 1;
1167 if (end < offset)
1168 goto out;
1169 }
1172 1170
1173 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file); 1171 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
1174 if (err) 1172 if (err)
1175 return err; 1173 goto out;
1176 if (EX_ISSYNC(fhp->fh_export)) { 1174 if (EX_ISSYNC(fhp->fh_export)) {
1177 if (file->f_op && file->f_op->fsync) { 1175 int err2 = vfs_fsync_range(file, file->f_path.dentry,
1178 err = nfserrno(nfsd_sync(file)); 1176 offset, end, 0);
1179 } else { 1177
1178 if (err2 != -EINVAL)
1179 err = nfserrno(err2);
1180 else
1180 err = nfserr_notsupp; 1181 err = nfserr_notsupp;
1181 }
1182 } 1182 }
1183 1183
1184 nfsd_close(file); 1184 nfsd_close(file);
1185out:
1185 return err; 1186 return err;
1186} 1187}
1187#endif /* CONFIG_NFSD_V3 */ 1188#endif /* CONFIG_NFSD_V3 */
@@ -1334,12 +1335,14 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1334 goto out_nfserr; 1335 goto out_nfserr;
1335 } 1336 }
1336 1337
1337 if (EX_ISSYNC(fhp->fh_export)) { 1338 err = nfsd_create_setattr(rqstp, resfhp, iap);
1338 err = nfserrno(nfsd_sync_dir(dentry));
1339 write_inode_now(dchild->d_inode, 1);
1340 }
1341 1339
1342 err2 = nfsd_create_setattr(rqstp, resfhp, iap); 1340 /*
1341 * nfsd_setattr already committed the child. Transactional filesystems
1342 * had a chance to commit changes for both parent and child
1343 * simultaneously making the following commit_metadata a noop.
1344 */
1345 err2 = nfserrno(commit_metadata(fhp));
1343 if (err2) 1346 if (err2)
1344 err = err2; 1347 err = err2;
1345 mnt_drop_write(fhp->fh_export->ex_path.mnt); 1348 mnt_drop_write(fhp->fh_export->ex_path.mnt);
@@ -1371,7 +1374,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1371 struct dentry *dentry, *dchild = NULL; 1374 struct dentry *dentry, *dchild = NULL;
1372 struct inode *dirp; 1375 struct inode *dirp;
1373 __be32 err; 1376 __be32 err;
1374 __be32 err2;
1375 int host_err; 1377 int host_err;
1376 __u32 v_mtime=0, v_atime=0; 1378 __u32 v_mtime=0, v_atime=0;
1377 1379
@@ -1466,11 +1468,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1466 if (created) 1468 if (created)
1467 *created = 1; 1469 *created = 1;
1468 1470
1469 if (EX_ISSYNC(fhp->fh_export)) {
1470 err = nfserrno(nfsd_sync_dir(dentry));
1471 /* setattr will sync the child (or not) */
1472 }
1473
1474 nfsd_check_ignore_resizing(iap); 1471 nfsd_check_ignore_resizing(iap);
1475 1472
1476 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1473 if (createmode == NFS3_CREATE_EXCLUSIVE) {
@@ -1485,9 +1482,13 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1485 } 1482 }
1486 1483
1487 set_attr: 1484 set_attr:
1488 err2 = nfsd_create_setattr(rqstp, resfhp, iap); 1485 err = nfsd_create_setattr(rqstp, resfhp, iap);
1489 if (err2) 1486
1490 err = err2; 1487 /*
1488 * nfsd_setattr already committed the child (and possibly also the parent).
1489 */
1490 if (!err)
1491 err = nfserrno(commit_metadata(fhp));
1491 1492
1492 mnt_drop_write(fhp->fh_export->ex_path.mnt); 1493 mnt_drop_write(fhp->fh_export->ex_path.mnt);
1493 /* 1494 /*
@@ -1602,12 +1603,9 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1602 } 1603 }
1603 } else 1604 } else
1604 host_err = vfs_symlink(dentry->d_inode, dnew, path); 1605 host_err = vfs_symlink(dentry->d_inode, dnew, path);
1605
1606 if (!host_err) {
1607 if (EX_ISSYNC(fhp->fh_export))
1608 host_err = nfsd_sync_dir(dentry);
1609 }
1610 err = nfserrno(host_err); 1606 err = nfserrno(host_err);
1607 if (!err)
1608 err = nfserrno(commit_metadata(fhp));
1611 fh_unlock(fhp); 1609 fh_unlock(fhp);
1612 1610
1613 mnt_drop_write(fhp->fh_export->ex_path.mnt); 1611 mnt_drop_write(fhp->fh_export->ex_path.mnt);
@@ -1669,11 +1667,9 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1669 } 1667 }
1670 host_err = vfs_link(dold, dirp, dnew); 1668 host_err = vfs_link(dold, dirp, dnew);
1671 if (!host_err) { 1669 if (!host_err) {
1672 if (EX_ISSYNC(ffhp->fh_export)) { 1670 err = nfserrno(commit_metadata(ffhp));
1673 err = nfserrno(nfsd_sync_dir(ddir)); 1671 if (!err)
1674 write_inode_now(dest, 1); 1672 err = nfserrno(commit_metadata(tfhp));
1675 }
1676 err = 0;
1677 } else { 1673 } else {
1678 if (host_err == -EXDEV && rqstp->rq_vers == 2) 1674 if (host_err == -EXDEV && rqstp->rq_vers == 2)
1679 err = nfserr_acces; 1675 err = nfserr_acces;
@@ -1769,10 +1765,10 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1769 goto out_dput_new; 1765 goto out_dput_new;
1770 1766
1771 host_err = vfs_rename(fdir, odentry, tdir, ndentry); 1767 host_err = vfs_rename(fdir, odentry, tdir, ndentry);
1772 if (!host_err && EX_ISSYNC(tfhp->fh_export)) { 1768 if (!host_err) {
1773 host_err = nfsd_sync_dir(tdentry); 1769 host_err = commit_metadata(tfhp);
1774 if (!host_err) 1770 if (!host_err)
1775 host_err = nfsd_sync_dir(fdentry); 1771 host_err = commit_metadata(ffhp);
1776 } 1772 }
1777 1773
1778 mnt_drop_write(ffhp->fh_export->ex_path.mnt); 1774 mnt_drop_write(ffhp->fh_export->ex_path.mnt);
@@ -1853,12 +1849,9 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
1853 1849
1854 dput(rdentry); 1850 dput(rdentry);
1855 1851
1856 if (host_err) 1852 if (!host_err)
1857 goto out_drop; 1853 host_err = commit_metadata(fhp);
1858 if (EX_ISSYNC(fhp->fh_export))
1859 host_err = nfsd_sync_dir(dentry);
1860 1854
1861out_drop:
1862 mnt_drop_write(fhp->fh_export->ex_path.mnt); 1855 mnt_drop_write(fhp->fh_export->ex_path.mnt);
1863out_nfserr: 1856out_nfserr:
1864 err = nfserrno(host_err); 1857 err = nfserrno(host_err);
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 21f9e71223ca..a6467f3d262e 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -457,7 +457,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
457 break; 457 break;
458 } 458 }
459 dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data; 459 dchunk = (struct ocfs2_local_disk_chunk *)hbh->b_data;
460 for_each_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) { 460 for_each_set_bit(bit, rchunk->rc_bitmap, ol_chunk_entries(sb)) {
461 qbh = NULL; 461 qbh = NULL;
462 status = ocfs2_read_quota_block(lqinode, 462 status = ocfs2_read_quota_block(lqinode,
463 ol_dqblk_block(sb, chunk, bit), 463 ol_dqblk_block(sb, chunk, bit),
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 18e20feee251..aa8637b81028 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -273,7 +273,7 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p)
273 rcu_read_lock(); /* FIXME: is this correct? */ 273 rcu_read_lock(); /* FIXME: is this correct? */
274 qsize = atomic_read(&__task_cred(p)->user->sigpending); 274 qsize = atomic_read(&__task_cred(p)->user->sigpending);
275 rcu_read_unlock(); 275 rcu_read_unlock();
276 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; 276 qlim = task_rlimit(p, RLIMIT_SIGPENDING);
277 unlock_task_sighand(p, &flags); 277 unlock_task_sighand(p, &flags);
278 } 278 }
279 279
@@ -420,7 +420,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
420 cutime = sig->cutime; 420 cutime = sig->cutime;
421 cstime = sig->cstime; 421 cstime = sig->cstime;
422 cgtime = sig->cgtime; 422 cgtime = sig->cgtime;
423 rsslim = sig->rlim[RLIMIT_RSS].rlim_cur; 423 rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
424 424
425 /* add up live thread stats at the group level */ 425 /* add up live thread stats at the group level */
426 if (whole) { 426 if (whole) {
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 9580abeadeb3..08f4d71dacd7 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -291,19 +291,17 @@ static const struct inode_operations proc_file_inode_operations = {
291 * returns the struct proc_dir_entry for "/proc/tty/driver", and 291 * returns the struct proc_dir_entry for "/proc/tty/driver", and
292 * returns "serial" in residual. 292 * returns "serial" in residual.
293 */ 293 */
294static int xlate_proc_name(const char *name, 294static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
295 struct proc_dir_entry **ret, const char **residual) 295 const char **residual)
296{ 296{
297 const char *cp = name, *next; 297 const char *cp = name, *next;
298 struct proc_dir_entry *de; 298 struct proc_dir_entry *de;
299 int len; 299 int len;
300 int rtn = 0;
301 300
302 de = *ret; 301 de = *ret;
303 if (!de) 302 if (!de)
304 de = &proc_root; 303 de = &proc_root;
305 304
306 spin_lock(&proc_subdir_lock);
307 while (1) { 305 while (1) {
308 next = strchr(cp, '/'); 306 next = strchr(cp, '/');
309 if (!next) 307 if (!next)
@@ -315,16 +313,25 @@ static int xlate_proc_name(const char *name,
315 break; 313 break;
316 } 314 }
317 if (!de) { 315 if (!de) {
318 rtn = -ENOENT; 316 WARN(1, "name '%s'\n", name);
319 goto out; 317 return -ENOENT;
320 } 318 }
321 cp += len + 1; 319 cp += len + 1;
322 } 320 }
323 *residual = cp; 321 *residual = cp;
324 *ret = de; 322 *ret = de;
325out: 323 return 0;
324}
325
326static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
327 const char **residual)
328{
329 int rv;
330
331 spin_lock(&proc_subdir_lock);
332 rv = __xlate_proc_name(name, ret, residual);
326 spin_unlock(&proc_subdir_lock); 333 spin_unlock(&proc_subdir_lock);
327 return rtn; 334 return rv;
328} 335}
329 336
330static DEFINE_IDA(proc_inum_ida); 337static DEFINE_IDA(proc_inum_ida);
@@ -797,11 +804,13 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
797 const char *fn = name; 804 const char *fn = name;
798 int len; 805 int len;
799 806
800 if (xlate_proc_name(name, &parent, &fn) != 0) 807 spin_lock(&proc_subdir_lock);
808 if (__xlate_proc_name(name, &parent, &fn) != 0) {
809 spin_unlock(&proc_subdir_lock);
801 return; 810 return;
811 }
802 len = strlen(fn); 812 len = strlen(fn);
803 813
804 spin_lock(&proc_subdir_lock);
805 for (p = &parent->subdir; *p; p=&(*p)->next ) { 814 for (p = &parent->subdir; *p; p=&(*p)->next ) {
806 if (proc_match(len, fn, *p)) { 815 if (proc_match(len, fn, *p)) {
807 de = *p; 816 de = *p;
@@ -811,8 +820,10 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
811 } 820 }
812 } 821 }
813 spin_unlock(&proc_subdir_lock); 822 spin_unlock(&proc_subdir_lock);
814 if (!de) 823 if (!de) {
824 WARN(1, "name '%s'\n", name);
815 return; 825 return;
826 }
816 827
817 spin_lock(&de->pde_unload_lock); 828 spin_lock(&de->pde_unload_lock);
818 /* 829 /*
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index f277c4a111cb..183f8ff5f400 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -16,7 +16,7 @@
16 16
17void task_mem(struct seq_file *m, struct mm_struct *mm) 17void task_mem(struct seq_file *m, struct mm_struct *mm)
18{ 18{
19 unsigned long data, text, lib; 19 unsigned long data, text, lib, swap;
20 unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; 20 unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
21 21
22 /* 22 /*
@@ -36,6 +36,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
36 data = mm->total_vm - mm->shared_vm - mm->stack_vm; 36 data = mm->total_vm - mm->shared_vm - mm->stack_vm;
37 text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10; 37 text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
38 lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text; 38 lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
39 swap = get_mm_counter(mm, MM_SWAPENTS);
39 seq_printf(m, 40 seq_printf(m,
40 "VmPeak:\t%8lu kB\n" 41 "VmPeak:\t%8lu kB\n"
41 "VmSize:\t%8lu kB\n" 42 "VmSize:\t%8lu kB\n"
@@ -46,7 +47,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
46 "VmStk:\t%8lu kB\n" 47 "VmStk:\t%8lu kB\n"
47 "VmExe:\t%8lu kB\n" 48 "VmExe:\t%8lu kB\n"
48 "VmLib:\t%8lu kB\n" 49 "VmLib:\t%8lu kB\n"
49 "VmPTE:\t%8lu kB\n", 50 "VmPTE:\t%8lu kB\n"
51 "VmSwap:\t%8lu kB\n",
50 hiwater_vm << (PAGE_SHIFT-10), 52 hiwater_vm << (PAGE_SHIFT-10),
51 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), 53 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
52 mm->locked_vm << (PAGE_SHIFT-10), 54 mm->locked_vm << (PAGE_SHIFT-10),
@@ -54,7 +56,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
54 total_rss << (PAGE_SHIFT-10), 56 total_rss << (PAGE_SHIFT-10),
55 data << (PAGE_SHIFT-10), 57 data << (PAGE_SHIFT-10),
56 mm->stack_vm << (PAGE_SHIFT-10), text, lib, 58 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
57 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); 59 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
60 swap << (PAGE_SHIFT-10));
58} 61}
59 62
60unsigned long task_vsize(struct mm_struct *mm) 63unsigned long task_vsize(struct mm_struct *mm)
@@ -65,11 +68,11 @@ unsigned long task_vsize(struct mm_struct *mm)
65int task_statm(struct mm_struct *mm, int *shared, int *text, 68int task_statm(struct mm_struct *mm, int *shared, int *text,
66 int *data, int *resident) 69 int *data, int *resident)
67{ 70{
68 *shared = get_mm_counter(mm, file_rss); 71 *shared = get_mm_counter(mm, MM_FILEPAGES);
69 *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) 72 *text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK))
70 >> PAGE_SHIFT; 73 >> PAGE_SHIFT;
71 *data = mm->total_vm - mm->shared_vm; 74 *data = mm->total_vm - mm->shared_vm;
72 *resident = *shared + get_mm_counter(mm, anon_rss); 75 *resident = *shared + get_mm_counter(mm, MM_ANONPAGES);
73 return mm->total_vm; 76 return mm->total_vm;
74} 77}
75 78
diff --git a/fs/select.c b/fs/select.c
index fd38ce2e32e3..73715e90030f 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -821,7 +821,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
821 struct poll_list *walk = head; 821 struct poll_list *walk = head;
822 unsigned long todo = nfds; 822 unsigned long todo = nfds;
823 823
824 if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur) 824 if (nfds > rlimit(RLIMIT_NOFILE))
825 return -EINVAL; 825 return -EINVAL;
826 826
827 len = min_t(unsigned int, nfds, N_STACK_PPS); 827 len = min_t(unsigned int, nfds, N_STACK_PPS);
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 5afd554efad3..e1f437be6c3c 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -734,7 +734,7 @@ EXPORT_SYMBOL(seq_hlist_start_head);
734 * seq_hlist_next - move to the next position of the hlist 734 * seq_hlist_next - move to the next position of the hlist
735 * @v: the current iterator 735 * @v: the current iterator
736 * @head: the head of the hlist 736 * @head: the head of the hlist
737 * @pos: the current posision 737 * @ppos: the current position
738 * 738 *
739 * Called at seq_file->op->next(). 739 * Called at seq_file->op->next().
740 */ 740 */
@@ -800,7 +800,7 @@ EXPORT_SYMBOL(seq_hlist_start_head_rcu);
800 * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU 800 * seq_hlist_next_rcu - move to the next position of the hlist protected by RCU
801 * @v: the current iterator 801 * @v: the current iterator
802 * @head: the head of the hlist 802 * @head: the head of the hlist
803 * @pos: the current posision 803 * @ppos: the current position
804 * 804 *
805 * Called at seq_file->op->next(). 805 * Called at seq_file->op->next().
806 * 806 *
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 5c5a366aa332..b4769e40e8bc 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -105,7 +105,6 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
105 xfs_globals.o \ 105 xfs_globals.o \
106 xfs_ioctl.o \ 106 xfs_ioctl.o \
107 xfs_iops.o \ 107 xfs_iops.o \
108 xfs_lrw.o \
109 xfs_super.o \ 108 xfs_super.o \
110 xfs_sync.o \ 109 xfs_sync.o \
111 xfs_xattr.o) 110 xfs_xattr.o)
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 66abe36c1213..9083357f9e44 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -39,6 +39,7 @@
39#include "xfs_iomap.h" 39#include "xfs_iomap.h"
40#include "xfs_vnodeops.h" 40#include "xfs_vnodeops.h"
41#include "xfs_trace.h" 41#include "xfs_trace.h"
42#include "xfs_bmap.h"
42#include <linux/mpage.h> 43#include <linux/mpage.h>
43#include <linux/pagevec.h> 44#include <linux/pagevec.h>
44#include <linux/writeback.h> 45#include <linux/writeback.h>
@@ -163,14 +164,17 @@ xfs_ioend_new_eof(
163} 164}
164 165
165/* 166/*
166 * Update on-disk file size now that data has been written to disk. 167 * Update on-disk file size now that data has been written to disk. The
167 * The current in-memory file size is i_size. If a write is beyond 168 * current in-memory file size is i_size. If a write is beyond eof i_new_size
168 * eof i_new_size will be the intended file size until i_size is 169 * will be the intended file size until i_size is updated. If this write does
169 * updated. If this write does not extend all the way to the valid 170 * not extend all the way to the valid file size then restrict this update to
170 * file size then restrict this update to the end of the write. 171 * the end of the write.
172 *
173 * This function does not block as blocking on the inode lock in IO completion
174 * can lead to IO completion order dependency deadlocks.. If it can't get the
175 * inode ilock it will return EAGAIN. Callers must handle this.
171 */ 176 */
172 177STATIC int
173STATIC void
174xfs_setfilesize( 178xfs_setfilesize(
175 xfs_ioend_t *ioend) 179 xfs_ioend_t *ioend)
176{ 180{
@@ -181,16 +185,40 @@ xfs_setfilesize(
181 ASSERT(ioend->io_type != IOMAP_READ); 185 ASSERT(ioend->io_type != IOMAP_READ);
182 186
183 if (unlikely(ioend->io_error)) 187 if (unlikely(ioend->io_error))
184 return; 188 return 0;
189
190 if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL))
191 return EAGAIN;
185 192
186 xfs_ilock(ip, XFS_ILOCK_EXCL);
187 isize = xfs_ioend_new_eof(ioend); 193 isize = xfs_ioend_new_eof(ioend);
188 if (isize) { 194 if (isize) {
189 ip->i_d.di_size = isize; 195 ip->i_d.di_size = isize;
190 xfs_mark_inode_dirty_sync(ip); 196 xfs_mark_inode_dirty(ip);
191 } 197 }
192 198
193 xfs_iunlock(ip, XFS_ILOCK_EXCL); 199 xfs_iunlock(ip, XFS_ILOCK_EXCL);
200 return 0;
201}
202
203/*
204 * Schedule IO completion handling on a xfsdatad if this was
205 * the final hold on this ioend. If we are asked to wait,
206 * flush the workqueue.
207 */
208STATIC void
209xfs_finish_ioend(
210 xfs_ioend_t *ioend,
211 int wait)
212{
213 if (atomic_dec_and_test(&ioend->io_remaining)) {
214 struct workqueue_struct *wq;
215
216 wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
217 xfsconvertd_workqueue : xfsdatad_workqueue;
218 queue_work(wq, &ioend->io_work);
219 if (wait)
220 flush_workqueue(wq);
221 }
194} 222}
195 223
196/* 224/*
@@ -198,11 +226,11 @@ xfs_setfilesize(
198 */ 226 */
199STATIC void 227STATIC void
200xfs_end_io( 228xfs_end_io(
201 struct work_struct *work) 229 struct work_struct *work)
202{ 230{
203 xfs_ioend_t *ioend = 231 xfs_ioend_t *ioend = container_of(work, xfs_ioend_t, io_work);
204 container_of(work, xfs_ioend_t, io_work); 232 struct xfs_inode *ip = XFS_I(ioend->io_inode);
205 struct xfs_inode *ip = XFS_I(ioend->io_inode); 233 int error = 0;
206 234
207 /* 235 /*
208 * For unwritten extents we need to issue transactions to convert a 236 * For unwritten extents we need to issue transactions to convert a
@@ -210,7 +238,6 @@ xfs_end_io(
210 */ 238 */
211 if (ioend->io_type == IOMAP_UNWRITTEN && 239 if (ioend->io_type == IOMAP_UNWRITTEN &&
212 likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) { 240 likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) {
213 int error;
214 241
215 error = xfs_iomap_write_unwritten(ip, ioend->io_offset, 242 error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
216 ioend->io_size); 243 ioend->io_size);
@@ -222,30 +249,23 @@ xfs_end_io(
222 * We might have to update the on-disk file size after extending 249 * We might have to update the on-disk file size after extending
223 * writes. 250 * writes.
224 */ 251 */
225 if (ioend->io_type != IOMAP_READ) 252 if (ioend->io_type != IOMAP_READ) {
226 xfs_setfilesize(ioend); 253 error = xfs_setfilesize(ioend);
227 xfs_destroy_ioend(ioend); 254 ASSERT(!error || error == EAGAIN);
228}
229
230/*
231 * Schedule IO completion handling on a xfsdatad if this was
232 * the final hold on this ioend. If we are asked to wait,
233 * flush the workqueue.
234 */
235STATIC void
236xfs_finish_ioend(
237 xfs_ioend_t *ioend,
238 int wait)
239{
240 if (atomic_dec_and_test(&ioend->io_remaining)) {
241 struct workqueue_struct *wq;
242
243 wq = (ioend->io_type == IOMAP_UNWRITTEN) ?
244 xfsconvertd_workqueue : xfsdatad_workqueue;
245 queue_work(wq, &ioend->io_work);
246 if (wait)
247 flush_workqueue(wq);
248 } 255 }
256
257 /*
258 * If we didn't complete processing of the ioend, requeue it to the
259 * tail of the workqueue for another attempt later. Otherwise destroy
260 * it.
261 */
262 if (error == EAGAIN) {
263 atomic_inc(&ioend->io_remaining);
264 xfs_finish_ioend(ioend, 0);
265 /* ensure we don't spin on blocked ioends */
266 delay(1);
267 } else
268 xfs_destroy_ioend(ioend);
249} 269}
250 270
251/* 271/*
@@ -341,7 +361,7 @@ xfs_submit_ioend_bio(
341 * but don't update the inode size until I/O completion. 361 * but don't update the inode size until I/O completion.
342 */ 362 */
343 if (xfs_ioend_new_eof(ioend)) 363 if (xfs_ioend_new_eof(ioend))
344 xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); 364 xfs_mark_inode_dirty(XFS_I(ioend->io_inode));
345 365
346 submit_bio(wbc->sync_mode == WB_SYNC_ALL ? 366 submit_bio(wbc->sync_mode == WB_SYNC_ALL ?
347 WRITE_SYNC_PLUG : WRITE, bio); 367 WRITE_SYNC_PLUG : WRITE, bio);
@@ -874,6 +894,118 @@ xfs_cluster_write(
874 } 894 }
875} 895}
876 896
897STATIC void
898xfs_vm_invalidatepage(
899 struct page *page,
900 unsigned long offset)
901{
902 trace_xfs_invalidatepage(page->mapping->host, page, offset);
903 block_invalidatepage(page, offset);
904}
905
906/*
907 * If the page has delalloc buffers on it, we need to punch them out before we
908 * invalidate the page. If we don't, we leave a stale delalloc mapping on the
909 * inode that can trip a BUG() in xfs_get_blocks() later on if a direct IO read
910 * is done on that same region - the delalloc extent is returned when none is
911 * supposed to be there.
912 *
913 * We prevent this by truncating away the delalloc regions on the page before
914 * invalidating it. Because they are delalloc, we can do this without needing a
915 * transaction. Indeed - if we get ENOSPC errors, we have to be able to do this
916 * truncation without a transaction as there is no space left for block
917 * reservation (typically why we see a ENOSPC in writeback).
918 *
919 * This is not a performance critical path, so for now just do the punching a
920 * buffer head at a time.
921 */
922STATIC void
923xfs_aops_discard_page(
924 struct page *page)
925{
926 struct inode *inode = page->mapping->host;
927 struct xfs_inode *ip = XFS_I(inode);
928 struct buffer_head *bh, *head;
929 loff_t offset = page_offset(page);
930 ssize_t len = 1 << inode->i_blkbits;
931
932 if (!xfs_is_delayed_page(page, IOMAP_DELAY))
933 goto out_invalidate;
934
935 xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
936 "page discard on page %p, inode 0x%llx, offset %llu.",
937 page, ip->i_ino, offset);
938
939 xfs_ilock(ip, XFS_ILOCK_EXCL);
940 bh = head = page_buffers(page);
941 do {
942 int done;
943 xfs_fileoff_t offset_fsb;
944 xfs_bmbt_irec_t imap;
945 int nimaps = 1;
946 int error;
947 xfs_fsblock_t firstblock;
948 xfs_bmap_free_t flist;
949
950 if (!buffer_delay(bh))
951 goto next_buffer;
952
953 offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
954
955 /*
956 * Map the range first and check that it is a delalloc extent
957 * before trying to unmap the range. Otherwise we will be
958 * trying to remove a real extent (which requires a
959 * transaction) or a hole, which is probably a bad idea...
960 */
961 error = xfs_bmapi(NULL, ip, offset_fsb, 1,
962 XFS_BMAPI_ENTIRE, NULL, 0, &imap,
963 &nimaps, NULL, NULL);
964
965 if (error) {
966 /* something screwed, just bail */
967 xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
968 "page discard failed delalloc mapping lookup.");
969 break;
970 }
971 if (!nimaps) {
972 /* nothing there */
973 goto next_buffer;
974 }
975 if (imap.br_startblock != DELAYSTARTBLOCK) {
976 /* been converted, ignore */
977 goto next_buffer;
978 }
979 WARN_ON(imap.br_blockcount == 0);
980
981 /*
982 * Note: while we initialise the firstblock/flist pair, they
983 * should never be used because blocks should never be
984 * allocated or freed for a delalloc extent and hence we need
985 * don't cancel or finish them after the xfs_bunmapi() call.
986 */
987 xfs_bmap_init(&flist, &firstblock);
988 error = xfs_bunmapi(NULL, ip, offset_fsb, 1, 0, 1, &firstblock,
989 &flist, NULL, &done);
990
991 ASSERT(!flist.xbf_count && !flist.xbf_first);
992 if (error) {
993 /* something screwed, just bail */
994 xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
995 "page discard unable to remove delalloc mapping.");
996 break;
997 }
998next_buffer:
999 offset += len;
1000
1001 } while ((bh = bh->b_this_page) != head);
1002
1003 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1004out_invalidate:
1005 xfs_vm_invalidatepage(page, 0);
1006 return;
1007}
1008
877/* 1009/*
878 * Calling this without startio set means we are being asked to make a dirty 1010 * Calling this without startio set means we are being asked to make a dirty
879 * page ready for freeing it's buffers. When called with startio set then 1011 * page ready for freeing it's buffers. When called with startio set then
@@ -1125,7 +1257,7 @@ error:
1125 */ 1257 */
1126 if (err != -EAGAIN) { 1258 if (err != -EAGAIN) {
1127 if (!unmapped) 1259 if (!unmapped)
1128 block_invalidatepage(page, 0); 1260 xfs_aops_discard_page(page);
1129 ClearPageUptodate(page); 1261 ClearPageUptodate(page);
1130 } 1262 }
1131 return err; 1263 return err;
@@ -1535,15 +1667,6 @@ xfs_vm_readpages(
1535 return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks); 1667 return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks);
1536} 1668}
1537 1669
1538STATIC void
1539xfs_vm_invalidatepage(
1540 struct page *page,
1541 unsigned long offset)
1542{
1543 trace_xfs_invalidatepage(page->mapping->host, page, offset);
1544 block_invalidatepage(page, offset);
1545}
1546
1547const struct address_space_operations xfs_address_space_operations = { 1670const struct address_space_operations xfs_address_space_operations = {
1548 .readpage = xfs_vm_readpage, 1671 .readpage = xfs_vm_readpage,
1549 .readpages = xfs_vm_readpages, 1672 .readpages = xfs_vm_readpages,
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 87b8cbd23d4b..846b75aeb2ab 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -29,6 +29,7 @@
29#include "xfs_vnodeops.h" 29#include "xfs_vnodeops.h"
30#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
31#include "xfs_inode.h" 31#include "xfs_inode.h"
32#include "xfs_inode_item.h"
32 33
33/* 34/*
34 * Note that we only accept fileids which are long enough rather than allow 35 * Note that we only accept fileids which are long enough rather than allow
@@ -215,9 +216,28 @@ xfs_fs_get_parent(
215 return d_obtain_alias(VFS_I(cip)); 216 return d_obtain_alias(VFS_I(cip));
216} 217}
217 218
219STATIC int
220xfs_fs_nfs_commit_metadata(
221 struct inode *inode)
222{
223 struct xfs_inode *ip = XFS_I(inode);
224 struct xfs_mount *mp = ip->i_mount;
225 int error = 0;
226
227 xfs_ilock(ip, XFS_ILOCK_SHARED);
228 if (xfs_ipincount(ip)) {
229 error = _xfs_log_force_lsn(mp, ip->i_itemp->ili_last_lsn,
230 XFS_LOG_SYNC, NULL);
231 }
232 xfs_iunlock(ip, XFS_ILOCK_SHARED);
233
234 return error;
235}
236
218const struct export_operations xfs_export_operations = { 237const struct export_operations xfs_export_operations = {
219 .encode_fh = xfs_fs_encode_fh, 238 .encode_fh = xfs_fs_encode_fh,
220 .fh_to_dentry = xfs_fs_fh_to_dentry, 239 .fh_to_dentry = xfs_fs_fh_to_dentry,
221 .fh_to_parent = xfs_fs_fh_to_parent, 240 .fh_to_parent = xfs_fs_fh_to_parent,
222 .get_parent = xfs_fs_get_parent, 241 .get_parent = xfs_fs_get_parent,
242 .commit_metadata = xfs_fs_nfs_commit_metadata,
223}; 243};
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index e4caeb28ce2e..42dd3bcfba6b 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -16,6 +16,7 @@
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18#include "xfs.h" 18#include "xfs.h"
19#include "xfs_fs.h"
19#include "xfs_bit.h" 20#include "xfs_bit.h"
20#include "xfs_log.h" 21#include "xfs_log.h"
21#include "xfs_inum.h" 22#include "xfs_inum.h"
@@ -34,52 +35,279 @@
34#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
35#include "xfs_dinode.h" 36#include "xfs_dinode.h"
36#include "xfs_inode.h" 37#include "xfs_inode.h"
38#include "xfs_inode_item.h"
39#include "xfs_bmap.h"
37#include "xfs_error.h" 40#include "xfs_error.h"
38#include "xfs_rw.h" 41#include "xfs_rw.h"
39#include "xfs_vnodeops.h" 42#include "xfs_vnodeops.h"
40#include "xfs_da_btree.h" 43#include "xfs_da_btree.h"
41#include "xfs_ioctl.h" 44#include "xfs_ioctl.h"
45#include "xfs_trace.h"
42 46
43#include <linux/dcache.h> 47#include <linux/dcache.h>
44 48
45static const struct vm_operations_struct xfs_file_vm_ops; 49static const struct vm_operations_struct xfs_file_vm_ops;
46 50
47STATIC ssize_t 51/*
48xfs_file_aio_read( 52 * xfs_iozero
49 struct kiocb *iocb, 53 *
50 const struct iovec *iov, 54 * xfs_iozero clears the specified range of buffer supplied,
51 unsigned long nr_segs, 55 * and marks all the affected blocks as valid and modified. If
52 loff_t pos) 56 * an affected block is not allocated, it will be allocated. If
57 * an affected block is not completely overwritten, and is not
58 * valid before the operation, it will be read from disk before
59 * being partially zeroed.
60 */
61STATIC int
62xfs_iozero(
63 struct xfs_inode *ip, /* inode */
64 loff_t pos, /* offset in file */
65 size_t count) /* size of data to zero */
53{ 66{
54 struct file *file = iocb->ki_filp; 67 struct page *page;
55 int ioflags = 0; 68 struct address_space *mapping;
69 int status;
56 70
57 BUG_ON(iocb->ki_pos != pos); 71 mapping = VFS_I(ip)->i_mapping;
58 if (unlikely(file->f_flags & O_DIRECT)) 72 do {
59 ioflags |= IO_ISDIRECT; 73 unsigned offset, bytes;
60 if (file->f_mode & FMODE_NOCMTIME) 74 void *fsdata;
61 ioflags |= IO_INVIS; 75
62 return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov, 76 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
63 nr_segs, &iocb->ki_pos, ioflags); 77 bytes = PAGE_CACHE_SIZE - offset;
78 if (bytes > count)
79 bytes = count;
80
81 status = pagecache_write_begin(NULL, mapping, pos, bytes,
82 AOP_FLAG_UNINTERRUPTIBLE,
83 &page, &fsdata);
84 if (status)
85 break;
86
87 zero_user(page, offset, bytes);
88
89 status = pagecache_write_end(NULL, mapping, pos, bytes, bytes,
90 page, fsdata);
91 WARN_ON(status <= 0); /* can't return less than zero! */
92 pos += bytes;
93 count -= bytes;
94 status = 0;
95 } while (count);
96
97 return (-status);
98}
99
100STATIC int
101xfs_file_fsync(
102 struct file *file,
103 struct dentry *dentry,
104 int datasync)
105{
106 struct xfs_inode *ip = XFS_I(dentry->d_inode);
107 struct xfs_trans *tp;
108 int error = 0;
109 int log_flushed = 0;
110
111 xfs_itrace_entry(ip);
112
113 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
114 return -XFS_ERROR(EIO);
115
116 xfs_iflags_clear(ip, XFS_ITRUNCATED);
117
118 /*
119 * We always need to make sure that the required inode state is safe on
120 * disk. The inode might be clean but we still might need to force the
121 * log because of committed transactions that haven't hit the disk yet.
122 * Likewise, there could be unflushed non-transactional changes to the
123 * inode core that have to go to disk and this requires us to issue
124 * a synchronous transaction to capture these changes correctly.
125 *
126 * This code relies on the assumption that if the i_update_core field
127 * of the inode is clear and the inode is unpinned then it is clean
128 * and no action is required.
129 */
130 xfs_ilock(ip, XFS_ILOCK_SHARED);
131
132 /*
133 * First check if the VFS inode is marked dirty. All the dirtying
134 * of non-transactional updates no goes through mark_inode_dirty*,
135 * which allows us to distinguish beteeen pure timestamp updates
136 * and i_size updates which need to be caught for fdatasync.
137 * After that also theck for the dirty state in the XFS inode, which
138 * might gets cleared when the inode gets written out via the AIL
139 * or xfs_iflush_cluster.
140 */
141 if (((dentry->d_inode->i_state & I_DIRTY_DATASYNC) ||
142 ((dentry->d_inode->i_state & I_DIRTY_SYNC) && !datasync)) &&
143 ip->i_update_core) {
144 /*
145 * Kick off a transaction to log the inode core to get the
146 * updates. The sync transaction will also force the log.
147 */
148 xfs_iunlock(ip, XFS_ILOCK_SHARED);
149 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
150 error = xfs_trans_reserve(tp, 0,
151 XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
152 if (error) {
153 xfs_trans_cancel(tp, 0);
154 return -error;
155 }
156 xfs_ilock(ip, XFS_ILOCK_EXCL);
157
158 /*
159 * Note - it's possible that we might have pushed ourselves out
160 * of the way during trans_reserve which would flush the inode.
161 * But there's no guarantee that the inode buffer has actually
162 * gone out yet (it's delwri). Plus the buffer could be pinned
163 * anyway if it's part of an inode in another recent
164 * transaction. So we play it safe and fire off the
165 * transaction anyway.
166 */
167 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
168 xfs_trans_ihold(tp, ip);
169 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
170 xfs_trans_set_sync(tp);
171 error = _xfs_trans_commit(tp, 0, &log_flushed);
172
173 xfs_iunlock(ip, XFS_ILOCK_EXCL);
174 } else {
175 /*
176 * Timestamps/size haven't changed since last inode flush or
177 * inode transaction commit. That means either nothing got
178 * written or a transaction committed which caught the updates.
179 * If the latter happened and the transaction hasn't hit the
180 * disk yet, the inode will be still be pinned. If it is,
181 * force the log.
182 */
183 if (xfs_ipincount(ip)) {
184 error = _xfs_log_force_lsn(ip->i_mount,
185 ip->i_itemp->ili_last_lsn,
186 XFS_LOG_SYNC, &log_flushed);
187 }
188 xfs_iunlock(ip, XFS_ILOCK_SHARED);
189 }
190
191 if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) {
192 /*
193 * If the log write didn't issue an ordered tag we need
194 * to flush the disk cache for the data device now.
195 */
196 if (!log_flushed)
197 xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
198
199 /*
200 * If this inode is on the RT dev we need to flush that
201 * cache as well.
202 */
203 if (XFS_IS_REALTIME_INODE(ip))
204 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
205 }
206
207 return -error;
64} 208}
65 209
66STATIC ssize_t 210STATIC ssize_t
67xfs_file_aio_write( 211xfs_file_aio_read(
68 struct kiocb *iocb, 212 struct kiocb *iocb,
69 const struct iovec *iov, 213 const struct iovec *iovp,
70 unsigned long nr_segs, 214 unsigned long nr_segs,
71 loff_t pos) 215 loff_t pos)
72{ 216{
73 struct file *file = iocb->ki_filp; 217 struct file *file = iocb->ki_filp;
218 struct inode *inode = file->f_mapping->host;
219 struct xfs_inode *ip = XFS_I(inode);
220 struct xfs_mount *mp = ip->i_mount;
221 size_t size = 0;
222 ssize_t ret = 0;
74 int ioflags = 0; 223 int ioflags = 0;
224 xfs_fsize_t n;
225 unsigned long seg;
226
227 XFS_STATS_INC(xs_read_calls);
75 228
76 BUG_ON(iocb->ki_pos != pos); 229 BUG_ON(iocb->ki_pos != pos);
230
77 if (unlikely(file->f_flags & O_DIRECT)) 231 if (unlikely(file->f_flags & O_DIRECT))
78 ioflags |= IO_ISDIRECT; 232 ioflags |= IO_ISDIRECT;
79 if (file->f_mode & FMODE_NOCMTIME) 233 if (file->f_mode & FMODE_NOCMTIME)
80 ioflags |= IO_INVIS; 234 ioflags |= IO_INVIS;
81 return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs, 235
82 &iocb->ki_pos, ioflags); 236 /* START copy & waste from filemap.c */
237 for (seg = 0; seg < nr_segs; seg++) {
238 const struct iovec *iv = &iovp[seg];
239
240 /*
241 * If any segment has a negative length, or the cumulative
242 * length ever wraps negative then return -EINVAL.
243 */
244 size += iv->iov_len;
245 if (unlikely((ssize_t)(size|iv->iov_len) < 0))
246 return XFS_ERROR(-EINVAL);
247 }
248 /* END copy & waste from filemap.c */
249
250 if (unlikely(ioflags & IO_ISDIRECT)) {
251 xfs_buftarg_t *target =
252 XFS_IS_REALTIME_INODE(ip) ?
253 mp->m_rtdev_targp : mp->m_ddev_targp;
254 if ((iocb->ki_pos & target->bt_smask) ||
255 (size & target->bt_smask)) {
256 if (iocb->ki_pos == ip->i_size)
257 return 0;
258 return -XFS_ERROR(EINVAL);
259 }
260 }
261
262 n = XFS_MAXIOFFSET(mp) - iocb->ki_pos;
263 if (n <= 0 || size == 0)
264 return 0;
265
266 if (n < size)
267 size = n;
268
269 if (XFS_FORCED_SHUTDOWN(mp))
270 return -EIO;
271
272 if (unlikely(ioflags & IO_ISDIRECT))
273 mutex_lock(&inode->i_mutex);
274 xfs_ilock(ip, XFS_IOLOCK_SHARED);
275
276 if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
277 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
278 int iolock = XFS_IOLOCK_SHARED;
279
280 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, iocb->ki_pos, size,
281 dmflags, &iolock);
282 if (ret) {
283 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
284 if (unlikely(ioflags & IO_ISDIRECT))
285 mutex_unlock(&inode->i_mutex);
286 return ret;
287 }
288 }
289
290 if (unlikely(ioflags & IO_ISDIRECT)) {
291 if (inode->i_mapping->nrpages) {
292 ret = -xfs_flushinval_pages(ip,
293 (iocb->ki_pos & PAGE_CACHE_MASK),
294 -1, FI_REMAPF_LOCKED);
295 }
296 mutex_unlock(&inode->i_mutex);
297 if (ret) {
298 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
299 return ret;
300 }
301 }
302
303 trace_xfs_file_read(ip, size, iocb->ki_pos, ioflags);
304
305 ret = generic_file_aio_read(iocb, iovp, nr_segs, iocb->ki_pos);
306 if (ret > 0)
307 XFS_STATS_ADD(xs_read_bytes, ret);
308
309 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
310 return ret;
83} 311}
84 312
85STATIC ssize_t 313STATIC ssize_t
@@ -87,16 +315,44 @@ xfs_file_splice_read(
87 struct file *infilp, 315 struct file *infilp,
88 loff_t *ppos, 316 loff_t *ppos,
89 struct pipe_inode_info *pipe, 317 struct pipe_inode_info *pipe,
90 size_t len, 318 size_t count,
91 unsigned int flags) 319 unsigned int flags)
92{ 320{
321 struct xfs_inode *ip = XFS_I(infilp->f_mapping->host);
322 struct xfs_mount *mp = ip->i_mount;
93 int ioflags = 0; 323 int ioflags = 0;
324 ssize_t ret;
325
326 XFS_STATS_INC(xs_read_calls);
94 327
95 if (infilp->f_mode & FMODE_NOCMTIME) 328 if (infilp->f_mode & FMODE_NOCMTIME)
96 ioflags |= IO_INVIS; 329 ioflags |= IO_INVIS;
97 330
98 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode), 331 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
99 infilp, ppos, pipe, len, flags, ioflags); 332 return -EIO;
333
334 xfs_ilock(ip, XFS_IOLOCK_SHARED);
335
336 if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
337 int iolock = XFS_IOLOCK_SHARED;
338 int error;
339
340 error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *ppos, count,
341 FILP_DELAY_FLAG(infilp), &iolock);
342 if (error) {
343 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
344 return -error;
345 }
346 }
347
348 trace_xfs_file_splice_read(ip, count, *ppos, ioflags);
349
350 ret = generic_file_splice_read(infilp, ppos, pipe, count, flags);
351 if (ret > 0)
352 XFS_STATS_ADD(xs_read_bytes, ret);
353
354 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
355 return ret;
100} 356}
101 357
102STATIC ssize_t 358STATIC ssize_t
@@ -104,16 +360,538 @@ xfs_file_splice_write(
104 struct pipe_inode_info *pipe, 360 struct pipe_inode_info *pipe,
105 struct file *outfilp, 361 struct file *outfilp,
106 loff_t *ppos, 362 loff_t *ppos,
107 size_t len, 363 size_t count,
108 unsigned int flags) 364 unsigned int flags)
109{ 365{
366 struct inode *inode = outfilp->f_mapping->host;
367 struct xfs_inode *ip = XFS_I(inode);
368 struct xfs_mount *mp = ip->i_mount;
369 xfs_fsize_t isize, new_size;
110 int ioflags = 0; 370 int ioflags = 0;
371 ssize_t ret;
372
373 XFS_STATS_INC(xs_write_calls);
111 374
112 if (outfilp->f_mode & FMODE_NOCMTIME) 375 if (outfilp->f_mode & FMODE_NOCMTIME)
113 ioflags |= IO_INVIS; 376 ioflags |= IO_INVIS;
114 377
115 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode), 378 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
116 pipe, outfilp, ppos, len, flags, ioflags); 379 return -EIO;
380
381 xfs_ilock(ip, XFS_IOLOCK_EXCL);
382
383 if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) {
384 int iolock = XFS_IOLOCK_EXCL;
385 int error;
386
387 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, *ppos, count,
388 FILP_DELAY_FLAG(outfilp), &iolock);
389 if (error) {
390 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
391 return -error;
392 }
393 }
394
395 new_size = *ppos + count;
396
397 xfs_ilock(ip, XFS_ILOCK_EXCL);
398 if (new_size > ip->i_size)
399 ip->i_new_size = new_size;
400 xfs_iunlock(ip, XFS_ILOCK_EXCL);
401
402 trace_xfs_file_splice_write(ip, count, *ppos, ioflags);
403
404 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
405 if (ret > 0)
406 XFS_STATS_ADD(xs_write_bytes, ret);
407
408 isize = i_size_read(inode);
409 if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
410 *ppos = isize;
411
412 if (*ppos > ip->i_size) {
413 xfs_ilock(ip, XFS_ILOCK_EXCL);
414 if (*ppos > ip->i_size)
415 ip->i_size = *ppos;
416 xfs_iunlock(ip, XFS_ILOCK_EXCL);
417 }
418
419 if (ip->i_new_size) {
420 xfs_ilock(ip, XFS_ILOCK_EXCL);
421 ip->i_new_size = 0;
422 if (ip->i_d.di_size > ip->i_size)
423 ip->i_d.di_size = ip->i_size;
424 xfs_iunlock(ip, XFS_ILOCK_EXCL);
425 }
426 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
427 return ret;
428}
429
430/*
431 * This routine is called to handle zeroing any space in the last
432 * block of the file that is beyond the EOF. We do this since the
433 * size is being increased without writing anything to that block
434 * and we don't want anyone to read the garbage on the disk.
435 */
436STATIC int /* error (positive) */
437xfs_zero_last_block(
438 xfs_inode_t *ip,
439 xfs_fsize_t offset,
440 xfs_fsize_t isize)
441{
442 xfs_fileoff_t last_fsb;
443 xfs_mount_t *mp = ip->i_mount;
444 int nimaps;
445 int zero_offset;
446 int zero_len;
447 int error = 0;
448 xfs_bmbt_irec_t imap;
449
450 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
451
452 zero_offset = XFS_B_FSB_OFFSET(mp, isize);
453 if (zero_offset == 0) {
454 /*
455 * There are no extra bytes in the last block on disk to
456 * zero, so return.
457 */
458 return 0;
459 }
460
461 last_fsb = XFS_B_TO_FSBT(mp, isize);
462 nimaps = 1;
463 error = xfs_bmapi(NULL, ip, last_fsb, 1, 0, NULL, 0, &imap,
464 &nimaps, NULL, NULL);
465 if (error) {
466 return error;
467 }
468 ASSERT(nimaps > 0);
469 /*
470 * If the block underlying isize is just a hole, then there
471 * is nothing to zero.
472 */
473 if (imap.br_startblock == HOLESTARTBLOCK) {
474 return 0;
475 }
476 /*
477 * Zero the part of the last block beyond the EOF, and write it
478 * out sync. We need to drop the ilock while we do this so we
479 * don't deadlock when the buffer cache calls back to us.
480 */
481 xfs_iunlock(ip, XFS_ILOCK_EXCL);
482
483 zero_len = mp->m_sb.sb_blocksize - zero_offset;
484 if (isize + zero_len > offset)
485 zero_len = offset - isize;
486 error = xfs_iozero(ip, isize, zero_len);
487
488 xfs_ilock(ip, XFS_ILOCK_EXCL);
489 ASSERT(error >= 0);
490 return error;
491}
492
493/*
494 * Zero any on disk space between the current EOF and the new,
495 * larger EOF. This handles the normal case of zeroing the remainder
496 * of the last block in the file and the unusual case of zeroing blocks
497 * out beyond the size of the file. This second case only happens
498 * with fixed size extents and when the system crashes before the inode
499 * size was updated but after blocks were allocated. If fill is set,
500 * then any holes in the range are filled and zeroed. If not, the holes
501 * are left alone as holes.
502 */
503
504int /* error (positive) */
505xfs_zero_eof(
506 xfs_inode_t *ip,
507 xfs_off_t offset, /* starting I/O offset */
508 xfs_fsize_t isize) /* current inode size */
509{
510 xfs_mount_t *mp = ip->i_mount;
511 xfs_fileoff_t start_zero_fsb;
512 xfs_fileoff_t end_zero_fsb;
513 xfs_fileoff_t zero_count_fsb;
514 xfs_fileoff_t last_fsb;
515 xfs_fileoff_t zero_off;
516 xfs_fsize_t zero_len;
517 int nimaps;
518 int error = 0;
519 xfs_bmbt_irec_t imap;
520
521 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
522 ASSERT(offset > isize);
523
524 /*
525 * First handle zeroing the block on which isize resides.
526 * We only zero a part of that block so it is handled specially.
527 */
528 error = xfs_zero_last_block(ip, offset, isize);
529 if (error) {
530 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
531 return error;
532 }
533
534 /*
535 * Calculate the range between the new size and the old
536 * where blocks needing to be zeroed may exist. To get the
537 * block where the last byte in the file currently resides,
538 * we need to subtract one from the size and truncate back
539 * to a block boundary. We subtract 1 in case the size is
540 * exactly on a block boundary.
541 */
542 last_fsb = isize ? XFS_B_TO_FSBT(mp, isize - 1) : (xfs_fileoff_t)-1;
543 start_zero_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize);
544 end_zero_fsb = XFS_B_TO_FSBT(mp, offset - 1);
545 ASSERT((xfs_sfiloff_t)last_fsb < (xfs_sfiloff_t)start_zero_fsb);
546 if (last_fsb == end_zero_fsb) {
547 /*
548 * The size was only incremented on its last block.
549 * We took care of that above, so just return.
550 */
551 return 0;
552 }
553
554 ASSERT(start_zero_fsb <= end_zero_fsb);
555 while (start_zero_fsb <= end_zero_fsb) {
556 nimaps = 1;
557 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
558 error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb,
559 0, NULL, 0, &imap, &nimaps, NULL, NULL);
560 if (error) {
561 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
562 return error;
563 }
564 ASSERT(nimaps > 0);
565
566 if (imap.br_state == XFS_EXT_UNWRITTEN ||
567 imap.br_startblock == HOLESTARTBLOCK) {
568 /*
569 * This loop handles initializing pages that were
570 * partially initialized by the code below this
571 * loop. It basically zeroes the part of the page
572 * that sits on a hole and sets the page as P_HOLE
573 * and calls remapf if it is a mapped file.
574 */
575 start_zero_fsb = imap.br_startoff + imap.br_blockcount;
576 ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
577 continue;
578 }
579
580 /*
581 * There are blocks we need to zero.
582 * Drop the inode lock while we're doing the I/O.
583 * We'll still have the iolock to protect us.
584 */
585 xfs_iunlock(ip, XFS_ILOCK_EXCL);
586
587 zero_off = XFS_FSB_TO_B(mp, start_zero_fsb);
588 zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount);
589
590 if ((zero_off + zero_len) > offset)
591 zero_len = offset - zero_off;
592
593 error = xfs_iozero(ip, zero_off, zero_len);
594 if (error) {
595 goto out_lock;
596 }
597
598 start_zero_fsb = imap.br_startoff + imap.br_blockcount;
599 ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
600
601 xfs_ilock(ip, XFS_ILOCK_EXCL);
602 }
603
604 return 0;
605
606out_lock:
607 xfs_ilock(ip, XFS_ILOCK_EXCL);
608 ASSERT(error >= 0);
609 return error;
610}
611
612STATIC ssize_t
613xfs_file_aio_write(
614 struct kiocb *iocb,
615 const struct iovec *iovp,
616 unsigned long nr_segs,
617 loff_t pos)
618{
619 struct file *file = iocb->ki_filp;
620 struct address_space *mapping = file->f_mapping;
621 struct inode *inode = mapping->host;
622 struct xfs_inode *ip = XFS_I(inode);
623 struct xfs_mount *mp = ip->i_mount;
624 ssize_t ret = 0, error = 0;
625 int ioflags = 0;
626 xfs_fsize_t isize, new_size;
627 int iolock;
628 int eventsent = 0;
629 size_t ocount = 0, count;
630 int need_i_mutex;
631
632 XFS_STATS_INC(xs_write_calls);
633
634 BUG_ON(iocb->ki_pos != pos);
635
636 if (unlikely(file->f_flags & O_DIRECT))
637 ioflags |= IO_ISDIRECT;
638 if (file->f_mode & FMODE_NOCMTIME)
639 ioflags |= IO_INVIS;
640
641 error = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ);
642 if (error)
643 return error;
644
645 count = ocount;
646 if (count == 0)
647 return 0;
648
649 xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
650
651 if (XFS_FORCED_SHUTDOWN(mp))
652 return -EIO;
653
654relock:
655 if (ioflags & IO_ISDIRECT) {
656 iolock = XFS_IOLOCK_SHARED;
657 need_i_mutex = 0;
658 } else {
659 iolock = XFS_IOLOCK_EXCL;
660 need_i_mutex = 1;
661 mutex_lock(&inode->i_mutex);
662 }
663
664 xfs_ilock(ip, XFS_ILOCK_EXCL|iolock);
665
666start:
667 error = -generic_write_checks(file, &pos, &count,
668 S_ISBLK(inode->i_mode));
669 if (error) {
670 xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock);
671 goto out_unlock_mutex;
672 }
673
674 if ((DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) &&
675 !(ioflags & IO_INVIS) && !eventsent)) {
676 int dmflags = FILP_DELAY_FLAG(file);
677
678 if (need_i_mutex)
679 dmflags |= DM_FLAGS_IMUX;
680
681 xfs_iunlock(ip, XFS_ILOCK_EXCL);
682 error = XFS_SEND_DATA(ip->i_mount, DM_EVENT_WRITE, ip,
683 pos, count, dmflags, &iolock);
684 if (error) {
685 goto out_unlock_internal;
686 }
687 xfs_ilock(ip, XFS_ILOCK_EXCL);
688 eventsent = 1;
689
690 /*
691 * The iolock was dropped and reacquired in XFS_SEND_DATA
692 * so we have to recheck the size when appending.
693 * We will only "goto start;" once, since having sent the
694 * event prevents another call to XFS_SEND_DATA, which is
695 * what allows the size to change in the first place.
696 */
697 if ((file->f_flags & O_APPEND) && pos != ip->i_size)
698 goto start;
699 }
700
701 if (ioflags & IO_ISDIRECT) {
702 xfs_buftarg_t *target =
703 XFS_IS_REALTIME_INODE(ip) ?
704 mp->m_rtdev_targp : mp->m_ddev_targp;
705
706 if ((pos & target->bt_smask) || (count & target->bt_smask)) {
707 xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock);
708 return XFS_ERROR(-EINVAL);
709 }
710
711 if (!need_i_mutex && (mapping->nrpages || pos > ip->i_size)) {
712 xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock);
713 iolock = XFS_IOLOCK_EXCL;
714 need_i_mutex = 1;
715 mutex_lock(&inode->i_mutex);
716 xfs_ilock(ip, XFS_ILOCK_EXCL|iolock);
717 goto start;
718 }
719 }
720
721 new_size = pos + count;
722 if (new_size > ip->i_size)
723 ip->i_new_size = new_size;
724
725 if (likely(!(ioflags & IO_INVIS)))
726 file_update_time(file);
727
728 /*
729 * If the offset is beyond the size of the file, we have a couple
730 * of things to do. First, if there is already space allocated
731 * we need to either create holes or zero the disk or ...
732 *
733 * If there is a page where the previous size lands, we need
734 * to zero it out up to the new size.
735 */
736
737 if (pos > ip->i_size) {
738 error = xfs_zero_eof(ip, pos, ip->i_size);
739 if (error) {
740 xfs_iunlock(ip, XFS_ILOCK_EXCL);
741 goto out_unlock_internal;
742 }
743 }
744 xfs_iunlock(ip, XFS_ILOCK_EXCL);
745
746 /*
747 * If we're writing the file then make sure to clear the
748 * setuid and setgid bits if the process is not being run
749 * by root. This keeps people from modifying setuid and
750 * setgid binaries.
751 */
752 error = -file_remove_suid(file);
753 if (unlikely(error))
754 goto out_unlock_internal;
755
756 /* We can write back this queue in page reclaim */
757 current->backing_dev_info = mapping->backing_dev_info;
758
759 if ((ioflags & IO_ISDIRECT)) {
760 if (mapping->nrpages) {
761 WARN_ON(need_i_mutex == 0);
762 error = xfs_flushinval_pages(ip,
763 (pos & PAGE_CACHE_MASK),
764 -1, FI_REMAPF_LOCKED);
765 if (error)
766 goto out_unlock_internal;
767 }
768
769 if (need_i_mutex) {
770 /* demote the lock now the cached pages are gone */
771 xfs_ilock_demote(ip, XFS_IOLOCK_EXCL);
772 mutex_unlock(&inode->i_mutex);
773
774 iolock = XFS_IOLOCK_SHARED;
775 need_i_mutex = 0;
776 }
777
778 trace_xfs_file_direct_write(ip, count, iocb->ki_pos, ioflags);
779 ret = generic_file_direct_write(iocb, iovp,
780 &nr_segs, pos, &iocb->ki_pos, count, ocount);
781
782 /*
783 * direct-io write to a hole: fall through to buffered I/O
784 * for completing the rest of the request.
785 */
786 if (ret >= 0 && ret != count) {
787 XFS_STATS_ADD(xs_write_bytes, ret);
788
789 pos += ret;
790 count -= ret;
791
792 ioflags &= ~IO_ISDIRECT;
793 xfs_iunlock(ip, iolock);
794 goto relock;
795 }
796 } else {
797 int enospc = 0;
798 ssize_t ret2 = 0;
799
800write_retry:
801 trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, ioflags);
802 ret2 = generic_file_buffered_write(iocb, iovp, nr_segs,
803 pos, &iocb->ki_pos, count, ret);
804 /*
805 * if we just got an ENOSPC, flush the inode now we
806 * aren't holding any page locks and retry *once*
807 */
808 if (ret2 == -ENOSPC && !enospc) {
809 error = xfs_flush_pages(ip, 0, -1, 0, FI_NONE);
810 if (error)
811 goto out_unlock_internal;
812 enospc = 1;
813 goto write_retry;
814 }
815 ret = ret2;
816 }
817
818 current->backing_dev_info = NULL;
819
820 isize = i_size_read(inode);
821 if (unlikely(ret < 0 && ret != -EFAULT && iocb->ki_pos > isize))
822 iocb->ki_pos = isize;
823
824 if (iocb->ki_pos > ip->i_size) {
825 xfs_ilock(ip, XFS_ILOCK_EXCL);
826 if (iocb->ki_pos > ip->i_size)
827 ip->i_size = iocb->ki_pos;
828 xfs_iunlock(ip, XFS_ILOCK_EXCL);
829 }
830
831 if (ret == -ENOSPC &&
832 DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) {
833 xfs_iunlock(ip, iolock);
834 if (need_i_mutex)
835 mutex_unlock(&inode->i_mutex);
836 error = XFS_SEND_NAMESP(ip->i_mount, DM_EVENT_NOSPACE, ip,
837 DM_RIGHT_NULL, ip, DM_RIGHT_NULL, NULL, NULL,
838 0, 0, 0); /* Delay flag intentionally unused */
839 if (need_i_mutex)
840 mutex_lock(&inode->i_mutex);
841 xfs_ilock(ip, iolock);
842 if (error)
843 goto out_unlock_internal;
844 goto start;
845 }
846
847 error = -ret;
848 if (ret <= 0)
849 goto out_unlock_internal;
850
851 XFS_STATS_ADD(xs_write_bytes, ret);
852
853 /* Handle various SYNC-type writes */
854 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
855 loff_t end = pos + ret - 1;
856 int error2;
857
858 xfs_iunlock(ip, iolock);
859 if (need_i_mutex)
860 mutex_unlock(&inode->i_mutex);
861
862 error2 = filemap_write_and_wait_range(mapping, pos, end);
863 if (!error)
864 error = error2;
865 if (need_i_mutex)
866 mutex_lock(&inode->i_mutex);
867 xfs_ilock(ip, iolock);
868
869 error2 = -xfs_file_fsync(file, file->f_path.dentry,
870 (file->f_flags & __O_SYNC) ? 0 : 1);
871 if (!error)
872 error = error2;
873 }
874
875 out_unlock_internal:
876 if (ip->i_new_size) {
877 xfs_ilock(ip, XFS_ILOCK_EXCL);
878 ip->i_new_size = 0;
879 /*
880 * If this was a direct or synchronous I/O that failed (such
881 * as ENOSPC) then part of the I/O may have been written to
882 * disk before the error occured. In this case the on-disk
883 * file size may have been adjusted beyond the in-memory file
884 * size and now needs to be truncated back.
885 */
886 if (ip->i_d.di_size > ip->i_size)
887 ip->i_d.di_size = ip->i_size;
888 xfs_iunlock(ip, XFS_ILOCK_EXCL);
889 }
890 xfs_iunlock(ip, iolock);
891 out_unlock_mutex:
892 if (need_i_mutex)
893 mutex_unlock(&inode->i_mutex);
894 return -error;
117} 895}
118 896
119STATIC int 897STATIC int
@@ -160,28 +938,6 @@ xfs_file_release(
160 return -xfs_release(XFS_I(inode)); 938 return -xfs_release(XFS_I(inode));
161} 939}
162 940
163/*
164 * We ignore the datasync flag here because a datasync is effectively
165 * identical to an fsync. That is, datasync implies that we need to write
166 * only the metadata needed to be able to access the data that is written
167 * if we crash after the call completes. Hence if we are writing beyond
168 * EOF we have to log the inode size change as well, which makes it a
169 * full fsync. If we don't write beyond EOF, the inode core will be
170 * clean in memory and so we don't need to log the inode, just like
171 * fsync.
172 */
173STATIC int
174xfs_file_fsync(
175 struct file *file,
176 struct dentry *dentry,
177 int datasync)
178{
179 struct xfs_inode *ip = XFS_I(dentry->d_inode);
180
181 xfs_iflags_clear(ip, XFS_ITRUNCATED);
182 return -xfs_fsync(ip);
183}
184
185STATIC int 941STATIC int
186xfs_file_readdir( 942xfs_file_readdir(
187 struct file *filp, 943 struct file *filp,
@@ -203,9 +959,9 @@ xfs_file_readdir(
203 * 959 *
204 * Try to give it an estimate that's good enough, maybe at some 960 * Try to give it an estimate that's good enough, maybe at some
205 * point we can change the ->readdir prototype to include the 961 * point we can change the ->readdir prototype to include the
206 * buffer size. 962 * buffer size. For now we use the current glibc buffer size.
207 */ 963 */
208 bufsize = (size_t)min_t(loff_t, PAGE_SIZE, ip->i_d.di_size); 964 bufsize = (size_t)min_t(loff_t, 32768, ip->i_d.di_size);
209 965
210 error = xfs_readdir(ip, dirent, bufsize, 966 error = xfs_readdir(ip, dirent, bufsize,
211 (xfs_off_t *)&filp->f_pos, filldir); 967 (xfs_off_t *)&filp->f_pos, filldir);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index e8566bbf0f00..61a99608731e 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -91,6 +91,16 @@ xfs_mark_inode_dirty_sync(
91 mark_inode_dirty_sync(inode); 91 mark_inode_dirty_sync(inode);
92} 92}
93 93
94void
95xfs_mark_inode_dirty(
96 xfs_inode_t *ip)
97{
98 struct inode *inode = VFS_I(ip);
99
100 if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR)))
101 mark_inode_dirty(inode);
102}
103
94/* 104/*
95 * Change the requested timestamp in the given inode. 105 * Change the requested timestamp in the given inode.
96 * We don't lock across timestamp updates, and we don't log them but 106 * We don't lock across timestamp updates, and we don't log them but
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 5af0c81ca1ae..facfb323a706 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -88,7 +88,6 @@
88#include <xfs_super.h> 88#include <xfs_super.h>
89#include <xfs_globals.h> 89#include <xfs_globals.h>
90#include <xfs_fs_subr.h> 90#include <xfs_fs_subr.h>
91#include <xfs_lrw.h>
92#include <xfs_buf.h> 91#include <xfs_buf.h>
93 92
94/* 93/*
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
deleted file mode 100644
index eac6f80d786d..000000000000
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ /dev/null
@@ -1,796 +0,0 @@
1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_bit.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_alloc.h"
28#include "xfs_dmapi.h"
29#include "xfs_quota.h"
30#include "xfs_mount.h"
31#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h"
34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
36#include "xfs_dinode.h"
37#include "xfs_inode.h"
38#include "xfs_bmap.h"
39#include "xfs_btree.h"
40#include "xfs_ialloc.h"
41#include "xfs_rtalloc.h"
42#include "xfs_error.h"
43#include "xfs_itable.h"
44#include "xfs_rw.h"
45#include "xfs_attr.h"
46#include "xfs_inode_item.h"
47#include "xfs_buf_item.h"
48#include "xfs_utils.h"
49#include "xfs_iomap.h"
50#include "xfs_vnodeops.h"
51#include "xfs_trace.h"
52
53#include <linux/capability.h>
54#include <linux/writeback.h>
55
56
57/*
58 * xfs_iozero
59 *
60 * xfs_iozero clears the specified range of buffer supplied,
61 * and marks all the affected blocks as valid and modified. If
62 * an affected block is not allocated, it will be allocated. If
63 * an affected block is not completely overwritten, and is not
64 * valid before the operation, it will be read from disk before
65 * being partially zeroed.
66 */
67STATIC int
68xfs_iozero(
69 struct xfs_inode *ip, /* inode */
70 loff_t pos, /* offset in file */
71 size_t count) /* size of data to zero */
72{
73 struct page *page;
74 struct address_space *mapping;
75 int status;
76
77 mapping = VFS_I(ip)->i_mapping;
78 do {
79 unsigned offset, bytes;
80 void *fsdata;
81
82 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
83 bytes = PAGE_CACHE_SIZE - offset;
84 if (bytes > count)
85 bytes = count;
86
87 status = pagecache_write_begin(NULL, mapping, pos, bytes,
88 AOP_FLAG_UNINTERRUPTIBLE,
89 &page, &fsdata);
90 if (status)
91 break;
92
93 zero_user(page, offset, bytes);
94
95 status = pagecache_write_end(NULL, mapping, pos, bytes, bytes,
96 page, fsdata);
97 WARN_ON(status <= 0); /* can't return less than zero! */
98 pos += bytes;
99 count -= bytes;
100 status = 0;
101 } while (count);
102
103 return (-status);
104}
105
106ssize_t /* bytes read, or (-) error */
107xfs_read(
108 xfs_inode_t *ip,
109 struct kiocb *iocb,
110 const struct iovec *iovp,
111 unsigned int segs,
112 loff_t *offset,
113 int ioflags)
114{
115 struct file *file = iocb->ki_filp;
116 struct inode *inode = file->f_mapping->host;
117 xfs_mount_t *mp = ip->i_mount;
118 size_t size = 0;
119 ssize_t ret = 0;
120 xfs_fsize_t n;
121 unsigned long seg;
122
123
124 XFS_STATS_INC(xs_read_calls);
125
126 /* START copy & waste from filemap.c */
127 for (seg = 0; seg < segs; seg++) {
128 const struct iovec *iv = &iovp[seg];
129
130 /*
131 * If any segment has a negative length, or the cumulative
132 * length ever wraps negative then return -EINVAL.
133 */
134 size += iv->iov_len;
135 if (unlikely((ssize_t)(size|iv->iov_len) < 0))
136 return XFS_ERROR(-EINVAL);
137 }
138 /* END copy & waste from filemap.c */
139
140 if (unlikely(ioflags & IO_ISDIRECT)) {
141 xfs_buftarg_t *target =
142 XFS_IS_REALTIME_INODE(ip) ?
143 mp->m_rtdev_targp : mp->m_ddev_targp;
144 if ((*offset & target->bt_smask) ||
145 (size & target->bt_smask)) {
146 if (*offset == ip->i_size) {
147 return (0);
148 }
149 return -XFS_ERROR(EINVAL);
150 }
151 }
152
153 n = XFS_MAXIOFFSET(mp) - *offset;
154 if ((n <= 0) || (size == 0))
155 return 0;
156
157 if (n < size)
158 size = n;
159
160 if (XFS_FORCED_SHUTDOWN(mp))
161 return -EIO;
162
163 if (unlikely(ioflags & IO_ISDIRECT))
164 mutex_lock(&inode->i_mutex);
165 xfs_ilock(ip, XFS_IOLOCK_SHARED);
166
167 if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
168 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
169 int iolock = XFS_IOLOCK_SHARED;
170
171 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *offset, size,
172 dmflags, &iolock);
173 if (ret) {
174 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
175 if (unlikely(ioflags & IO_ISDIRECT))
176 mutex_unlock(&inode->i_mutex);
177 return ret;
178 }
179 }
180
181 if (unlikely(ioflags & IO_ISDIRECT)) {
182 if (inode->i_mapping->nrpages)
183 ret = -xfs_flushinval_pages(ip, (*offset & PAGE_CACHE_MASK),
184 -1, FI_REMAPF_LOCKED);
185 mutex_unlock(&inode->i_mutex);
186 if (ret) {
187 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
188 return ret;
189 }
190 }
191
192 trace_xfs_file_read(ip, size, *offset, ioflags);
193
194 iocb->ki_pos = *offset;
195 ret = generic_file_aio_read(iocb, iovp, segs, *offset);
196 if (ret > 0)
197 XFS_STATS_ADD(xs_read_bytes, ret);
198
199 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
200 return ret;
201}
202
203ssize_t
204xfs_splice_read(
205 xfs_inode_t *ip,
206 struct file *infilp,
207 loff_t *ppos,
208 struct pipe_inode_info *pipe,
209 size_t count,
210 int flags,
211 int ioflags)
212{
213 xfs_mount_t *mp = ip->i_mount;
214 ssize_t ret;
215
216 XFS_STATS_INC(xs_read_calls);
217 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
218 return -EIO;
219
220 xfs_ilock(ip, XFS_IOLOCK_SHARED);
221
222 if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
223 int iolock = XFS_IOLOCK_SHARED;
224 int error;
225
226 error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *ppos, count,
227 FILP_DELAY_FLAG(infilp), &iolock);
228 if (error) {
229 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
230 return -error;
231 }
232 }
233
234 trace_xfs_file_splice_read(ip, count, *ppos, ioflags);
235
236 ret = generic_file_splice_read(infilp, ppos, pipe, count, flags);
237 if (ret > 0)
238 XFS_STATS_ADD(xs_read_bytes, ret);
239
240 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
241 return ret;
242}
243
244ssize_t
245xfs_splice_write(
246 xfs_inode_t *ip,
247 struct pipe_inode_info *pipe,
248 struct file *outfilp,
249 loff_t *ppos,
250 size_t count,
251 int flags,
252 int ioflags)
253{
254 xfs_mount_t *mp = ip->i_mount;
255 ssize_t ret;
256 struct inode *inode = outfilp->f_mapping->host;
257 xfs_fsize_t isize, new_size;
258
259 XFS_STATS_INC(xs_write_calls);
260 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
261 return -EIO;
262
263 xfs_ilock(ip, XFS_IOLOCK_EXCL);
264
265 if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) {
266 int iolock = XFS_IOLOCK_EXCL;
267 int error;
268
269 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, *ppos, count,
270 FILP_DELAY_FLAG(outfilp), &iolock);
271 if (error) {
272 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
273 return -error;
274 }
275 }
276
277 new_size = *ppos + count;
278
279 xfs_ilock(ip, XFS_ILOCK_EXCL);
280 if (new_size > ip->i_size)
281 ip->i_new_size = new_size;
282 xfs_iunlock(ip, XFS_ILOCK_EXCL);
283
284 trace_xfs_file_splice_write(ip, count, *ppos, ioflags);
285
286 ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
287 if (ret > 0)
288 XFS_STATS_ADD(xs_write_bytes, ret);
289
290 isize = i_size_read(inode);
291 if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
292 *ppos = isize;
293
294 if (*ppos > ip->i_size) {
295 xfs_ilock(ip, XFS_ILOCK_EXCL);
296 if (*ppos > ip->i_size)
297 ip->i_size = *ppos;
298 xfs_iunlock(ip, XFS_ILOCK_EXCL);
299 }
300
301 if (ip->i_new_size) {
302 xfs_ilock(ip, XFS_ILOCK_EXCL);
303 ip->i_new_size = 0;
304 if (ip->i_d.di_size > ip->i_size)
305 ip->i_d.di_size = ip->i_size;
306 xfs_iunlock(ip, XFS_ILOCK_EXCL);
307 }
308 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
309 return ret;
310}
311
312/*
313 * This routine is called to handle zeroing any space in the last
314 * block of the file that is beyond the EOF. We do this since the
315 * size is being increased without writing anything to that block
316 * and we don't want anyone to read the garbage on the disk.
317 */
318STATIC int /* error (positive) */
319xfs_zero_last_block(
320 xfs_inode_t *ip,
321 xfs_fsize_t offset,
322 xfs_fsize_t isize)
323{
324 xfs_fileoff_t last_fsb;
325 xfs_mount_t *mp = ip->i_mount;
326 int nimaps;
327 int zero_offset;
328 int zero_len;
329 int error = 0;
330 xfs_bmbt_irec_t imap;
331
332 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
333
334 zero_offset = XFS_B_FSB_OFFSET(mp, isize);
335 if (zero_offset == 0) {
336 /*
337 * There are no extra bytes in the last block on disk to
338 * zero, so return.
339 */
340 return 0;
341 }
342
343 last_fsb = XFS_B_TO_FSBT(mp, isize);
344 nimaps = 1;
345 error = xfs_bmapi(NULL, ip, last_fsb, 1, 0, NULL, 0, &imap,
346 &nimaps, NULL, NULL);
347 if (error) {
348 return error;
349 }
350 ASSERT(nimaps > 0);
351 /*
352 * If the block underlying isize is just a hole, then there
353 * is nothing to zero.
354 */
355 if (imap.br_startblock == HOLESTARTBLOCK) {
356 return 0;
357 }
358 /*
359 * Zero the part of the last block beyond the EOF, and write it
360 * out sync. We need to drop the ilock while we do this so we
361 * don't deadlock when the buffer cache calls back to us.
362 */
363 xfs_iunlock(ip, XFS_ILOCK_EXCL);
364
365 zero_len = mp->m_sb.sb_blocksize - zero_offset;
366 if (isize + zero_len > offset)
367 zero_len = offset - isize;
368 error = xfs_iozero(ip, isize, zero_len);
369
370 xfs_ilock(ip, XFS_ILOCK_EXCL);
371 ASSERT(error >= 0);
372 return error;
373}
374
375/*
376 * Zero any on disk space between the current EOF and the new,
377 * larger EOF. This handles the normal case of zeroing the remainder
378 * of the last block in the file and the unusual case of zeroing blocks
379 * out beyond the size of the file. This second case only happens
380 * with fixed size extents and when the system crashes before the inode
381 * size was updated but after blocks were allocated. If fill is set,
382 * then any holes in the range are filled and zeroed. If not, the holes
383 * are left alone as holes.
384 */
385
386int /* error (positive) */
387xfs_zero_eof(
388 xfs_inode_t *ip,
389 xfs_off_t offset, /* starting I/O offset */
390 xfs_fsize_t isize) /* current inode size */
391{
392 xfs_mount_t *mp = ip->i_mount;
393 xfs_fileoff_t start_zero_fsb;
394 xfs_fileoff_t end_zero_fsb;
395 xfs_fileoff_t zero_count_fsb;
396 xfs_fileoff_t last_fsb;
397 xfs_fileoff_t zero_off;
398 xfs_fsize_t zero_len;
399 int nimaps;
400 int error = 0;
401 xfs_bmbt_irec_t imap;
402
403 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
404 ASSERT(offset > isize);
405
406 /*
407 * First handle zeroing the block on which isize resides.
408 * We only zero a part of that block so it is handled specially.
409 */
410 error = xfs_zero_last_block(ip, offset, isize);
411 if (error) {
412 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
413 return error;
414 }
415
416 /*
417 * Calculate the range between the new size and the old
418 * where blocks needing to be zeroed may exist. To get the
419 * block where the last byte in the file currently resides,
420 * we need to subtract one from the size and truncate back
421 * to a block boundary. We subtract 1 in case the size is
422 * exactly on a block boundary.
423 */
424 last_fsb = isize ? XFS_B_TO_FSBT(mp, isize - 1) : (xfs_fileoff_t)-1;
425 start_zero_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)isize);
426 end_zero_fsb = XFS_B_TO_FSBT(mp, offset - 1);
427 ASSERT((xfs_sfiloff_t)last_fsb < (xfs_sfiloff_t)start_zero_fsb);
428 if (last_fsb == end_zero_fsb) {
429 /*
430 * The size was only incremented on its last block.
431 * We took care of that above, so just return.
432 */
433 return 0;
434 }
435
436 ASSERT(start_zero_fsb <= end_zero_fsb);
437 while (start_zero_fsb <= end_zero_fsb) {
438 nimaps = 1;
439 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
440 error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb,
441 0, NULL, 0, &imap, &nimaps, NULL, NULL);
442 if (error) {
443 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
444 return error;
445 }
446 ASSERT(nimaps > 0);
447
448 if (imap.br_state == XFS_EXT_UNWRITTEN ||
449 imap.br_startblock == HOLESTARTBLOCK) {
450 /*
451 * This loop handles initializing pages that were
452 * partially initialized by the code below this
453 * loop. It basically zeroes the part of the page
454 * that sits on a hole and sets the page as P_HOLE
455 * and calls remapf if it is a mapped file.
456 */
457 start_zero_fsb = imap.br_startoff + imap.br_blockcount;
458 ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
459 continue;
460 }
461
462 /*
463 * There are blocks we need to zero.
464 * Drop the inode lock while we're doing the I/O.
465 * We'll still have the iolock to protect us.
466 */
467 xfs_iunlock(ip, XFS_ILOCK_EXCL);
468
469 zero_off = XFS_FSB_TO_B(mp, start_zero_fsb);
470 zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount);
471
472 if ((zero_off + zero_len) > offset)
473 zero_len = offset - zero_off;
474
475 error = xfs_iozero(ip, zero_off, zero_len);
476 if (error) {
477 goto out_lock;
478 }
479
480 start_zero_fsb = imap.br_startoff + imap.br_blockcount;
481 ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
482
483 xfs_ilock(ip, XFS_ILOCK_EXCL);
484 }
485
486 return 0;
487
488out_lock:
489 xfs_ilock(ip, XFS_ILOCK_EXCL);
490 ASSERT(error >= 0);
491 return error;
492}
493
494ssize_t /* bytes written, or (-) error */
495xfs_write(
496 struct xfs_inode *xip,
497 struct kiocb *iocb,
498 const struct iovec *iovp,
499 unsigned int nsegs,
500 loff_t *offset,
501 int ioflags)
502{
503 struct file *file = iocb->ki_filp;
504 struct address_space *mapping = file->f_mapping;
505 struct inode *inode = mapping->host;
506 unsigned long segs = nsegs;
507 xfs_mount_t *mp;
508 ssize_t ret = 0, error = 0;
509 xfs_fsize_t isize, new_size;
510 int iolock;
511 int eventsent = 0;
512 size_t ocount = 0, count;
513 loff_t pos;
514 int need_i_mutex;
515
516 XFS_STATS_INC(xs_write_calls);
517
518 error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ);
519 if (error)
520 return error;
521
522 count = ocount;
523 pos = *offset;
524
525 if (count == 0)
526 return 0;
527
528 mp = xip->i_mount;
529
530 xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
531
532 if (XFS_FORCED_SHUTDOWN(mp))
533 return -EIO;
534
535relock:
536 if (ioflags & IO_ISDIRECT) {
537 iolock = XFS_IOLOCK_SHARED;
538 need_i_mutex = 0;
539 } else {
540 iolock = XFS_IOLOCK_EXCL;
541 need_i_mutex = 1;
542 mutex_lock(&inode->i_mutex);
543 }
544
545 xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
546
547start:
548 error = -generic_write_checks(file, &pos, &count,
549 S_ISBLK(inode->i_mode));
550 if (error) {
551 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
552 goto out_unlock_mutex;
553 }
554
555 if ((DM_EVENT_ENABLED(xip, DM_EVENT_WRITE) &&
556 !(ioflags & IO_INVIS) && !eventsent)) {
557 int dmflags = FILP_DELAY_FLAG(file);
558
559 if (need_i_mutex)
560 dmflags |= DM_FLAGS_IMUX;
561
562 xfs_iunlock(xip, XFS_ILOCK_EXCL);
563 error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, xip,
564 pos, count, dmflags, &iolock);
565 if (error) {
566 goto out_unlock_internal;
567 }
568 xfs_ilock(xip, XFS_ILOCK_EXCL);
569 eventsent = 1;
570
571 /*
572 * The iolock was dropped and reacquired in XFS_SEND_DATA
573 * so we have to recheck the size when appending.
574 * We will only "goto start;" once, since having sent the
575 * event prevents another call to XFS_SEND_DATA, which is
576 * what allows the size to change in the first place.
577 */
578 if ((file->f_flags & O_APPEND) && pos != xip->i_size)
579 goto start;
580 }
581
582 if (ioflags & IO_ISDIRECT) {
583 xfs_buftarg_t *target =
584 XFS_IS_REALTIME_INODE(xip) ?
585 mp->m_rtdev_targp : mp->m_ddev_targp;
586
587 if ((pos & target->bt_smask) || (count & target->bt_smask)) {
588 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
589 return XFS_ERROR(-EINVAL);
590 }
591
592 if (!need_i_mutex && (mapping->nrpages || pos > xip->i_size)) {
593 xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
594 iolock = XFS_IOLOCK_EXCL;
595 need_i_mutex = 1;
596 mutex_lock(&inode->i_mutex);
597 xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
598 goto start;
599 }
600 }
601
602 new_size = pos + count;
603 if (new_size > xip->i_size)
604 xip->i_new_size = new_size;
605
606 if (likely(!(ioflags & IO_INVIS)))
607 file_update_time(file);
608
609 /*
610 * If the offset is beyond the size of the file, we have a couple
611 * of things to do. First, if there is already space allocated
612 * we need to either create holes or zero the disk or ...
613 *
614 * If there is a page where the previous size lands, we need
615 * to zero it out up to the new size.
616 */
617
618 if (pos > xip->i_size) {
619 error = xfs_zero_eof(xip, pos, xip->i_size);
620 if (error) {
621 xfs_iunlock(xip, XFS_ILOCK_EXCL);
622 goto out_unlock_internal;
623 }
624 }
625 xfs_iunlock(xip, XFS_ILOCK_EXCL);
626
627 /*
628 * If we're writing the file then make sure to clear the
629 * setuid and setgid bits if the process is not being run
630 * by root. This keeps people from modifying setuid and
631 * setgid binaries.
632 */
633 error = -file_remove_suid(file);
634 if (unlikely(error))
635 goto out_unlock_internal;
636
637 /* We can write back this queue in page reclaim */
638 current->backing_dev_info = mapping->backing_dev_info;
639
640 if ((ioflags & IO_ISDIRECT)) {
641 if (mapping->nrpages) {
642 WARN_ON(need_i_mutex == 0);
643 error = xfs_flushinval_pages(xip,
644 (pos & PAGE_CACHE_MASK),
645 -1, FI_REMAPF_LOCKED);
646 if (error)
647 goto out_unlock_internal;
648 }
649
650 if (need_i_mutex) {
651 /* demote the lock now the cached pages are gone */
652 xfs_ilock_demote(xip, XFS_IOLOCK_EXCL);
653 mutex_unlock(&inode->i_mutex);
654
655 iolock = XFS_IOLOCK_SHARED;
656 need_i_mutex = 0;
657 }
658
659 trace_xfs_file_direct_write(xip, count, *offset, ioflags);
660 ret = generic_file_direct_write(iocb, iovp,
661 &segs, pos, offset, count, ocount);
662
663 /*
664 * direct-io write to a hole: fall through to buffered I/O
665 * for completing the rest of the request.
666 */
667 if (ret >= 0 && ret != count) {
668 XFS_STATS_ADD(xs_write_bytes, ret);
669
670 pos += ret;
671 count -= ret;
672
673 ioflags &= ~IO_ISDIRECT;
674 xfs_iunlock(xip, iolock);
675 goto relock;
676 }
677 } else {
678 int enospc = 0;
679 ssize_t ret2 = 0;
680
681write_retry:
682 trace_xfs_file_buffered_write(xip, count, *offset, ioflags);
683 ret2 = generic_file_buffered_write(iocb, iovp, segs,
684 pos, offset, count, ret);
685 /*
686 * if we just got an ENOSPC, flush the inode now we
687 * aren't holding any page locks and retry *once*
688 */
689 if (ret2 == -ENOSPC && !enospc) {
690 error = xfs_flush_pages(xip, 0, -1, 0, FI_NONE);
691 if (error)
692 goto out_unlock_internal;
693 enospc = 1;
694 goto write_retry;
695 }
696 ret = ret2;
697 }
698
699 current->backing_dev_info = NULL;
700
701 isize = i_size_read(inode);
702 if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
703 *offset = isize;
704
705 if (*offset > xip->i_size) {
706 xfs_ilock(xip, XFS_ILOCK_EXCL);
707 if (*offset > xip->i_size)
708 xip->i_size = *offset;
709 xfs_iunlock(xip, XFS_ILOCK_EXCL);
710 }
711
712 if (ret == -ENOSPC &&
713 DM_EVENT_ENABLED(xip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) {
714 xfs_iunlock(xip, iolock);
715 if (need_i_mutex)
716 mutex_unlock(&inode->i_mutex);
717 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, xip,
718 DM_RIGHT_NULL, xip, DM_RIGHT_NULL, NULL, NULL,
719 0, 0, 0); /* Delay flag intentionally unused */
720 if (need_i_mutex)
721 mutex_lock(&inode->i_mutex);
722 xfs_ilock(xip, iolock);
723 if (error)
724 goto out_unlock_internal;
725 goto start;
726 }
727
728 error = -ret;
729 if (ret <= 0)
730 goto out_unlock_internal;
731
732 XFS_STATS_ADD(xs_write_bytes, ret);
733
734 /* Handle various SYNC-type writes */
735 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
736 loff_t end = pos + ret - 1;
737 int error2;
738
739 xfs_iunlock(xip, iolock);
740 if (need_i_mutex)
741 mutex_unlock(&inode->i_mutex);
742
743 error2 = filemap_write_and_wait_range(mapping, pos, end);
744 if (!error)
745 error = error2;
746 if (need_i_mutex)
747 mutex_lock(&inode->i_mutex);
748 xfs_ilock(xip, iolock);
749
750 error2 = xfs_fsync(xip);
751 if (!error)
752 error = error2;
753 }
754
755 out_unlock_internal:
756 if (xip->i_new_size) {
757 xfs_ilock(xip, XFS_ILOCK_EXCL);
758 xip->i_new_size = 0;
759 /*
760 * If this was a direct or synchronous I/O that failed (such
761 * as ENOSPC) then part of the I/O may have been written to
762 * disk before the error occured. In this case the on-disk
763 * file size may have been adjusted beyond the in-memory file
764 * size and now needs to be truncated back.
765 */
766 if (xip->i_d.di_size > xip->i_size)
767 xip->i_d.di_size = xip->i_size;
768 xfs_iunlock(xip, XFS_ILOCK_EXCL);
769 }
770 xfs_iunlock(xip, iolock);
771 out_unlock_mutex:
772 if (need_i_mutex)
773 mutex_unlock(&inode->i_mutex);
774 return -error;
775}
776
777/*
778 * If the underlying (data/log/rt) device is readonly, there are some
779 * operations that cannot proceed.
780 */
781int
782xfs_dev_is_read_only(
783 xfs_mount_t *mp,
784 char *message)
785{
786 if (xfs_readonly_buftarg(mp->m_ddev_targp) ||
787 xfs_readonly_buftarg(mp->m_logdev_targp) ||
788 (mp->m_rtdev_targp && xfs_readonly_buftarg(mp->m_rtdev_targp))) {
789 cmn_err(CE_NOTE,
790 "XFS: %s required on read-only device.", message);
791 cmn_err(CE_NOTE,
792 "XFS: write access unavailable, cannot proceed.");
793 return EROFS;
794 }
795 return 0;
796}
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
deleted file mode 100644
index 342ae8c0d011..000000000000
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_LRW_H__
19#define __XFS_LRW_H__
20
21struct xfs_mount;
22struct xfs_inode;
23struct xfs_buf;
24
25extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
26
27extern int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t);
28
29#endif /* __XFS_LRW_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index a9f6d20aff41..05cd85317f6f 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -607,7 +607,8 @@ xfssyncd(
607 set_freezable(); 607 set_freezable();
608 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); 608 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
609 for (;;) { 609 for (;;) {
610 timeleft = schedule_timeout_interruptible(timeleft); 610 if (list_empty(&mp->m_sync_list))
611 timeleft = schedule_timeout_interruptible(timeleft);
611 /* swsusp */ 612 /* swsusp */
612 try_to_freeze(); 613 try_to_freeze();
613 if (kthread_should_stop() && list_empty(&mp->m_sync_list)) 614 if (kthread_should_stop() && list_empty(&mp->m_sync_list))
@@ -627,8 +628,7 @@ xfssyncd(
627 list_add_tail(&mp->m_sync_work.w_list, 628 list_add_tail(&mp->m_sync_work.w_list,
628 &mp->m_sync_list); 629 &mp->m_sync_list);
629 } 630 }
630 list_for_each_entry_safe(work, n, &mp->m_sync_list, w_list) 631 list_splice_init(&mp->m_sync_list, &tmp);
631 list_move(&work->w_list, &tmp);
632 spin_unlock(&mp->m_sync_lock); 632 spin_unlock(&mp->m_sync_lock);
633 633
634 list_for_each_entry_safe(work, n, &tmp, w_list) { 634 list_for_each_entry_safe(work, n, &tmp, w_list) {
@@ -688,12 +688,12 @@ xfs_inode_set_reclaim_tag(
688 struct xfs_perag *pag; 688 struct xfs_perag *pag;
689 689
690 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); 690 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
691 read_lock(&pag->pag_ici_lock); 691 write_lock(&pag->pag_ici_lock);
692 spin_lock(&ip->i_flags_lock); 692 spin_lock(&ip->i_flags_lock);
693 __xfs_inode_set_reclaim_tag(pag, ip); 693 __xfs_inode_set_reclaim_tag(pag, ip);
694 __xfs_iflags_set(ip, XFS_IRECLAIMABLE); 694 __xfs_iflags_set(ip, XFS_IRECLAIMABLE);
695 spin_unlock(&ip->i_flags_lock); 695 spin_unlock(&ip->i_flags_lock);
696 read_unlock(&pag->pag_ici_lock); 696 write_unlock(&pag->pag_ici_lock);
697 xfs_perag_put(pag); 697 xfs_perag_put(pag);
698} 698}
699 699
diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c
index 856eb3c8d605..5a107601e969 100644
--- a/fs/xfs/linux-2.6/xfs_trace.c
+++ b/fs/xfs/linux-2.6/xfs_trace.c
@@ -52,22 +52,6 @@
52#include "quota/xfs_dquot.h" 52#include "quota/xfs_dquot.h"
53 53
54/* 54/*
55 * Format fsblock number into a static buffer & return it.
56 */
57STATIC char *xfs_fmtfsblock(xfs_fsblock_t bno)
58{
59 static char rval[50];
60
61 if (bno == NULLFSBLOCK)
62 sprintf(rval, "NULLFSBLOCK");
63 else if (isnullstartblock(bno))
64 sprintf(rval, "NULLSTARTBLOCK(%lld)", startblockval(bno));
65 else
66 sprintf(rval, "%lld", (xfs_dfsbno_t)bno);
67 return rval;
68}
69
70/*
71 * We include this last to have the helpers above available for the trace 55 * We include this last to have the helpers above available for the trace
72 * event implementations. 56 * event implementations.
73 */ 57 */
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index a4574dcf5065..fcaa62f0799e 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -197,13 +197,13 @@ TRACE_EVENT(xfs_iext_insert,
197 __entry->caller_ip = caller_ip; 197 __entry->caller_ip = caller_ip;
198 ), 198 ),
199 TP_printk("dev %d:%d ino 0x%llx state %s idx %ld " 199 TP_printk("dev %d:%d ino 0x%llx state %s idx %ld "
200 "offset %lld block %s count %lld flag %d caller %pf", 200 "offset %lld block %lld count %lld flag %d caller %pf",
201 MAJOR(__entry->dev), MINOR(__entry->dev), 201 MAJOR(__entry->dev), MINOR(__entry->dev),
202 __entry->ino, 202 __entry->ino,
203 __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS), 203 __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS),
204 (long)__entry->idx, 204 (long)__entry->idx,
205 __entry->startoff, 205 __entry->startoff,
206 xfs_fmtfsblock(__entry->startblock), 206 (__int64_t)__entry->startblock,
207 __entry->blockcount, 207 __entry->blockcount,
208 __entry->state, 208 __entry->state,
209 (char *)__entry->caller_ip) 209 (char *)__entry->caller_ip)
@@ -241,13 +241,13 @@ DECLARE_EVENT_CLASS(xfs_bmap_class,
241 __entry->caller_ip = caller_ip; 241 __entry->caller_ip = caller_ip;
242 ), 242 ),
243 TP_printk("dev %d:%d ino 0x%llx state %s idx %ld " 243 TP_printk("dev %d:%d ino 0x%llx state %s idx %ld "
244 "offset %lld block %s count %lld flag %d caller %pf", 244 "offset %lld block %lld count %lld flag %d caller %pf",
245 MAJOR(__entry->dev), MINOR(__entry->dev), 245 MAJOR(__entry->dev), MINOR(__entry->dev),
246 __entry->ino, 246 __entry->ino,
247 __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS), 247 __print_flags(__entry->bmap_state, "|", XFS_BMAP_EXT_FLAGS),
248 (long)__entry->idx, 248 (long)__entry->idx,
249 __entry->startoff, 249 __entry->startoff,
250 xfs_fmtfsblock(__entry->startblock), 250 (__int64_t)__entry->startblock,
251 __entry->blockcount, 251 __entry->blockcount,
252 __entry->state, 252 __entry->state,
253 (char *)__entry->caller_ip) 253 (char *)__entry->caller_ip)
@@ -593,7 +593,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
593 TP_ARGS(dqp), 593 TP_ARGS(dqp),
594 TP_STRUCT__entry( 594 TP_STRUCT__entry(
595 __field(dev_t, dev) 595 __field(dev_t, dev)
596 __field(__be32, id) 596 __field(u32, id)
597 __field(unsigned, flags) 597 __field(unsigned, flags)
598 __field(unsigned, nrefs) 598 __field(unsigned, nrefs)
599 __field(unsigned long long, res_bcount) 599 __field(unsigned long long, res_bcount)
@@ -606,7 +606,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
606 ), \ 606 ), \
607 TP_fast_assign( 607 TP_fast_assign(
608 __entry->dev = dqp->q_mount->m_super->s_dev; 608 __entry->dev = dqp->q_mount->m_super->s_dev;
609 __entry->id = dqp->q_core.d_id; 609 __entry->id = be32_to_cpu(dqp->q_core.d_id);
610 __entry->flags = dqp->dq_flags; 610 __entry->flags = dqp->dq_flags;
611 __entry->nrefs = dqp->q_nrefs; 611 __entry->nrefs = dqp->q_nrefs;
612 __entry->res_bcount = dqp->q_res_bcount; 612 __entry->res_bcount = dqp->q_res_bcount;
@@ -622,10 +622,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
622 be64_to_cpu(dqp->q_core.d_ino_softlimit); 622 be64_to_cpu(dqp->q_core.d_ino_softlimit);
623 ), 623 ),
624 TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx " 624 TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
625 "bcnt 0x%llx [hard 0x%llx | soft 0x%llx] " 625 "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
626 "icnt 0x%llx [hard 0x%llx | soft 0x%llx]", 626 "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]",
627 MAJOR(__entry->dev), MINOR(__entry->dev), 627 MAJOR(__entry->dev), MINOR(__entry->dev),
628 be32_to_cpu(__entry->id), 628 __entry->id,
629 __print_flags(__entry->flags, "|", XFS_DQ_FLAGS), 629 __print_flags(__entry->flags, "|", XFS_DQ_FLAGS),
630 __entry->nrefs, 630 __entry->nrefs,
631 __entry->res_bcount, 631 __entry->res_bcount,
@@ -881,7 +881,7 @@ TRACE_EVENT(name, \
881 ), \ 881 ), \
882 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \ 882 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " \
883 "offset 0x%llx count %zd flags %s " \ 883 "offset 0x%llx count %zd flags %s " \
884 "startoff 0x%llx startblock %s blockcount 0x%llx", \ 884 "startoff 0x%llx startblock %lld blockcount 0x%llx", \
885 MAJOR(__entry->dev), MINOR(__entry->dev), \ 885 MAJOR(__entry->dev), MINOR(__entry->dev), \
886 __entry->ino, \ 886 __entry->ino, \
887 __entry->size, \ 887 __entry->size, \
@@ -890,7 +890,7 @@ TRACE_EVENT(name, \
890 __entry->count, \ 890 __entry->count, \
891 __print_flags(__entry->flags, "|", BMAPI_FLAGS), \ 891 __print_flags(__entry->flags, "|", BMAPI_FLAGS), \
892 __entry->startoff, \ 892 __entry->startoff, \
893 xfs_fmtfsblock(__entry->startblock), \ 893 (__int64_t)__entry->startblock, \
894 __entry->blockcount) \ 894 __entry->blockcount) \
895) 895)
896DEFINE_IOMAP_EVENT(xfs_iomap_enter); 896DEFINE_IOMAP_EVENT(xfs_iomap_enter);
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 1869fb973819..5c11e4d17010 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2550,22 +2550,134 @@ xfs_bmap_rtalloc(
2550} 2550}
2551 2551
2552STATIC int 2552STATIC int
2553xfs_bmap_btalloc_nullfb(
2554 struct xfs_bmalloca *ap,
2555 struct xfs_alloc_arg *args,
2556 xfs_extlen_t *blen)
2557{
2558 struct xfs_mount *mp = ap->ip->i_mount;
2559 struct xfs_perag *pag;
2560 xfs_agnumber_t ag, startag;
2561 int notinit = 0;
2562 int error;
2563
2564 if (ap->userdata && xfs_inode_is_filestream(ap->ip))
2565 args->type = XFS_ALLOCTYPE_NEAR_BNO;
2566 else
2567 args->type = XFS_ALLOCTYPE_START_BNO;
2568 args->total = ap->total;
2569
2570 /*
2571 * Search for an allocation group with a single extent large enough
2572 * for the request. If one isn't found, then adjust the minimum
2573 * allocation size to the largest space found.
2574 */
2575 startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
2576 if (startag == NULLAGNUMBER)
2577 startag = ag = 0;
2578
2579 pag = xfs_perag_get(mp, ag);
2580 while (*blen < ap->alen) {
2581 if (!pag->pagf_init) {
2582 error = xfs_alloc_pagf_init(mp, args->tp, ag,
2583 XFS_ALLOC_FLAG_TRYLOCK);
2584 if (error) {
2585 xfs_perag_put(pag);
2586 return error;
2587 }
2588 }
2589
2590 /*
2591 * See xfs_alloc_fix_freelist...
2592 */
2593 if (pag->pagf_init) {
2594 xfs_extlen_t longest;
2595 longest = xfs_alloc_longest_free_extent(mp, pag);
2596 if (*blen < longest)
2597 *blen = longest;
2598 } else
2599 notinit = 1;
2600
2601 if (xfs_inode_is_filestream(ap->ip)) {
2602 if (*blen >= ap->alen)
2603 break;
2604
2605 if (ap->userdata) {
2606 /*
2607 * If startag is an invalid AG, we've
2608 * come here once before and
2609 * xfs_filestream_new_ag picked the
2610 * best currently available.
2611 *
2612 * Don't continue looping, since we
2613 * could loop forever.
2614 */
2615 if (startag == NULLAGNUMBER)
2616 break;
2617
2618 error = xfs_filestream_new_ag(ap, &ag);
2619 xfs_perag_put(pag);
2620 if (error)
2621 return error;
2622
2623 /* loop again to set 'blen'*/
2624 startag = NULLAGNUMBER;
2625 pag = xfs_perag_get(mp, ag);
2626 continue;
2627 }
2628 }
2629 if (++ag == mp->m_sb.sb_agcount)
2630 ag = 0;
2631 if (ag == startag)
2632 break;
2633 xfs_perag_put(pag);
2634 pag = xfs_perag_get(mp, ag);
2635 }
2636 xfs_perag_put(pag);
2637
2638 /*
2639 * Since the above loop did a BUF_TRYLOCK, it is
2640 * possible that there is space for this request.
2641 */
2642 if (notinit || *blen < ap->minlen)
2643 args->minlen = ap->minlen;
2644 /*
2645 * If the best seen length is less than the request
2646 * length, use the best as the minimum.
2647 */
2648 else if (*blen < ap->alen)
2649 args->minlen = *blen;
2650 /*
2651 * Otherwise we've seen an extent as big as alen,
2652 * use that as the minimum.
2653 */
2654 else
2655 args->minlen = ap->alen;
2656
2657 /*
2658 * set the failure fallback case to look in the selected
2659 * AG as the stream may have moved.
2660 */
2661 if (xfs_inode_is_filestream(ap->ip))
2662 ap->rval = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
2663
2664 return 0;
2665}
2666
2667STATIC int
2553xfs_bmap_btalloc( 2668xfs_bmap_btalloc(
2554 xfs_bmalloca_t *ap) /* bmap alloc argument struct */ 2669 xfs_bmalloca_t *ap) /* bmap alloc argument struct */
2555{ 2670{
2556 xfs_mount_t *mp; /* mount point structure */ 2671 xfs_mount_t *mp; /* mount point structure */
2557 xfs_alloctype_t atype = 0; /* type for allocation routines */ 2672 xfs_alloctype_t atype = 0; /* type for allocation routines */
2558 xfs_extlen_t align; /* minimum allocation alignment */ 2673 xfs_extlen_t align; /* minimum allocation alignment */
2559 xfs_agnumber_t ag;
2560 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */ 2674 xfs_agnumber_t fb_agno; /* ag number of ap->firstblock */
2561 xfs_agnumber_t startag; 2675 xfs_agnumber_t ag;
2562 xfs_alloc_arg_t args; 2676 xfs_alloc_arg_t args;
2563 xfs_extlen_t blen; 2677 xfs_extlen_t blen;
2564 xfs_extlen_t nextminlen = 0; 2678 xfs_extlen_t nextminlen = 0;
2565 xfs_perag_t *pag;
2566 int nullfb; /* true if ap->firstblock isn't set */ 2679 int nullfb; /* true if ap->firstblock isn't set */
2567 int isaligned; 2680 int isaligned;
2568 int notinit;
2569 int tryagain; 2681 int tryagain;
2570 int error; 2682 int error;
2571 2683
@@ -2612,103 +2724,9 @@ xfs_bmap_btalloc(
2612 args.firstblock = ap->firstblock; 2724 args.firstblock = ap->firstblock;
2613 blen = 0; 2725 blen = 0;
2614 if (nullfb) { 2726 if (nullfb) {
2615 if (ap->userdata && xfs_inode_is_filestream(ap->ip)) 2727 error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
2616 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2728 if (error)
2617 else 2729 return error;
2618 args.type = XFS_ALLOCTYPE_START_BNO;
2619 args.total = ap->total;
2620
2621 /*
2622 * Search for an allocation group with a single extent
2623 * large enough for the request.
2624 *
2625 * If one isn't found, then adjust the minimum allocation
2626 * size to the largest space found.
2627 */
2628 startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno);
2629 if (startag == NULLAGNUMBER)
2630 startag = ag = 0;
2631 notinit = 0;
2632 pag = xfs_perag_get(mp, ag);
2633 while (blen < ap->alen) {
2634 if (!pag->pagf_init &&
2635 (error = xfs_alloc_pagf_init(mp, args.tp,
2636 ag, XFS_ALLOC_FLAG_TRYLOCK))) {
2637 xfs_perag_put(pag);
2638 return error;
2639 }
2640 /*
2641 * See xfs_alloc_fix_freelist...
2642 */
2643 if (pag->pagf_init) {
2644 xfs_extlen_t longest;
2645 longest = xfs_alloc_longest_free_extent(mp, pag);
2646 if (blen < longest)
2647 blen = longest;
2648 } else
2649 notinit = 1;
2650
2651 if (xfs_inode_is_filestream(ap->ip)) {
2652 if (blen >= ap->alen)
2653 break;
2654
2655 if (ap->userdata) {
2656 /*
2657 * If startag is an invalid AG, we've
2658 * come here once before and
2659 * xfs_filestream_new_ag picked the
2660 * best currently available.
2661 *
2662 * Don't continue looping, since we
2663 * could loop forever.
2664 */
2665 if (startag == NULLAGNUMBER)
2666 break;
2667
2668 error = xfs_filestream_new_ag(ap, &ag);
2669 xfs_perag_put(pag);
2670 if (error)
2671 return error;
2672
2673 /* loop again to set 'blen'*/
2674 startag = NULLAGNUMBER;
2675 pag = xfs_perag_get(mp, ag);
2676 continue;
2677 }
2678 }
2679 if (++ag == mp->m_sb.sb_agcount)
2680 ag = 0;
2681 if (ag == startag)
2682 break;
2683 xfs_perag_put(pag);
2684 pag = xfs_perag_get(mp, ag);
2685 }
2686 xfs_perag_put(pag);
2687 /*
2688 * Since the above loop did a BUF_TRYLOCK, it is
2689 * possible that there is space for this request.
2690 */
2691 if (notinit || blen < ap->minlen)
2692 args.minlen = ap->minlen;
2693 /*
2694 * If the best seen length is less than the request
2695 * length, use the best as the minimum.
2696 */
2697 else if (blen < ap->alen)
2698 args.minlen = blen;
2699 /*
2700 * Otherwise we've seen an extent as big as alen,
2701 * use that as the minimum.
2702 */
2703 else
2704 args.minlen = ap->alen;
2705
2706 /*
2707 * set the failure fallback case to look in the selected
2708 * AG as the stream may have moved.
2709 */
2710 if (xfs_inode_is_filestream(ap->ip))
2711 ap->rval = args.fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
2712 } else if (ap->low) { 2730 } else if (ap->low) {
2713 if (xfs_inode_is_filestream(ap->ip)) 2731 if (xfs_inode_is_filestream(ap->ip))
2714 args.type = XFS_ALLOCTYPE_FIRST_AG; 2732 args.type = XFS_ALLOCTYPE_FIRST_AG;
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index f52ac276277e..7cf7220e7d5f 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -292,7 +292,8 @@ typedef struct xfs_bstat {
292 __s32 bs_extents; /* number of extents */ 292 __s32 bs_extents; /* number of extents */
293 __u32 bs_gen; /* generation count */ 293 __u32 bs_gen; /* generation count */
294 __u16 bs_projid; /* project id */ 294 __u16 bs_projid; /* project id */
295 unsigned char bs_pad[14]; /* pad space, unused */ 295 __u16 bs_forkoff; /* inode fork offset in bytes */
296 unsigned char bs_pad[12]; /* pad space, unused */
296 __u32 bs_dmevmask; /* DMIG event mask */ 297 __u32 bs_dmevmask; /* DMIG event mask */
297 __u16 bs_dmstate; /* DMIG state info */ 298 __u16 bs_dmstate; /* DMIG state info */
298 __u16 bs_aextents; /* attribute number of extents */ 299 __u16 bs_aextents; /* attribute number of extents */
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index e281eb4a1c49..6845db90818f 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -190,13 +190,12 @@ xfs_iget_cache_hit(
190 trace_xfs_iget_reclaim(ip); 190 trace_xfs_iget_reclaim(ip);
191 191
192 /* 192 /*
193 * We need to set XFS_INEW atomically with clearing the 193 * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode
194 * reclaimable tag so that we do have an indicator of the 194 * from stomping over us while we recycle the inode. We can't
195 * inode still being initialized. 195 * clear the radix tree reclaimable tag yet as it requires
196 * pag_ici_lock to be held exclusive.
196 */ 197 */
197 ip->i_flags |= XFS_INEW; 198 ip->i_flags |= XFS_IRECLAIM;
198 ip->i_flags &= ~XFS_IRECLAIMABLE;
199 __xfs_inode_clear_reclaim_tag(mp, pag, ip);
200 199
201 spin_unlock(&ip->i_flags_lock); 200 spin_unlock(&ip->i_flags_lock);
202 read_unlock(&pag->pag_ici_lock); 201 read_unlock(&pag->pag_ici_lock);
@@ -216,7 +215,15 @@ xfs_iget_cache_hit(
216 trace_xfs_iget_reclaim(ip); 215 trace_xfs_iget_reclaim(ip);
217 goto out_error; 216 goto out_error;
218 } 217 }
218
219 write_lock(&pag->pag_ici_lock);
220 spin_lock(&ip->i_flags_lock);
221 ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM);
222 ip->i_flags |= XFS_INEW;
223 __xfs_inode_clear_reclaim_tag(mp, pag, ip);
219 inode->i_state = I_NEW; 224 inode->i_state = I_NEW;
225 spin_unlock(&ip->i_flags_lock);
226 write_unlock(&pag->pag_ici_lock);
220 } else { 227 } else {
221 /* If the VFS inode is being torn down, pause and try again. */ 228 /* If the VFS inode is being torn down, pause and try again. */
222 if (!igrab(inode)) { 229 if (!igrab(inode)) {
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index fa31360046d4..0ffd56447045 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2439,75 +2439,31 @@ xfs_idestroy_fork(
2439} 2439}
2440 2440
2441/* 2441/*
2442 * Increment the pin count of the given buffer. 2442 * This is called to unpin an inode. The caller must have the inode locked
2443 * This value is protected by ipinlock spinlock in the mount structure. 2443 * in at least shared mode so that the buffer cannot be subsequently pinned
2444 * once someone is waiting for it to be unpinned.
2444 */ 2445 */
2445void 2446static void
2446xfs_ipin( 2447xfs_iunpin_nowait(
2447 xfs_inode_t *ip) 2448 struct xfs_inode *ip)
2448{
2449 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2450
2451 atomic_inc(&ip->i_pincount);
2452}
2453
2454/*
2455 * Decrement the pin count of the given inode, and wake up
2456 * anyone in xfs_iwait_unpin() if the count goes to 0. The
2457 * inode must have been previously pinned with a call to xfs_ipin().
2458 */
2459void
2460xfs_iunpin(
2461 xfs_inode_t *ip)
2462{
2463 ASSERT(atomic_read(&ip->i_pincount) > 0);
2464
2465 if (atomic_dec_and_test(&ip->i_pincount))
2466 wake_up(&ip->i_ipin_wait);
2467}
2468
2469/*
2470 * This is called to unpin an inode. It can be directed to wait or to return
2471 * immediately without waiting for the inode to be unpinned. The caller must
2472 * have the inode locked in at least shared mode so that the buffer cannot be
2473 * subsequently pinned once someone is waiting for it to be unpinned.
2474 */
2475STATIC void
2476__xfs_iunpin_wait(
2477 xfs_inode_t *ip,
2478 int wait)
2479{ 2449{
2480 xfs_inode_log_item_t *iip = ip->i_itemp;
2481
2482 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 2450 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
2483 if (atomic_read(&ip->i_pincount) == 0)
2484 return;
2485 2451
2486 /* Give the log a push to start the unpinning I/O */ 2452 /* Give the log a push to start the unpinning I/O */
2487 if (iip && iip->ili_last_lsn) 2453 xfs_log_force_lsn(ip->i_mount, ip->i_itemp->ili_last_lsn, 0);
2488 xfs_log_force_lsn(ip->i_mount, iip->ili_last_lsn, 0);
2489 else
2490 xfs_log_force(ip->i_mount, 0);
2491 2454
2492 if (wait)
2493 wait_event(ip->i_ipin_wait, (atomic_read(&ip->i_pincount) == 0));
2494} 2455}
2495 2456
2496void 2457void
2497xfs_iunpin_wait( 2458xfs_iunpin_wait(
2498 xfs_inode_t *ip) 2459 struct xfs_inode *ip)
2499{ 2460{
2500 __xfs_iunpin_wait(ip, 1); 2461 if (xfs_ipincount(ip)) {
2501} 2462 xfs_iunpin_nowait(ip);
2502 2463 wait_event(ip->i_ipin_wait, (xfs_ipincount(ip) == 0));
2503static inline void 2464 }
2504xfs_iunpin_nowait(
2505 xfs_inode_t *ip)
2506{
2507 __xfs_iunpin_wait(ip, 0);
2508} 2465}
2509 2466
2510
2511/* 2467/*
2512 * xfs_iextents_copy() 2468 * xfs_iextents_copy()
2513 * 2469 *
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 6c912b027596..9965e40a4615 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -471,8 +471,6 @@ int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
471int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); 471int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
472 472
473void xfs_iext_realloc(xfs_inode_t *, int, int); 473void xfs_iext_realloc(xfs_inode_t *, int, int);
474void xfs_ipin(xfs_inode_t *);
475void xfs_iunpin(xfs_inode_t *);
476void xfs_iunpin_wait(xfs_inode_t *); 474void xfs_iunpin_wait(xfs_inode_t *);
477int xfs_iflush(xfs_inode_t *, uint); 475int xfs_iflush(xfs_inode_t *, uint);
478void xfs_ichgtime(xfs_inode_t *, int); 476void xfs_ichgtime(xfs_inode_t *, int);
@@ -480,6 +478,7 @@ void xfs_lock_inodes(xfs_inode_t **, int, uint);
480void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); 478void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
481 479
482void xfs_synchronize_times(xfs_inode_t *); 480void xfs_synchronize_times(xfs_inode_t *);
481void xfs_mark_inode_dirty(xfs_inode_t *);
483void xfs_mark_inode_dirty_sync(xfs_inode_t *); 482void xfs_mark_inode_dirty_sync(xfs_inode_t *);
484 483
485#define IHOLD(ip) \ 484#define IHOLD(ip) \
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index d4dc063111f8..7bfea8540159 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -535,23 +535,23 @@ xfs_inode_item_format(
535 535
536/* 536/*
537 * This is called to pin the inode associated with the inode log 537 * This is called to pin the inode associated with the inode log
538 * item in memory so it cannot be written out. Do this by calling 538 * item in memory so it cannot be written out.
539 * xfs_ipin() to bump the pin count in the inode while holding the
540 * inode pin lock.
541 */ 539 */
542STATIC void 540STATIC void
543xfs_inode_item_pin( 541xfs_inode_item_pin(
544 xfs_inode_log_item_t *iip) 542 xfs_inode_log_item_t *iip)
545{ 543{
546 ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL)); 544 ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL));
547 xfs_ipin(iip->ili_inode); 545
546 atomic_inc(&iip->ili_inode->i_pincount);
548} 547}
549 548
550 549
551/* 550/*
552 * This is called to unpin the inode associated with the inode log 551 * This is called to unpin the inode associated with the inode log
553 * item which was previously pinned with a call to xfs_inode_item_pin(). 552 * item which was previously pinned with a call to xfs_inode_item_pin().
554 * Just call xfs_iunpin() on the inode to do this. 553 *
554 * Also wake up anyone in xfs_iunpin_wait() if the count goes to 0.
555 */ 555 */
556/* ARGSUSED */ 556/* ARGSUSED */
557STATIC void 557STATIC void
@@ -559,7 +559,11 @@ xfs_inode_item_unpin(
559 xfs_inode_log_item_t *iip, 559 xfs_inode_log_item_t *iip,
560 int stale) 560 int stale)
561{ 561{
562 xfs_iunpin(iip->ili_inode); 562 struct xfs_inode *ip = iip->ili_inode;
563
564 ASSERT(atomic_read(&ip->i_pincount) > 0);
565 if (atomic_dec_and_test(&ip->i_pincount))
566 wake_up(&ip->i_ipin_wait);
563} 567}
564 568
565/* ARGSUSED */ 569/* ARGSUSED */
@@ -568,7 +572,7 @@ xfs_inode_item_unpin_remove(
568 xfs_inode_log_item_t *iip, 572 xfs_inode_log_item_t *iip,
569 xfs_trans_t *tp) 573 xfs_trans_t *tp)
570{ 574{
571 xfs_iunpin(iip->ili_inode); 575 xfs_inode_item_unpin(iip, 0);
572} 576}
573 577
574/* 578/*
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 3af02314c605..b1b801e4a28e 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -106,6 +106,7 @@ xfs_bulkstat_one_iget(
106 buf->bs_dmevmask = dic->di_dmevmask; 106 buf->bs_dmevmask = dic->di_dmevmask;
107 buf->bs_dmstate = dic->di_dmstate; 107 buf->bs_dmstate = dic->di_dmstate;
108 buf->bs_aextents = dic->di_anextents; 108 buf->bs_aextents = dic->di_anextents;
109 buf->bs_forkoff = XFS_IFORK_BOFF(ip);
109 110
110 switch (dic->di_format) { 111 switch (dic->di_format) {
111 case XFS_DINODE_FMT_DEV: 112 case XFS_DINODE_FMT_DEV:
@@ -176,6 +177,7 @@ xfs_bulkstat_one_dinode(
176 buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask); 177 buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask);
177 buf->bs_dmstate = be16_to_cpu(dic->di_dmstate); 178 buf->bs_dmstate = be16_to_cpu(dic->di_dmstate);
178 buf->bs_aextents = be16_to_cpu(dic->di_anextents); 179 buf->bs_aextents = be16_to_cpu(dic->di_anextents);
180 buf->bs_forkoff = XFS_DFORK_BOFF(dic);
179 181
180 switch (dic->di_format) { 182 switch (dic->di_format) {
181 case XFS_DINODE_FMT_DEV: 183 case XFS_DINODE_FMT_DEV:
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 4f16be4b6ee5..e8fba92d7cd9 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -60,7 +60,7 @@ STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes);
60STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); 60STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
61STATIC void xlog_dealloc_log(xlog_t *log); 61STATIC void xlog_dealloc_log(xlog_t *log);
62STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[], 62STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
63 int nentries, xfs_log_ticket_t tic, 63 int nentries, struct xlog_ticket *tic,
64 xfs_lsn_t *start_lsn, 64 xfs_lsn_t *start_lsn,
65 xlog_in_core_t **commit_iclog, 65 xlog_in_core_t **commit_iclog,
66 uint flags); 66 uint flags);
@@ -243,14 +243,14 @@ xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type)
243 * out when the next write occurs. 243 * out when the next write occurs.
244 */ 244 */
245xfs_lsn_t 245xfs_lsn_t
246xfs_log_done(xfs_mount_t *mp, 246xfs_log_done(
247 xfs_log_ticket_t xtic, 247 struct xfs_mount *mp,
248 void **iclog, 248 struct xlog_ticket *ticket,
249 uint flags) 249 struct xlog_in_core **iclog,
250 uint flags)
250{ 251{
251 xlog_t *log = mp->m_log; 252 struct log *log = mp->m_log;
252 xlog_ticket_t *ticket = (xfs_log_ticket_t) xtic; 253 xfs_lsn_t lsn = 0;
253 xfs_lsn_t lsn = 0;
254 254
255 if (XLOG_FORCED_SHUTDOWN(log) || 255 if (XLOG_FORCED_SHUTDOWN(log) ||
256 /* 256 /*
@@ -258,8 +258,7 @@ xfs_log_done(xfs_mount_t *mp,
258 * If we get an error, just continue and give back the log ticket. 258 * If we get an error, just continue and give back the log ticket.
259 */ 259 */
260 (((ticket->t_flags & XLOG_TIC_INITED) == 0) && 260 (((ticket->t_flags & XLOG_TIC_INITED) == 0) &&
261 (xlog_commit_record(mp, ticket, 261 (xlog_commit_record(mp, ticket, iclog, &lsn)))) {
262 (xlog_in_core_t **)iclog, &lsn)))) {
263 lsn = (xfs_lsn_t) -1; 262 lsn = (xfs_lsn_t) -1;
264 if (ticket->t_flags & XLOG_TIC_PERM_RESERV) { 263 if (ticket->t_flags & XLOG_TIC_PERM_RESERV) {
265 flags |= XFS_LOG_REL_PERM_RESERV; 264 flags |= XFS_LOG_REL_PERM_RESERV;
@@ -289,7 +288,7 @@ xfs_log_done(xfs_mount_t *mp,
289 } 288 }
290 289
291 return lsn; 290 return lsn;
292} /* xfs_log_done */ 291}
293 292
294/* 293/*
295 * Attaches a new iclog I/O completion callback routine during 294 * Attaches a new iclog I/O completion callback routine during
@@ -298,11 +297,11 @@ xfs_log_done(xfs_mount_t *mp,
298 * executing the callback at an appropriate time. 297 * executing the callback at an appropriate time.
299 */ 298 */
300int 299int
301xfs_log_notify(xfs_mount_t *mp, /* mount of partition */ 300xfs_log_notify(
302 void *iclog_hndl, /* iclog to hang callback off */ 301 struct xfs_mount *mp,
303 xfs_log_callback_t *cb) 302 struct xlog_in_core *iclog,
303 xfs_log_callback_t *cb)
304{ 304{
305 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
306 int abortflg; 305 int abortflg;
307 306
308 spin_lock(&iclog->ic_callback_lock); 307 spin_lock(&iclog->ic_callback_lock);
@@ -316,16 +315,14 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
316 } 315 }
317 spin_unlock(&iclog->ic_callback_lock); 316 spin_unlock(&iclog->ic_callback_lock);
318 return abortflg; 317 return abortflg;
319} /* xfs_log_notify */ 318}
320 319
321int 320int
322xfs_log_release_iclog(xfs_mount_t *mp, 321xfs_log_release_iclog(
323 void *iclog_hndl) 322 struct xfs_mount *mp,
323 struct xlog_in_core *iclog)
324{ 324{
325 xlog_t *log = mp->m_log; 325 if (xlog_state_release_iclog(mp->m_log, iclog)) {
326 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
327
328 if (xlog_state_release_iclog(log, iclog)) {
329 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); 326 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
330 return EIO; 327 return EIO;
331 } 328 }
@@ -344,17 +341,18 @@ xfs_log_release_iclog(xfs_mount_t *mp,
344 * reservation, we prevent over allocation problems. 341 * reservation, we prevent over allocation problems.
345 */ 342 */
346int 343int
347xfs_log_reserve(xfs_mount_t *mp, 344xfs_log_reserve(
348 int unit_bytes, 345 struct xfs_mount *mp,
349 int cnt, 346 int unit_bytes,
350 xfs_log_ticket_t *ticket, 347 int cnt,
351 __uint8_t client, 348 struct xlog_ticket **ticket,
352 uint flags, 349 __uint8_t client,
353 uint t_type) 350 uint flags,
351 uint t_type)
354{ 352{
355 xlog_t *log = mp->m_log; 353 struct log *log = mp->m_log;
356 xlog_ticket_t *internal_ticket; 354 struct xlog_ticket *internal_ticket;
357 int retval = 0; 355 int retval = 0;
358 356
359 ASSERT(client == XFS_TRANSACTION || client == XFS_LOG); 357 ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
360 ASSERT((flags & XFS_LOG_NOSLEEP) == 0); 358 ASSERT((flags & XFS_LOG_NOSLEEP) == 0);
@@ -367,7 +365,7 @@ xfs_log_reserve(xfs_mount_t *mp,
367 365
368 if (*ticket != NULL) { 366 if (*ticket != NULL) {
369 ASSERT(flags & XFS_LOG_PERM_RESERV); 367 ASSERT(flags & XFS_LOG_PERM_RESERV);
370 internal_ticket = (xlog_ticket_t *)*ticket; 368 internal_ticket = *ticket;
371 369
372 trace_xfs_log_reserve(log, internal_ticket); 370 trace_xfs_log_reserve(log, internal_ticket);
373 371
@@ -519,7 +517,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
519 xlog_in_core_t *first_iclog; 517 xlog_in_core_t *first_iclog;
520#endif 518#endif
521 xfs_log_iovec_t reg[1]; 519 xfs_log_iovec_t reg[1];
522 xfs_log_ticket_t tic = NULL; 520 xlog_ticket_t *tic = NULL;
523 xfs_lsn_t lsn; 521 xfs_lsn_t lsn;
524 int error; 522 int error;
525 523
@@ -656,24 +654,24 @@ xfs_log_unmount(xfs_mount_t *mp)
656 * transaction occur with one call to xfs_log_write(). 654 * transaction occur with one call to xfs_log_write().
657 */ 655 */
658int 656int
659xfs_log_write(xfs_mount_t * mp, 657xfs_log_write(
660 xfs_log_iovec_t reg[], 658 struct xfs_mount *mp,
661 int nentries, 659 struct xfs_log_iovec reg[],
662 xfs_log_ticket_t tic, 660 int nentries,
663 xfs_lsn_t *start_lsn) 661 struct xlog_ticket *tic,
662 xfs_lsn_t *start_lsn)
664{ 663{
665 int error; 664 struct log *log = mp->m_log;
666 xlog_t *log = mp->m_log; 665 int error;
667 666
668 if (XLOG_FORCED_SHUTDOWN(log)) 667 if (XLOG_FORCED_SHUTDOWN(log))
669 return XFS_ERROR(EIO); 668 return XFS_ERROR(EIO);
670 669
671 if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { 670 error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0);
671 if (error)
672 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); 672 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
673 }
674 return error; 673 return error;
675} /* xfs_log_write */ 674}
676
677 675
678void 676void
679xfs_log_move_tail(xfs_mount_t *mp, 677xfs_log_move_tail(xfs_mount_t *mp,
@@ -1642,16 +1640,16 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)
1642 * bytes have been written out. 1640 * bytes have been written out.
1643 */ 1641 */
1644STATIC int 1642STATIC int
1645xlog_write(xfs_mount_t * mp, 1643xlog_write(
1646 xfs_log_iovec_t reg[], 1644 struct xfs_mount *mp,
1647 int nentries, 1645 struct xfs_log_iovec reg[],
1648 xfs_log_ticket_t tic, 1646 int nentries,
1649 xfs_lsn_t *start_lsn, 1647 struct xlog_ticket *ticket,
1650 xlog_in_core_t **commit_iclog, 1648 xfs_lsn_t *start_lsn,
1651 uint flags) 1649 struct xlog_in_core **commit_iclog,
1650 uint flags)
1652{ 1651{
1653 xlog_t *log = mp->m_log; 1652 xlog_t *log = mp->m_log;
1654 xlog_ticket_t *ticket = (xlog_ticket_t *)tic;
1655 xlog_in_core_t *iclog = NULL; /* ptr to current in-core log */ 1653 xlog_in_core_t *iclog = NULL; /* ptr to current in-core log */
1656 xlog_op_header_t *logop_head; /* ptr to log operation header */ 1654 xlog_op_header_t *logop_head; /* ptr to log operation header */
1657 __psint_t ptr; /* copy address into data region */ 1655 __psint_t ptr; /* copy address into data region */
@@ -1765,7 +1763,7 @@ xlog_write(xfs_mount_t * mp,
1765 default: 1763 default:
1766 xfs_fs_cmn_err(CE_WARN, mp, 1764 xfs_fs_cmn_err(CE_WARN, mp,
1767 "Bad XFS transaction clientid 0x%x in ticket 0x%p", 1765 "Bad XFS transaction clientid 0x%x in ticket 0x%p",
1768 logop_head->oh_clientid, tic); 1766 logop_head->oh_clientid, ticket);
1769 return XFS_ERROR(EIO); 1767 return XFS_ERROR(EIO);
1770 } 1768 }
1771 1769
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 7074be9d13e9..97a24c7795a4 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -110,8 +110,6 @@ typedef struct xfs_log_iovec {
110 uint i_type; /* type of region */ 110 uint i_type; /* type of region */
111} xfs_log_iovec_t; 111} xfs_log_iovec_t;
112 112
113typedef void* xfs_log_ticket_t;
114
115/* 113/*
116 * Structure used to pass callback function and the function's argument 114 * Structure used to pass callback function and the function's argument
117 * to the log manager. 115 * to the log manager.
@@ -126,10 +124,12 @@ typedef struct xfs_log_callback {
126#ifdef __KERNEL__ 124#ifdef __KERNEL__
127/* Log manager interfaces */ 125/* Log manager interfaces */
128struct xfs_mount; 126struct xfs_mount;
127struct xlog_in_core;
129struct xlog_ticket; 128struct xlog_ticket;
129
130xfs_lsn_t xfs_log_done(struct xfs_mount *mp, 130xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
131 xfs_log_ticket_t ticket, 131 struct xlog_ticket *ticket,
132 void **iclog, 132 struct xlog_in_core **iclog,
133 uint flags); 133 uint flags);
134int _xfs_log_force(struct xfs_mount *mp, 134int _xfs_log_force(struct xfs_mount *mp,
135 uint flags, 135 uint flags,
@@ -151,21 +151,21 @@ int xfs_log_mount_finish(struct xfs_mount *mp);
151void xfs_log_move_tail(struct xfs_mount *mp, 151void xfs_log_move_tail(struct xfs_mount *mp,
152 xfs_lsn_t tail_lsn); 152 xfs_lsn_t tail_lsn);
153int xfs_log_notify(struct xfs_mount *mp, 153int xfs_log_notify(struct xfs_mount *mp,
154 void *iclog, 154 struct xlog_in_core *iclog,
155 xfs_log_callback_t *callback_entry); 155 xfs_log_callback_t *callback_entry);
156int xfs_log_release_iclog(struct xfs_mount *mp, 156int xfs_log_release_iclog(struct xfs_mount *mp,
157 void *iclog_hndl); 157 struct xlog_in_core *iclog);
158int xfs_log_reserve(struct xfs_mount *mp, 158int xfs_log_reserve(struct xfs_mount *mp,
159 int length, 159 int length,
160 int count, 160 int count,
161 xfs_log_ticket_t *ticket, 161 struct xlog_ticket **ticket,
162 __uint8_t clientid, 162 __uint8_t clientid,
163 uint flags, 163 uint flags,
164 uint t_type); 164 uint t_type);
165int xfs_log_write(struct xfs_mount *mp, 165int xfs_log_write(struct xfs_mount *mp,
166 xfs_log_iovec_t region[], 166 xfs_log_iovec_t region[],
167 int nentries, 167 int nentries,
168 xfs_log_ticket_t ticket, 168 struct xlog_ticket *ticket,
169 xfs_lsn_t *start_lsn); 169 xfs_lsn_t *start_lsn);
170int xfs_log_unmount_write(struct xfs_mount *mp); 170int xfs_log_unmount_write(struct xfs_mount *mp);
171void xfs_log_unmount(struct xfs_mount *mp); 171void xfs_log_unmount(struct xfs_mount *mp);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 6afaaeb2950a..e79b56b4bca6 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1097,13 +1097,15 @@ xfs_default_resblks(xfs_mount_t *mp)
1097 __uint64_t resblks; 1097 __uint64_t resblks;
1098 1098
1099 /* 1099 /*
1100 * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. 1100 * We default to 5% or 8192 fsbs of space reserved, whichever is
1101 * This may drive us straight to ENOSPC on mount, but that implies 1101 * smaller. This is intended to cover concurrent allocation
1102 * we were already there on the last unmount. Warn if this occurs. 1102 * transactions when we initially hit enospc. These each require a 4
1103 * block reservation. Hence by default we cover roughly 2000 concurrent
1104 * allocation reservations.
1103 */ 1105 */
1104 resblks = mp->m_sb.sb_dblocks; 1106 resblks = mp->m_sb.sb_dblocks;
1105 do_div(resblks, 20); 1107 do_div(resblks, 20);
1106 resblks = min_t(__uint64_t, resblks, 1024); 1108 resblks = min_t(__uint64_t, resblks, 8192);
1107 return resblks; 1109 return resblks;
1108} 1110}
1109 1111
@@ -1417,6 +1419,9 @@ xfs_mountfs(
1417 * when at ENOSPC. This is needed for operations like create with 1419 * when at ENOSPC. This is needed for operations like create with
1418 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations 1420 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations
1419 * are not allowed to use this reserved space. 1421 * are not allowed to use this reserved space.
1422 *
1423 * This may drive us straight to ENOSPC on mount, but that implies
1424 * we were already there on the last unmount. Warn if this occurs.
1420 */ 1425 */
1421 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { 1426 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
1422 resblks = xfs_default_resblks(mp); 1427 resblks = xfs_default_resblks(mp);
@@ -1725,26 +1730,30 @@ xfs_mod_incore_sb_unlocked(
1725 lcounter += rem; 1730 lcounter += rem;
1726 } 1731 }
1727 } else { /* Taking blocks away */ 1732 } else { /* Taking blocks away */
1728
1729 lcounter += delta; 1733 lcounter += delta;
1734 if (lcounter >= 0) {
1735 mp->m_sb.sb_fdblocks = lcounter +
1736 XFS_ALLOC_SET_ASIDE(mp);
1737 return 0;
1738 }
1730 1739
1731 /* 1740 /*
1732 * If were out of blocks, use any available reserved blocks if 1741 * We are out of blocks, use any available reserved
1733 * were allowed to. 1742 * blocks if were allowed to.
1734 */ 1743 */
1744 if (!rsvd)
1745 return XFS_ERROR(ENOSPC);
1735 1746
1736 if (lcounter < 0) { 1747 lcounter = (long long)mp->m_resblks_avail + delta;
1737 if (rsvd) { 1748 if (lcounter >= 0) {
1738 lcounter = (long long)mp->m_resblks_avail + delta; 1749 mp->m_resblks_avail = lcounter;
1739 if (lcounter < 0) { 1750 return 0;
1740 return XFS_ERROR(ENOSPC);
1741 }
1742 mp->m_resblks_avail = lcounter;
1743 return 0;
1744 } else { /* not reserved */
1745 return XFS_ERROR(ENOSPC);
1746 }
1747 } 1751 }
1752 printk_once(KERN_WARNING
1753 "Filesystem \"%s\": reserve blocks depleted! "
1754 "Consider increasing reserve pool size.",
1755 mp->m_fsname);
1756 return XFS_ERROR(ENOSPC);
1748 } 1757 }
1749 1758
1750 mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp); 1759 mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
@@ -2052,6 +2061,26 @@ xfs_mount_log_sb(
2052 return error; 2061 return error;
2053} 2062}
2054 2063
2064/*
2065 * If the underlying (data/log/rt) device is readonly, there are some
2066 * operations that cannot proceed.
2067 */
2068int
2069xfs_dev_is_read_only(
2070 struct xfs_mount *mp,
2071 char *message)
2072{
2073 if (xfs_readonly_buftarg(mp->m_ddev_targp) ||
2074 xfs_readonly_buftarg(mp->m_logdev_targp) ||
2075 (mp->m_rtdev_targp && xfs_readonly_buftarg(mp->m_rtdev_targp))) {
2076 cmn_err(CE_NOTE,
2077 "XFS: %s required on read-only device.", message);
2078 cmn_err(CE_NOTE,
2079 "XFS: write access unavailable, cannot proceed.");
2080 return EROFS;
2081 }
2082 return 0;
2083}
2055 2084
2056#ifdef HAVE_PERCPU_SB 2085#ifdef HAVE_PERCPU_SB
2057/* 2086/*
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 14dafd608230..4fa0bc7b983e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -436,6 +436,8 @@ extern void xfs_freesb(xfs_mount_t *);
436extern int xfs_fs_writable(xfs_mount_t *); 436extern int xfs_fs_writable(xfs_mount_t *);
437extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); 437extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
438 438
439extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
440
439extern int xfs_dmops_get(struct xfs_mount *); 441extern int xfs_dmops_get(struct xfs_mount *);
440extern void xfs_dmops_put(struct xfs_mount *); 442extern void xfs_dmops_put(struct xfs_mount *);
441 443
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index be942d4e3324..f73e358bae8d 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -796,7 +796,7 @@ _xfs_trans_commit(
796 int sync; 796 int sync;
797#define XFS_TRANS_LOGVEC_COUNT 16 797#define XFS_TRANS_LOGVEC_COUNT 16
798 xfs_log_iovec_t log_vector_fast[XFS_TRANS_LOGVEC_COUNT]; 798 xfs_log_iovec_t log_vector_fast[XFS_TRANS_LOGVEC_COUNT];
799 void *commit_iclog; 799 struct xlog_in_core *commit_iclog;
800 int shutdown; 800 int shutdown;
801 801
802 commit_lsn = -1; 802 commit_lsn = -1;
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index c93e3a102857..79c8bab9dfff 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -910,7 +910,7 @@ typedef struct xfs_trans {
910 unsigned int t_blk_res_used; /* # of resvd blocks used */ 910 unsigned int t_blk_res_used; /* # of resvd blocks used */
911 unsigned int t_rtx_res; /* # of rt extents resvd */ 911 unsigned int t_rtx_res; /* # of rt extents resvd */
912 unsigned int t_rtx_res_used; /* # of resvd rt extents used */ 912 unsigned int t_rtx_res_used; /* # of resvd rt extents used */
913 xfs_log_ticket_t t_ticket; /* log mgr ticket */ 913 struct xlog_ticket *t_ticket; /* log mgr ticket */
914 xfs_lsn_t t_lsn; /* log seq num of start of 914 xfs_lsn_t t_lsn; /* log seq num of start of
915 * transaction. */ 915 * transaction. */
916 xfs_lsn_t t_commit_lsn; /* log seq num of end of 916 xfs_lsn_t t_commit_lsn; /* log seq num of end of
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 5ffd544434eb..fb586360d1c9 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -46,6 +46,65 @@ STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *,
46STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *, 46STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *,
47 xfs_daddr_t, int); 47 xfs_daddr_t, int);
48 48
49/*
50 * Add the locked buffer to the transaction.
51 *
52 * The buffer must be locked, and it cannot be associated with any
53 * transaction.
54 *
55 * If the buffer does not yet have a buf log item associated with it,
56 * then allocate one for it. Then add the buf item to the transaction.
57 */
58STATIC void
59_xfs_trans_bjoin(
60 struct xfs_trans *tp,
61 struct xfs_buf *bp,
62 int reset_recur)
63{
64 struct xfs_buf_log_item *bip;
65
66 ASSERT(XFS_BUF_ISBUSY(bp));
67 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
68
69 /*
70 * The xfs_buf_log_item pointer is stored in b_fsprivate. If
71 * it doesn't have one yet, then allocate one and initialize it.
72 * The checks to see if one is there are in xfs_buf_item_init().
73 */
74 xfs_buf_item_init(bp, tp->t_mountp);
75 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
76 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
77 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
78 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
79 if (reset_recur)
80 bip->bli_recur = 0;
81
82 /*
83 * Take a reference for this transaction on the buf item.
84 */
85 atomic_inc(&bip->bli_refcount);
86
87 /*
88 * Get a log_item_desc to point at the new item.
89 */
90 (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
91
92 /*
93 * Initialize b_fsprivate2 so we can find it with incore_match()
94 * in xfs_trans_get_buf() and friends above.
95 */
96 XFS_BUF_SET_FSPRIVATE2(bp, tp);
97
98}
99
100void
101xfs_trans_bjoin(
102 struct xfs_trans *tp,
103 struct xfs_buf *bp)
104{
105 _xfs_trans_bjoin(tp, bp, 0);
106 trace_xfs_trans_bjoin(bp->b_fspriv);
107}
49 108
50/* 109/*
51 * Get and lock the buffer for the caller if it is not already 110 * Get and lock the buffer for the caller if it is not already
@@ -132,40 +191,8 @@ xfs_trans_get_buf(xfs_trans_t *tp,
132 191
133 ASSERT(!XFS_BUF_GETERROR(bp)); 192 ASSERT(!XFS_BUF_GETERROR(bp));
134 193
135 /* 194 _xfs_trans_bjoin(tp, bp, 1);
136 * The xfs_buf_log_item pointer is stored in b_fsprivate. If 195 trace_xfs_trans_get_buf(bp->b_fspriv);
137 * it doesn't have one yet, then allocate one and initialize it.
138 * The checks to see if one is there are in xfs_buf_item_init().
139 */
140 xfs_buf_item_init(bp, tp->t_mountp);
141
142 /*
143 * Set the recursion count for the buffer within this transaction
144 * to 0.
145 */
146 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
147 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
148 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
149 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
150 bip->bli_recur = 0;
151
152 /*
153 * Take a reference for this transaction on the buf item.
154 */
155 atomic_inc(&bip->bli_refcount);
156
157 /*
158 * Get a log_item_desc to point at the new item.
159 */
160 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
161
162 /*
163 * Initialize b_fsprivate2 so we can find it with incore_match()
164 * above.
165 */
166 XFS_BUF_SET_FSPRIVATE2(bp, tp);
167
168 trace_xfs_trans_get_buf(bip);
169 return (bp); 196 return (bp);
170} 197}
171 198
@@ -210,44 +237,11 @@ xfs_trans_getsb(xfs_trans_t *tp,
210 } 237 }
211 238
212 bp = xfs_getsb(mp, flags); 239 bp = xfs_getsb(mp, flags);
213 if (bp == NULL) { 240 if (bp == NULL)
214 return NULL; 241 return NULL;
215 }
216
217 /*
218 * The xfs_buf_log_item pointer is stored in b_fsprivate. If
219 * it doesn't have one yet, then allocate one and initialize it.
220 * The checks to see if one is there are in xfs_buf_item_init().
221 */
222 xfs_buf_item_init(bp, mp);
223
224 /*
225 * Set the recursion count for the buffer within this transaction
226 * to 0.
227 */
228 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
229 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
230 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
231 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
232 bip->bli_recur = 0;
233
234 /*
235 * Take a reference for this transaction on the buf item.
236 */
237 atomic_inc(&bip->bli_refcount);
238
239 /*
240 * Get a log_item_desc to point at the new item.
241 */
242 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
243
244 /*
245 * Initialize b_fsprivate2 so we can find it with incore_match()
246 * above.
247 */
248 XFS_BUF_SET_FSPRIVATE2(bp, tp);
249 242
250 trace_xfs_trans_getsb(bip); 243 _xfs_trans_bjoin(tp, bp, 1);
244 trace_xfs_trans_getsb(bp->b_fspriv);
251 return (bp); 245 return (bp);
252} 246}
253 247
@@ -425,40 +419,9 @@ xfs_trans_read_buf(
425 if (XFS_FORCED_SHUTDOWN(mp)) 419 if (XFS_FORCED_SHUTDOWN(mp))
426 goto shutdown_abort; 420 goto shutdown_abort;
427 421
428 /* 422 _xfs_trans_bjoin(tp, bp, 1);
429 * The xfs_buf_log_item pointer is stored in b_fsprivate. If 423 trace_xfs_trans_read_buf(bp->b_fspriv);
430 * it doesn't have one yet, then allocate one and initialize it.
431 * The checks to see if one is there are in xfs_buf_item_init().
432 */
433 xfs_buf_item_init(bp, tp->t_mountp);
434 424
435 /*
436 * Set the recursion count for the buffer within this transaction
437 * to 0.
438 */
439 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
440 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
441 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
442 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
443 bip->bli_recur = 0;
444
445 /*
446 * Take a reference for this transaction on the buf item.
447 */
448 atomic_inc(&bip->bli_refcount);
449
450 /*
451 * Get a log_item_desc to point at the new item.
452 */
453 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
454
455 /*
456 * Initialize b_fsprivate2 so we can find it with incore_match()
457 * above.
458 */
459 XFS_BUF_SET_FSPRIVATE2(bp, tp);
460
461 trace_xfs_trans_read_buf(bip);
462 *bpp = bp; 425 *bpp = bp;
463 return 0; 426 return 0;
464 427
@@ -623,53 +586,6 @@ xfs_trans_brelse(xfs_trans_t *tp,
623} 586}
624 587
625/* 588/*
626 * Add the locked buffer to the transaction.
627 * The buffer must be locked, and it cannot be associated with any
628 * transaction.
629 *
630 * If the buffer does not yet have a buf log item associated with it,
631 * then allocate one for it. Then add the buf item to the transaction.
632 */
633void
634xfs_trans_bjoin(xfs_trans_t *tp,
635 xfs_buf_t *bp)
636{
637 xfs_buf_log_item_t *bip;
638
639 ASSERT(XFS_BUF_ISBUSY(bp));
640 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
641
642 /*
643 * The xfs_buf_log_item pointer is stored in b_fsprivate. If
644 * it doesn't have one yet, then allocate one and initialize it.
645 * The checks to see if one is there are in xfs_buf_item_init().
646 */
647 xfs_buf_item_init(bp, tp->t_mountp);
648 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
649 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
650 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
651 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
652
653 /*
654 * Take a reference for this transaction on the buf item.
655 */
656 atomic_inc(&bip->bli_refcount);
657
658 /*
659 * Get a log_item_desc to point at the new item.
660 */
661 (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
662
663 /*
664 * Initialize b_fsprivate2 so we can find it with incore_match()
665 * in xfs_trans_get_buf() and friends above.
666 */
667 XFS_BUF_SET_FSPRIVATE2(bp, tp);
668
669 trace_xfs_trans_bjoin(bip);
670}
671
672/*
673 * Mark the buffer as not needing to be unlocked when the buf item's 589 * Mark the buffer as not needing to be unlocked when the buf item's
674 * IOP_UNLOCK() routine is called. The buffer must already be locked 590 * IOP_UNLOCK() routine is called. The buffer must already be locked
675 * and associated with the given transaction. 591 * and associated with the given transaction.
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index ddd2c5d1b854..9d376be0ea38 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -584,113 +584,6 @@ xfs_readlink(
584} 584}
585 585
586/* 586/*
587 * xfs_fsync
588 *
589 * This is called to sync the inode and its data out to disk. We need to hold
590 * the I/O lock while flushing the data, and the inode lock while flushing the
591 * inode. The inode lock CANNOT be held while flushing the data, so acquire
592 * after we're done with that.
593 */
594int
595xfs_fsync(
596 xfs_inode_t *ip)
597{
598 xfs_trans_t *tp;
599 int error = 0;
600 int log_flushed = 0;
601
602 xfs_itrace_entry(ip);
603
604 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
605 return XFS_ERROR(EIO);
606
607 /*
608 * We always need to make sure that the required inode state is safe on
609 * disk. The inode might be clean but we still might need to force the
610 * log because of committed transactions that haven't hit the disk yet.
611 * Likewise, there could be unflushed non-transactional changes to the
612 * inode core that have to go to disk and this requires us to issue
613 * a synchronous transaction to capture these changes correctly.
614 *
615 * This code relies on the assumption that if the update_* fields
616 * of the inode are clear and the inode is unpinned then it is clean
617 * and no action is required.
618 */
619 xfs_ilock(ip, XFS_ILOCK_SHARED);
620
621 if (!ip->i_update_core) {
622 /*
623 * Timestamps/size haven't changed since last inode flush or
624 * inode transaction commit. That means either nothing got
625 * written or a transaction committed which caught the updates.
626 * If the latter happened and the transaction hasn't hit the
627 * disk yet, the inode will be still be pinned. If it is,
628 * force the log.
629 */
630 xfs_iunlock(ip, XFS_ILOCK_SHARED);
631 if (xfs_ipincount(ip)) {
632 if (ip->i_itemp->ili_last_lsn) {
633 error = _xfs_log_force_lsn(ip->i_mount,
634 ip->i_itemp->ili_last_lsn,
635 XFS_LOG_SYNC, &log_flushed);
636 } else {
637 error = _xfs_log_force(ip->i_mount,
638 XFS_LOG_SYNC, &log_flushed);
639 }
640 }
641 } else {
642 /*
643 * Kick off a transaction to log the inode core to get the
644 * updates. The sync transaction will also force the log.
645 */
646 xfs_iunlock(ip, XFS_ILOCK_SHARED);
647 tp = xfs_trans_alloc(ip->i_mount, XFS_TRANS_FSYNC_TS);
648 error = xfs_trans_reserve(tp, 0,
649 XFS_FSYNC_TS_LOG_RES(ip->i_mount), 0, 0, 0);
650 if (error) {
651 xfs_trans_cancel(tp, 0);
652 return error;
653 }
654 xfs_ilock(ip, XFS_ILOCK_EXCL);
655
656 /*
657 * Note - it's possible that we might have pushed ourselves out
658 * of the way during trans_reserve which would flush the inode.
659 * But there's no guarantee that the inode buffer has actually
660 * gone out yet (it's delwri). Plus the buffer could be pinned
661 * anyway if it's part of an inode in another recent
662 * transaction. So we play it safe and fire off the
663 * transaction anyway.
664 */
665 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
666 xfs_trans_ihold(tp, ip);
667 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
668 xfs_trans_set_sync(tp);
669 error = _xfs_trans_commit(tp, 0, &log_flushed);
670
671 xfs_iunlock(ip, XFS_ILOCK_EXCL);
672 }
673
674 if (ip->i_mount->m_flags & XFS_MOUNT_BARRIER) {
675 /*
676 * If the log write didn't issue an ordered tag we need
677 * to flush the disk cache for the data device now.
678 */
679 if (!log_flushed)
680 xfs_blkdev_issue_flush(ip->i_mount->m_ddev_targp);
681
682 /*
683 * If this inode is on the RT dev we need to flush that
684 * cache as well.
685 */
686 if (XFS_IS_REALTIME_INODE(ip))
687 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
688 }
689
690 return error;
691}
692
693/*
694 * Flags for xfs_free_eofblocks 587 * Flags for xfs_free_eofblocks
695 */ 588 */
696#define XFS_FREE_EOF_TRYLOCK (1<<0) 589#define XFS_FREE_EOF_TRYLOCK (1<<0)
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 774f40729ca1..d8dfa8d0dadd 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -21,7 +21,6 @@ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags);
21#define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */ 21#define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */
22 22
23int xfs_readlink(struct xfs_inode *ip, char *link); 23int xfs_readlink(struct xfs_inode *ip, char *link);
24int xfs_fsync(struct xfs_inode *ip);
25int xfs_release(struct xfs_inode *ip); 24int xfs_release(struct xfs_inode *ip);
26int xfs_inactive(struct xfs_inode *ip); 25int xfs_inactive(struct xfs_inode *ip);
27int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, 26int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,
@@ -50,18 +49,6 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
50int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags); 49int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags);
51int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, 50int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
52 int flags, struct attrlist_cursor_kern *cursor); 51 int flags, struct attrlist_cursor_kern *cursor);
53ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb,
54 const struct iovec *iovp, unsigned int segs,
55 loff_t *offset, int ioflags);
56ssize_t xfs_splice_read(struct xfs_inode *ip, struct file *infilp,
57 loff_t *ppos, struct pipe_inode_info *pipe, size_t count,
58 int flags, int ioflags);
59ssize_t xfs_splice_write(struct xfs_inode *ip,
60 struct pipe_inode_info *pipe, struct file *outfilp,
61 loff_t *ppos, size_t count, int flags, int ioflags);
62ssize_t xfs_write(struct xfs_inode *xip, struct kiocb *iocb,
63 const struct iovec *iovp, unsigned int nsegs,
64 loff_t *offset, int ioflags);
65int xfs_bmap(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, 52int xfs_bmap(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
66 int flags, struct xfs_iomap *iomapp, int *niomaps); 53 int flags, struct xfs_iomap *iomapp, int *niomaps);
67void xfs_tosspages(struct xfs_inode *inode, xfs_off_t first, 54void xfs_tosspages(struct xfs_inode *inode, xfs_off_t first,
@@ -72,4 +59,6 @@ int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,
72 xfs_off_t last, uint64_t flags, int fiopt); 59 xfs_off_t last, uint64_t flags, int fiopt);
73int xfs_wait_on_pages(struct xfs_inode *ip, xfs_off_t first, xfs_off_t last); 60int xfs_wait_on_pages(struct xfs_inode *ip, xfs_off_t first, xfs_off_t last);
74 61
62int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t);
63
75#endif /* _XFS_VNODEOPS_H */ 64#endif /* _XFS_VNODEOPS_H */
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 485eeb6c4ef3..979c6a57f2f1 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -136,6 +136,32 @@ extern int __gpio_cansleep(unsigned gpio);
136 136
137extern int __gpio_to_irq(unsigned gpio); 137extern int __gpio_to_irq(unsigned gpio);
138 138
139#define GPIOF_DIR_OUT (0 << 0)
140#define GPIOF_DIR_IN (1 << 0)
141
142#define GPIOF_INIT_LOW (0 << 1)
143#define GPIOF_INIT_HIGH (1 << 1)
144
145#define GPIOF_IN (GPIOF_DIR_IN)
146#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
147#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
148
149/**
150 * struct gpio - a structure describing a GPIO with configuration
151 * @gpio: the GPIO number
152 * @flags: GPIO configuration as specified by GPIOF_*
153 * @label: a literal description string of this GPIO
154 */
155struct gpio {
156 unsigned gpio;
157 unsigned long flags;
158 const char *label;
159};
160
161extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
162extern int gpio_request_array(struct gpio *array, size_t num);
163extern void gpio_free_array(struct gpio *array, size_t num);
164
139#ifdef CONFIG_GPIO_SYSFS 165#ifdef CONFIG_GPIO_SYSFS
140 166
141/* 167/*
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 89c6249fc561..c809e286d213 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -74,6 +74,7 @@ struct coredump_params {
74 struct pt_regs *regs; 74 struct pt_regs *regs;
75 struct file *file; 75 struct file *file;
76 unsigned long limit; 76 unsigned long limit;
77 unsigned long mm_flags;
77}; 78};
78 79
79/* 80/*
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 25b8b2f33ae9..b79389879238 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -16,11 +16,13 @@
16 */ 16 */
17#include <asm/bitops.h> 17#include <asm/bitops.h>
18 18
19#define for_each_bit(bit, addr, size) \ 19#define for_each_set_bit(bit, addr, size) \
20 for ((bit) = find_first_bit((addr), (size)); \ 20 for ((bit) = find_first_bit((addr), (size)); \
21 (bit) < (size); \ 21 (bit) < (size); \
22 (bit) = find_next_bit((addr), (size), (bit) + 1)) 22 (bit) = find_next_bit((addr), (size), (bit) + 1))
23 23
24/* Temporary */
25#define for_each_bit(bit, addr, size) for_each_set_bit(bit, addr, size)
24 26
25static __inline__ int get_bitmask_order(unsigned int count) 27static __inline__ int get_bitmask_order(unsigned int count)
26{ 28{
diff --git a/include/linux/btree-128.h b/include/linux/btree-128.h
new file mode 100644
index 000000000000..0b3414c4c928
--- /dev/null
+++ b/include/linux/btree-128.h
@@ -0,0 +1,109 @@
1extern struct btree_geo btree_geo128;
2
3struct btree_head128 { struct btree_head h; };
4
5static inline void btree_init_mempool128(struct btree_head128 *head,
6 mempool_t *mempool)
7{
8 btree_init_mempool(&head->h, mempool);
9}
10
11static inline int btree_init128(struct btree_head128 *head)
12{
13 return btree_init(&head->h);
14}
15
16static inline void btree_destroy128(struct btree_head128 *head)
17{
18 btree_destroy(&head->h);
19}
20
21static inline void *btree_lookup128(struct btree_head128 *head, u64 k1, u64 k2)
22{
23 u64 key[2] = {k1, k2};
24 return btree_lookup(&head->h, &btree_geo128, (unsigned long *)&key);
25}
26
27static inline void *btree_get_prev128(struct btree_head128 *head,
28 u64 *k1, u64 *k2)
29{
30 u64 key[2] = {*k1, *k2};
31 void *val;
32
33 val = btree_get_prev(&head->h, &btree_geo128,
34 (unsigned long *)&key);
35 *k1 = key[0];
36 *k2 = key[1];
37 return val;
38}
39
40static inline int btree_insert128(struct btree_head128 *head, u64 k1, u64 k2,
41 void *val, gfp_t gfp)
42{
43 u64 key[2] = {k1, k2};
44 return btree_insert(&head->h, &btree_geo128,
45 (unsigned long *)&key, val, gfp);
46}
47
48static inline int btree_update128(struct btree_head128 *head, u64 k1, u64 k2,
49 void *val)
50{
51 u64 key[2] = {k1, k2};
52 return btree_update(&head->h, &btree_geo128,
53 (unsigned long *)&key, val);
54}
55
56static inline void *btree_remove128(struct btree_head128 *head, u64 k1, u64 k2)
57{
58 u64 key[2] = {k1, k2};
59 return btree_remove(&head->h, &btree_geo128, (unsigned long *)&key);
60}
61
62static inline void *btree_last128(struct btree_head128 *head, u64 *k1, u64 *k2)
63{
64 u64 key[2];
65 void *val;
66
67 val = btree_last(&head->h, &btree_geo128, (unsigned long *)&key[0]);
68 if (val) {
69 *k1 = key[0];
70 *k2 = key[1];
71 }
72
73 return val;
74}
75
76static inline int btree_merge128(struct btree_head128 *target,
77 struct btree_head128 *victim,
78 gfp_t gfp)
79{
80 return btree_merge(&target->h, &victim->h, &btree_geo128, gfp);
81}
82
83void visitor128(void *elem, unsigned long opaque, unsigned long *__key,
84 size_t index, void *__func);
85
86typedef void (*visitor128_t)(void *elem, unsigned long opaque,
87 u64 key1, u64 key2, size_t index);
88
89static inline size_t btree_visitor128(struct btree_head128 *head,
90 unsigned long opaque,
91 visitor128_t func2)
92{
93 return btree_visitor(&head->h, &btree_geo128, opaque,
94 visitor128, func2);
95}
96
97static inline size_t btree_grim_visitor128(struct btree_head128 *head,
98 unsigned long opaque,
99 visitor128_t func2)
100{
101 return btree_grim_visitor(&head->h, &btree_geo128, opaque,
102 visitor128, func2);
103}
104
105#define btree_for_each_safe128(head, k1, k2, val) \
106 for (val = btree_last128(head, &k1, &k2); \
107 val; \
108 val = btree_get_prev128(head, &k1, &k2))
109
diff --git a/include/linux/btree-type.h b/include/linux/btree-type.h
new file mode 100644
index 000000000000..9a1147ef8563
--- /dev/null
+++ b/include/linux/btree-type.h
@@ -0,0 +1,147 @@
1#define __BTREE_TP(pfx, type, sfx) pfx ## type ## sfx
2#define _BTREE_TP(pfx, type, sfx) __BTREE_TP(pfx, type, sfx)
3#define BTREE_TP(pfx) _BTREE_TP(pfx, BTREE_TYPE_SUFFIX,)
4#define BTREE_FN(name) BTREE_TP(btree_ ## name)
5#define BTREE_TYPE_HEAD BTREE_TP(struct btree_head)
6#define VISITOR_FN BTREE_TP(visitor)
7#define VISITOR_FN_T _BTREE_TP(visitor, BTREE_TYPE_SUFFIX, _t)
8
9BTREE_TYPE_HEAD {
10 struct btree_head h;
11};
12
13static inline void BTREE_FN(init_mempool)(BTREE_TYPE_HEAD *head,
14 mempool_t *mempool)
15{
16 btree_init_mempool(&head->h, mempool);
17}
18
19static inline int BTREE_FN(init)(BTREE_TYPE_HEAD *head)
20{
21 return btree_init(&head->h);
22}
23
24static inline void BTREE_FN(destroy)(BTREE_TYPE_HEAD *head)
25{
26 btree_destroy(&head->h);
27}
28
29static inline int BTREE_FN(merge)(BTREE_TYPE_HEAD *target,
30 BTREE_TYPE_HEAD *victim,
31 gfp_t gfp)
32{
33 return btree_merge(&target->h, &victim->h, BTREE_TYPE_GEO, gfp);
34}
35
36#if (BITS_PER_LONG > BTREE_TYPE_BITS)
37static inline void *BTREE_FN(lookup)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
38{
39 unsigned long _key = key;
40 return btree_lookup(&head->h, BTREE_TYPE_GEO, &_key);
41}
42
43static inline int BTREE_FN(insert)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
44 void *val, gfp_t gfp)
45{
46 unsigned long _key = key;
47 return btree_insert(&head->h, BTREE_TYPE_GEO, &_key, val, gfp);
48}
49
50static inline int BTREE_FN(update)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
51 void *val)
52{
53 unsigned long _key = key;
54 return btree_update(&head->h, BTREE_TYPE_GEO, &_key, val);
55}
56
57static inline void *BTREE_FN(remove)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
58{
59 unsigned long _key = key;
60 return btree_remove(&head->h, BTREE_TYPE_GEO, &_key);
61}
62
63static inline void *BTREE_FN(last)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
64{
65 unsigned long _key;
66 void *val = btree_last(&head->h, BTREE_TYPE_GEO, &_key);
67 if (val)
68 *key = _key;
69 return val;
70}
71
72static inline void *BTREE_FN(get_prev)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
73{
74 unsigned long _key = *key;
75 void *val = btree_get_prev(&head->h, BTREE_TYPE_GEO, &_key);
76 if (val)
77 *key = _key;
78 return val;
79}
80#else
81static inline void *BTREE_FN(lookup)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
82{
83 return btree_lookup(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key);
84}
85
86static inline int BTREE_FN(insert)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
87 void *val, gfp_t gfp)
88{
89 return btree_insert(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key,
90 val, gfp);
91}
92
93static inline int BTREE_FN(update)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key,
94 void *val)
95{
96 return btree_update(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key, val);
97}
98
99static inline void *BTREE_FN(remove)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE key)
100{
101 return btree_remove(&head->h, BTREE_TYPE_GEO, (unsigned long *)&key);
102}
103
104static inline void *BTREE_FN(last)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
105{
106 return btree_last(&head->h, BTREE_TYPE_GEO, (unsigned long *)key);
107}
108
109static inline void *BTREE_FN(get_prev)(BTREE_TYPE_HEAD *head, BTREE_KEYTYPE *key)
110{
111 return btree_get_prev(&head->h, BTREE_TYPE_GEO, (unsigned long *)key);
112}
113#endif
114
115void VISITOR_FN(void *elem, unsigned long opaque, unsigned long *key,
116 size_t index, void *__func);
117
118typedef void (*VISITOR_FN_T)(void *elem, unsigned long opaque,
119 BTREE_KEYTYPE key, size_t index);
120
121static inline size_t BTREE_FN(visitor)(BTREE_TYPE_HEAD *head,
122 unsigned long opaque,
123 VISITOR_FN_T func2)
124{
125 return btree_visitor(&head->h, BTREE_TYPE_GEO, opaque,
126 visitorl, func2);
127}
128
129static inline size_t BTREE_FN(grim_visitor)(BTREE_TYPE_HEAD *head,
130 unsigned long opaque,
131 VISITOR_FN_T func2)
132{
133 return btree_grim_visitor(&head->h, BTREE_TYPE_GEO, opaque,
134 visitorl, func2);
135}
136
137#undef VISITOR_FN
138#undef VISITOR_FN_T
139#undef __BTREE_TP
140#undef _BTREE_TP
141#undef BTREE_TP
142#undef BTREE_FN
143#undef BTREE_TYPE_HEAD
144#undef BTREE_TYPE_SUFFIX
145#undef BTREE_TYPE_GEO
146#undef BTREE_KEYTYPE
147#undef BTREE_TYPE_BITS
diff --git a/include/linux/btree.h b/include/linux/btree.h
new file mode 100644
index 000000000000..65b5bb058324
--- /dev/null
+++ b/include/linux/btree.h
@@ -0,0 +1,243 @@
1#ifndef BTREE_H
2#define BTREE_H
3
4#include <linux/kernel.h>
5#include <linux/mempool.h>
6
7/**
8 * DOC: B+Tree basics
9 *
10 * A B+Tree is a data structure for looking up arbitrary (currently allowing
11 * unsigned long, u32, u64 and 2 * u64) keys into pointers. The data structure
12 * is described at http://en.wikipedia.org/wiki/B-tree, we currently do not
13 * use binary search to find the key on lookups.
14 *
15 * Each B+Tree consists of a head, that contains bookkeeping information and
16 * a variable number (starting with zero) nodes. Each node contains the keys
17 * and pointers to sub-nodes, or, for leaf nodes, the keys and values for the
18 * tree entries.
19 *
20 * Each node in this implementation has the following layout:
21 * [key1, key2, ..., keyN] [val1, val2, ..., valN]
22 *
23 * Each key here is an array of unsigned longs, geo->no_longs in total. The
24 * number of keys and values (N) is geo->no_pairs.
25 */
26
27/**
28 * struct btree_head - btree head
29 *
30 * @node: the first node in the tree
31 * @mempool: mempool used for node allocations
32 * @height: current of the tree
33 */
34struct btree_head {
35 unsigned long *node;
36 mempool_t *mempool;
37 int height;
38};
39
40/* btree geometry */
41struct btree_geo;
42
43/**
44 * btree_alloc - allocate function for the mempool
45 * @gfp_mask: gfp mask for the allocation
46 * @pool_data: unused
47 */
48void *btree_alloc(gfp_t gfp_mask, void *pool_data);
49
50/**
51 * btree_free - free function for the mempool
52 * @element: the element to free
53 * @pool_data: unused
54 */
55void btree_free(void *element, void *pool_data);
56
57/**
58 * btree_init_mempool - initialise a btree with given mempool
59 *
60 * @head: the btree head to initialise
61 * @mempool: the mempool to use
62 *
63 * When this function is used, there is no need to destroy
64 * the mempool.
65 */
66void btree_init_mempool(struct btree_head *head, mempool_t *mempool);
67
68/**
69 * btree_init - initialise a btree
70 *
71 * @head: the btree head to initialise
72 *
73 * This function allocates the memory pool that the
74 * btree needs. Returns zero or a negative error code
75 * (-%ENOMEM) when memory allocation fails.
76 *
77 */
78int __must_check btree_init(struct btree_head *head);
79
80/**
81 * btree_destroy - destroy mempool
82 *
83 * @head: the btree head to destroy
84 *
85 * This function destroys the internal memory pool, use only
86 * when using btree_init(), not with btree_init_mempool().
87 */
88void btree_destroy(struct btree_head *head);
89
90/**
91 * btree_lookup - look up a key in the btree
92 *
93 * @head: the btree to look in
94 * @geo: the btree geometry
95 * @key: the key to look up
96 *
97 * This function returns the value for the given key, or %NULL.
98 */
99void *btree_lookup(struct btree_head *head, struct btree_geo *geo,
100 unsigned long *key);
101
102/**
103 * btree_insert - insert an entry into the btree
104 *
105 * @head: the btree to add to
106 * @geo: the btree geometry
107 * @key: the key to add (must not already be present)
108 * @val: the value to add (must not be %NULL)
109 * @gfp: allocation flags for node allocations
110 *
111 * This function returns 0 if the item could be added, or an
112 * error code if it failed (may fail due to memory pressure).
113 */
114int __must_check btree_insert(struct btree_head *head, struct btree_geo *geo,
115 unsigned long *key, void *val, gfp_t gfp);
116/**
117 * btree_update - update an entry in the btree
118 *
119 * @head: the btree to update
120 * @geo: the btree geometry
121 * @key: the key to update
122 * @val: the value to change it to (must not be %NULL)
123 *
124 * This function returns 0 if the update was successful, or
125 * -%ENOENT if the key could not be found.
126 */
127int btree_update(struct btree_head *head, struct btree_geo *geo,
128 unsigned long *key, void *val);
129/**
130 * btree_remove - remove an entry from the btree
131 *
132 * @head: the btree to update
133 * @geo: the btree geometry
134 * @key: the key to remove
135 *
136 * This function returns the removed entry, or %NULL if the key
137 * could not be found.
138 */
139void *btree_remove(struct btree_head *head, struct btree_geo *geo,
140 unsigned long *key);
141
142/**
143 * btree_merge - merge two btrees
144 *
145 * @target: the tree that gets all the entries
146 * @victim: the tree that gets merged into @target
147 * @geo: the btree geometry
148 * @gfp: allocation flags
149 *
150 * The two trees @target and @victim may not contain the same keys,
151 * that is a bug and triggers a BUG(). This function returns zero
152 * if the trees were merged successfully, and may return a failure
153 * when memory allocation fails, in which case both trees might have
154 * been partially merged, i.e. some entries have been moved from
155 * @victim to @target.
156 */
157int btree_merge(struct btree_head *target, struct btree_head *victim,
158 struct btree_geo *geo, gfp_t gfp);
159
160/**
161 * btree_last - get last entry in btree
162 *
163 * @head: btree head
164 * @geo: btree geometry
165 * @key: last key
166 *
167 * Returns the last entry in the btree, and sets @key to the key
168 * of that entry; returns NULL if the tree is empty, in that case
169 * key is not changed.
170 */
171void *btree_last(struct btree_head *head, struct btree_geo *geo,
172 unsigned long *key);
173
174/**
175 * btree_get_prev - get previous entry
176 *
177 * @head: btree head
178 * @geo: btree geometry
179 * @key: pointer to key
180 *
181 * The function returns the next item right before the value pointed to by
182 * @key, and updates @key with its key, or returns %NULL when there is no
183 * entry with a key smaller than the given key.
184 */
185void *btree_get_prev(struct btree_head *head, struct btree_geo *geo,
186 unsigned long *key);
187
188
189/* internal use, use btree_visitor{l,32,64,128} */
190size_t btree_visitor(struct btree_head *head, struct btree_geo *geo,
191 unsigned long opaque,
192 void (*func)(void *elem, unsigned long opaque,
193 unsigned long *key, size_t index,
194 void *func2),
195 void *func2);
196
197/* internal use, use btree_grim_visitor{l,32,64,128} */
198size_t btree_grim_visitor(struct btree_head *head, struct btree_geo *geo,
199 unsigned long opaque,
200 void (*func)(void *elem, unsigned long opaque,
201 unsigned long *key,
202 size_t index, void *func2),
203 void *func2);
204
205
206#include <linux/btree-128.h>
207
208extern struct btree_geo btree_geo32;
209#define BTREE_TYPE_SUFFIX l
210#define BTREE_TYPE_BITS BITS_PER_LONG
211#define BTREE_TYPE_GEO &btree_geo32
212#define BTREE_KEYTYPE unsigned long
213#include <linux/btree-type.h>
214
215#define btree_for_each_safel(head, key, val) \
216 for (val = btree_lastl(head, &key); \
217 val; \
218 val = btree_get_prevl(head, &key))
219
220#define BTREE_TYPE_SUFFIX 32
221#define BTREE_TYPE_BITS 32
222#define BTREE_TYPE_GEO &btree_geo32
223#define BTREE_KEYTYPE u32
224#include <linux/btree-type.h>
225
226#define btree_for_each_safe32(head, key, val) \
227 for (val = btree_last32(head, &key); \
228 val; \
229 val = btree_get_prev32(head, &key))
230
231extern struct btree_geo btree_geo64;
232#define BTREE_TYPE_SUFFIX 64
233#define BTREE_TYPE_BITS 64
234#define BTREE_TYPE_GEO &btree_geo64
235#define BTREE_KEYTYPE u64
236#include <linux/btree-type.h>
237
238#define btree_for_each_safe64(head, key, val) \
239 for (val = btree_last64(head, &key); \
240 val; \
241 val = btree_get_prev64(head, &key))
242
243#endif
diff --git a/include/linux/coredump.h b/include/linux/coredump.h
new file mode 100644
index 000000000000..b3c91d7cede4
--- /dev/null
+++ b/include/linux/coredump.h
@@ -0,0 +1,41 @@
1#ifndef _LINUX_COREDUMP_H
2#define _LINUX_COREDUMP_H
3
4#include <linux/types.h>
5#include <linux/mm.h>
6#include <linux/fs.h>
7
8/*
9 * These are the only things you should do on a core-file: use only these
10 * functions to write out all the necessary info.
11 */
12static inline int dump_write(struct file *file, const void *addr, int nr)
13{
14 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
15}
16
17static inline int dump_seek(struct file *file, loff_t off)
18{
19 if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
20 if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
21 return 0;
22 } else {
23 char *buf = (char *)get_zeroed_page(GFP_KERNEL);
24
25 if (!buf)
26 return 0;
27 while (off > 0) {
28 unsigned long n = off;
29
30 if (n > PAGE_SIZE)
31 n = PAGE_SIZE;
32 if (!dump_write(file, buf, n))
33 return 0;
34 off -= n;
35 }
36 free_page((unsigned long)buf);
37 }
38 return 1;
39}
40
41#endif /* _LINUX_COREDUMP_H */
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index dbcee7647d9a..bae6fe24d1f9 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -90,10 +90,10 @@ extern const struct cpumask *const cpu_active_mask;
90#define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask) 90#define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask)
91#define cpu_active(cpu) cpumask_test_cpu((cpu), cpu_active_mask) 91#define cpu_active(cpu) cpumask_test_cpu((cpu), cpu_active_mask)
92#else 92#else
93#define num_online_cpus() 1 93#define num_online_cpus() 1U
94#define num_possible_cpus() 1 94#define num_possible_cpus() 1U
95#define num_present_cpus() 1 95#define num_present_cpus() 1U
96#define num_active_cpus() 1 96#define num_active_cpus() 1U
97#define cpu_online(cpu) ((cpu) == 0) 97#define cpu_online(cpu) ((cpu) == 0)
98#define cpu_possible(cpu) ((cpu) == 0) 98#define cpu_possible(cpu) ((cpu) == 0)
99#define cpu_present(cpu) ((cpu) == 0) 99#define cpu_present(cpu) ((cpu) == 0)
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index d4c9c0b88adc..1381cd97b4ed 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -118,10 +118,9 @@ struct dm_dev {
118/* 118/*
119 * Constructors should call these functions to ensure destination devices 119 * Constructors should call these functions to ensure destination devices
120 * are opened/closed correctly. 120 * are opened/closed correctly.
121 * FIXME: too many arguments.
122 */ 121 */
123int dm_get_device(struct dm_target *ti, const char *path, sector_t start, 122int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
124 sector_t len, fmode_t mode, struct dm_dev **result); 123 struct dm_dev **result);
125void dm_put_device(struct dm_target *ti, struct dm_dev *d); 124void dm_put_device(struct dm_target *ti, struct dm_dev *d);
126 125
127/* 126/*
diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h
index b6bf17ee2f61..5c9186b93fff 100644
--- a/include/linux/dm-io.h
+++ b/include/linux/dm-io.h
@@ -37,14 +37,14 @@ enum dm_io_mem_type {
37struct dm_io_memory { 37struct dm_io_memory {
38 enum dm_io_mem_type type; 38 enum dm_io_mem_type type;
39 39
40 unsigned offset;
41
40 union { 42 union {
41 struct page_list *pl; 43 struct page_list *pl;
42 struct bio_vec *bvec; 44 struct bio_vec *bvec;
43 void *vma; 45 void *vma;
44 void *addr; 46 void *addr;
45 } ptr; 47 } ptr;
46
47 unsigned offset;
48}; 48};
49 49
50struct dm_io_notify { 50struct dm_io_notify {
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index aa95508d2f95..2c445e113790 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -266,9 +266,9 @@ enum {
266#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) 266#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
267 267
268#define DM_VERSION_MAJOR 4 268#define DM_VERSION_MAJOR 4
269#define DM_VERSION_MINOR 16 269#define DM_VERSION_MINOR 17
270#define DM_VERSION_PATCHLEVEL 0 270#define DM_VERSION_PATCHLEVEL 0
271#define DM_VERSION_EXTRA "-ioctl (2009-11-05)" 271#define DM_VERSION_EXTRA "-ioctl (2010-03-05)"
272 272
273/* Status bits */ 273/* Status bits */
274#define DM_READONLY_FLAG (1 << 0) /* In/Out */ 274#define DM_READONLY_FLAG (1 << 0) /* In/Out */
@@ -316,4 +316,9 @@ enum {
316 */ 316 */
317#define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */ 317#define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */
318 318
319/*
320 * If set, a uevent was generated for which the caller may need to wait.
321 */
322#define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */
323
319#endif /* _LINUX_DM_IOCTL_H */ 324#endif /* _LINUX_DM_IOCTL_H */
diff --git a/include/linux/elf.h b/include/linux/elf.h
index ad990c5f63f6..597858418051 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -50,6 +50,28 @@ typedef __s64 Elf64_Sxword;
50 50
51#define PT_GNU_STACK (PT_LOOS + 0x474e551) 51#define PT_GNU_STACK (PT_LOOS + 0x474e551)
52 52
53/*
54 * Extended Numbering
55 *
56 * If the real number of program header table entries is larger than
57 * or equal to PN_XNUM(0xffff), it is set to sh_info field of the
58 * section header at index 0, and PN_XNUM is set to e_phnum
59 * field. Otherwise, the section header at index 0 is zero
60 * initialized, if it exists.
61 *
62 * Specifications are available in:
63 *
64 * - Sun microsystems: Linker and Libraries.
65 * Part No: 817-1984-17, September 2008.
66 * URL: http://docs.sun.com/app/docs/doc/817-1984
67 *
68 * - System V ABI AMD64 Architecture Processor Supplement
69 * Draft Version 0.99.,
70 * May 11, 2009.
71 * URL: http://www.x86-64.org/
72 */
73#define PN_XNUM 0xffff
74
53/* These constants define the different elf file types */ 75/* These constants define the different elf file types */
54#define ET_NONE 0 76#define ET_NONE 0
55#define ET_REL 1 77#define ET_REL 1
@@ -286,7 +308,7 @@ typedef struct elf64_phdr {
286#define SHN_COMMON 0xfff2 308#define SHN_COMMON 0xfff2
287#define SHN_HIRESERVE 0xffff 309#define SHN_HIRESERVE 0xffff
288 310
289typedef struct { 311typedef struct elf32_shdr {
290 Elf32_Word sh_name; 312 Elf32_Word sh_name;
291 Elf32_Word sh_type; 313 Elf32_Word sh_type;
292 Elf32_Word sh_flags; 314 Elf32_Word sh_flags;
@@ -394,16 +416,20 @@ typedef struct elf64_note {
394extern Elf32_Dyn _DYNAMIC []; 416extern Elf32_Dyn _DYNAMIC [];
395#define elfhdr elf32_hdr 417#define elfhdr elf32_hdr
396#define elf_phdr elf32_phdr 418#define elf_phdr elf32_phdr
419#define elf_shdr elf32_shdr
397#define elf_note elf32_note 420#define elf_note elf32_note
398#define elf_addr_t Elf32_Off 421#define elf_addr_t Elf32_Off
422#define Elf_Half Elf32_Half
399 423
400#else 424#else
401 425
402extern Elf64_Dyn _DYNAMIC []; 426extern Elf64_Dyn _DYNAMIC [];
403#define elfhdr elf64_hdr 427#define elfhdr elf64_hdr
404#define elf_phdr elf64_phdr 428#define elf_phdr elf64_phdr
429#define elf_shdr elf64_shdr
405#define elf_note elf64_note 430#define elf_note elf64_note
406#define elf_addr_t Elf64_Off 431#define elf_addr_t Elf64_Off
432#define Elf_Half Elf64_Half
407 433
408#endif 434#endif
409 435
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h
index 00d6a68d0421..e687bc3ba4da 100644
--- a/include/linux/elfcore.h
+++ b/include/linux/elfcore.h
@@ -8,6 +8,8 @@
8#include <linux/user.h> 8#include <linux/user.h>
9#endif 9#endif
10#include <linux/ptrace.h> 10#include <linux/ptrace.h>
11#include <linux/elf.h>
12#include <linux/fs.h>
11 13
12struct elf_siginfo 14struct elf_siginfo
13{ 15{
@@ -150,5 +152,20 @@ static inline int elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregse
150 152
151#endif /* __KERNEL__ */ 153#endif /* __KERNEL__ */
152 154
155/*
156 * These functions parameterize elf_core_dump in fs/binfmt_elf.c to write out
157 * extra segments containing the gate DSO contents. Dumping its
158 * contents makes post-mortem fully interpretable later without matching up
159 * the same kernel and hardware config to see what PC values meant.
160 * Dumping its extra ELF program headers includes all the other information
161 * a debugger needs to easily find how the gate DSO was being used.
162 */
163extern Elf_Half elf_core_extra_phdrs(void);
164extern int
165elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
166 unsigned long limit);
167extern int
168elf_core_write_extra_data(struct file *file, size_t *size, unsigned long limit);
169extern size_t elf_core_extra_data_size(void);
153 170
154#endif /* _LINUX_ELFCORE_H */ 171#endif /* _LINUX_ELFCORE_H */
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index dc12f416a49f..a9cd507f8cd2 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -96,6 +96,7 @@ struct fid {
96 * @fh_to_parent: find the implied object's parent and get a dentry for it 96 * @fh_to_parent: find the implied object's parent and get a dentry for it
97 * @get_name: find the name for a given inode in a given directory 97 * @get_name: find the name for a given inode in a given directory
98 * @get_parent: find the parent of a given directory 98 * @get_parent: find the parent of a given directory
99 * @commit_metadata: commit metadata changes to stable storage
99 * 100 *
100 * See Documentation/filesystems/nfs/Exporting for details on how to use 101 * See Documentation/filesystems/nfs/Exporting for details on how to use
101 * this interface correctly. 102 * this interface correctly.
@@ -137,6 +138,9 @@ struct fid {
137 * is also a directory. In the event that it cannot be found, or storage 138 * is also a directory. In the event that it cannot be found, or storage
138 * space cannot be allocated, a %ERR_PTR should be returned. 139 * space cannot be allocated, a %ERR_PTR should be returned.
139 * 140 *
141 * commit_metadata:
142 * @commit_metadata should commit metadata changes to stable storage.
143 *
140 * Locking rules: 144 * Locking rules:
141 * get_parent is called with child->d_inode->i_mutex down 145 * get_parent is called with child->d_inode->i_mutex down
142 * get_name is not (which is possibly inconsistent) 146 * get_name is not (which is possibly inconsistent)
@@ -152,6 +156,7 @@ struct export_operations {
152 int (*get_name)(struct dentry *parent, char *name, 156 int (*get_name)(struct dentry *parent, char *name,
153 struct dentry *child); 157 struct dentry *child);
154 struct dentry * (*get_parent)(struct dentry *child); 158 struct dentry * (*get_parent)(struct dentry *child);
159 int (*commit_metadata)(struct inode *inode);
155}; 160};
156 161
157extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, 162extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
diff --git a/include/linux/firmware-map.h b/include/linux/firmware-map.h
index 875451f1373a..c6dcc1dfe781 100644
--- a/include/linux/firmware-map.h
+++ b/include/linux/firmware-map.h
@@ -24,17 +24,17 @@
24 */ 24 */
25#ifdef CONFIG_FIRMWARE_MEMMAP 25#ifdef CONFIG_FIRMWARE_MEMMAP
26 26
27int firmware_map_add(u64 start, u64 end, const char *type);
28int firmware_map_add_early(u64 start, u64 end, const char *type); 27int firmware_map_add_early(u64 start, u64 end, const char *type);
28int firmware_map_add_hotplug(u64 start, u64 end, const char *type);
29 29
30#else /* CONFIG_FIRMWARE_MEMMAP */ 30#else /* CONFIG_FIRMWARE_MEMMAP */
31 31
32static inline int firmware_map_add(u64 start, u64 end, const char *type) 32static inline int firmware_map_add_early(u64 start, u64 end, const char *type)
33{ 33{
34 return 0; 34 return 0;
35} 35}
36 36
37static inline int firmware_map_add_early(u64 start, u64 end, const char *type) 37static inline int firmware_map_add_hotplug(u64 start, u64 end, const char *type)
38{ 38{
39 return 0; 39 return 0;
40} 40}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 45689621a851..10b8dedcd18b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -60,24 +60,24 @@ struct inodes_stat_t {
60 */ 60 */
61 61
62/* file is open for reading */ 62/* file is open for reading */
63#define FMODE_READ ((__force fmode_t)1) 63#define FMODE_READ ((__force fmode_t)0x1)
64/* file is open for writing */ 64/* file is open for writing */
65#define FMODE_WRITE ((__force fmode_t)2) 65#define FMODE_WRITE ((__force fmode_t)0x2)
66/* file is seekable */ 66/* file is seekable */
67#define FMODE_LSEEK ((__force fmode_t)4) 67#define FMODE_LSEEK ((__force fmode_t)0x4)
68/* file can be accessed using pread */ 68/* file can be accessed using pread */
69#define FMODE_PREAD ((__force fmode_t)8) 69#define FMODE_PREAD ((__force fmode_t)0x8)
70/* file can be accessed using pwrite */ 70/* file can be accessed using pwrite */
71#define FMODE_PWRITE ((__force fmode_t)16) 71#define FMODE_PWRITE ((__force fmode_t)0x10)
72/* File is opened for execution with sys_execve / sys_uselib */ 72/* File is opened for execution with sys_execve / sys_uselib */
73#define FMODE_EXEC ((__force fmode_t)32) 73#define FMODE_EXEC ((__force fmode_t)0x20)
74/* File is opened with O_NDELAY (only set for block devices) */ 74/* File is opened with O_NDELAY (only set for block devices) */
75#define FMODE_NDELAY ((__force fmode_t)64) 75#define FMODE_NDELAY ((__force fmode_t)0x40)
76/* File is opened with O_EXCL (only set for block devices) */ 76/* File is opened with O_EXCL (only set for block devices) */
77#define FMODE_EXCL ((__force fmode_t)128) 77#define FMODE_EXCL ((__force fmode_t)0x80)
78/* File is opened using open(.., 3, ..) and is writeable only for ioctls 78/* File is opened using open(.., 3, ..) and is writeable only for ioctls
79 (specialy hack for floppy.c) */ 79 (specialy hack for floppy.c) */
80#define FMODE_WRITE_IOCTL ((__force fmode_t)256) 80#define FMODE_WRITE_IOCTL ((__force fmode_t)0x100)
81 81
82/* 82/*
83 * Don't update ctime and mtime. 83 * Don't update ctime and mtime.
@@ -85,7 +85,10 @@ struct inodes_stat_t {
85 * Currently a special hack for the XFS open_by_handle ioctl, but we'll 85 * Currently a special hack for the XFS open_by_handle ioctl, but we'll
86 * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon. 86 * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
87 */ 87 */
88#define FMODE_NOCMTIME ((__force fmode_t)2048) 88#define FMODE_NOCMTIME ((__force fmode_t)0x800)
89
90/* Expect random access pattern */
91#define FMODE_RANDOM ((__force fmode_t)0x1000)
89 92
90/* 93/*
91 * The below are the various read and write types that we support. Some of 94 * The below are the various read and write types that we support. Some of
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 557bdad320b6..4c6d41333f98 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -30,7 +30,8 @@ struct vm_area_struct;
30 * _might_ fail. This depends upon the particular VM implementation. 30 * _might_ fail. This depends upon the particular VM implementation.
31 * 31 *
32 * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller 32 * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
33 * cannot handle allocation failures. 33 * cannot handle allocation failures. This modifier is deprecated and no new
34 * users should be added.
34 * 35 *
35 * __GFP_NORETRY: The VM implementation must not retry indefinitely. 36 * __GFP_NORETRY: The VM implementation must not retry indefinitely.
36 * 37 *
@@ -83,6 +84,7 @@ struct vm_area_struct;
83#define GFP_HIGHUSER_MOVABLE (__GFP_WAIT | __GFP_IO | __GFP_FS | \ 84#define GFP_HIGHUSER_MOVABLE (__GFP_WAIT | __GFP_IO | __GFP_FS | \
84 __GFP_HARDWALL | __GFP_HIGHMEM | \ 85 __GFP_HARDWALL | __GFP_HIGHMEM | \
85 __GFP_MOVABLE) 86 __GFP_MOVABLE)
87#define GFP_IOFS (__GFP_IO | __GFP_FS)
86 88
87#ifdef CONFIG_NUMA 89#ifdef CONFIG_NUMA
88#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) 90#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
@@ -325,7 +327,7 @@ void free_pages_exact(void *virt, size_t size);
325 327
326extern void __free_pages(struct page *page, unsigned int order); 328extern void __free_pages(struct page *page, unsigned int order);
327extern void free_pages(unsigned long addr, unsigned int order); 329extern void free_pages(unsigned long addr, unsigned int order);
328extern void free_hot_page(struct page *page); 330extern void free_hot_cold_page(struct page *page, int cold);
329 331
330#define __free_page(page) __free_pages((page), 0) 332#define __free_page(page) __free_pages((page), 0)
331#define free_page(addr) free_pages((addr),0) 333#define free_page(addr) free_pages((addr),0)
@@ -337,9 +339,7 @@ void drain_local_pages(void *dummy);
337 339
338extern gfp_t gfp_allowed_mask; 340extern gfp_t gfp_allowed_mask;
339 341
340static inline void set_gfp_allowed_mask(gfp_t mask) 342extern void set_gfp_allowed_mask(gfp_t mask);
341{ 343extern gfp_t clear_gfp_allowed_mask(gfp_t mask);
342 gfp_allowed_mask = mask;
343}
344 344
345#endif /* __LINUX_GFP_H */ 345#endif /* __LINUX_GFP_H */
diff --git a/include/linux/htcpld.h b/include/linux/htcpld.h
new file mode 100644
index 000000000000..ab3f6cb4dddc
--- /dev/null
+++ b/include/linux/htcpld.h
@@ -0,0 +1,24 @@
1#ifndef __LINUX_HTCPLD_H
2#define __LINUX_HTCPLD_H
3
4struct htcpld_chip_platform_data {
5 unsigned int addr;
6 unsigned int reset;
7 unsigned int num_gpios;
8 unsigned int gpio_out_base;
9 unsigned int gpio_in_base;
10 unsigned int irq_base;
11 unsigned int num_irqs;
12};
13
14struct htcpld_core_platform_data {
15 unsigned int int_reset_gpio_hi;
16 unsigned int int_reset_gpio_lo;
17 unsigned int i2c_adapter_id;
18
19 struct htcpld_chip_platform_data *chip;
20 unsigned int num_chip;
21};
22
23#endif /* __LINUX_HTCPLD_H */
24
diff --git a/include/linux/i2c/pca953x.h b/include/linux/i2c/pca953x.h
index 81736d6a8db7..d5c5a60c8a0b 100644
--- a/include/linux/i2c/pca953x.h
+++ b/include/linux/i2c/pca953x.h
@@ -1,3 +1,9 @@
1#ifndef _LINUX_PCA953X_H
2#define _LINUX_PCA953X_H
3
4#include <linux/types.h>
5#include <linux/i2c.h>
6
1/* platform data for the PCA9539 16-bit I/O expander driver */ 7/* platform data for the PCA9539 16-bit I/O expander driver */
2 8
3struct pca953x_platform_data { 9struct pca953x_platform_data {
@@ -7,6 +13,9 @@ struct pca953x_platform_data {
7 /* initial polarity inversion setting */ 13 /* initial polarity inversion setting */
8 uint16_t invert; 14 uint16_t invert;
9 15
16 /* interrupt base */
17 int irq_base;
18
10 void *context; /* param to setup/teardown */ 19 void *context; /* param to setup/teardown */
11 20
12 int (*setup)(struct i2c_client *client, 21 int (*setup)(struct i2c_client *client,
@@ -17,3 +26,5 @@ struct pca953x_platform_data {
17 void *context); 26 void *context);
18 char **names; 27 char **names;
19}; 28};
29
30#endif /* _LINUX_PCA953X_H */
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 7897f3096560..fb6784e86d5f 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -80,6 +80,11 @@
80#define TWL_MODULE_PM_MASTER TWL4030_MODULE_PM_MASTER 80#define TWL_MODULE_PM_MASTER TWL4030_MODULE_PM_MASTER
81#define TWL_MODULE_PM_RECEIVER TWL4030_MODULE_PM_RECEIVER 81#define TWL_MODULE_PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
82#define TWL_MODULE_RTC TWL4030_MODULE_RTC 82#define TWL_MODULE_RTC TWL4030_MODULE_RTC
83#define TWL_MODULE_PWM TWL4030_MODULE_PWM0
84
85#define TWL6030_MODULE_ID0 0x0D
86#define TWL6030_MODULE_ID1 0x0E
87#define TWL6030_MODULE_ID2 0x0F
83 88
84#define GPIO_INTR_OFFSET 0 89#define GPIO_INTR_OFFSET 0
85#define KEYPAD_INTR_OFFSET 1 90#define KEYPAD_INTR_OFFSET 1
@@ -239,6 +244,21 @@ int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
239 244
240/*----------------------------------------------------------------------*/ 245/*----------------------------------------------------------------------*/
241 246
247/*Interface Bit Register (INTBR) offsets
248 *(Use TWL_4030_MODULE_INTBR)
249 */
250
251#define REG_GPPUPDCTR1 0x0F
252
253/*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */
254
255#define I2C_SCL_CTRL_PU BIT(0)
256#define I2C_SDA_CTRL_PU BIT(2)
257#define SR_I2C_SCL_CTRL_PU BIT(4)
258#define SR_I2C_SDA_CTRL_PU BIT(6)
259
260/*----------------------------------------------------------------------*/
261
242/* 262/*
243 * Keypad register offsets (use TWL4030_MODULE_KEYPAD) 263 * Keypad register offsets (use TWL4030_MODULE_KEYPAD)
244 * ... SIH/interrupt only 264 * ... SIH/interrupt only
@@ -530,6 +550,7 @@ struct twl4030_power_data {
530}; 550};
531 551
532extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); 552extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
553extern int twl4030_remove_script(u8 flags);
533 554
534struct twl4030_codec_audio_data { 555struct twl4030_codec_audio_data {
535 unsigned int audio_mclk; 556 unsigned int audio_mclk;
@@ -605,12 +626,7 @@ int twl4030_sih_setup(int module);
605#define TWL4030_VAUX3_DEV_GRP 0x1F 626#define TWL4030_VAUX3_DEV_GRP 0x1F
606#define TWL4030_VAUX3_DEDICATED 0x22 627#define TWL4030_VAUX3_DEDICATED 0x22
607 628
608#if defined(CONFIG_TWL4030_BCI_BATTERY) || \ 629static inline int twl4030charger_usb_en(int enable) { return 0; }
609 defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
610 extern int twl4030charger_usb_en(int enable);
611#else
612 static inline int twl4030charger_usb_en(int enable) { return 0; }
613#endif
614 630
615/*----------------------------------------------------------------------*/ 631/*----------------------------------------------------------------------*/
616 632
diff --git a/include/linux/list.h b/include/linux/list.h
index 5d9c6558e8ab..8392884a2977 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -498,7 +498,7 @@ static inline void list_splice_tail_init(struct list_head *list,
498 pos = n, n = list_entry(n->member.next, typeof(*n), member)) 498 pos = n, n = list_entry(n->member.next, typeof(*n), member))
499 499
500/** 500/**
501 * list_for_each_entry_safe_continue 501 * list_for_each_entry_safe_continue - continue list iteration safe against removal
502 * @pos: the type * to use as a loop cursor. 502 * @pos: the type * to use as a loop cursor.
503 * @n: another type * to use as temporary storage 503 * @n: another type * to use as temporary storage
504 * @head: the head for your list. 504 * @head: the head for your list.
@@ -514,7 +514,7 @@ static inline void list_splice_tail_init(struct list_head *list,
514 pos = n, n = list_entry(n->member.next, typeof(*n), member)) 514 pos = n, n = list_entry(n->member.next, typeof(*n), member))
515 515
516/** 516/**
517 * list_for_each_entry_safe_from 517 * list_for_each_entry_safe_from - iterate over list from current point safe against removal
518 * @pos: the type * to use as a loop cursor. 518 * @pos: the type * to use as a loop cursor.
519 * @n: another type * to use as temporary storage 519 * @n: another type * to use as temporary storage
520 * @head: the head for your list. 520 * @head: the head for your list.
@@ -529,7 +529,7 @@ static inline void list_splice_tail_init(struct list_head *list,
529 pos = n, n = list_entry(n->member.next, typeof(*n), member)) 529 pos = n, n = list_entry(n->member.next, typeof(*n), member))
530 530
531/** 531/**
532 * list_for_each_entry_safe_reverse 532 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
533 * @pos: the type * to use as a loop cursor. 533 * @pos: the type * to use as a loop cursor.
534 * @n: another type * to use as temporary storage 534 * @n: another type * to use as temporary storage
535 * @head: the head for your list. 535 * @head: the head for your list.
diff --git a/include/linux/mfd/88pm8607.h b/include/linux/mfd/88pm8607.h
deleted file mode 100644
index f41b428d2cec..000000000000
--- a/include/linux/mfd/88pm8607.h
+++ /dev/null
@@ -1,217 +0,0 @@
1/*
2 * Marvell 88PM8607 Interface
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_MFD_88PM8607_H
13#define __LINUX_MFD_88PM8607_H
14
15enum {
16 PM8607_ID_BUCK1 = 0,
17 PM8607_ID_BUCK2,
18 PM8607_ID_BUCK3,
19
20 PM8607_ID_LDO1,
21 PM8607_ID_LDO2,
22 PM8607_ID_LDO3,
23 PM8607_ID_LDO4,
24 PM8607_ID_LDO5,
25 PM8607_ID_LDO6,
26 PM8607_ID_LDO7,
27 PM8607_ID_LDO8,
28 PM8607_ID_LDO9,
29 PM8607_ID_LDO10,
30 PM8607_ID_LDO12,
31 PM8607_ID_LDO14,
32
33 PM8607_ID_RG_MAX,
34};
35
36#define CHIP_ID (0x40)
37#define CHIP_ID_MASK (0xF8)
38
39/* Interrupt Registers */
40#define PM8607_STATUS_1 (0x01)
41#define PM8607_STATUS_2 (0x02)
42#define PM8607_INT_STATUS1 (0x03)
43#define PM8607_INT_STATUS2 (0x04)
44#define PM8607_INT_STATUS3 (0x05)
45#define PM8607_INT_MASK_1 (0x06)
46#define PM8607_INT_MASK_2 (0x07)
47#define PM8607_INT_MASK_3 (0x08)
48
49/* Regulator Control Registers */
50#define PM8607_LDO1 (0x10)
51#define PM8607_LDO2 (0x11)
52#define PM8607_LDO3 (0x12)
53#define PM8607_LDO4 (0x13)
54#define PM8607_LDO5 (0x14)
55#define PM8607_LDO6 (0x15)
56#define PM8607_LDO7 (0x16)
57#define PM8607_LDO8 (0x17)
58#define PM8607_LDO9 (0x18)
59#define PM8607_LDO10 (0x19)
60#define PM8607_LDO12 (0x1A)
61#define PM8607_LDO14 (0x1B)
62#define PM8607_SLEEP_MODE1 (0x1C)
63#define PM8607_SLEEP_MODE2 (0x1D)
64#define PM8607_SLEEP_MODE3 (0x1E)
65#define PM8607_SLEEP_MODE4 (0x1F)
66#define PM8607_GO (0x20)
67#define PM8607_SLEEP_BUCK1 (0x21)
68#define PM8607_SLEEP_BUCK2 (0x22)
69#define PM8607_SLEEP_BUCK3 (0x23)
70#define PM8607_BUCK1 (0x24)
71#define PM8607_BUCK2 (0x25)
72#define PM8607_BUCK3 (0x26)
73#define PM8607_BUCK_CONTROLS (0x27)
74#define PM8607_SUPPLIES_EN11 (0x2B)
75#define PM8607_SUPPLIES_EN12 (0x2C)
76#define PM8607_GROUP1 (0x2D)
77#define PM8607_GROUP2 (0x2E)
78#define PM8607_GROUP3 (0x2F)
79#define PM8607_GROUP4 (0x30)
80#define PM8607_GROUP5 (0x31)
81#define PM8607_GROUP6 (0x32)
82#define PM8607_SUPPLIES_EN21 (0x33)
83#define PM8607_SUPPLIES_EN22 (0x34)
84
85/* RTC Control Registers */
86#define PM8607_RTC1 (0xA0)
87#define PM8607_RTC_COUNTER1 (0xA1)
88#define PM8607_RTC_COUNTER2 (0xA2)
89#define PM8607_RTC_COUNTER3 (0xA3)
90#define PM8607_RTC_COUNTER4 (0xA4)
91#define PM8607_RTC_EXPIRE1 (0xA5)
92#define PM8607_RTC_EXPIRE2 (0xA6)
93#define PM8607_RTC_EXPIRE3 (0xA7)
94#define PM8607_RTC_EXPIRE4 (0xA8)
95#define PM8607_RTC_TRIM1 (0xA9)
96#define PM8607_RTC_TRIM2 (0xAA)
97#define PM8607_RTC_TRIM3 (0xAB)
98#define PM8607_RTC_TRIM4 (0xAC)
99#define PM8607_RTC_MISC1 (0xAD)
100#define PM8607_RTC_MISC2 (0xAE)
101#define PM8607_RTC_MISC3 (0xAF)
102
103/* Misc Registers */
104#define PM8607_CHIP_ID (0x00)
105#define PM8607_LDO1 (0x10)
106#define PM8607_DVC3 (0x26)
107#define PM8607_MISC1 (0x40)
108
109/* bit definitions for PM8607 events */
110#define PM8607_EVENT_ONKEY (1 << 0)
111#define PM8607_EVENT_EXTON (1 << 1)
112#define PM8607_EVENT_CHG (1 << 2)
113#define PM8607_EVENT_BAT (1 << 3)
114#define PM8607_EVENT_RTC (1 << 4)
115#define PM8607_EVENT_CC (1 << 5)
116#define PM8607_EVENT_VBAT (1 << 8)
117#define PM8607_EVENT_VCHG (1 << 9)
118#define PM8607_EVENT_VSYS (1 << 10)
119#define PM8607_EVENT_TINT (1 << 11)
120#define PM8607_EVENT_GPADC0 (1 << 12)
121#define PM8607_EVENT_GPADC1 (1 << 13)
122#define PM8607_EVENT_GPADC2 (1 << 14)
123#define PM8607_EVENT_GPADC3 (1 << 15)
124#define PM8607_EVENT_AUDIO_SHORT (1 << 16)
125#define PM8607_EVENT_PEN (1 << 17)
126#define PM8607_EVENT_HEADSET (1 << 18)
127#define PM8607_EVENT_HOOK (1 << 19)
128#define PM8607_EVENT_MICIN (1 << 20)
129#define PM8607_EVENT_CHG_TIMEOUT (1 << 21)
130#define PM8607_EVENT_CHG_DONE (1 << 22)
131#define PM8607_EVENT_CHG_FAULT (1 << 23)
132
133/* bit definitions of Status Query Interface */
134#define PM8607_STATUS_CC (1 << 3)
135#define PM8607_STATUS_PEN (1 << 4)
136#define PM8607_STATUS_HEADSET (1 << 5)
137#define PM8607_STATUS_HOOK (1 << 6)
138#define PM8607_STATUS_MICIN (1 << 7)
139#define PM8607_STATUS_ONKEY (1 << 8)
140#define PM8607_STATUS_EXTON (1 << 9)
141#define PM8607_STATUS_CHG (1 << 10)
142#define PM8607_STATUS_BAT (1 << 11)
143#define PM8607_STATUS_VBUS (1 << 12)
144#define PM8607_STATUS_OV (1 << 13)
145
146/* bit definitions of BUCK3 */
147#define PM8607_BUCK3_DOUBLE (1 << 6)
148
149/* bit definitions of Misc1 */
150#define PM8607_MISC1_PI2C (1 << 0)
151
152/* Interrupt Number in 88PM8607 */
153enum {
154 PM8607_IRQ_ONKEY = 0,
155 PM8607_IRQ_EXTON,
156 PM8607_IRQ_CHG,
157 PM8607_IRQ_BAT,
158 PM8607_IRQ_RTC,
159 PM8607_IRQ_VBAT = 8,
160 PM8607_IRQ_VCHG,
161 PM8607_IRQ_VSYS,
162 PM8607_IRQ_TINT,
163 PM8607_IRQ_GPADC0,
164 PM8607_IRQ_GPADC1,
165 PM8607_IRQ_GPADC2,
166 PM8607_IRQ_GPADC3,
167 PM8607_IRQ_AUDIO_SHORT = 16,
168 PM8607_IRQ_PEN,
169 PM8607_IRQ_HEADSET,
170 PM8607_IRQ_HOOK,
171 PM8607_IRQ_MICIN,
172 PM8607_IRQ_CHG_FAIL,
173 PM8607_IRQ_CHG_DONE,
174 PM8607_IRQ_CHG_FAULT,
175};
176
177enum {
178 PM8607_CHIP_A0 = 0x40,
179 PM8607_CHIP_A1 = 0x41,
180 PM8607_CHIP_B0 = 0x48,
181};
182
183
184struct pm8607_chip {
185 struct device *dev;
186 struct mutex io_lock;
187 struct i2c_client *client;
188
189 int (*read)(struct pm8607_chip *chip, int reg, int bytes, void *dest);
190 int (*write)(struct pm8607_chip *chip, int reg, int bytes, void *src);
191
192 int buck3_double; /* DVC ramp slope double */
193 unsigned char chip_id;
194
195};
196
197#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */
198
199enum {
200 GI2C_PORT = 0,
201 PI2C_PORT,
202};
203
204struct pm8607_platform_data {
205 int i2c_port; /* Controlled by GI2C or PI2C */
206 struct regulator_init_data *regulator[PM8607_MAX_REGULATOR];
207};
208
209extern int pm8607_reg_read(struct pm8607_chip *, int);
210extern int pm8607_reg_write(struct pm8607_chip *, int, unsigned char);
211extern int pm8607_bulk_read(struct pm8607_chip *, int, int,
212 unsigned char *);
213extern int pm8607_bulk_write(struct pm8607_chip *, int, int,
214 unsigned char *);
215extern int pm8607_set_bits(struct pm8607_chip *, int, unsigned char,
216 unsigned char);
217#endif /* __LINUX_MFD_88PM8607_H */
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
new file mode 100644
index 000000000000..73f92c5feea2
--- /dev/null
+++ b/include/linux/mfd/88pm860x.h
@@ -0,0 +1,375 @@
1/*
2 * Marvell 88PM860x Interface
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_MFD_88PM860X_H
13#define __LINUX_MFD_88PM860X_H
14
15#include <linux/interrupt.h>
16
17#define MFD_NAME_SIZE (40)
18
19enum {
20 CHIP_INVALID = 0,
21 CHIP_PM8606,
22 CHIP_PM8607,
23 CHIP_MAX,
24};
25
26enum {
27 PM8606_ID_INVALID,
28 PM8606_ID_BACKLIGHT,
29 PM8606_ID_LED,
30 PM8606_ID_VIBRATOR,
31 PM8606_ID_TOUCH,
32 PM8606_ID_SOUND,
33 PM8606_ID_CHARGER,
34 PM8606_ID_MAX,
35};
36
37enum {
38 PM8606_BACKLIGHT1 = 0,
39 PM8606_BACKLIGHT2,
40 PM8606_BACKLIGHT3,
41};
42
43enum {
44 PM8606_LED1_RED = 0,
45 PM8606_LED1_GREEN,
46 PM8606_LED1_BLUE,
47 PM8606_LED2_RED,
48 PM8606_LED2_GREEN,
49 PM8606_LED2_BLUE,
50 PM8607_LED_VIBRATOR,
51};
52
53
54/* 8606 Registers */
55#define PM8606_DCM_BOOST (0x00)
56#define PM8606_PWM (0x01)
57
58/* Backlight Registers */
59#define PM8606_WLED1A (0x02)
60#define PM8606_WLED1B (0x03)
61#define PM8606_WLED2A (0x04)
62#define PM8606_WLED2B (0x05)
63#define PM8606_WLED3A (0x06)
64#define PM8606_WLED3B (0x07)
65
66/* LED Registers */
67#define PM8606_RGB2A (0x08)
68#define PM8606_RGB2B (0x09)
69#define PM8606_RGB2C (0x0A)
70#define PM8606_RGB2D (0x0B)
71#define PM8606_RGB1A (0x0C)
72#define PM8606_RGB1B (0x0D)
73#define PM8606_RGB1C (0x0E)
74#define PM8606_RGB1D (0x0F)
75
76#define PM8606_PREREGULATORA (0x10)
77#define PM8606_PREREGULATORB (0x11)
78#define PM8606_VIBRATORA (0x12)
79#define PM8606_VIBRATORB (0x13)
80#define PM8606_VCHG (0x14)
81#define PM8606_VSYS (0x15)
82#define PM8606_MISC (0x16)
83#define PM8606_CHIP_ID (0x17)
84#define PM8606_STATUS (0x18)
85#define PM8606_FLAGS (0x19)
86#define PM8606_PROTECTA (0x1A)
87#define PM8606_PROTECTB (0x1B)
88#define PM8606_PROTECTC (0x1C)
89
90/* Bit definitions of PM8606 registers */
91#define PM8606_DCM_500MA (0x0) /* current limit */
92#define PM8606_DCM_750MA (0x1)
93#define PM8606_DCM_1000MA (0x2)
94#define PM8606_DCM_1250MA (0x3)
95#define PM8606_DCM_250MV (0x0 << 2)
96#define PM8606_DCM_300MV (0x1 << 2)
97#define PM8606_DCM_350MV (0x2 << 2)
98#define PM8606_DCM_400MV (0x3 << 2)
99
100#define PM8606_PWM_31200HZ (0x0)
101#define PM8606_PWM_15600HZ (0x1)
102#define PM8606_PWM_7800HZ (0x2)
103#define PM8606_PWM_3900HZ (0x3)
104#define PM8606_PWM_1950HZ (0x4)
105#define PM8606_PWM_976HZ (0x5)
106#define PM8606_PWM_488HZ (0x6)
107#define PM8606_PWM_244HZ (0x7)
108#define PM8606_PWM_FREQ_MASK (0x7)
109
110#define PM8606_WLED_ON (1 << 0)
111#define PM8606_WLED_CURRENT(x) ((x & 0x1F) << 1)
112
113#define PM8606_LED_CURRENT(x) (((x >> 2) & 0x07) << 5)
114
115#define PM8606_VSYS_EN (1 << 1)
116
117#define PM8606_MISC_OSC_EN (1 << 4)
118
119enum {
120 PM8607_ID_BUCK1 = 0,
121 PM8607_ID_BUCK2,
122 PM8607_ID_BUCK3,
123
124 PM8607_ID_LDO1,
125 PM8607_ID_LDO2,
126 PM8607_ID_LDO3,
127 PM8607_ID_LDO4,
128 PM8607_ID_LDO5,
129 PM8607_ID_LDO6,
130 PM8607_ID_LDO7,
131 PM8607_ID_LDO8,
132 PM8607_ID_LDO9,
133 PM8607_ID_LDO10,
134 PM8607_ID_LDO12,
135 PM8607_ID_LDO14,
136
137 PM8607_ID_RG_MAX,
138};
139
140#define PM8607_VERSION (0x40) /* 8607 chip ID */
141#define PM8607_VERSION_MASK (0xF0) /* 8607 chip ID mask */
142
143/* Interrupt Registers */
144#define PM8607_STATUS_1 (0x01)
145#define PM8607_STATUS_2 (0x02)
146#define PM8607_INT_STATUS1 (0x03)
147#define PM8607_INT_STATUS2 (0x04)
148#define PM8607_INT_STATUS3 (0x05)
149#define PM8607_INT_MASK_1 (0x06)
150#define PM8607_INT_MASK_2 (0x07)
151#define PM8607_INT_MASK_3 (0x08)
152
153/* Regulator Control Registers */
154#define PM8607_LDO1 (0x10)
155#define PM8607_LDO2 (0x11)
156#define PM8607_LDO3 (0x12)
157#define PM8607_LDO4 (0x13)
158#define PM8607_LDO5 (0x14)
159#define PM8607_LDO6 (0x15)
160#define PM8607_LDO7 (0x16)
161#define PM8607_LDO8 (0x17)
162#define PM8607_LDO9 (0x18)
163#define PM8607_LDO10 (0x19)
164#define PM8607_LDO12 (0x1A)
165#define PM8607_LDO14 (0x1B)
166#define PM8607_SLEEP_MODE1 (0x1C)
167#define PM8607_SLEEP_MODE2 (0x1D)
168#define PM8607_SLEEP_MODE3 (0x1E)
169#define PM8607_SLEEP_MODE4 (0x1F)
170#define PM8607_GO (0x20)
171#define PM8607_SLEEP_BUCK1 (0x21)
172#define PM8607_SLEEP_BUCK2 (0x22)
173#define PM8607_SLEEP_BUCK3 (0x23)
174#define PM8607_BUCK1 (0x24)
175#define PM8607_BUCK2 (0x25)
176#define PM8607_BUCK3 (0x26)
177#define PM8607_BUCK_CONTROLS (0x27)
178#define PM8607_SUPPLIES_EN11 (0x2B)
179#define PM8607_SUPPLIES_EN12 (0x2C)
180#define PM8607_GROUP1 (0x2D)
181#define PM8607_GROUP2 (0x2E)
182#define PM8607_GROUP3 (0x2F)
183#define PM8607_GROUP4 (0x30)
184#define PM8607_GROUP5 (0x31)
185#define PM8607_GROUP6 (0x32)
186#define PM8607_SUPPLIES_EN21 (0x33)
187#define PM8607_SUPPLIES_EN22 (0x34)
188
189/* Vibrator Control Registers */
190#define PM8607_VIBRATOR_SET (0x28)
191#define PM8607_VIBRATOR_PWM (0x29)
192
193/* GPADC Registers */
194#define PM8607_GP_BIAS1 (0x4F)
195#define PM8607_MEAS_EN1 (0x50)
196#define PM8607_MEAS_EN2 (0x51)
197#define PM8607_MEAS_EN3 (0x52)
198#define PM8607_MEAS_OFF_TIME1 (0x53)
199#define PM8607_MEAS_OFF_TIME2 (0x54)
200#define PM8607_TSI_PREBIAS (0x55) /* prebias time */
201#define PM8607_PD_PREBIAS (0x56) /* prebias time */
202#define PM8607_GPADC_MISC1 (0x57)
203
204/* RTC Control Registers */
205#define PM8607_RTC1 (0xA0)
206#define PM8607_RTC_COUNTER1 (0xA1)
207#define PM8607_RTC_COUNTER2 (0xA2)
208#define PM8607_RTC_COUNTER3 (0xA3)
209#define PM8607_RTC_COUNTER4 (0xA4)
210#define PM8607_RTC_EXPIRE1 (0xA5)
211#define PM8607_RTC_EXPIRE2 (0xA6)
212#define PM8607_RTC_EXPIRE3 (0xA7)
213#define PM8607_RTC_EXPIRE4 (0xA8)
214#define PM8607_RTC_TRIM1 (0xA9)
215#define PM8607_RTC_TRIM2 (0xAA)
216#define PM8607_RTC_TRIM3 (0xAB)
217#define PM8607_RTC_TRIM4 (0xAC)
218#define PM8607_RTC_MISC1 (0xAD)
219#define PM8607_RTC_MISC2 (0xAE)
220#define PM8607_RTC_MISC3 (0xAF)
221
222/* Misc Registers */
223#define PM8607_CHIP_ID (0x00)
224#define PM8607_B0_MISC1 (0x0C)
225#define PM8607_LDO1 (0x10)
226#define PM8607_DVC3 (0x26)
227#define PM8607_A1_MISC1 (0x40)
228
229/* bit definitions of Status Query Interface */
230#define PM8607_STATUS_CC (1 << 3)
231#define PM8607_STATUS_PEN (1 << 4)
232#define PM8607_STATUS_HEADSET (1 << 5)
233#define PM8607_STATUS_HOOK (1 << 6)
234#define PM8607_STATUS_MICIN (1 << 7)
235#define PM8607_STATUS_ONKEY (1 << 8)
236#define PM8607_STATUS_EXTON (1 << 9)
237#define PM8607_STATUS_CHG (1 << 10)
238#define PM8607_STATUS_BAT (1 << 11)
239#define PM8607_STATUS_VBUS (1 << 12)
240#define PM8607_STATUS_OV (1 << 13)
241
242/* bit definitions of BUCK3 */
243#define PM8607_BUCK3_DOUBLE (1 << 6)
244
245/* bit definitions of Misc1 */
246#define PM8607_A1_MISC1_PI2C (1 << 0)
247#define PM8607_B0_MISC1_INV_INT (1 << 0)
248#define PM8607_B0_MISC1_INT_CLEAR (1 << 1)
249#define PM8607_B0_MISC1_INT_MASK (1 << 2)
250#define PM8607_B0_MISC1_PI2C (1 << 3)
251#define PM8607_B0_MISC1_RESET (1 << 6)
252
253/* bits definitions of GPADC */
254#define PM8607_GPADC_EN (1 << 0)
255#define PM8607_GPADC_PREBIAS_MASK (3 << 1)
256#define PM8607_GPADC_SLOT_CYCLE_MASK (3 << 3) /* slow mode */
257#define PM8607_GPADC_OFF_SCALE_MASK (3 << 5) /* GP sleep mode */
258#define PM8607_GPADC_SW_CAL_MASK (1 << 7)
259
260#define PM8607_PD_PREBIAS_MASK (0x1F << 0)
261#define PM8607_PD_PRECHG_MASK (7 << 5)
262
263/* Interrupt Number in 88PM8607 */
264enum {
265 PM8607_IRQ_ONKEY,
266 PM8607_IRQ_EXTON,
267 PM8607_IRQ_CHG,
268 PM8607_IRQ_BAT,
269 PM8607_IRQ_RTC,
270 PM8607_IRQ_CC,
271 PM8607_IRQ_VBAT,
272 PM8607_IRQ_VCHG,
273 PM8607_IRQ_VSYS,
274 PM8607_IRQ_TINT,
275 PM8607_IRQ_GPADC0,
276 PM8607_IRQ_GPADC1,
277 PM8607_IRQ_GPADC2,
278 PM8607_IRQ_GPADC3,
279 PM8607_IRQ_AUDIO_SHORT,
280 PM8607_IRQ_PEN,
281 PM8607_IRQ_HEADSET,
282 PM8607_IRQ_HOOK,
283 PM8607_IRQ_MICIN,
284 PM8607_IRQ_CHG_FAIL,
285 PM8607_IRQ_CHG_DONE,
286 PM8607_IRQ_CHG_FAULT,
287};
288
289enum {
290 PM8607_CHIP_A0 = 0x40,
291 PM8607_CHIP_A1 = 0x41,
292 PM8607_CHIP_B0 = 0x48,
293};
294
295struct pm860x_chip {
296 struct device *dev;
297 struct mutex io_lock;
298 struct mutex irq_lock;
299 struct i2c_client *client;
300 struct i2c_client *companion; /* companion chip client */
301
302 int buck3_double; /* DVC ramp slope double */
303 unsigned short companion_addr;
304 int id;
305 int irq_mode;
306 int irq_base;
307 int core_irq;
308 unsigned char chip_version;
309
310};
311
312#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */
313
314enum {
315 GI2C_PORT = 0,
316 PI2C_PORT,
317};
318
319struct pm860x_backlight_pdata {
320 int id;
321 int pwm;
322 int iset;
323 unsigned long flags;
324};
325
326struct pm860x_led_pdata {
327 int id;
328 int iset;
329 unsigned long flags;
330};
331
332struct pm860x_touch_pdata {
333 int gpadc_prebias;
334 int slot_cycle;
335 int off_scale;
336 int sw_cal;
337 int tsi_prebias; /* time, slot */
338 int pen_prebias; /* time, slot */
339 int pen_prechg; /* time, slot */
340 int res_x; /* resistor of Xplate */
341 unsigned long flags;
342};
343
344struct pm860x_power_pdata {
345 unsigned fast_charge; /* charge current */
346};
347
348struct pm860x_platform_data {
349 struct pm860x_backlight_pdata *backlight;
350 struct pm860x_led_pdata *led;
351 struct pm860x_touch_pdata *touch;
352 struct pm860x_power_pdata *power;
353
354 unsigned short companion_addr; /* I2C address of companion chip */
355 int i2c_port; /* Controlled by GI2C or PI2C */
356 int irq_mode; /* Clear interrupt by read/write(0/1) */
357 int irq_base; /* IRQ base number of 88pm860x */
358 struct regulator_init_data *regulator[PM8607_MAX_REGULATOR];
359};
360
361extern char pm860x_backlight_name[][MFD_NAME_SIZE];
362extern char pm860x_led_name[][MFD_NAME_SIZE];
363
364extern int pm860x_reg_read(struct i2c_client *, int);
365extern int pm860x_reg_write(struct i2c_client *, int, unsigned char);
366extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *);
367extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *);
368extern int pm860x_set_bits(struct i2c_client *, int, unsigned char,
369 unsigned char);
370
371extern int pm860x_device_init(struct pm860x_chip *chip,
372 struct pm860x_platform_data *pdata);
373extern void pm860x_device_exit(struct pm860x_chip *chip);
374
375#endif /* __LINUX_MFD_88PM860X_H */
diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h
index e9aa4c9d749d..9a881c305a50 100644
--- a/include/linux/mfd/ab3100.h
+++ b/include/linux/mfd/ab3100.h
@@ -6,7 +6,6 @@
6 */ 6 */
7 7
8#include <linux/device.h> 8#include <linux/device.h>
9#include <linux/workqueue.h>
10#include <linux/regulator/machine.h> 9#include <linux/regulator/machine.h>
11 10
12#ifndef MFD_AB3100_H 11#ifndef MFD_AB3100_H
@@ -74,7 +73,6 @@
74 * @testreg_client: secondary client for test registers 73 * @testreg_client: secondary client for test registers
75 * @chip_name: name of this chip variant 74 * @chip_name: name of this chip variant
76 * @chip_id: 8 bit chip ID for this chip variant 75 * @chip_id: 8 bit chip ID for this chip variant
77 * @work: an event handling worker
78 * @event_subscribers: event subscribers are listed here 76 * @event_subscribers: event subscribers are listed here
79 * @startup_events: a copy of the first reading of the event registers 77 * @startup_events: a copy of the first reading of the event registers
80 * @startup_events_read: whether the first events have been read 78 * @startup_events_read: whether the first events have been read
@@ -90,7 +88,6 @@ struct ab3100 {
90 struct i2c_client *testreg_client; 88 struct i2c_client *testreg_client;
91 char chip_name[32]; 89 char chip_name[32];
92 u8 chip_id; 90 u8 chip_id;
93 struct work_struct work;
94 struct blocking_notifier_head event_subscribers; 91 struct blocking_notifier_head event_subscribers;
95 u32 startup_events; 92 u32 startup_events;
96 bool startup_events_read; 93 bool startup_events_read;
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
new file mode 100644
index 000000000000..5259dfe8c585
--- /dev/null
+++ b/include/linux/mfd/max8925.h
@@ -0,0 +1,253 @@
1/*
2 * Maxim8925 Interface
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_MFD_MAX8925_H
13#define __LINUX_MFD_MAX8925_H
14
15#include <linux/mutex.h>
16#include <linux/interrupt.h>
17
18/* Unified sub device IDs for MAX8925 */
19enum {
20 MAX8925_ID_SD1,
21 MAX8925_ID_SD2,
22 MAX8925_ID_SD3,
23 MAX8925_ID_LDO1,
24 MAX8925_ID_LDO2,
25 MAX8925_ID_LDO3,
26 MAX8925_ID_LDO4,
27 MAX8925_ID_LDO5,
28 MAX8925_ID_LDO6,
29 MAX8925_ID_LDO7,
30 MAX8925_ID_LDO8,
31 MAX8925_ID_LDO9,
32 MAX8925_ID_LDO10,
33 MAX8925_ID_LDO11,
34 MAX8925_ID_LDO12,
35 MAX8925_ID_LDO13,
36 MAX8925_ID_LDO14,
37 MAX8925_ID_LDO15,
38 MAX8925_ID_LDO16,
39 MAX8925_ID_LDO17,
40 MAX8925_ID_LDO18,
41 MAX8925_ID_LDO19,
42 MAX8925_ID_LDO20,
43 MAX8925_ID_MAX,
44};
45
46enum {
47 /*
48 * Charging current threshold trigger going from fast charge
49 * to TOPOFF charge. From 5% to 20% of fasting charging current.
50 */
51 MAX8925_TOPOFF_THR_5PER,
52 MAX8925_TOPOFF_THR_10PER,
53 MAX8925_TOPOFF_THR_15PER,
54 MAX8925_TOPOFF_THR_20PER,
55};
56
57enum {
58 /* Fast charging current */
59 MAX8925_FCHG_85MA,
60 MAX8925_FCHG_300MA,
61 MAX8925_FCHG_460MA,
62 MAX8925_FCHG_600MA,
63 MAX8925_FCHG_700MA,
64 MAX8925_FCHG_800MA,
65 MAX8925_FCHG_900MA,
66 MAX8925_FCHG_1000MA,
67};
68
69/* Charger registers */
70#define MAX8925_CHG_IRQ1 (0x7e)
71#define MAX8925_CHG_IRQ2 (0x7f)
72#define MAX8925_CHG_IRQ1_MASK (0x80)
73#define MAX8925_CHG_IRQ2_MASK (0x81)
74#define MAX8925_CHG_STATUS (0x82)
75
76/* GPM registers */
77#define MAX8925_SYSENSEL (0x00)
78#define MAX8925_ON_OFF_IRQ1 (0x01)
79#define MAX8925_ON_OFF_IRQ1_MASK (0x02)
80#define MAX8925_ON_OFF_STATUS (0x03)
81#define MAX8925_ON_OFF_IRQ2 (0x0d)
82#define MAX8925_ON_OFF_IRQ2_MASK (0x0e)
83#define MAX8925_RESET_CNFG (0x0f)
84
85/* Touch registers */
86#define MAX8925_TSC_IRQ (0x00)
87#define MAX8925_TSC_IRQ_MASK (0x01)
88#define MAX8925_TSC_CNFG1 (0x02)
89#define MAX8925_ADC_SCHED (0x10)
90#define MAX8925_ADC_RES_END (0x6f)
91
92#define MAX8925_NREF_OK (1 << 4)
93
94/* RTC registers */
95#define MAX8925_ALARM0_CNTL (0x18)
96#define MAX8925_ALARM1_CNTL (0x19)
97#define MAX8925_RTC_IRQ (0x1c)
98#define MAX8925_RTC_IRQ_MASK (0x1d)
99#define MAX8925_MPL_CNTL (0x1e)
100
101/* WLED registers */
102#define MAX8925_WLED_MODE_CNTL (0x84)
103#define MAX8925_WLED_CNTL (0x85)
104
105/* MAX8925 Registers */
106#define MAX8925_SDCTL1 (0x04)
107#define MAX8925_SDCTL2 (0x07)
108#define MAX8925_SDCTL3 (0x0A)
109#define MAX8925_SDV1 (0x06)
110#define MAX8925_SDV2 (0x09)
111#define MAX8925_SDV3 (0x0C)
112#define MAX8925_LDOCTL1 (0x18)
113#define MAX8925_LDOCTL2 (0x1C)
114#define MAX8925_LDOCTL3 (0x20)
115#define MAX8925_LDOCTL4 (0x24)
116#define MAX8925_LDOCTL5 (0x28)
117#define MAX8925_LDOCTL6 (0x2C)
118#define MAX8925_LDOCTL7 (0x30)
119#define MAX8925_LDOCTL8 (0x34)
120#define MAX8925_LDOCTL9 (0x38)
121#define MAX8925_LDOCTL10 (0x3C)
122#define MAX8925_LDOCTL11 (0x40)
123#define MAX8925_LDOCTL12 (0x44)
124#define MAX8925_LDOCTL13 (0x48)
125#define MAX8925_LDOCTL14 (0x4C)
126#define MAX8925_LDOCTL15 (0x50)
127#define MAX8925_LDOCTL16 (0x10)
128#define MAX8925_LDOCTL17 (0x14)
129#define MAX8925_LDOCTL18 (0x72)
130#define MAX8925_LDOCTL19 (0x5C)
131#define MAX8925_LDOCTL20 (0x9C)
132#define MAX8925_LDOVOUT1 (0x1A)
133#define MAX8925_LDOVOUT2 (0x1E)
134#define MAX8925_LDOVOUT3 (0x22)
135#define MAX8925_LDOVOUT4 (0x26)
136#define MAX8925_LDOVOUT5 (0x2A)
137#define MAX8925_LDOVOUT6 (0x2E)
138#define MAX8925_LDOVOUT7 (0x32)
139#define MAX8925_LDOVOUT8 (0x36)
140#define MAX8925_LDOVOUT9 (0x3A)
141#define MAX8925_LDOVOUT10 (0x3E)
142#define MAX8925_LDOVOUT11 (0x42)
143#define MAX8925_LDOVOUT12 (0x46)
144#define MAX8925_LDOVOUT13 (0x4A)
145#define MAX8925_LDOVOUT14 (0x4E)
146#define MAX8925_LDOVOUT15 (0x52)
147#define MAX8925_LDOVOUT16 (0x12)
148#define MAX8925_LDOVOUT17 (0x16)
149#define MAX8925_LDOVOUT18 (0x74)
150#define MAX8925_LDOVOUT19 (0x5E)
151#define MAX8925_LDOVOUT20 (0x9E)
152
153/* bit definitions */
154#define CHG_IRQ1_MASK (0x07)
155#define CHG_IRQ2_MASK (0xff)
156#define ON_OFF_IRQ1_MASK (0xff)
157#define ON_OFF_IRQ2_MASK (0x03)
158#define TSC_IRQ_MASK (0x03)
159#define RTC_IRQ_MASK (0x0c)
160
161#define MAX8925_MAX_REGULATOR (23)
162
163#define MAX8925_NAME_SIZE (32)
164
165/* IRQ definitions */
166enum {
167 MAX8925_IRQ_VCHG_DC_OVP,
168 MAX8925_IRQ_VCHG_DC_F,
169 MAX8925_IRQ_VCHG_DC_R,
170 MAX8925_IRQ_VCHG_USB_OVP,
171 MAX8925_IRQ_VCHG_USB_F,
172 MAX8925_IRQ_VCHG_USB_R,
173 MAX8925_IRQ_VCHG_THM_OK_R,
174 MAX8925_IRQ_VCHG_THM_OK_F,
175 MAX8925_IRQ_VCHG_SYSLOW_F,
176 MAX8925_IRQ_VCHG_SYSLOW_R,
177 MAX8925_IRQ_VCHG_RST,
178 MAX8925_IRQ_VCHG_DONE,
179 MAX8925_IRQ_VCHG_TOPOFF,
180 MAX8925_IRQ_VCHG_TMR_FAULT,
181 MAX8925_IRQ_GPM_RSTIN,
182 MAX8925_IRQ_GPM_MPL,
183 MAX8925_IRQ_GPM_SW_3SEC,
184 MAX8925_IRQ_GPM_EXTON_F,
185 MAX8925_IRQ_GPM_EXTON_R,
186 MAX8925_IRQ_GPM_SW_1SEC,
187 MAX8925_IRQ_GPM_SW_F,
188 MAX8925_IRQ_GPM_SW_R,
189 MAX8925_IRQ_GPM_SYSCKEN_F,
190 MAX8925_IRQ_GPM_SYSCKEN_R,
191 MAX8925_IRQ_RTC_ALARM1,
192 MAX8925_IRQ_RTC_ALARM0,
193 MAX8925_IRQ_TSC_STICK,
194 MAX8925_IRQ_TSC_NSTICK,
195 MAX8925_NR_IRQS,
196};
197
198struct max8925_chip {
199 struct device *dev;
200 struct i2c_client *i2c;
201 struct i2c_client *adc;
202 struct i2c_client *rtc;
203 struct mutex io_lock;
204 struct mutex irq_lock;
205
206 int irq_base;
207 int core_irq;
208 int tsc_irq;
209};
210
211struct max8925_backlight_pdata {
212 int lxw_scl; /* 0/1 -- 0.8Ohm/0.4Ohm */
213 int lxw_freq; /* 700KHz ~ 1400KHz */
214 int dual_string; /* 0/1 -- single/dual string */
215};
216
217struct max8925_touch_pdata {
218 unsigned int flags;
219};
220
221struct max8925_power_pdata {
222 int (*set_charger)(int);
223 unsigned batt_detect:1;
224 unsigned topoff_threshold:2;
225 unsigned fast_charge:3; /* charge current */
226};
227
228/*
229 * irq_base: stores IRQ base number of MAX8925 in platform
230 * tsc_irq: stores IRQ number of MAX8925 TSC
231 */
232struct max8925_platform_data {
233 struct max8925_backlight_pdata *backlight;
234 struct max8925_touch_pdata *touch;
235 struct max8925_power_pdata *power;
236 struct regulator_init_data *regulator[MAX8925_MAX_REGULATOR];
237
238 int irq_base;
239 int tsc_irq;
240};
241
242extern int max8925_reg_read(struct i2c_client *, int);
243extern int max8925_reg_write(struct i2c_client *, int, unsigned char);
244extern int max8925_bulk_read(struct i2c_client *, int, int, unsigned char *);
245extern int max8925_bulk_write(struct i2c_client *, int, int, unsigned char *);
246extern int max8925_set_bits(struct i2c_client *, int, unsigned char,
247 unsigned char);
248
249extern int max8925_device_init(struct max8925_chip *,
250 struct max8925_platform_data *);
251extern void max8925_device_exit(struct max8925_chip *);
252#endif /* __LINUX_MFD_MAX8925_H */
253
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
index 94cb51a64037..8895d9d8879c 100644
--- a/include/linux/mfd/mc13783.h
+++ b/include/linux/mfd/mc13783.h
@@ -26,10 +26,30 @@ int mc13783_irq_request(struct mc13783 *mc13783, int irq,
26int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq, 26int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
27 irq_handler_t handler, const char *name, void *dev); 27 irq_handler_t handler, const char *name, void *dev);
28int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev); 28int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev);
29int mc13783_ackirq(struct mc13783 *mc13783, int irq);
30 29
31int mc13783_mask(struct mc13783 *mc13783, int irq); 30int mc13783_irq_mask(struct mc13783 *mc13783, int irq);
32int mc13783_unmask(struct mc13783 *mc13783, int irq); 31int mc13783_irq_unmask(struct mc13783 *mc13783, int irq);
32int mc13783_irq_status(struct mc13783 *mc13783, int irq,
33 int *enabled, int *pending);
34int mc13783_irq_ack(struct mc13783 *mc13783, int irq);
35
36static inline int mc13783_mask(struct mc13783 *mc13783, int irq) __deprecated;
37static inline int mc13783_mask(struct mc13783 *mc13783, int irq)
38{
39 return mc13783_irq_mask(mc13783, irq);
40}
41
42static inline int mc13783_unmask(struct mc13783 *mc13783, int irq) __deprecated;
43static inline int mc13783_unmask(struct mc13783 *mc13783, int irq)
44{
45 return mc13783_irq_unmask(mc13783, irq);
46}
47
48static inline int mc13783_ackirq(struct mc13783 *mc13783, int irq) __deprecated;
49static inline int mc13783_ackirq(struct mc13783 *mc13783, int irq)
50{
51 return mc13783_irq_ack(mc13783, irq);
52}
33 53
34#define MC13783_ADC0 43 54#define MC13783_ADC0 43
35#define MC13783_ADC0_ADREFEN (1 << 10) 55#define MC13783_ADC0_ADREFEN (1 << 10)
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index 9cb1834deffa..c3f7dff8effc 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -59,7 +59,8 @@ void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state);
59 * data for the MMC controller 59 * data for the MMC controller
60 */ 60 */
61struct tmio_mmc_data { 61struct tmio_mmc_data {
62 const unsigned int hclk; 62 unsigned int hclk;
63 unsigned long capabilities;
63 void (*set_pwr)(struct platform_device *host, int state); 64 void (*set_pwr)(struct platform_device *host, int state);
64 void (*set_clk_div)(struct platform_device *host, int state); 65 void (*set_clk_div)(struct platform_device *host, int state);
65}; 66};
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h
index aa9c3789bed4..4321f044d1e4 100644
--- a/include/linux/mfd/ucb1x00.h
+++ b/include/linux/mfd/ucb1x00.h
@@ -12,6 +12,7 @@
12 12
13#include <linux/mfd/mcp.h> 13#include <linux/mfd/mcp.h>
14#include <linux/gpio.h> 14#include <linux/gpio.h>
15#include <linux/semaphore.h>
15 16
16#define UCB_IO_DATA 0x00 17#define UCB_IO_DATA 0x00
17#define UCB_IO_DIR 0x01 18#define UCB_IO_DIR 0x01
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index 5184b79c700b..5915f6e3d9ab 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -15,6 +15,7 @@
15#ifndef __MFD_WM831X_CORE_H__ 15#ifndef __MFD_WM831X_CORE_H__
16#define __MFD_WM831X_CORE_H__ 16#define __MFD_WM831X_CORE_H__
17 17
18#include <linux/completion.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19 20
20/* 21/*
@@ -254,9 +255,14 @@ struct wm831x {
254 int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */ 255 int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */
255 int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */ 256 int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */
256 257
258 /* Chip revision based flags */
259 unsigned has_gpio_ena:1; /* Has GPIO enable bit */
260 unsigned has_cs_sts:1; /* Has current sink status bit */
261
257 int num_gpio; 262 int num_gpio;
258 263
259 struct mutex auxadc_lock; 264 struct mutex auxadc_lock;
265 struct completion auxadc_done;
260 266
261 /* The WM831x has a security key blocking access to certain 267 /* The WM831x has a security key blocking access to certain
262 * registers. The mutex is taken by the accessors for locking 268 * registers. The mutex is taken by the accessors for locking
diff --git a/include/linux/mfd/wm831x/gpio.h b/include/linux/mfd/wm831x/gpio.h
index 2835614af0e3..9b163c58865f 100644
--- a/include/linux/mfd/wm831x/gpio.h
+++ b/include/linux/mfd/wm831x/gpio.h
@@ -41,6 +41,10 @@
41#define WM831X_GPN_OD_MASK 0x0200 /* GPN_OD */ 41#define WM831X_GPN_OD_MASK 0x0200 /* GPN_OD */
42#define WM831X_GPN_OD_SHIFT 9 /* GPN_OD */ 42#define WM831X_GPN_OD_SHIFT 9 /* GPN_OD */
43#define WM831X_GPN_OD_WIDTH 1 /* GPN_OD */ 43#define WM831X_GPN_OD_WIDTH 1 /* GPN_OD */
44#define WM831X_GPN_ENA 0x0080 /* GPN_ENA */
45#define WM831X_GPN_ENA_MASK 0x0080 /* GPN_ENA */
46#define WM831X_GPN_ENA_SHIFT 7 /* GPN_ENA */
47#define WM831X_GPN_ENA_WIDTH 1 /* GPN_ENA */
44#define WM831X_GPN_TRI 0x0080 /* GPN_TRI */ 48#define WM831X_GPN_TRI 0x0080 /* GPN_TRI */
45#define WM831X_GPN_TRI_MASK 0x0080 /* GPN_TRI */ 49#define WM831X_GPN_TRI_MASK 0x0080 /* GPN_TRI */
46#define WM831X_GPN_TRI_SHIFT 7 /* GPN_TRI */ 50#define WM831X_GPN_TRI_SHIFT 7 /* GPN_TRI */
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
index 43868899bf49..98fcc977e82b 100644
--- a/include/linux/mfd/wm8350/core.h
+++ b/include/linux/mfd/wm8350/core.h
@@ -16,6 +16,7 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/mutex.h> 17#include <linux/mutex.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/completion.h>
19 20
20#include <linux/mfd/wm8350/audio.h> 21#include <linux/mfd/wm8350/audio.h>
21#include <linux/mfd/wm8350/gpio.h> 22#include <linux/mfd/wm8350/gpio.h>
@@ -579,6 +580,8 @@
579 580
580#define WM8350_NUM_IRQ 63 581#define WM8350_NUM_IRQ 63
581 582
583#define WM8350_NUM_IRQ_REGS 7
584
582struct wm8350_reg_access { 585struct wm8350_reg_access {
583 u16 readable; /* Mask of readable bits */ 586 u16 readable; /* Mask of readable bits */
584 u16 writable; /* Mask of writable bits */ 587 u16 writable; /* Mask of writable bits */
@@ -600,11 +603,6 @@ extern const u16 wm8352_mode3_defaults[];
600 603
601struct wm8350; 604struct wm8350;
602 605
603struct wm8350_irq {
604 irq_handler_t handler;
605 void *data;
606};
607
608struct wm8350_hwmon { 606struct wm8350_hwmon {
609 struct platform_device *pdev; 607 struct platform_device *pdev;
610 struct device *classdev; 608 struct device *classdev;
@@ -624,11 +622,13 @@ struct wm8350 {
624 u16 *reg_cache; 622 u16 *reg_cache;
625 623
626 struct mutex auxadc_mutex; 624 struct mutex auxadc_mutex;
625 struct completion auxadc_done;
627 626
628 /* Interrupt handling */ 627 /* Interrupt handling */
629 struct mutex irq_mutex; /* IRQ table mutex */ 628 struct mutex irq_lock;
630 struct wm8350_irq irq[WM8350_NUM_IRQ];
631 int chip_irq; 629 int chip_irq;
630 int irq_base;
631 u16 irq_masks[WM8350_NUM_IRQ_REGS];
632 632
633 /* Client devices */ 633 /* Client devices */
634 struct wm8350_codec codec; 634 struct wm8350_codec codec;
@@ -647,11 +647,13 @@ struct wm8350 {
647 * used by the platform to configure GPIO functions and similar. 647 * used by the platform to configure GPIO functions and similar.
648 * @irq_high: Set if WM8350 IRQ is active high. 648 * @irq_high: Set if WM8350 IRQ is active high.
649 * @irq_base: Base IRQ for genirq (not currently used). 649 * @irq_base: Base IRQ for genirq (not currently used).
650 * @gpio_base: Base for gpiolib.
650 */ 651 */
651struct wm8350_platform_data { 652struct wm8350_platform_data {
652 int (*init)(struct wm8350 *wm8350); 653 int (*init)(struct wm8350 *wm8350);
653 int irq_high; 654 int irq_high;
654 int irq_base; 655 int irq_base;
656 int gpio_base;
655}; 657};
656 658
657 659
@@ -677,12 +679,33 @@ int wm8350_block_write(struct wm8350 *wm8350, int reg, int size, u16 *src);
677/* 679/*
678 * WM8350 internal interrupts 680 * WM8350 internal interrupts
679 */ 681 */
680int wm8350_register_irq(struct wm8350 *wm8350, int irq, 682static inline int wm8350_register_irq(struct wm8350 *wm8350, int irq,
681 irq_handler_t handler, unsigned long flags, 683 irq_handler_t handler,
682 const char *name, void *data); 684 unsigned long flags,
683int wm8350_free_irq(struct wm8350 *wm8350, int irq); 685 const char *name, void *data)
684int wm8350_mask_irq(struct wm8350 *wm8350, int irq); 686{
685int wm8350_unmask_irq(struct wm8350 *wm8350, int irq); 687 if (!wm8350->irq_base)
688 return -ENODEV;
689
690 return request_threaded_irq(irq + wm8350->irq_base, NULL,
691 handler, flags, name, data);
692}
693
694static inline void wm8350_free_irq(struct wm8350 *wm8350, int irq, void *data)
695{
696 free_irq(irq + wm8350->irq_base, data);
697}
698
699static inline void wm8350_mask_irq(struct wm8350 *wm8350, int irq)
700{
701 disable_irq(irq + wm8350->irq_base);
702}
703
704static inline void wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
705{
706 enable_irq(irq + wm8350->irq_base);
707}
708
686int wm8350_irq_init(struct wm8350 *wm8350, int irq, 709int wm8350_irq_init(struct wm8350 *wm8350, int irq,
687 struct wm8350_platform_data *pdata); 710 struct wm8350_platform_data *pdata);
688int wm8350_irq_exit(struct wm8350 *wm8350); 711int wm8350_irq_exit(struct wm8350 *wm8350);
diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h
index 71af3d6ebe9d..d657bcd6d955 100644
--- a/include/linux/mfd/wm8350/gpio.h
+++ b/include/linux/mfd/wm8350/gpio.h
@@ -29,6 +29,7 @@
29#define WM8350_GPIO_FUNCTION_SELECT_2 0x8D 29#define WM8350_GPIO_FUNCTION_SELECT_2 0x8D
30#define WM8350_GPIO_FUNCTION_SELECT_3 0x8E 30#define WM8350_GPIO_FUNCTION_SELECT_3 0x8E
31#define WM8350_GPIO_FUNCTION_SELECT_4 0x8F 31#define WM8350_GPIO_FUNCTION_SELECT_4 0x8F
32#define WM8350_GPIO_LEVEL 0xE6
32 33
33/* 34/*
34 * GPIO Functions 35 * GPIO Functions
diff --git a/include/linux/mfd/wm8350/rtc.h b/include/linux/mfd/wm8350/rtc.h
index 24add2bef6c9..ebd72ffc62d1 100644
--- a/include/linux/mfd/wm8350/rtc.h
+++ b/include/linux/mfd/wm8350/rtc.h
@@ -263,6 +263,7 @@ struct wm8350_rtc {
263 struct platform_device *pdev; 263 struct platform_device *pdev;
264 struct rtc_device *rtc; 264 struct rtc_device *rtc;
265 int alarm_enabled; /* used over suspend/resume */ 265 int alarm_enabled; /* used over suspend/resume */
266 int update_enabled;
266}; 267};
267 268
268#endif 269#endif
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
new file mode 100644
index 000000000000..b06ff2846748
--- /dev/null
+++ b/include/linux/mfd/wm8994/core.h
@@ -0,0 +1,54 @@
1/*
2 * include/linux/mfd/wm8994/core.h -- Core interface for WM8994
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef __MFD_WM8994_CORE_H__
16#define __MFD_WM8994_CORE_H__
17
18struct regulator_dev;
19struct regulator_bulk_data;
20
21#define WM8994_NUM_GPIO_REGS 11
22#define WM8994_NUM_LDO_REGS 2
23
24struct wm8994 {
25 struct mutex io_lock;
26
27 struct device *dev;
28 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
29 int bytes, void *dest);
30 int (*write_dev)(struct wm8994 *wm8994, unsigned short reg,
31 int bytes, void *src);
32
33 void *control_data;
34
35 int gpio_base;
36
37 /* Used over suspend/resume */
38 u16 ldo_regs[WM8994_NUM_LDO_REGS];
39 u16 gpio_regs[WM8994_NUM_GPIO_REGS];
40
41 struct regulator_dev *dbvdd;
42 struct regulator_bulk_data *supplies;
43};
44
45/* Device I/O API */
46int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg);
47int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
48 unsigned short val);
49int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
50 unsigned short mask, unsigned short val);
51int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
52 int count, u16 *buf);
53
54#endif
diff --git a/include/linux/mfd/wm8994/gpio.h b/include/linux/mfd/wm8994/gpio.h
new file mode 100644
index 000000000000..b4d4c22991e8
--- /dev/null
+++ b/include/linux/mfd/wm8994/gpio.h
@@ -0,0 +1,72 @@
1/*
2 * include/linux/mfd/wm8994/gpio.h - GPIO configuration for WM8994
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef __MFD_WM8994_GPIO_H__
16#define __MFD_WM8994_GPIO_H__
17
18#define WM8994_GPIO_MAX 11
19
20#define WM8994_GP_FN_PIN_SPECIFIC 0
21#define WM8994_GP_FN_GPIO 1
22#define WM8994_GP_FN_SDOUT 2
23#define WM8994_GP_FN_IRQ 3
24#define WM8994_GP_FN_TEMPERATURE 4
25#define WM8994_GP_FN_MICBIAS1_DET 5
26#define WM8994_GP_FN_MICBIAS1_SHORT 6
27#define WM8994_GP_FN_MICBIAS2_DET 7
28#define WM8994_GP_FN_MICBIAS2_SHORT 8
29#define WM8994_GP_FN_FLL1_LOCK 9
30#define WM8994_GP_FN_FLL2_LOCK 10
31#define WM8994_GP_FN_SRC1_LOCK 11
32#define WM8994_GP_FN_SRC2_LOCK 12
33#define WM8994_GP_FN_DRC1_ACT 13
34#define WM8994_GP_FN_DRC2_ACT 14
35#define WM8994_GP_FN_DRC3_ACT 15
36#define WM8994_GP_FN_WSEQ_STATUS 16
37#define WM8994_GP_FN_FIFO_ERROR 17
38#define WM8994_GP_FN_OPCLK 18
39
40#define WM8994_GPN_DIR 0x8000 /* GPN_DIR */
41#define WM8994_GPN_DIR_MASK 0x8000 /* GPN_DIR */
42#define WM8994_GPN_DIR_SHIFT 15 /* GPN_DIR */
43#define WM8994_GPN_DIR_WIDTH 1 /* GPN_DIR */
44#define WM8994_GPN_PU 0x4000 /* GPN_PU */
45#define WM8994_GPN_PU_MASK 0x4000 /* GPN_PU */
46#define WM8994_GPN_PU_SHIFT 14 /* GPN_PU */
47#define WM8994_GPN_PU_WIDTH 1 /* GPN_PU */
48#define WM8994_GPN_PD 0x2000 /* GPN_PD */
49#define WM8994_GPN_PD_MASK 0x2000 /* GPN_PD */
50#define WM8994_GPN_PD_SHIFT 13 /* GPN_PD */
51#define WM8994_GPN_PD_WIDTH 1 /* GPN_PD */
52#define WM8994_GPN_POL 0x0400 /* GPN_POL */
53#define WM8994_GPN_POL_MASK 0x0400 /* GPN_POL */
54#define WM8994_GPN_POL_SHIFT 10 /* GPN_POL */
55#define WM8994_GPN_POL_WIDTH 1 /* GPN_POL */
56#define WM8994_GPN_OP_CFG 0x0200 /* GPN_OP_CFG */
57#define WM8994_GPN_OP_CFG_MASK 0x0200 /* GPN_OP_CFG */
58#define WM8994_GPN_OP_CFG_SHIFT 9 /* GPN_OP_CFG */
59#define WM8994_GPN_OP_CFG_WIDTH 1 /* GPN_OP_CFG */
60#define WM8994_GPN_DB 0x0100 /* GPN_DB */
61#define WM8994_GPN_DB_MASK 0x0100 /* GPN_DB */
62#define WM8994_GPN_DB_SHIFT 8 /* GPN_DB */
63#define WM8994_GPN_DB_WIDTH 1 /* GPN_DB */
64#define WM8994_GPN_LVL 0x0040 /* GPN_LVL */
65#define WM8994_GPN_LVL_MASK 0x0040 /* GPN_LVL */
66#define WM8994_GPN_LVL_SHIFT 6 /* GPN_LVL */
67#define WM8994_GPN_LVL_WIDTH 1 /* GPN_LVL */
68#define WM8994_GPN_FN_MASK 0x001F /* GPN_FN - [4:0] */
69#define WM8994_GPN_FN_SHIFT 0 /* GPN_FN - [4:0] */
70#define WM8994_GPN_FN_WIDTH 5 /* GPN_FN - [4:0] */
71
72#endif
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
new file mode 100644
index 000000000000..70d6a8687dc5
--- /dev/null
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -0,0 +1,97 @@
1/*
2 * include/linux/mfd/wm8994/pdata.h -- Platform data for WM8994
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef __MFD_WM8994_PDATA_H__
16#define __MFD_WM8994_PDATA_H__
17
18#define WM8994_NUM_LDO 2
19#define WM8994_NUM_GPIO 11
20
21struct wm8994_ldo_pdata {
22 /** GPIOs to enable regulator, 0 or less if not available */
23 int enable;
24
25 const char *supply;
26 struct regulator_init_data *init_data;
27};
28
29#define WM8994_CONFIGURE_GPIO 0x8000
30
31#define WM8994_DRC_REGS 5
32#define WM8994_EQ_REGS 19
33
34/**
35 * DRC configurations are specified with a label and a set of register
36 * values to write (the enable bits will be ignored). At runtime an
37 * enumerated control will be presented for each DRC block allowing
38 * the user to choose the configration to use.
39 *
40 * Configurations may be generated by hand or by using the DRC control
41 * panel provided by the WISCE - see http://www.wolfsonmicro.com/wisce/
42 * for details.
43 */
44struct wm8994_drc_cfg {
45 const char *name;
46 u16 regs[WM8994_DRC_REGS];
47};
48
49/**
50 * ReTune Mobile configurations are specified with a label, sample
51 * rate and set of values to write (the enable bits will be ignored).
52 *
53 * Configurations are expected to be generated using the ReTune Mobile
54 * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
55 */
56struct wm8994_retune_mobile_cfg {
57 const char *name;
58 unsigned int rate;
59 u16 regs[WM8994_EQ_REGS];
60};
61
62struct wm8994_pdata {
63 int gpio_base;
64
65 /**
66 * Default values for GPIOs if non-zero, WM8994_CONFIGURE_GPIO
67 * can be used for all zero values.
68 */
69 int gpio_defaults[WM8994_NUM_GPIO];
70
71 struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO];
72
73
74 int num_drc_cfgs;
75 struct wm8994_drc_cfg *drc_cfgs;
76
77 int num_retune_mobile_cfgs;
78 struct wm8994_retune_mobile_cfg *retune_mobile_cfgs;
79
80 /* LINEOUT can be differential or single ended */
81 unsigned int lineout1_diff:1;
82 unsigned int lineout2_diff:1;
83
84 /* Common mode feedback */
85 unsigned int lineout1fb:1;
86 unsigned int lineout2fb:1;
87
88 /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
89 unsigned int micbias1_lvl:1;
90 unsigned int micbias2_lvl:1;
91
92 /* Jack detect threashold levels, see datasheet for values */
93 unsigned int jd_scthr:2;
94 unsigned int jd_thr:2;
95};
96
97#endif
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h
new file mode 100644
index 000000000000..967f62f54159
--- /dev/null
+++ b/include/linux/mfd/wm8994/registers.h
@@ -0,0 +1,4292 @@
1/*
2 * include/linux/mfd/wm8994/registers.h -- Register definitions for WM8994
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#ifndef __MFD_WM8994_REGISTERS_H__
16#define __MFD_WM8994_REGISTERS_H__
17
18/*
19 * Register values.
20 */
21#define WM8994_SOFTWARE_RESET 0x00
22#define WM8994_POWER_MANAGEMENT_1 0x01
23#define WM8994_POWER_MANAGEMENT_2 0x02
24#define WM8994_POWER_MANAGEMENT_3 0x03
25#define WM8994_POWER_MANAGEMENT_4 0x04
26#define WM8994_POWER_MANAGEMENT_5 0x05
27#define WM8994_POWER_MANAGEMENT_6 0x06
28#define WM8994_INPUT_MIXER_1 0x15
29#define WM8994_LEFT_LINE_INPUT_1_2_VOLUME 0x18
30#define WM8994_LEFT_LINE_INPUT_3_4_VOLUME 0x19
31#define WM8994_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
32#define WM8994_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
33#define WM8994_LEFT_OUTPUT_VOLUME 0x1C
34#define WM8994_RIGHT_OUTPUT_VOLUME 0x1D
35#define WM8994_LINE_OUTPUTS_VOLUME 0x1E
36#define WM8994_HPOUT2_VOLUME 0x1F
37#define WM8994_LEFT_OPGA_VOLUME 0x20
38#define WM8994_RIGHT_OPGA_VOLUME 0x21
39#define WM8994_SPKMIXL_ATTENUATION 0x22
40#define WM8994_SPKMIXR_ATTENUATION 0x23
41#define WM8994_SPKOUT_MIXERS 0x24
42#define WM8994_CLASSD 0x25
43#define WM8994_SPEAKER_VOLUME_LEFT 0x26
44#define WM8994_SPEAKER_VOLUME_RIGHT 0x27
45#define WM8994_INPUT_MIXER_2 0x28
46#define WM8994_INPUT_MIXER_3 0x29
47#define WM8994_INPUT_MIXER_4 0x2A
48#define WM8994_INPUT_MIXER_5 0x2B
49#define WM8994_INPUT_MIXER_6 0x2C
50#define WM8994_OUTPUT_MIXER_1 0x2D
51#define WM8994_OUTPUT_MIXER_2 0x2E
52#define WM8994_OUTPUT_MIXER_3 0x2F
53#define WM8994_OUTPUT_MIXER_4 0x30
54#define WM8994_OUTPUT_MIXER_5 0x31
55#define WM8994_OUTPUT_MIXER_6 0x32
56#define WM8994_HPOUT2_MIXER 0x33
57#define WM8994_LINE_MIXER_1 0x34
58#define WM8994_LINE_MIXER_2 0x35
59#define WM8994_SPEAKER_MIXER 0x36
60#define WM8994_ADDITIONAL_CONTROL 0x37
61#define WM8994_ANTIPOP_1 0x38
62#define WM8994_ANTIPOP_2 0x39
63#define WM8994_MICBIAS 0x3A
64#define WM8994_LDO_1 0x3B
65#define WM8994_LDO_2 0x3C
66#define WM8994_CHARGE_PUMP_1 0x4C
67#define WM8994_CLASS_W_1 0x51
68#define WM8994_DC_SERVO_1 0x54
69#define WM8994_DC_SERVO_2 0x55
70#define WM8994_DC_SERVO_4 0x57
71#define WM8994_DC_SERVO_READBACK 0x58
72#define WM8994_ANALOGUE_HP_1 0x60
73#define WM8994_CHIP_REVISION 0x100
74#define WM8994_CONTROL_INTERFACE 0x101
75#define WM8994_WRITE_SEQUENCER_CTRL_1 0x110
76#define WM8994_WRITE_SEQUENCER_CTRL_2 0x111
77#define WM8994_AIF1_CLOCKING_1 0x200
78#define WM8994_AIF1_CLOCKING_2 0x201
79#define WM8994_AIF2_CLOCKING_1 0x204
80#define WM8994_AIF2_CLOCKING_2 0x205
81#define WM8994_CLOCKING_1 0x208
82#define WM8994_CLOCKING_2 0x209
83#define WM8994_AIF1_RATE 0x210
84#define WM8994_AIF2_RATE 0x211
85#define WM8994_RATE_STATUS 0x212
86#define WM8994_FLL1_CONTROL_1 0x220
87#define WM8994_FLL1_CONTROL_2 0x221
88#define WM8994_FLL1_CONTROL_3 0x222
89#define WM8994_FLL1_CONTROL_4 0x223
90#define WM8994_FLL1_CONTROL_5 0x224
91#define WM8994_FLL2_CONTROL_1 0x240
92#define WM8994_FLL2_CONTROL_2 0x241
93#define WM8994_FLL2_CONTROL_3 0x242
94#define WM8994_FLL2_CONTROL_4 0x243
95#define WM8994_FLL2_CONTROL_5 0x244
96#define WM8994_AIF1_CONTROL_1 0x300
97#define WM8994_AIF1_CONTROL_2 0x301
98#define WM8994_AIF1_MASTER_SLAVE 0x302
99#define WM8994_AIF1_BCLK 0x303
100#define WM8994_AIF1ADC_LRCLK 0x304
101#define WM8994_AIF1DAC_LRCLK 0x305
102#define WM8994_AIF1DAC_DATA 0x306
103#define WM8994_AIF1ADC_DATA 0x307
104#define WM8994_AIF2_CONTROL_1 0x310
105#define WM8994_AIF2_CONTROL_2 0x311
106#define WM8994_AIF2_MASTER_SLAVE 0x312
107#define WM8994_AIF2_BCLK 0x313
108#define WM8994_AIF2ADC_LRCLK 0x314
109#define WM8994_AIF2DAC_LRCLK 0x315
110#define WM8994_AIF2DAC_DATA 0x316
111#define WM8994_AIF2ADC_DATA 0x317
112#define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400
113#define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401
114#define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402
115#define WM8994_AIF1_DAC1_RIGHT_VOLUME 0x403
116#define WM8994_AIF1_ADC2_LEFT_VOLUME 0x404
117#define WM8994_AIF1_ADC2_RIGHT_VOLUME 0x405
118#define WM8994_AIF1_DAC2_LEFT_VOLUME 0x406
119#define WM8994_AIF1_DAC2_RIGHT_VOLUME 0x407
120#define WM8994_AIF1_ADC1_FILTERS 0x410
121#define WM8994_AIF1_ADC2_FILTERS 0x411
122#define WM8994_AIF1_DAC1_FILTERS_1 0x420
123#define WM8994_AIF1_DAC1_FILTERS_2 0x421
124#define WM8994_AIF1_DAC2_FILTERS_1 0x422
125#define WM8994_AIF1_DAC2_FILTERS_2 0x423
126#define WM8994_AIF1_DRC1_1 0x440
127#define WM8994_AIF1_DRC1_2 0x441
128#define WM8994_AIF1_DRC1_3 0x442
129#define WM8994_AIF1_DRC1_4 0x443
130#define WM8994_AIF1_DRC1_5 0x444
131#define WM8994_AIF1_DRC2_1 0x450
132#define WM8994_AIF1_DRC2_2 0x451
133#define WM8994_AIF1_DRC2_3 0x452
134#define WM8994_AIF1_DRC2_4 0x453
135#define WM8994_AIF1_DRC2_5 0x454
136#define WM8994_AIF1_DAC1_EQ_GAINS_1 0x480
137#define WM8994_AIF1_DAC1_EQ_GAINS_2 0x481
138#define WM8994_AIF1_DAC1_EQ_BAND_1_A 0x482
139#define WM8994_AIF1_DAC1_EQ_BAND_1_B 0x483
140#define WM8994_AIF1_DAC1_EQ_BAND_1_PG 0x484
141#define WM8994_AIF1_DAC1_EQ_BAND_2_A 0x485
142#define WM8994_AIF1_DAC1_EQ_BAND_2_B 0x486
143#define WM8994_AIF1_DAC1_EQ_BAND_2_C 0x487
144#define WM8994_AIF1_DAC1_EQ_BAND_2_PG 0x488
145#define WM8994_AIF1_DAC1_EQ_BAND_3_A 0x489
146#define WM8994_AIF1_DAC1_EQ_BAND_3_B 0x48A
147#define WM8994_AIF1_DAC1_EQ_BAND_3_C 0x48B
148#define WM8994_AIF1_DAC1_EQ_BAND_3_PG 0x48C
149#define WM8994_AIF1_DAC1_EQ_BAND_4_A 0x48D
150#define WM8994_AIF1_DAC1_EQ_BAND_4_B 0x48E
151#define WM8994_AIF1_DAC1_EQ_BAND_4_C 0x48F
152#define WM8994_AIF1_DAC1_EQ_BAND_4_PG 0x490
153#define WM8994_AIF1_DAC1_EQ_BAND_5_A 0x491
154#define WM8994_AIF1_DAC1_EQ_BAND_5_B 0x492
155#define WM8994_AIF1_DAC1_EQ_BAND_5_PG 0x493
156#define WM8994_AIF1_DAC2_EQ_GAINS_1 0x4A0
157#define WM8994_AIF1_DAC2_EQ_GAINS_2 0x4A1
158#define WM8994_AIF1_DAC2_EQ_BAND_1_A 0x4A2
159#define WM8994_AIF1_DAC2_EQ_BAND_1_B 0x4A3
160#define WM8994_AIF1_DAC2_EQ_BAND_1_PG 0x4A4
161#define WM8994_AIF1_DAC2_EQ_BAND_2_A 0x4A5
162#define WM8994_AIF1_DAC2_EQ_BAND_2_B 0x4A6
163#define WM8994_AIF1_DAC2_EQ_BAND_2_C 0x4A7
164#define WM8994_AIF1_DAC2_EQ_BAND_2_PG 0x4A8
165#define WM8994_AIF1_DAC2_EQ_BAND_3_A 0x4A9
166#define WM8994_AIF1_DAC2_EQ_BAND_3_B 0x4AA
167#define WM8994_AIF1_DAC2_EQ_BAND_3_C 0x4AB
168#define WM8994_AIF1_DAC2_EQ_BAND_3_PG 0x4AC
169#define WM8994_AIF1_DAC2_EQ_BAND_4_A 0x4AD
170#define WM8994_AIF1_DAC2_EQ_BAND_4_B 0x4AE
171#define WM8994_AIF1_DAC2_EQ_BAND_4_C 0x4AF
172#define WM8994_AIF1_DAC2_EQ_BAND_4_PG 0x4B0
173#define WM8994_AIF1_DAC2_EQ_BAND_5_A 0x4B1
174#define WM8994_AIF1_DAC2_EQ_BAND_5_B 0x4B2
175#define WM8994_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
176#define WM8994_AIF2_ADC_LEFT_VOLUME 0x500
177#define WM8994_AIF2_ADC_RIGHT_VOLUME 0x501
178#define WM8994_AIF2_DAC_LEFT_VOLUME 0x502
179#define WM8994_AIF2_DAC_RIGHT_VOLUME 0x503
180#define WM8994_AIF2_ADC_FILTERS 0x510
181#define WM8994_AIF2_DAC_FILTERS_1 0x520
182#define WM8994_AIF2_DAC_FILTERS_2 0x521
183#define WM8994_AIF2_DRC_1 0x540
184#define WM8994_AIF2_DRC_2 0x541
185#define WM8994_AIF2_DRC_3 0x542
186#define WM8994_AIF2_DRC_4 0x543
187#define WM8994_AIF2_DRC_5 0x544
188#define WM8994_AIF2_EQ_GAINS_1 0x580
189#define WM8994_AIF2_EQ_GAINS_2 0x581
190#define WM8994_AIF2_EQ_BAND_1_A 0x582
191#define WM8994_AIF2_EQ_BAND_1_B 0x583
192#define WM8994_AIF2_EQ_BAND_1_PG 0x584
193#define WM8994_AIF2_EQ_BAND_2_A 0x585
194#define WM8994_AIF2_EQ_BAND_2_B 0x586
195#define WM8994_AIF2_EQ_BAND_2_C 0x587
196#define WM8994_AIF2_EQ_BAND_2_PG 0x588
197#define WM8994_AIF2_EQ_BAND_3_A 0x589
198#define WM8994_AIF2_EQ_BAND_3_B 0x58A
199#define WM8994_AIF2_EQ_BAND_3_C 0x58B
200#define WM8994_AIF2_EQ_BAND_3_PG 0x58C
201#define WM8994_AIF2_EQ_BAND_4_A 0x58D
202#define WM8994_AIF2_EQ_BAND_4_B 0x58E
203#define WM8994_AIF2_EQ_BAND_4_C 0x58F
204#define WM8994_AIF2_EQ_BAND_4_PG 0x590
205#define WM8994_AIF2_EQ_BAND_5_A 0x591
206#define WM8994_AIF2_EQ_BAND_5_B 0x592
207#define WM8994_AIF2_EQ_BAND_5_PG 0x593
208#define WM8994_DAC1_MIXER_VOLUMES 0x600
209#define WM8994_DAC1_LEFT_MIXER_ROUTING 0x601
210#define WM8994_DAC1_RIGHT_MIXER_ROUTING 0x602
211#define WM8994_DAC2_MIXER_VOLUMES 0x603
212#define WM8994_DAC2_LEFT_MIXER_ROUTING 0x604
213#define WM8994_DAC2_RIGHT_MIXER_ROUTING 0x605
214#define WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606
215#define WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607
216#define WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608
217#define WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609
218#define WM8994_DAC1_LEFT_VOLUME 0x610
219#define WM8994_DAC1_RIGHT_VOLUME 0x611
220#define WM8994_DAC2_LEFT_VOLUME 0x612
221#define WM8994_DAC2_RIGHT_VOLUME 0x613
222#define WM8994_DAC_SOFTMUTE 0x614
223#define WM8994_OVERSAMPLING 0x620
224#define WM8994_SIDETONE 0x621
225#define WM8994_GPIO_1 0x700
226#define WM8994_GPIO_2 0x701
227#define WM8994_GPIO_3 0x702
228#define WM8994_GPIO_4 0x703
229#define WM8994_GPIO_5 0x704
230#define WM8994_GPIO_6 0x705
231#define WM8994_GPIO_7 0x706
232#define WM8994_GPIO_8 0x707
233#define WM8994_GPIO_9 0x708
234#define WM8994_GPIO_10 0x709
235#define WM8994_GPIO_11 0x70A
236#define WM8994_PULL_CONTROL_1 0x720
237#define WM8994_PULL_CONTROL_2 0x721
238#define WM8994_INTERRUPT_STATUS_1 0x730
239#define WM8994_INTERRUPT_STATUS_2 0x731
240#define WM8994_INTERRUPT_RAW_STATUS_2 0x732
241#define WM8994_INTERRUPT_STATUS_1_MASK 0x738
242#define WM8994_INTERRUPT_STATUS_2_MASK 0x739
243#define WM8994_INTERRUPT_CONTROL 0x740
244#define WM8994_IRQ_DEBOUNCE 0x748
245#define WM8994_WRITE_SEQUENCER_0 0x3000
246#define WM8994_WRITE_SEQUENCER_1 0x3001
247#define WM8994_WRITE_SEQUENCER_2 0x3002
248#define WM8994_WRITE_SEQUENCER_3 0x3003
249#define WM8994_WRITE_SEQUENCER_4 0x3004
250#define WM8994_WRITE_SEQUENCER_5 0x3005
251#define WM8994_WRITE_SEQUENCER_6 0x3006
252#define WM8994_WRITE_SEQUENCER_7 0x3007
253#define WM8994_WRITE_SEQUENCER_8 0x3008
254#define WM8994_WRITE_SEQUENCER_9 0x3009
255#define WM8994_WRITE_SEQUENCER_10 0x300A
256#define WM8994_WRITE_SEQUENCER_11 0x300B
257#define WM8994_WRITE_SEQUENCER_12 0x300C
258#define WM8994_WRITE_SEQUENCER_13 0x300D
259#define WM8994_WRITE_SEQUENCER_14 0x300E
260#define WM8994_WRITE_SEQUENCER_15 0x300F
261#define WM8994_WRITE_SEQUENCER_16 0x3010
262#define WM8994_WRITE_SEQUENCER_17 0x3011
263#define WM8994_WRITE_SEQUENCER_18 0x3012
264#define WM8994_WRITE_SEQUENCER_19 0x3013
265#define WM8994_WRITE_SEQUENCER_20 0x3014
266#define WM8994_WRITE_SEQUENCER_21 0x3015
267#define WM8994_WRITE_SEQUENCER_22 0x3016
268#define WM8994_WRITE_SEQUENCER_23 0x3017
269#define WM8994_WRITE_SEQUENCER_24 0x3018
270#define WM8994_WRITE_SEQUENCER_25 0x3019
271#define WM8994_WRITE_SEQUENCER_26 0x301A
272#define WM8994_WRITE_SEQUENCER_27 0x301B
273#define WM8994_WRITE_SEQUENCER_28 0x301C
274#define WM8994_WRITE_SEQUENCER_29 0x301D
275#define WM8994_WRITE_SEQUENCER_30 0x301E
276#define WM8994_WRITE_SEQUENCER_31 0x301F
277#define WM8994_WRITE_SEQUENCER_32 0x3020
278#define WM8994_WRITE_SEQUENCER_33 0x3021
279#define WM8994_WRITE_SEQUENCER_34 0x3022
280#define WM8994_WRITE_SEQUENCER_35 0x3023
281#define WM8994_WRITE_SEQUENCER_36 0x3024
282#define WM8994_WRITE_SEQUENCER_37 0x3025
283#define WM8994_WRITE_SEQUENCER_38 0x3026
284#define WM8994_WRITE_SEQUENCER_39 0x3027
285#define WM8994_WRITE_SEQUENCER_40 0x3028
286#define WM8994_WRITE_SEQUENCER_41 0x3029
287#define WM8994_WRITE_SEQUENCER_42 0x302A
288#define WM8994_WRITE_SEQUENCER_43 0x302B
289#define WM8994_WRITE_SEQUENCER_44 0x302C
290#define WM8994_WRITE_SEQUENCER_45 0x302D
291#define WM8994_WRITE_SEQUENCER_46 0x302E
292#define WM8994_WRITE_SEQUENCER_47 0x302F
293#define WM8994_WRITE_SEQUENCER_48 0x3030
294#define WM8994_WRITE_SEQUENCER_49 0x3031
295#define WM8994_WRITE_SEQUENCER_50 0x3032
296#define WM8994_WRITE_SEQUENCER_51 0x3033
297#define WM8994_WRITE_SEQUENCER_52 0x3034
298#define WM8994_WRITE_SEQUENCER_53 0x3035
299#define WM8994_WRITE_SEQUENCER_54 0x3036
300#define WM8994_WRITE_SEQUENCER_55 0x3037
301#define WM8994_WRITE_SEQUENCER_56 0x3038
302#define WM8994_WRITE_SEQUENCER_57 0x3039
303#define WM8994_WRITE_SEQUENCER_58 0x303A
304#define WM8994_WRITE_SEQUENCER_59 0x303B
305#define WM8994_WRITE_SEQUENCER_60 0x303C
306#define WM8994_WRITE_SEQUENCER_61 0x303D
307#define WM8994_WRITE_SEQUENCER_62 0x303E
308#define WM8994_WRITE_SEQUENCER_63 0x303F
309#define WM8994_WRITE_SEQUENCER_64 0x3040
310#define WM8994_WRITE_SEQUENCER_65 0x3041
311#define WM8994_WRITE_SEQUENCER_66 0x3042
312#define WM8994_WRITE_SEQUENCER_67 0x3043
313#define WM8994_WRITE_SEQUENCER_68 0x3044
314#define WM8994_WRITE_SEQUENCER_69 0x3045
315#define WM8994_WRITE_SEQUENCER_70 0x3046
316#define WM8994_WRITE_SEQUENCER_71 0x3047
317#define WM8994_WRITE_SEQUENCER_72 0x3048
318#define WM8994_WRITE_SEQUENCER_73 0x3049
319#define WM8994_WRITE_SEQUENCER_74 0x304A
320#define WM8994_WRITE_SEQUENCER_75 0x304B
321#define WM8994_WRITE_SEQUENCER_76 0x304C
322#define WM8994_WRITE_SEQUENCER_77 0x304D
323#define WM8994_WRITE_SEQUENCER_78 0x304E
324#define WM8994_WRITE_SEQUENCER_79 0x304F
325#define WM8994_WRITE_SEQUENCER_80 0x3050
326#define WM8994_WRITE_SEQUENCER_81 0x3051
327#define WM8994_WRITE_SEQUENCER_82 0x3052
328#define WM8994_WRITE_SEQUENCER_83 0x3053
329#define WM8994_WRITE_SEQUENCER_84 0x3054
330#define WM8994_WRITE_SEQUENCER_85 0x3055
331#define WM8994_WRITE_SEQUENCER_86 0x3056
332#define WM8994_WRITE_SEQUENCER_87 0x3057
333#define WM8994_WRITE_SEQUENCER_88 0x3058
334#define WM8994_WRITE_SEQUENCER_89 0x3059
335#define WM8994_WRITE_SEQUENCER_90 0x305A
336#define WM8994_WRITE_SEQUENCER_91 0x305B
337#define WM8994_WRITE_SEQUENCER_92 0x305C
338#define WM8994_WRITE_SEQUENCER_93 0x305D
339#define WM8994_WRITE_SEQUENCER_94 0x305E
340#define WM8994_WRITE_SEQUENCER_95 0x305F
341#define WM8994_WRITE_SEQUENCER_96 0x3060
342#define WM8994_WRITE_SEQUENCER_97 0x3061
343#define WM8994_WRITE_SEQUENCER_98 0x3062
344#define WM8994_WRITE_SEQUENCER_99 0x3063
345#define WM8994_WRITE_SEQUENCER_100 0x3064
346#define WM8994_WRITE_SEQUENCER_101 0x3065
347#define WM8994_WRITE_SEQUENCER_102 0x3066
348#define WM8994_WRITE_SEQUENCER_103 0x3067
349#define WM8994_WRITE_SEQUENCER_104 0x3068
350#define WM8994_WRITE_SEQUENCER_105 0x3069
351#define WM8994_WRITE_SEQUENCER_106 0x306A
352#define WM8994_WRITE_SEQUENCER_107 0x306B
353#define WM8994_WRITE_SEQUENCER_108 0x306C
354#define WM8994_WRITE_SEQUENCER_109 0x306D
355#define WM8994_WRITE_SEQUENCER_110 0x306E
356#define WM8994_WRITE_SEQUENCER_111 0x306F
357#define WM8994_WRITE_SEQUENCER_112 0x3070
358#define WM8994_WRITE_SEQUENCER_113 0x3071
359#define WM8994_WRITE_SEQUENCER_114 0x3072
360#define WM8994_WRITE_SEQUENCER_115 0x3073
361#define WM8994_WRITE_SEQUENCER_116 0x3074
362#define WM8994_WRITE_SEQUENCER_117 0x3075
363#define WM8994_WRITE_SEQUENCER_118 0x3076
364#define WM8994_WRITE_SEQUENCER_119 0x3077
365#define WM8994_WRITE_SEQUENCER_120 0x3078
366#define WM8994_WRITE_SEQUENCER_121 0x3079
367#define WM8994_WRITE_SEQUENCER_122 0x307A
368#define WM8994_WRITE_SEQUENCER_123 0x307B
369#define WM8994_WRITE_SEQUENCER_124 0x307C
370#define WM8994_WRITE_SEQUENCER_125 0x307D
371#define WM8994_WRITE_SEQUENCER_126 0x307E
372#define WM8994_WRITE_SEQUENCER_127 0x307F
373#define WM8994_WRITE_SEQUENCER_128 0x3080
374#define WM8994_WRITE_SEQUENCER_129 0x3081
375#define WM8994_WRITE_SEQUENCER_130 0x3082
376#define WM8994_WRITE_SEQUENCER_131 0x3083
377#define WM8994_WRITE_SEQUENCER_132 0x3084
378#define WM8994_WRITE_SEQUENCER_133 0x3085
379#define WM8994_WRITE_SEQUENCER_134 0x3086
380#define WM8994_WRITE_SEQUENCER_135 0x3087
381#define WM8994_WRITE_SEQUENCER_136 0x3088
382#define WM8994_WRITE_SEQUENCER_137 0x3089
383#define WM8994_WRITE_SEQUENCER_138 0x308A
384#define WM8994_WRITE_SEQUENCER_139 0x308B
385#define WM8994_WRITE_SEQUENCER_140 0x308C
386#define WM8994_WRITE_SEQUENCER_141 0x308D
387#define WM8994_WRITE_SEQUENCER_142 0x308E
388#define WM8994_WRITE_SEQUENCER_143 0x308F
389#define WM8994_WRITE_SEQUENCER_144 0x3090
390#define WM8994_WRITE_SEQUENCER_145 0x3091
391#define WM8994_WRITE_SEQUENCER_146 0x3092
392#define WM8994_WRITE_SEQUENCER_147 0x3093
393#define WM8994_WRITE_SEQUENCER_148 0x3094
394#define WM8994_WRITE_SEQUENCER_149 0x3095
395#define WM8994_WRITE_SEQUENCER_150 0x3096
396#define WM8994_WRITE_SEQUENCER_151 0x3097
397#define WM8994_WRITE_SEQUENCER_152 0x3098
398#define WM8994_WRITE_SEQUENCER_153 0x3099
399#define WM8994_WRITE_SEQUENCER_154 0x309A
400#define WM8994_WRITE_SEQUENCER_155 0x309B
401#define WM8994_WRITE_SEQUENCER_156 0x309C
402#define WM8994_WRITE_SEQUENCER_157 0x309D
403#define WM8994_WRITE_SEQUENCER_158 0x309E
404#define WM8994_WRITE_SEQUENCER_159 0x309F
405#define WM8994_WRITE_SEQUENCER_160 0x30A0
406#define WM8994_WRITE_SEQUENCER_161 0x30A1
407#define WM8994_WRITE_SEQUENCER_162 0x30A2
408#define WM8994_WRITE_SEQUENCER_163 0x30A3
409#define WM8994_WRITE_SEQUENCER_164 0x30A4
410#define WM8994_WRITE_SEQUENCER_165 0x30A5
411#define WM8994_WRITE_SEQUENCER_166 0x30A6
412#define WM8994_WRITE_SEQUENCER_167 0x30A7
413#define WM8994_WRITE_SEQUENCER_168 0x30A8
414#define WM8994_WRITE_SEQUENCER_169 0x30A9
415#define WM8994_WRITE_SEQUENCER_170 0x30AA
416#define WM8994_WRITE_SEQUENCER_171 0x30AB
417#define WM8994_WRITE_SEQUENCER_172 0x30AC
418#define WM8994_WRITE_SEQUENCER_173 0x30AD
419#define WM8994_WRITE_SEQUENCER_174 0x30AE
420#define WM8994_WRITE_SEQUENCER_175 0x30AF
421#define WM8994_WRITE_SEQUENCER_176 0x30B0
422#define WM8994_WRITE_SEQUENCER_177 0x30B1
423#define WM8994_WRITE_SEQUENCER_178 0x30B2
424#define WM8994_WRITE_SEQUENCER_179 0x30B3
425#define WM8994_WRITE_SEQUENCER_180 0x30B4
426#define WM8994_WRITE_SEQUENCER_181 0x30B5
427#define WM8994_WRITE_SEQUENCER_182 0x30B6
428#define WM8994_WRITE_SEQUENCER_183 0x30B7
429#define WM8994_WRITE_SEQUENCER_184 0x30B8
430#define WM8994_WRITE_SEQUENCER_185 0x30B9
431#define WM8994_WRITE_SEQUENCER_186 0x30BA
432#define WM8994_WRITE_SEQUENCER_187 0x30BB
433#define WM8994_WRITE_SEQUENCER_188 0x30BC
434#define WM8994_WRITE_SEQUENCER_189 0x30BD
435#define WM8994_WRITE_SEQUENCER_190 0x30BE
436#define WM8994_WRITE_SEQUENCER_191 0x30BF
437#define WM8994_WRITE_SEQUENCER_192 0x30C0
438#define WM8994_WRITE_SEQUENCER_193 0x30C1
439#define WM8994_WRITE_SEQUENCER_194 0x30C2
440#define WM8994_WRITE_SEQUENCER_195 0x30C3
441#define WM8994_WRITE_SEQUENCER_196 0x30C4
442#define WM8994_WRITE_SEQUENCER_197 0x30C5
443#define WM8994_WRITE_SEQUENCER_198 0x30C6
444#define WM8994_WRITE_SEQUENCER_199 0x30C7
445#define WM8994_WRITE_SEQUENCER_200 0x30C8
446#define WM8994_WRITE_SEQUENCER_201 0x30C9
447#define WM8994_WRITE_SEQUENCER_202 0x30CA
448#define WM8994_WRITE_SEQUENCER_203 0x30CB
449#define WM8994_WRITE_SEQUENCER_204 0x30CC
450#define WM8994_WRITE_SEQUENCER_205 0x30CD
451#define WM8994_WRITE_SEQUENCER_206 0x30CE
452#define WM8994_WRITE_SEQUENCER_207 0x30CF
453#define WM8994_WRITE_SEQUENCER_208 0x30D0
454#define WM8994_WRITE_SEQUENCER_209 0x30D1
455#define WM8994_WRITE_SEQUENCER_210 0x30D2
456#define WM8994_WRITE_SEQUENCER_211 0x30D3
457#define WM8994_WRITE_SEQUENCER_212 0x30D4
458#define WM8994_WRITE_SEQUENCER_213 0x30D5
459#define WM8994_WRITE_SEQUENCER_214 0x30D6
460#define WM8994_WRITE_SEQUENCER_215 0x30D7
461#define WM8994_WRITE_SEQUENCER_216 0x30D8
462#define WM8994_WRITE_SEQUENCER_217 0x30D9
463#define WM8994_WRITE_SEQUENCER_218 0x30DA
464#define WM8994_WRITE_SEQUENCER_219 0x30DB
465#define WM8994_WRITE_SEQUENCER_220 0x30DC
466#define WM8994_WRITE_SEQUENCER_221 0x30DD
467#define WM8994_WRITE_SEQUENCER_222 0x30DE
468#define WM8994_WRITE_SEQUENCER_223 0x30DF
469#define WM8994_WRITE_SEQUENCER_224 0x30E0
470#define WM8994_WRITE_SEQUENCER_225 0x30E1
471#define WM8994_WRITE_SEQUENCER_226 0x30E2
472#define WM8994_WRITE_SEQUENCER_227 0x30E3
473#define WM8994_WRITE_SEQUENCER_228 0x30E4
474#define WM8994_WRITE_SEQUENCER_229 0x30E5
475#define WM8994_WRITE_SEQUENCER_230 0x30E6
476#define WM8994_WRITE_SEQUENCER_231 0x30E7
477#define WM8994_WRITE_SEQUENCER_232 0x30E8
478#define WM8994_WRITE_SEQUENCER_233 0x30E9
479#define WM8994_WRITE_SEQUENCER_234 0x30EA
480#define WM8994_WRITE_SEQUENCER_235 0x30EB
481#define WM8994_WRITE_SEQUENCER_236 0x30EC
482#define WM8994_WRITE_SEQUENCER_237 0x30ED
483#define WM8994_WRITE_SEQUENCER_238 0x30EE
484#define WM8994_WRITE_SEQUENCER_239 0x30EF
485#define WM8994_WRITE_SEQUENCER_240 0x30F0
486#define WM8994_WRITE_SEQUENCER_241 0x30F1
487#define WM8994_WRITE_SEQUENCER_242 0x30F2
488#define WM8994_WRITE_SEQUENCER_243 0x30F3
489#define WM8994_WRITE_SEQUENCER_244 0x30F4
490#define WM8994_WRITE_SEQUENCER_245 0x30F5
491#define WM8994_WRITE_SEQUENCER_246 0x30F6
492#define WM8994_WRITE_SEQUENCER_247 0x30F7
493#define WM8994_WRITE_SEQUENCER_248 0x30F8
494#define WM8994_WRITE_SEQUENCER_249 0x30F9
495#define WM8994_WRITE_SEQUENCER_250 0x30FA
496#define WM8994_WRITE_SEQUENCER_251 0x30FB
497#define WM8994_WRITE_SEQUENCER_252 0x30FC
498#define WM8994_WRITE_SEQUENCER_253 0x30FD
499#define WM8994_WRITE_SEQUENCER_254 0x30FE
500#define WM8994_WRITE_SEQUENCER_255 0x30FF
501#define WM8994_WRITE_SEQUENCER_256 0x3100
502#define WM8994_WRITE_SEQUENCER_257 0x3101
503#define WM8994_WRITE_SEQUENCER_258 0x3102
504#define WM8994_WRITE_SEQUENCER_259 0x3103
505#define WM8994_WRITE_SEQUENCER_260 0x3104
506#define WM8994_WRITE_SEQUENCER_261 0x3105
507#define WM8994_WRITE_SEQUENCER_262 0x3106
508#define WM8994_WRITE_SEQUENCER_263 0x3107
509#define WM8994_WRITE_SEQUENCER_264 0x3108
510#define WM8994_WRITE_SEQUENCER_265 0x3109
511#define WM8994_WRITE_SEQUENCER_266 0x310A
512#define WM8994_WRITE_SEQUENCER_267 0x310B
513#define WM8994_WRITE_SEQUENCER_268 0x310C
514#define WM8994_WRITE_SEQUENCER_269 0x310D
515#define WM8994_WRITE_SEQUENCER_270 0x310E
516#define WM8994_WRITE_SEQUENCER_271 0x310F
517#define WM8994_WRITE_SEQUENCER_272 0x3110
518#define WM8994_WRITE_SEQUENCER_273 0x3111
519#define WM8994_WRITE_SEQUENCER_274 0x3112
520#define WM8994_WRITE_SEQUENCER_275 0x3113
521#define WM8994_WRITE_SEQUENCER_276 0x3114
522#define WM8994_WRITE_SEQUENCER_277 0x3115
523#define WM8994_WRITE_SEQUENCER_278 0x3116
524#define WM8994_WRITE_SEQUENCER_279 0x3117
525#define WM8994_WRITE_SEQUENCER_280 0x3118
526#define WM8994_WRITE_SEQUENCER_281 0x3119
527#define WM8994_WRITE_SEQUENCER_282 0x311A
528#define WM8994_WRITE_SEQUENCER_283 0x311B
529#define WM8994_WRITE_SEQUENCER_284 0x311C
530#define WM8994_WRITE_SEQUENCER_285 0x311D
531#define WM8994_WRITE_SEQUENCER_286 0x311E
532#define WM8994_WRITE_SEQUENCER_287 0x311F
533#define WM8994_WRITE_SEQUENCER_288 0x3120
534#define WM8994_WRITE_SEQUENCER_289 0x3121
535#define WM8994_WRITE_SEQUENCER_290 0x3122
536#define WM8994_WRITE_SEQUENCER_291 0x3123
537#define WM8994_WRITE_SEQUENCER_292 0x3124
538#define WM8994_WRITE_SEQUENCER_293 0x3125
539#define WM8994_WRITE_SEQUENCER_294 0x3126
540#define WM8994_WRITE_SEQUENCER_295 0x3127
541#define WM8994_WRITE_SEQUENCER_296 0x3128
542#define WM8994_WRITE_SEQUENCER_297 0x3129
543#define WM8994_WRITE_SEQUENCER_298 0x312A
544#define WM8994_WRITE_SEQUENCER_299 0x312B
545#define WM8994_WRITE_SEQUENCER_300 0x312C
546#define WM8994_WRITE_SEQUENCER_301 0x312D
547#define WM8994_WRITE_SEQUENCER_302 0x312E
548#define WM8994_WRITE_SEQUENCER_303 0x312F
549#define WM8994_WRITE_SEQUENCER_304 0x3130
550#define WM8994_WRITE_SEQUENCER_305 0x3131
551#define WM8994_WRITE_SEQUENCER_306 0x3132
552#define WM8994_WRITE_SEQUENCER_307 0x3133
553#define WM8994_WRITE_SEQUENCER_308 0x3134
554#define WM8994_WRITE_SEQUENCER_309 0x3135
555#define WM8994_WRITE_SEQUENCER_310 0x3136
556#define WM8994_WRITE_SEQUENCER_311 0x3137
557#define WM8994_WRITE_SEQUENCER_312 0x3138
558#define WM8994_WRITE_SEQUENCER_313 0x3139
559#define WM8994_WRITE_SEQUENCER_314 0x313A
560#define WM8994_WRITE_SEQUENCER_315 0x313B
561#define WM8994_WRITE_SEQUENCER_316 0x313C
562#define WM8994_WRITE_SEQUENCER_317 0x313D
563#define WM8994_WRITE_SEQUENCER_318 0x313E
564#define WM8994_WRITE_SEQUENCER_319 0x313F
565#define WM8994_WRITE_SEQUENCER_320 0x3140
566#define WM8994_WRITE_SEQUENCER_321 0x3141
567#define WM8994_WRITE_SEQUENCER_322 0x3142
568#define WM8994_WRITE_SEQUENCER_323 0x3143
569#define WM8994_WRITE_SEQUENCER_324 0x3144
570#define WM8994_WRITE_SEQUENCER_325 0x3145
571#define WM8994_WRITE_SEQUENCER_326 0x3146
572#define WM8994_WRITE_SEQUENCER_327 0x3147
573#define WM8994_WRITE_SEQUENCER_328 0x3148
574#define WM8994_WRITE_SEQUENCER_329 0x3149
575#define WM8994_WRITE_SEQUENCER_330 0x314A
576#define WM8994_WRITE_SEQUENCER_331 0x314B
577#define WM8994_WRITE_SEQUENCER_332 0x314C
578#define WM8994_WRITE_SEQUENCER_333 0x314D
579#define WM8994_WRITE_SEQUENCER_334 0x314E
580#define WM8994_WRITE_SEQUENCER_335 0x314F
581#define WM8994_WRITE_SEQUENCER_336 0x3150
582#define WM8994_WRITE_SEQUENCER_337 0x3151
583#define WM8994_WRITE_SEQUENCER_338 0x3152
584#define WM8994_WRITE_SEQUENCER_339 0x3153
585#define WM8994_WRITE_SEQUENCER_340 0x3154
586#define WM8994_WRITE_SEQUENCER_341 0x3155
587#define WM8994_WRITE_SEQUENCER_342 0x3156
588#define WM8994_WRITE_SEQUENCER_343 0x3157
589#define WM8994_WRITE_SEQUENCER_344 0x3158
590#define WM8994_WRITE_SEQUENCER_345 0x3159
591#define WM8994_WRITE_SEQUENCER_346 0x315A
592#define WM8994_WRITE_SEQUENCER_347 0x315B
593#define WM8994_WRITE_SEQUENCER_348 0x315C
594#define WM8994_WRITE_SEQUENCER_349 0x315D
595#define WM8994_WRITE_SEQUENCER_350 0x315E
596#define WM8994_WRITE_SEQUENCER_351 0x315F
597#define WM8994_WRITE_SEQUENCER_352 0x3160
598#define WM8994_WRITE_SEQUENCER_353 0x3161
599#define WM8994_WRITE_SEQUENCER_354 0x3162
600#define WM8994_WRITE_SEQUENCER_355 0x3163
601#define WM8994_WRITE_SEQUENCER_356 0x3164
602#define WM8994_WRITE_SEQUENCER_357 0x3165
603#define WM8994_WRITE_SEQUENCER_358 0x3166
604#define WM8994_WRITE_SEQUENCER_359 0x3167
605#define WM8994_WRITE_SEQUENCER_360 0x3168
606#define WM8994_WRITE_SEQUENCER_361 0x3169
607#define WM8994_WRITE_SEQUENCER_362 0x316A
608#define WM8994_WRITE_SEQUENCER_363 0x316B
609#define WM8994_WRITE_SEQUENCER_364 0x316C
610#define WM8994_WRITE_SEQUENCER_365 0x316D
611#define WM8994_WRITE_SEQUENCER_366 0x316E
612#define WM8994_WRITE_SEQUENCER_367 0x316F
613#define WM8994_WRITE_SEQUENCER_368 0x3170
614#define WM8994_WRITE_SEQUENCER_369 0x3171
615#define WM8994_WRITE_SEQUENCER_370 0x3172
616#define WM8994_WRITE_SEQUENCER_371 0x3173
617#define WM8994_WRITE_SEQUENCER_372 0x3174
618#define WM8994_WRITE_SEQUENCER_373 0x3175
619#define WM8994_WRITE_SEQUENCER_374 0x3176
620#define WM8994_WRITE_SEQUENCER_375 0x3177
621#define WM8994_WRITE_SEQUENCER_376 0x3178
622#define WM8994_WRITE_SEQUENCER_377 0x3179
623#define WM8994_WRITE_SEQUENCER_378 0x317A
624#define WM8994_WRITE_SEQUENCER_379 0x317B
625#define WM8994_WRITE_SEQUENCER_380 0x317C
626#define WM8994_WRITE_SEQUENCER_381 0x317D
627#define WM8994_WRITE_SEQUENCER_382 0x317E
628#define WM8994_WRITE_SEQUENCER_383 0x317F
629#define WM8994_WRITE_SEQUENCER_384 0x3180
630#define WM8994_WRITE_SEQUENCER_385 0x3181
631#define WM8994_WRITE_SEQUENCER_386 0x3182
632#define WM8994_WRITE_SEQUENCER_387 0x3183
633#define WM8994_WRITE_SEQUENCER_388 0x3184
634#define WM8994_WRITE_SEQUENCER_389 0x3185
635#define WM8994_WRITE_SEQUENCER_390 0x3186
636#define WM8994_WRITE_SEQUENCER_391 0x3187
637#define WM8994_WRITE_SEQUENCER_392 0x3188
638#define WM8994_WRITE_SEQUENCER_393 0x3189
639#define WM8994_WRITE_SEQUENCER_394 0x318A
640#define WM8994_WRITE_SEQUENCER_395 0x318B
641#define WM8994_WRITE_SEQUENCER_396 0x318C
642#define WM8994_WRITE_SEQUENCER_397 0x318D
643#define WM8994_WRITE_SEQUENCER_398 0x318E
644#define WM8994_WRITE_SEQUENCER_399 0x318F
645#define WM8994_WRITE_SEQUENCER_400 0x3190
646#define WM8994_WRITE_SEQUENCER_401 0x3191
647#define WM8994_WRITE_SEQUENCER_402 0x3192
648#define WM8994_WRITE_SEQUENCER_403 0x3193
649#define WM8994_WRITE_SEQUENCER_404 0x3194
650#define WM8994_WRITE_SEQUENCER_405 0x3195
651#define WM8994_WRITE_SEQUENCER_406 0x3196
652#define WM8994_WRITE_SEQUENCER_407 0x3197
653#define WM8994_WRITE_SEQUENCER_408 0x3198
654#define WM8994_WRITE_SEQUENCER_409 0x3199
655#define WM8994_WRITE_SEQUENCER_410 0x319A
656#define WM8994_WRITE_SEQUENCER_411 0x319B
657#define WM8994_WRITE_SEQUENCER_412 0x319C
658#define WM8994_WRITE_SEQUENCER_413 0x319D
659#define WM8994_WRITE_SEQUENCER_414 0x319E
660#define WM8994_WRITE_SEQUENCER_415 0x319F
661#define WM8994_WRITE_SEQUENCER_416 0x31A0
662#define WM8994_WRITE_SEQUENCER_417 0x31A1
663#define WM8994_WRITE_SEQUENCER_418 0x31A2
664#define WM8994_WRITE_SEQUENCER_419 0x31A3
665#define WM8994_WRITE_SEQUENCER_420 0x31A4
666#define WM8994_WRITE_SEQUENCER_421 0x31A5
667#define WM8994_WRITE_SEQUENCER_422 0x31A6
668#define WM8994_WRITE_SEQUENCER_423 0x31A7
669#define WM8994_WRITE_SEQUENCER_424 0x31A8
670#define WM8994_WRITE_SEQUENCER_425 0x31A9
671#define WM8994_WRITE_SEQUENCER_426 0x31AA
672#define WM8994_WRITE_SEQUENCER_427 0x31AB
673#define WM8994_WRITE_SEQUENCER_428 0x31AC
674#define WM8994_WRITE_SEQUENCER_429 0x31AD
675#define WM8994_WRITE_SEQUENCER_430 0x31AE
676#define WM8994_WRITE_SEQUENCER_431 0x31AF
677#define WM8994_WRITE_SEQUENCER_432 0x31B0
678#define WM8994_WRITE_SEQUENCER_433 0x31B1
679#define WM8994_WRITE_SEQUENCER_434 0x31B2
680#define WM8994_WRITE_SEQUENCER_435 0x31B3
681#define WM8994_WRITE_SEQUENCER_436 0x31B4
682#define WM8994_WRITE_SEQUENCER_437 0x31B5
683#define WM8994_WRITE_SEQUENCER_438 0x31B6
684#define WM8994_WRITE_SEQUENCER_439 0x31B7
685#define WM8994_WRITE_SEQUENCER_440 0x31B8
686#define WM8994_WRITE_SEQUENCER_441 0x31B9
687#define WM8994_WRITE_SEQUENCER_442 0x31BA
688#define WM8994_WRITE_SEQUENCER_443 0x31BB
689#define WM8994_WRITE_SEQUENCER_444 0x31BC
690#define WM8994_WRITE_SEQUENCER_445 0x31BD
691#define WM8994_WRITE_SEQUENCER_446 0x31BE
692#define WM8994_WRITE_SEQUENCER_447 0x31BF
693#define WM8994_WRITE_SEQUENCER_448 0x31C0
694#define WM8994_WRITE_SEQUENCER_449 0x31C1
695#define WM8994_WRITE_SEQUENCER_450 0x31C2
696#define WM8994_WRITE_SEQUENCER_451 0x31C3
697#define WM8994_WRITE_SEQUENCER_452 0x31C4
698#define WM8994_WRITE_SEQUENCER_453 0x31C5
699#define WM8994_WRITE_SEQUENCER_454 0x31C6
700#define WM8994_WRITE_SEQUENCER_455 0x31C7
701#define WM8994_WRITE_SEQUENCER_456 0x31C8
702#define WM8994_WRITE_SEQUENCER_457 0x31C9
703#define WM8994_WRITE_SEQUENCER_458 0x31CA
704#define WM8994_WRITE_SEQUENCER_459 0x31CB
705#define WM8994_WRITE_SEQUENCER_460 0x31CC
706#define WM8994_WRITE_SEQUENCER_461 0x31CD
707#define WM8994_WRITE_SEQUENCER_462 0x31CE
708#define WM8994_WRITE_SEQUENCER_463 0x31CF
709#define WM8994_WRITE_SEQUENCER_464 0x31D0
710#define WM8994_WRITE_SEQUENCER_465 0x31D1
711#define WM8994_WRITE_SEQUENCER_466 0x31D2
712#define WM8994_WRITE_SEQUENCER_467 0x31D3
713#define WM8994_WRITE_SEQUENCER_468 0x31D4
714#define WM8994_WRITE_SEQUENCER_469 0x31D5
715#define WM8994_WRITE_SEQUENCER_470 0x31D6
716#define WM8994_WRITE_SEQUENCER_471 0x31D7
717#define WM8994_WRITE_SEQUENCER_472 0x31D8
718#define WM8994_WRITE_SEQUENCER_473 0x31D9
719#define WM8994_WRITE_SEQUENCER_474 0x31DA
720#define WM8994_WRITE_SEQUENCER_475 0x31DB
721#define WM8994_WRITE_SEQUENCER_476 0x31DC
722#define WM8994_WRITE_SEQUENCER_477 0x31DD
723#define WM8994_WRITE_SEQUENCER_478 0x31DE
724#define WM8994_WRITE_SEQUENCER_479 0x31DF
725#define WM8994_WRITE_SEQUENCER_480 0x31E0
726#define WM8994_WRITE_SEQUENCER_481 0x31E1
727#define WM8994_WRITE_SEQUENCER_482 0x31E2
728#define WM8994_WRITE_SEQUENCER_483 0x31E3
729#define WM8994_WRITE_SEQUENCER_484 0x31E4
730#define WM8994_WRITE_SEQUENCER_485 0x31E5
731#define WM8994_WRITE_SEQUENCER_486 0x31E6
732#define WM8994_WRITE_SEQUENCER_487 0x31E7
733#define WM8994_WRITE_SEQUENCER_488 0x31E8
734#define WM8994_WRITE_SEQUENCER_489 0x31E9
735#define WM8994_WRITE_SEQUENCER_490 0x31EA
736#define WM8994_WRITE_SEQUENCER_491 0x31EB
737#define WM8994_WRITE_SEQUENCER_492 0x31EC
738#define WM8994_WRITE_SEQUENCER_493 0x31ED
739#define WM8994_WRITE_SEQUENCER_494 0x31EE
740#define WM8994_WRITE_SEQUENCER_495 0x31EF
741#define WM8994_WRITE_SEQUENCER_496 0x31F0
742#define WM8994_WRITE_SEQUENCER_497 0x31F1
743#define WM8994_WRITE_SEQUENCER_498 0x31F2
744#define WM8994_WRITE_SEQUENCER_499 0x31F3
745#define WM8994_WRITE_SEQUENCER_500 0x31F4
746#define WM8994_WRITE_SEQUENCER_501 0x31F5
747#define WM8994_WRITE_SEQUENCER_502 0x31F6
748#define WM8994_WRITE_SEQUENCER_503 0x31F7
749#define WM8994_WRITE_SEQUENCER_504 0x31F8
750#define WM8994_WRITE_SEQUENCER_505 0x31F9
751#define WM8994_WRITE_SEQUENCER_506 0x31FA
752#define WM8994_WRITE_SEQUENCER_507 0x31FB
753#define WM8994_WRITE_SEQUENCER_508 0x31FC
754#define WM8994_WRITE_SEQUENCER_509 0x31FD
755#define WM8994_WRITE_SEQUENCER_510 0x31FE
756#define WM8994_WRITE_SEQUENCER_511 0x31FF
757
758#define WM8994_REGISTER_COUNT 736
759#define WM8994_MAX_REGISTER 0x31FF
760#define WM8994_MAX_CACHED_REGISTER 0x749
761
762/*
763 * Field Definitions.
764 */
765
766/*
767 * R0 (0x00) - Software Reset
768 */
769#define WM8994_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
770#define WM8994_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
771#define WM8994_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
772
773/*
774 * R1 (0x01) - Power Management (1)
775 */
776#define WM8994_SPKOUTR_ENA 0x2000 /* SPKOUTR_ENA */
777#define WM8994_SPKOUTR_ENA_MASK 0x2000 /* SPKOUTR_ENA */
778#define WM8994_SPKOUTR_ENA_SHIFT 13 /* SPKOUTR_ENA */
779#define WM8994_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
780#define WM8994_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
781#define WM8994_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
782#define WM8994_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
783#define WM8994_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
784#define WM8994_HPOUT2_ENA 0x0800 /* HPOUT2_ENA */
785#define WM8994_HPOUT2_ENA_MASK 0x0800 /* HPOUT2_ENA */
786#define WM8994_HPOUT2_ENA_SHIFT 11 /* HPOUT2_ENA */
787#define WM8994_HPOUT2_ENA_WIDTH 1 /* HPOUT2_ENA */
788#define WM8994_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
789#define WM8994_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
790#define WM8994_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
791#define WM8994_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
792#define WM8994_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
793#define WM8994_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
794#define WM8994_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
795#define WM8994_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
796#define WM8994_MICB2_ENA 0x0020 /* MICB2_ENA */
797#define WM8994_MICB2_ENA_MASK 0x0020 /* MICB2_ENA */
798#define WM8994_MICB2_ENA_SHIFT 5 /* MICB2_ENA */
799#define WM8994_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
800#define WM8994_MICB1_ENA 0x0010 /* MICB1_ENA */
801#define WM8994_MICB1_ENA_MASK 0x0010 /* MICB1_ENA */
802#define WM8994_MICB1_ENA_SHIFT 4 /* MICB1_ENA */
803#define WM8994_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
804#define WM8994_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */
805#define WM8994_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */
806#define WM8994_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */
807#define WM8994_BIAS_ENA 0x0001 /* BIAS_ENA */
808#define WM8994_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
809#define WM8994_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
810#define WM8994_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
811
812/*
813 * R2 (0x02) - Power Management (2)
814 */
815#define WM8994_TSHUT_ENA 0x4000 /* TSHUT_ENA */
816#define WM8994_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
817#define WM8994_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
818#define WM8994_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
819#define WM8994_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
820#define WM8994_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
821#define WM8994_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
822#define WM8994_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
823#define WM8994_OPCLK_ENA 0x0800 /* OPCLK_ENA */
824#define WM8994_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
825#define WM8994_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
826#define WM8994_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
827#define WM8994_MIXINL_ENA 0x0200 /* MIXINL_ENA */
828#define WM8994_MIXINL_ENA_MASK 0x0200 /* MIXINL_ENA */
829#define WM8994_MIXINL_ENA_SHIFT 9 /* MIXINL_ENA */
830#define WM8994_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
831#define WM8994_MIXINR_ENA 0x0100 /* MIXINR_ENA */
832#define WM8994_MIXINR_ENA_MASK 0x0100 /* MIXINR_ENA */
833#define WM8994_MIXINR_ENA_SHIFT 8 /* MIXINR_ENA */
834#define WM8994_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
835#define WM8994_IN2L_ENA 0x0080 /* IN2L_ENA */
836#define WM8994_IN2L_ENA_MASK 0x0080 /* IN2L_ENA */
837#define WM8994_IN2L_ENA_SHIFT 7 /* IN2L_ENA */
838#define WM8994_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
839#define WM8994_IN1L_ENA 0x0040 /* IN1L_ENA */
840#define WM8994_IN1L_ENA_MASK 0x0040 /* IN1L_ENA */
841#define WM8994_IN1L_ENA_SHIFT 6 /* IN1L_ENA */
842#define WM8994_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
843#define WM8994_IN2R_ENA 0x0020 /* IN2R_ENA */
844#define WM8994_IN2R_ENA_MASK 0x0020 /* IN2R_ENA */
845#define WM8994_IN2R_ENA_SHIFT 5 /* IN2R_ENA */
846#define WM8994_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
847#define WM8994_IN1R_ENA 0x0010 /* IN1R_ENA */
848#define WM8994_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
849#define WM8994_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
850#define WM8994_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
851
852/*
853 * R3 (0x03) - Power Management (3)
854 */
855#define WM8994_LINEOUT1N_ENA 0x2000 /* LINEOUT1N_ENA */
856#define WM8994_LINEOUT1N_ENA_MASK 0x2000 /* LINEOUT1N_ENA */
857#define WM8994_LINEOUT1N_ENA_SHIFT 13 /* LINEOUT1N_ENA */
858#define WM8994_LINEOUT1N_ENA_WIDTH 1 /* LINEOUT1N_ENA */
859#define WM8994_LINEOUT1P_ENA 0x1000 /* LINEOUT1P_ENA */
860#define WM8994_LINEOUT1P_ENA_MASK 0x1000 /* LINEOUT1P_ENA */
861#define WM8994_LINEOUT1P_ENA_SHIFT 12 /* LINEOUT1P_ENA */
862#define WM8994_LINEOUT1P_ENA_WIDTH 1 /* LINEOUT1P_ENA */
863#define WM8994_LINEOUT2N_ENA 0x0800 /* LINEOUT2N_ENA */
864#define WM8994_LINEOUT2N_ENA_MASK 0x0800 /* LINEOUT2N_ENA */
865#define WM8994_LINEOUT2N_ENA_SHIFT 11 /* LINEOUT2N_ENA */
866#define WM8994_LINEOUT2N_ENA_WIDTH 1 /* LINEOUT2N_ENA */
867#define WM8994_LINEOUT2P_ENA 0x0400 /* LINEOUT2P_ENA */
868#define WM8994_LINEOUT2P_ENA_MASK 0x0400 /* LINEOUT2P_ENA */
869#define WM8994_LINEOUT2P_ENA_SHIFT 10 /* LINEOUT2P_ENA */
870#define WM8994_LINEOUT2P_ENA_WIDTH 1 /* LINEOUT2P_ENA */
871#define WM8994_SPKRVOL_ENA 0x0200 /* SPKRVOL_ENA */
872#define WM8994_SPKRVOL_ENA_MASK 0x0200 /* SPKRVOL_ENA */
873#define WM8994_SPKRVOL_ENA_SHIFT 9 /* SPKRVOL_ENA */
874#define WM8994_SPKRVOL_ENA_WIDTH 1 /* SPKRVOL_ENA */
875#define WM8994_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
876#define WM8994_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
877#define WM8994_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
878#define WM8994_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
879#define WM8994_MIXOUTLVOL_ENA 0x0080 /* MIXOUTLVOL_ENA */
880#define WM8994_MIXOUTLVOL_ENA_MASK 0x0080 /* MIXOUTLVOL_ENA */
881#define WM8994_MIXOUTLVOL_ENA_SHIFT 7 /* MIXOUTLVOL_ENA */
882#define WM8994_MIXOUTLVOL_ENA_WIDTH 1 /* MIXOUTLVOL_ENA */
883#define WM8994_MIXOUTRVOL_ENA 0x0040 /* MIXOUTRVOL_ENA */
884#define WM8994_MIXOUTRVOL_ENA_MASK 0x0040 /* MIXOUTRVOL_ENA */
885#define WM8994_MIXOUTRVOL_ENA_SHIFT 6 /* MIXOUTRVOL_ENA */
886#define WM8994_MIXOUTRVOL_ENA_WIDTH 1 /* MIXOUTRVOL_ENA */
887#define WM8994_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
888#define WM8994_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
889#define WM8994_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
890#define WM8994_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
891#define WM8994_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
892#define WM8994_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
893#define WM8994_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
894#define WM8994_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
895
896/*
897 * R4 (0x04) - Power Management (4)
898 */
899#define WM8994_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */
900#define WM8994_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */
901#define WM8994_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */
902#define WM8994_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */
903#define WM8994_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */
904#define WM8994_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */
905#define WM8994_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */
906#define WM8994_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */
907#define WM8994_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */
908#define WM8994_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */
909#define WM8994_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */
910#define WM8994_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */
911#define WM8994_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */
912#define WM8994_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */
913#define WM8994_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */
914#define WM8994_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */
915#define WM8994_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */
916#define WM8994_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */
917#define WM8994_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */
918#define WM8994_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */
919#define WM8994_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */
920#define WM8994_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */
921#define WM8994_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */
922#define WM8994_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */
923#define WM8994_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
924#define WM8994_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
925#define WM8994_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
926#define WM8994_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
927#define WM8994_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
928#define WM8994_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
929#define WM8994_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
930#define WM8994_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
931#define WM8994_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
932#define WM8994_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
933#define WM8994_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
934#define WM8994_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
935#define WM8994_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
936#define WM8994_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
937#define WM8994_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
938#define WM8994_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
939#define WM8994_ADCL_ENA 0x0002 /* ADCL_ENA */
940#define WM8994_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
941#define WM8994_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
942#define WM8994_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
943#define WM8994_ADCR_ENA 0x0001 /* ADCR_ENA */
944#define WM8994_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
945#define WM8994_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
946#define WM8994_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
947
948/*
949 * R5 (0x05) - Power Management (5)
950 */
951#define WM8994_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */
952#define WM8994_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */
953#define WM8994_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */
954#define WM8994_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */
955#define WM8994_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */
956#define WM8994_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */
957#define WM8994_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */
958#define WM8994_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */
959#define WM8994_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */
960#define WM8994_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */
961#define WM8994_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */
962#define WM8994_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */
963#define WM8994_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */
964#define WM8994_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */
965#define WM8994_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */
966#define WM8994_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */
967#define WM8994_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */
968#define WM8994_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */
969#define WM8994_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */
970#define WM8994_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */
971#define WM8994_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */
972#define WM8994_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */
973#define WM8994_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */
974#define WM8994_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */
975#define WM8994_DAC2L_ENA 0x0008 /* DAC2L_ENA */
976#define WM8994_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
977#define WM8994_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
978#define WM8994_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
979#define WM8994_DAC2R_ENA 0x0004 /* DAC2R_ENA */
980#define WM8994_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
981#define WM8994_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
982#define WM8994_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
983#define WM8994_DAC1L_ENA 0x0002 /* DAC1L_ENA */
984#define WM8994_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
985#define WM8994_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
986#define WM8994_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
987#define WM8994_DAC1R_ENA 0x0001 /* DAC1R_ENA */
988#define WM8994_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
989#define WM8994_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
990#define WM8994_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
991
992/*
993 * R6 (0x06) - Power Management (6)
994 */
995#define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */
996#define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
997#define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
998#define WM8994_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
999#define WM8994_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */
1000#define WM8994_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */
1001#define WM8994_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */
1002#define WM8994_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */
1003#define WM8994_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */
1004#define WM8994_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */
1005#define WM8994_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */
1006#define WM8994_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */
1007#define WM8994_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */
1008#define WM8994_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */
1009#define WM8994_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */
1010#define WM8994_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */
1011#define WM8994_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */
1012#define WM8994_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */
1013#define WM8994_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */
1014
1015/*
1016 * R21 (0x15) - Input Mixer (1)
1017 */
1018#define WM8994_IN1RP_MIXINR_BOOST 0x0100 /* IN1RP_MIXINR_BOOST */
1019#define WM8994_IN1RP_MIXINR_BOOST_MASK 0x0100 /* IN1RP_MIXINR_BOOST */
1020#define WM8994_IN1RP_MIXINR_BOOST_SHIFT 8 /* IN1RP_MIXINR_BOOST */
1021#define WM8994_IN1RP_MIXINR_BOOST_WIDTH 1 /* IN1RP_MIXINR_BOOST */
1022#define WM8994_IN1LP_MIXINL_BOOST 0x0080 /* IN1LP_MIXINL_BOOST */
1023#define WM8994_IN1LP_MIXINL_BOOST_MASK 0x0080 /* IN1LP_MIXINL_BOOST */
1024#define WM8994_IN1LP_MIXINL_BOOST_SHIFT 7 /* IN1LP_MIXINL_BOOST */
1025#define WM8994_IN1LP_MIXINL_BOOST_WIDTH 1 /* IN1LP_MIXINL_BOOST */
1026#define WM8994_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */
1027#define WM8994_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */
1028#define WM8994_INPUTS_CLAMP_SHIFT 6 /* INPUTS_CLAMP */
1029#define WM8994_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */
1030
1031/*
1032 * R24 (0x18) - Left Line Input 1&2 Volume
1033 */
1034#define WM8994_IN1_VU 0x0100 /* IN1_VU */
1035#define WM8994_IN1_VU_MASK 0x0100 /* IN1_VU */
1036#define WM8994_IN1_VU_SHIFT 8 /* IN1_VU */
1037#define WM8994_IN1_VU_WIDTH 1 /* IN1_VU */
1038#define WM8994_IN1L_MUTE 0x0080 /* IN1L_MUTE */
1039#define WM8994_IN1L_MUTE_MASK 0x0080 /* IN1L_MUTE */
1040#define WM8994_IN1L_MUTE_SHIFT 7 /* IN1L_MUTE */
1041#define WM8994_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
1042#define WM8994_IN1L_ZC 0x0040 /* IN1L_ZC */
1043#define WM8994_IN1L_ZC_MASK 0x0040 /* IN1L_ZC */
1044#define WM8994_IN1L_ZC_SHIFT 6 /* IN1L_ZC */
1045#define WM8994_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
1046#define WM8994_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
1047#define WM8994_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
1048#define WM8994_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
1049
1050/*
1051 * R25 (0x19) - Left Line Input 3&4 Volume
1052 */
1053#define WM8994_IN2_VU 0x0100 /* IN2_VU */
1054#define WM8994_IN2_VU_MASK 0x0100 /* IN2_VU */
1055#define WM8994_IN2_VU_SHIFT 8 /* IN2_VU */
1056#define WM8994_IN2_VU_WIDTH 1 /* IN2_VU */
1057#define WM8994_IN2L_MUTE 0x0080 /* IN2L_MUTE */
1058#define WM8994_IN2L_MUTE_MASK 0x0080 /* IN2L_MUTE */
1059#define WM8994_IN2L_MUTE_SHIFT 7 /* IN2L_MUTE */
1060#define WM8994_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
1061#define WM8994_IN2L_ZC 0x0040 /* IN2L_ZC */
1062#define WM8994_IN2L_ZC_MASK 0x0040 /* IN2L_ZC */
1063#define WM8994_IN2L_ZC_SHIFT 6 /* IN2L_ZC */
1064#define WM8994_IN2L_ZC_WIDTH 1 /* IN2L_ZC */
1065#define WM8994_IN2L_VOL_MASK 0x001F /* IN2L_VOL - [4:0] */
1066#define WM8994_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [4:0] */
1067#define WM8994_IN2L_VOL_WIDTH 5 /* IN2L_VOL - [4:0] */
1068
1069/*
1070 * R26 (0x1A) - Right Line Input 1&2 Volume
1071 */
1072#define WM8994_IN1_VU 0x0100 /* IN1_VU */
1073#define WM8994_IN1_VU_MASK 0x0100 /* IN1_VU */
1074#define WM8994_IN1_VU_SHIFT 8 /* IN1_VU */
1075#define WM8994_IN1_VU_WIDTH 1 /* IN1_VU */
1076#define WM8994_IN1R_MUTE 0x0080 /* IN1R_MUTE */
1077#define WM8994_IN1R_MUTE_MASK 0x0080 /* IN1R_MUTE */
1078#define WM8994_IN1R_MUTE_SHIFT 7 /* IN1R_MUTE */
1079#define WM8994_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
1080#define WM8994_IN1R_ZC 0x0040 /* IN1R_ZC */
1081#define WM8994_IN1R_ZC_MASK 0x0040 /* IN1R_ZC */
1082#define WM8994_IN1R_ZC_SHIFT 6 /* IN1R_ZC */
1083#define WM8994_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
1084#define WM8994_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
1085#define WM8994_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
1086#define WM8994_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
1087
1088/*
1089 * R27 (0x1B) - Right Line Input 3&4 Volume
1090 */
1091#define WM8994_IN2_VU 0x0100 /* IN2_VU */
1092#define WM8994_IN2_VU_MASK 0x0100 /* IN2_VU */
1093#define WM8994_IN2_VU_SHIFT 8 /* IN2_VU */
1094#define WM8994_IN2_VU_WIDTH 1 /* IN2_VU */
1095#define WM8994_IN2R_MUTE 0x0080 /* IN2R_MUTE */
1096#define WM8994_IN2R_MUTE_MASK 0x0080 /* IN2R_MUTE */
1097#define WM8994_IN2R_MUTE_SHIFT 7 /* IN2R_MUTE */
1098#define WM8994_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
1099#define WM8994_IN2R_ZC 0x0040 /* IN2R_ZC */
1100#define WM8994_IN2R_ZC_MASK 0x0040 /* IN2R_ZC */
1101#define WM8994_IN2R_ZC_SHIFT 6 /* IN2R_ZC */
1102#define WM8994_IN2R_ZC_WIDTH 1 /* IN2R_ZC */
1103#define WM8994_IN2R_VOL_MASK 0x001F /* IN2R_VOL - [4:0] */
1104#define WM8994_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [4:0] */
1105#define WM8994_IN2R_VOL_WIDTH 5 /* IN2R_VOL - [4:0] */
1106
1107/*
1108 * R28 (0x1C) - Left Output Volume
1109 */
1110#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */
1111#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
1112#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
1113#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
1114#define WM8994_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
1115#define WM8994_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
1116#define WM8994_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
1117#define WM8994_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
1118#define WM8994_HPOUT1L_MUTE_N 0x0040 /* HPOUT1L_MUTE_N */
1119#define WM8994_HPOUT1L_MUTE_N_MASK 0x0040 /* HPOUT1L_MUTE_N */
1120#define WM8994_HPOUT1L_MUTE_N_SHIFT 6 /* HPOUT1L_MUTE_N */
1121#define WM8994_HPOUT1L_MUTE_N_WIDTH 1 /* HPOUT1L_MUTE_N */
1122#define WM8994_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
1123#define WM8994_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
1124#define WM8994_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
1125
1126/*
1127 * R29 (0x1D) - Right Output Volume
1128 */
1129#define WM8994_HPOUT1_VU 0x0100 /* HPOUT1_VU */
1130#define WM8994_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
1131#define WM8994_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
1132#define WM8994_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
1133#define WM8994_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
1134#define WM8994_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
1135#define WM8994_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
1136#define WM8994_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
1137#define WM8994_HPOUT1R_MUTE_N 0x0040 /* HPOUT1R_MUTE_N */
1138#define WM8994_HPOUT1R_MUTE_N_MASK 0x0040 /* HPOUT1R_MUTE_N */
1139#define WM8994_HPOUT1R_MUTE_N_SHIFT 6 /* HPOUT1R_MUTE_N */
1140#define WM8994_HPOUT1R_MUTE_N_WIDTH 1 /* HPOUT1R_MUTE_N */
1141#define WM8994_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
1142#define WM8994_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
1143#define WM8994_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
1144
1145/*
1146 * R30 (0x1E) - Line Outputs Volume
1147 */
1148#define WM8994_LINEOUT1N_MUTE 0x0040 /* LINEOUT1N_MUTE */
1149#define WM8994_LINEOUT1N_MUTE_MASK 0x0040 /* LINEOUT1N_MUTE */
1150#define WM8994_LINEOUT1N_MUTE_SHIFT 6 /* LINEOUT1N_MUTE */
1151#define WM8994_LINEOUT1N_MUTE_WIDTH 1 /* LINEOUT1N_MUTE */
1152#define WM8994_LINEOUT1P_MUTE 0x0020 /* LINEOUT1P_MUTE */
1153#define WM8994_LINEOUT1P_MUTE_MASK 0x0020 /* LINEOUT1P_MUTE */
1154#define WM8994_LINEOUT1P_MUTE_SHIFT 5 /* LINEOUT1P_MUTE */
1155#define WM8994_LINEOUT1P_MUTE_WIDTH 1 /* LINEOUT1P_MUTE */
1156#define WM8994_LINEOUT1_VOL 0x0010 /* LINEOUT1_VOL */
1157#define WM8994_LINEOUT1_VOL_MASK 0x0010 /* LINEOUT1_VOL */
1158#define WM8994_LINEOUT1_VOL_SHIFT 4 /* LINEOUT1_VOL */
1159#define WM8994_LINEOUT1_VOL_WIDTH 1 /* LINEOUT1_VOL */
1160#define WM8994_LINEOUT2N_MUTE 0x0004 /* LINEOUT2N_MUTE */
1161#define WM8994_LINEOUT2N_MUTE_MASK 0x0004 /* LINEOUT2N_MUTE */
1162#define WM8994_LINEOUT2N_MUTE_SHIFT 2 /* LINEOUT2N_MUTE */
1163#define WM8994_LINEOUT2N_MUTE_WIDTH 1 /* LINEOUT2N_MUTE */
1164#define WM8994_LINEOUT2P_MUTE 0x0002 /* LINEOUT2P_MUTE */
1165#define WM8994_LINEOUT2P_MUTE_MASK 0x0002 /* LINEOUT2P_MUTE */
1166#define WM8994_LINEOUT2P_MUTE_SHIFT 1 /* LINEOUT2P_MUTE */
1167#define WM8994_LINEOUT2P_MUTE_WIDTH 1 /* LINEOUT2P_MUTE */
1168#define WM8994_LINEOUT2_VOL 0x0001 /* LINEOUT2_VOL */
1169#define WM8994_LINEOUT2_VOL_MASK 0x0001 /* LINEOUT2_VOL */
1170#define WM8994_LINEOUT2_VOL_SHIFT 0 /* LINEOUT2_VOL */
1171#define WM8994_LINEOUT2_VOL_WIDTH 1 /* LINEOUT2_VOL */
1172
1173/*
1174 * R31 (0x1F) - HPOUT2 Volume
1175 */
1176#define WM8994_HPOUT2_MUTE 0x0020 /* HPOUT2_MUTE */
1177#define WM8994_HPOUT2_MUTE_MASK 0x0020 /* HPOUT2_MUTE */
1178#define WM8994_HPOUT2_MUTE_SHIFT 5 /* HPOUT2_MUTE */
1179#define WM8994_HPOUT2_MUTE_WIDTH 1 /* HPOUT2_MUTE */
1180#define WM8994_HPOUT2_VOL 0x0010 /* HPOUT2_VOL */
1181#define WM8994_HPOUT2_VOL_MASK 0x0010 /* HPOUT2_VOL */
1182#define WM8994_HPOUT2_VOL_SHIFT 4 /* HPOUT2_VOL */
1183#define WM8994_HPOUT2_VOL_WIDTH 1 /* HPOUT2_VOL */
1184
1185/*
1186 * R32 (0x20) - Left OPGA Volume
1187 */
1188#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */
1189#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
1190#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
1191#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
1192#define WM8994_MIXOUTL_ZC 0x0080 /* MIXOUTL_ZC */
1193#define WM8994_MIXOUTL_ZC_MASK 0x0080 /* MIXOUTL_ZC */
1194#define WM8994_MIXOUTL_ZC_SHIFT 7 /* MIXOUTL_ZC */
1195#define WM8994_MIXOUTL_ZC_WIDTH 1 /* MIXOUTL_ZC */
1196#define WM8994_MIXOUTL_MUTE_N 0x0040 /* MIXOUTL_MUTE_N */
1197#define WM8994_MIXOUTL_MUTE_N_MASK 0x0040 /* MIXOUTL_MUTE_N */
1198#define WM8994_MIXOUTL_MUTE_N_SHIFT 6 /* MIXOUTL_MUTE_N */
1199#define WM8994_MIXOUTL_MUTE_N_WIDTH 1 /* MIXOUTL_MUTE_N */
1200#define WM8994_MIXOUTL_VOL_MASK 0x003F /* MIXOUTL_VOL - [5:0] */
1201#define WM8994_MIXOUTL_VOL_SHIFT 0 /* MIXOUTL_VOL - [5:0] */
1202#define WM8994_MIXOUTL_VOL_WIDTH 6 /* MIXOUTL_VOL - [5:0] */
1203
1204/*
1205 * R33 (0x21) - Right OPGA Volume
1206 */
1207#define WM8994_MIXOUT_VU 0x0100 /* MIXOUT_VU */
1208#define WM8994_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
1209#define WM8994_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
1210#define WM8994_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
1211#define WM8994_MIXOUTR_ZC 0x0080 /* MIXOUTR_ZC */
1212#define WM8994_MIXOUTR_ZC_MASK 0x0080 /* MIXOUTR_ZC */
1213#define WM8994_MIXOUTR_ZC_SHIFT 7 /* MIXOUTR_ZC */
1214#define WM8994_MIXOUTR_ZC_WIDTH 1 /* MIXOUTR_ZC */
1215#define WM8994_MIXOUTR_MUTE_N 0x0040 /* MIXOUTR_MUTE_N */
1216#define WM8994_MIXOUTR_MUTE_N_MASK 0x0040 /* MIXOUTR_MUTE_N */
1217#define WM8994_MIXOUTR_MUTE_N_SHIFT 6 /* MIXOUTR_MUTE_N */
1218#define WM8994_MIXOUTR_MUTE_N_WIDTH 1 /* MIXOUTR_MUTE_N */
1219#define WM8994_MIXOUTR_VOL_MASK 0x003F /* MIXOUTR_VOL - [5:0] */
1220#define WM8994_MIXOUTR_VOL_SHIFT 0 /* MIXOUTR_VOL - [5:0] */
1221#define WM8994_MIXOUTR_VOL_WIDTH 6 /* MIXOUTR_VOL - [5:0] */
1222
1223/*
1224 * R34 (0x22) - SPKMIXL Attenuation
1225 */
1226#define WM8994_DAC2L_SPKMIXL_VOL 0x0040 /* DAC2L_SPKMIXL_VOL */
1227#define WM8994_DAC2L_SPKMIXL_VOL_MASK 0x0040 /* DAC2L_SPKMIXL_VOL */
1228#define WM8994_DAC2L_SPKMIXL_VOL_SHIFT 6 /* DAC2L_SPKMIXL_VOL */
1229#define WM8994_DAC2L_SPKMIXL_VOL_WIDTH 1 /* DAC2L_SPKMIXL_VOL */
1230#define WM8994_MIXINL_SPKMIXL_VOL 0x0020 /* MIXINL_SPKMIXL_VOL */
1231#define WM8994_MIXINL_SPKMIXL_VOL_MASK 0x0020 /* MIXINL_SPKMIXL_VOL */
1232#define WM8994_MIXINL_SPKMIXL_VOL_SHIFT 5 /* MIXINL_SPKMIXL_VOL */
1233#define WM8994_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
1234#define WM8994_IN1LP_SPKMIXL_VOL 0x0010 /* IN1LP_SPKMIXL_VOL */
1235#define WM8994_IN1LP_SPKMIXL_VOL_MASK 0x0010 /* IN1LP_SPKMIXL_VOL */
1236#define WM8994_IN1LP_SPKMIXL_VOL_SHIFT 4 /* IN1LP_SPKMIXL_VOL */
1237#define WM8994_IN1LP_SPKMIXL_VOL_WIDTH 1 /* IN1LP_SPKMIXL_VOL */
1238#define WM8994_MIXOUTL_SPKMIXL_VOL 0x0008 /* MIXOUTL_SPKMIXL_VOL */
1239#define WM8994_MIXOUTL_SPKMIXL_VOL_MASK 0x0008 /* MIXOUTL_SPKMIXL_VOL */
1240#define WM8994_MIXOUTL_SPKMIXL_VOL_SHIFT 3 /* MIXOUTL_SPKMIXL_VOL */
1241#define WM8994_MIXOUTL_SPKMIXL_VOL_WIDTH 1 /* MIXOUTL_SPKMIXL_VOL */
1242#define WM8994_DAC1L_SPKMIXL_VOL 0x0004 /* DAC1L_SPKMIXL_VOL */
1243#define WM8994_DAC1L_SPKMIXL_VOL_MASK 0x0004 /* DAC1L_SPKMIXL_VOL */
1244#define WM8994_DAC1L_SPKMIXL_VOL_SHIFT 2 /* DAC1L_SPKMIXL_VOL */
1245#define WM8994_DAC1L_SPKMIXL_VOL_WIDTH 1 /* DAC1L_SPKMIXL_VOL */
1246#define WM8994_SPKMIXL_VOL_MASK 0x0003 /* SPKMIXL_VOL - [1:0] */
1247#define WM8994_SPKMIXL_VOL_SHIFT 0 /* SPKMIXL_VOL - [1:0] */
1248#define WM8994_SPKMIXL_VOL_WIDTH 2 /* SPKMIXL_VOL - [1:0] */
1249
1250/*
1251 * R35 (0x23) - SPKMIXR Attenuation
1252 */
1253#define WM8994_SPKOUT_CLASSAB 0x0100 /* SPKOUT_CLASSAB */
1254#define WM8994_SPKOUT_CLASSAB_MASK 0x0100 /* SPKOUT_CLASSAB */
1255#define WM8994_SPKOUT_CLASSAB_SHIFT 8 /* SPKOUT_CLASSAB */
1256#define WM8994_SPKOUT_CLASSAB_WIDTH 1 /* SPKOUT_CLASSAB */
1257#define WM8994_DAC2R_SPKMIXR_VOL 0x0040 /* DAC2R_SPKMIXR_VOL */
1258#define WM8994_DAC2R_SPKMIXR_VOL_MASK 0x0040 /* DAC2R_SPKMIXR_VOL */
1259#define WM8994_DAC2R_SPKMIXR_VOL_SHIFT 6 /* DAC2R_SPKMIXR_VOL */
1260#define WM8994_DAC2R_SPKMIXR_VOL_WIDTH 1 /* DAC2R_SPKMIXR_VOL */
1261#define WM8994_MIXINR_SPKMIXR_VOL 0x0020 /* MIXINR_SPKMIXR_VOL */
1262#define WM8994_MIXINR_SPKMIXR_VOL_MASK 0x0020 /* MIXINR_SPKMIXR_VOL */
1263#define WM8994_MIXINR_SPKMIXR_VOL_SHIFT 5 /* MIXINR_SPKMIXR_VOL */
1264#define WM8994_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
1265#define WM8994_IN1RP_SPKMIXR_VOL 0x0010 /* IN1RP_SPKMIXR_VOL */
1266#define WM8994_IN1RP_SPKMIXR_VOL_MASK 0x0010 /* IN1RP_SPKMIXR_VOL */
1267#define WM8994_IN1RP_SPKMIXR_VOL_SHIFT 4 /* IN1RP_SPKMIXR_VOL */
1268#define WM8994_IN1RP_SPKMIXR_VOL_WIDTH 1 /* IN1RP_SPKMIXR_VOL */
1269#define WM8994_MIXOUTR_SPKMIXR_VOL 0x0008 /* MIXOUTR_SPKMIXR_VOL */
1270#define WM8994_MIXOUTR_SPKMIXR_VOL_MASK 0x0008 /* MIXOUTR_SPKMIXR_VOL */
1271#define WM8994_MIXOUTR_SPKMIXR_VOL_SHIFT 3 /* MIXOUTR_SPKMIXR_VOL */
1272#define WM8994_MIXOUTR_SPKMIXR_VOL_WIDTH 1 /* MIXOUTR_SPKMIXR_VOL */
1273#define WM8994_DAC1R_SPKMIXR_VOL 0x0004 /* DAC1R_SPKMIXR_VOL */
1274#define WM8994_DAC1R_SPKMIXR_VOL_MASK 0x0004 /* DAC1R_SPKMIXR_VOL */
1275#define WM8994_DAC1R_SPKMIXR_VOL_SHIFT 2 /* DAC1R_SPKMIXR_VOL */
1276#define WM8994_DAC1R_SPKMIXR_VOL_WIDTH 1 /* DAC1R_SPKMIXR_VOL */
1277#define WM8994_SPKMIXR_VOL_MASK 0x0003 /* SPKMIXR_VOL - [1:0] */
1278#define WM8994_SPKMIXR_VOL_SHIFT 0 /* SPKMIXR_VOL - [1:0] */
1279#define WM8994_SPKMIXR_VOL_WIDTH 2 /* SPKMIXR_VOL - [1:0] */
1280
1281/*
1282 * R36 (0x24) - SPKOUT Mixers
1283 */
1284#define WM8994_IN2LRP_TO_SPKOUTL 0x0020 /* IN2LRP_TO_SPKOUTL */
1285#define WM8994_IN2LRP_TO_SPKOUTL_MASK 0x0020 /* IN2LRP_TO_SPKOUTL */
1286#define WM8994_IN2LRP_TO_SPKOUTL_SHIFT 5 /* IN2LRP_TO_SPKOUTL */
1287#define WM8994_IN2LRP_TO_SPKOUTL_WIDTH 1 /* IN2LRP_TO_SPKOUTL */
1288#define WM8994_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
1289#define WM8994_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
1290#define WM8994_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
1291#define WM8994_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
1292#define WM8994_SPKMIXR_TO_SPKOUTL 0x0008 /* SPKMIXR_TO_SPKOUTL */
1293#define WM8994_SPKMIXR_TO_SPKOUTL_MASK 0x0008 /* SPKMIXR_TO_SPKOUTL */
1294#define WM8994_SPKMIXR_TO_SPKOUTL_SHIFT 3 /* SPKMIXR_TO_SPKOUTL */
1295#define WM8994_SPKMIXR_TO_SPKOUTL_WIDTH 1 /* SPKMIXR_TO_SPKOUTL */
1296#define WM8994_IN2LRP_TO_SPKOUTR 0x0004 /* IN2LRP_TO_SPKOUTR */
1297#define WM8994_IN2LRP_TO_SPKOUTR_MASK 0x0004 /* IN2LRP_TO_SPKOUTR */
1298#define WM8994_IN2LRP_TO_SPKOUTR_SHIFT 2 /* IN2LRP_TO_SPKOUTR */
1299#define WM8994_IN2LRP_TO_SPKOUTR_WIDTH 1 /* IN2LRP_TO_SPKOUTR */
1300#define WM8994_SPKMIXL_TO_SPKOUTR 0x0002 /* SPKMIXL_TO_SPKOUTR */
1301#define WM8994_SPKMIXL_TO_SPKOUTR_MASK 0x0002 /* SPKMIXL_TO_SPKOUTR */
1302#define WM8994_SPKMIXL_TO_SPKOUTR_SHIFT 1 /* SPKMIXL_TO_SPKOUTR */
1303#define WM8994_SPKMIXL_TO_SPKOUTR_WIDTH 1 /* SPKMIXL_TO_SPKOUTR */
1304#define WM8994_SPKMIXR_TO_SPKOUTR 0x0001 /* SPKMIXR_TO_SPKOUTR */
1305#define WM8994_SPKMIXR_TO_SPKOUTR_MASK 0x0001 /* SPKMIXR_TO_SPKOUTR */
1306#define WM8994_SPKMIXR_TO_SPKOUTR_SHIFT 0 /* SPKMIXR_TO_SPKOUTR */
1307#define WM8994_SPKMIXR_TO_SPKOUTR_WIDTH 1 /* SPKMIXR_TO_SPKOUTR */
1308
1309/*
1310 * R37 (0x25) - ClassD
1311 */
1312#define WM8994_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
1313#define WM8994_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
1314#define WM8994_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
1315#define WM8994_SPKOUTR_BOOST_MASK 0x0007 /* SPKOUTR_BOOST - [2:0] */
1316#define WM8994_SPKOUTR_BOOST_SHIFT 0 /* SPKOUTR_BOOST - [2:0] */
1317#define WM8994_SPKOUTR_BOOST_WIDTH 3 /* SPKOUTR_BOOST - [2:0] */
1318
1319/*
1320 * R38 (0x26) - Speaker Volume Left
1321 */
1322#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */
1323#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
1324#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
1325#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
1326#define WM8994_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
1327#define WM8994_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
1328#define WM8994_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
1329#define WM8994_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
1330#define WM8994_SPKOUTL_MUTE_N 0x0040 /* SPKOUTL_MUTE_N */
1331#define WM8994_SPKOUTL_MUTE_N_MASK 0x0040 /* SPKOUTL_MUTE_N */
1332#define WM8994_SPKOUTL_MUTE_N_SHIFT 6 /* SPKOUTL_MUTE_N */
1333#define WM8994_SPKOUTL_MUTE_N_WIDTH 1 /* SPKOUTL_MUTE_N */
1334#define WM8994_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
1335#define WM8994_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
1336#define WM8994_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
1337
1338/*
1339 * R39 (0x27) - Speaker Volume Right
1340 */
1341#define WM8994_SPKOUT_VU 0x0100 /* SPKOUT_VU */
1342#define WM8994_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
1343#define WM8994_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
1344#define WM8994_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
1345#define WM8994_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
1346#define WM8994_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
1347#define WM8994_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
1348#define WM8994_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
1349#define WM8994_SPKOUTR_MUTE_N 0x0040 /* SPKOUTR_MUTE_N */
1350#define WM8994_SPKOUTR_MUTE_N_MASK 0x0040 /* SPKOUTR_MUTE_N */
1351#define WM8994_SPKOUTR_MUTE_N_SHIFT 6 /* SPKOUTR_MUTE_N */
1352#define WM8994_SPKOUTR_MUTE_N_WIDTH 1 /* SPKOUTR_MUTE_N */
1353#define WM8994_SPKOUTR_VOL_MASK 0x003F /* SPKOUTR_VOL - [5:0] */
1354#define WM8994_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [5:0] */
1355#define WM8994_SPKOUTR_VOL_WIDTH 6 /* SPKOUTR_VOL - [5:0] */
1356
1357/*
1358 * R40 (0x28) - Input Mixer (2)
1359 */
1360#define WM8994_IN2LP_TO_IN2L 0x0080 /* IN2LP_TO_IN2L */
1361#define WM8994_IN2LP_TO_IN2L_MASK 0x0080 /* IN2LP_TO_IN2L */
1362#define WM8994_IN2LP_TO_IN2L_SHIFT 7 /* IN2LP_TO_IN2L */
1363#define WM8994_IN2LP_TO_IN2L_WIDTH 1 /* IN2LP_TO_IN2L */
1364#define WM8994_IN2LN_TO_IN2L 0x0040 /* IN2LN_TO_IN2L */
1365#define WM8994_IN2LN_TO_IN2L_MASK 0x0040 /* IN2LN_TO_IN2L */
1366#define WM8994_IN2LN_TO_IN2L_SHIFT 6 /* IN2LN_TO_IN2L */
1367#define WM8994_IN2LN_TO_IN2L_WIDTH 1 /* IN2LN_TO_IN2L */
1368#define WM8994_IN1LP_TO_IN1L 0x0020 /* IN1LP_TO_IN1L */
1369#define WM8994_IN1LP_TO_IN1L_MASK 0x0020 /* IN1LP_TO_IN1L */
1370#define WM8994_IN1LP_TO_IN1L_SHIFT 5 /* IN1LP_TO_IN1L */
1371#define WM8994_IN1LP_TO_IN1L_WIDTH 1 /* IN1LP_TO_IN1L */
1372#define WM8994_IN1LN_TO_IN1L 0x0010 /* IN1LN_TO_IN1L */
1373#define WM8994_IN1LN_TO_IN1L_MASK 0x0010 /* IN1LN_TO_IN1L */
1374#define WM8994_IN1LN_TO_IN1L_SHIFT 4 /* IN1LN_TO_IN1L */
1375#define WM8994_IN1LN_TO_IN1L_WIDTH 1 /* IN1LN_TO_IN1L */
1376#define WM8994_IN2RP_TO_IN2R 0x0008 /* IN2RP_TO_IN2R */
1377#define WM8994_IN2RP_TO_IN2R_MASK 0x0008 /* IN2RP_TO_IN2R */
1378#define WM8994_IN2RP_TO_IN2R_SHIFT 3 /* IN2RP_TO_IN2R */
1379#define WM8994_IN2RP_TO_IN2R_WIDTH 1 /* IN2RP_TO_IN2R */
1380#define WM8994_IN2RN_TO_IN2R 0x0004 /* IN2RN_TO_IN2R */
1381#define WM8994_IN2RN_TO_IN2R_MASK 0x0004 /* IN2RN_TO_IN2R */
1382#define WM8994_IN2RN_TO_IN2R_SHIFT 2 /* IN2RN_TO_IN2R */
1383#define WM8994_IN2RN_TO_IN2R_WIDTH 1 /* IN2RN_TO_IN2R */
1384#define WM8994_IN1RP_TO_IN1R 0x0002 /* IN1RP_TO_IN1R */
1385#define WM8994_IN1RP_TO_IN1R_MASK 0x0002 /* IN1RP_TO_IN1R */
1386#define WM8994_IN1RP_TO_IN1R_SHIFT 1 /* IN1RP_TO_IN1R */
1387#define WM8994_IN1RP_TO_IN1R_WIDTH 1 /* IN1RP_TO_IN1R */
1388#define WM8994_IN1RN_TO_IN1R 0x0001 /* IN1RN_TO_IN1R */
1389#define WM8994_IN1RN_TO_IN1R_MASK 0x0001 /* IN1RN_TO_IN1R */
1390#define WM8994_IN1RN_TO_IN1R_SHIFT 0 /* IN1RN_TO_IN1R */
1391#define WM8994_IN1RN_TO_IN1R_WIDTH 1 /* IN1RN_TO_IN1R */
1392
1393/*
1394 * R41 (0x29) - Input Mixer (3)
1395 */
1396#define WM8994_IN2L_TO_MIXINL 0x0100 /* IN2L_TO_MIXINL */
1397#define WM8994_IN2L_TO_MIXINL_MASK 0x0100 /* IN2L_TO_MIXINL */
1398#define WM8994_IN2L_TO_MIXINL_SHIFT 8 /* IN2L_TO_MIXINL */
1399#define WM8994_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
1400#define WM8994_IN2L_MIXINL_VOL 0x0080 /* IN2L_MIXINL_VOL */
1401#define WM8994_IN2L_MIXINL_VOL_MASK 0x0080 /* IN2L_MIXINL_VOL */
1402#define WM8994_IN2L_MIXINL_VOL_SHIFT 7 /* IN2L_MIXINL_VOL */
1403#define WM8994_IN2L_MIXINL_VOL_WIDTH 1 /* IN2L_MIXINL_VOL */
1404#define WM8994_IN1L_TO_MIXINL 0x0020 /* IN1L_TO_MIXINL */
1405#define WM8994_IN1L_TO_MIXINL_MASK 0x0020 /* IN1L_TO_MIXINL */
1406#define WM8994_IN1L_TO_MIXINL_SHIFT 5 /* IN1L_TO_MIXINL */
1407#define WM8994_IN1L_TO_MIXINL_WIDTH 1 /* IN1L_TO_MIXINL */
1408#define WM8994_IN1L_MIXINL_VOL 0x0010 /* IN1L_MIXINL_VOL */
1409#define WM8994_IN1L_MIXINL_VOL_MASK 0x0010 /* IN1L_MIXINL_VOL */
1410#define WM8994_IN1L_MIXINL_VOL_SHIFT 4 /* IN1L_MIXINL_VOL */
1411#define WM8994_IN1L_MIXINL_VOL_WIDTH 1 /* IN1L_MIXINL_VOL */
1412#define WM8994_MIXOUTL_MIXINL_VOL_MASK 0x0007 /* MIXOUTL_MIXINL_VOL - [2:0] */
1413#define WM8994_MIXOUTL_MIXINL_VOL_SHIFT 0 /* MIXOUTL_MIXINL_VOL - [2:0] */
1414#define WM8994_MIXOUTL_MIXINL_VOL_WIDTH 3 /* MIXOUTL_MIXINL_VOL - [2:0] */
1415
1416/*
1417 * R42 (0x2A) - Input Mixer (4)
1418 */
1419#define WM8994_IN2R_TO_MIXINR 0x0100 /* IN2R_TO_MIXINR */
1420#define WM8994_IN2R_TO_MIXINR_MASK 0x0100 /* IN2R_TO_MIXINR */
1421#define WM8994_IN2R_TO_MIXINR_SHIFT 8 /* IN2R_TO_MIXINR */
1422#define WM8994_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
1423#define WM8994_IN2R_MIXINR_VOL 0x0080 /* IN2R_MIXINR_VOL */
1424#define WM8994_IN2R_MIXINR_VOL_MASK 0x0080 /* IN2R_MIXINR_VOL */
1425#define WM8994_IN2R_MIXINR_VOL_SHIFT 7 /* IN2R_MIXINR_VOL */
1426#define WM8994_IN2R_MIXINR_VOL_WIDTH 1 /* IN2R_MIXINR_VOL */
1427#define WM8994_IN1R_TO_MIXINR 0x0020 /* IN1R_TO_MIXINR */
1428#define WM8994_IN1R_TO_MIXINR_MASK 0x0020 /* IN1R_TO_MIXINR */
1429#define WM8994_IN1R_TO_MIXINR_SHIFT 5 /* IN1R_TO_MIXINR */
1430#define WM8994_IN1R_TO_MIXINR_WIDTH 1 /* IN1R_TO_MIXINR */
1431#define WM8994_IN1R_MIXINR_VOL 0x0010 /* IN1R_MIXINR_VOL */
1432#define WM8994_IN1R_MIXINR_VOL_MASK 0x0010 /* IN1R_MIXINR_VOL */
1433#define WM8994_IN1R_MIXINR_VOL_SHIFT 4 /* IN1R_MIXINR_VOL */
1434#define WM8994_IN1R_MIXINR_VOL_WIDTH 1 /* IN1R_MIXINR_VOL */
1435#define WM8994_MIXOUTR_MIXINR_VOL_MASK 0x0007 /* MIXOUTR_MIXINR_VOL - [2:0] */
1436#define WM8994_MIXOUTR_MIXINR_VOL_SHIFT 0 /* MIXOUTR_MIXINR_VOL - [2:0] */
1437#define WM8994_MIXOUTR_MIXINR_VOL_WIDTH 3 /* MIXOUTR_MIXINR_VOL - [2:0] */
1438
1439/*
1440 * R43 (0x2B) - Input Mixer (5)
1441 */
1442#define WM8994_IN1LP_MIXINL_VOL_MASK 0x01C0 /* IN1LP_MIXINL_VOL - [8:6] */
1443#define WM8994_IN1LP_MIXINL_VOL_SHIFT 6 /* IN1LP_MIXINL_VOL - [8:6] */
1444#define WM8994_IN1LP_MIXINL_VOL_WIDTH 3 /* IN1LP_MIXINL_VOL - [8:6] */
1445#define WM8994_IN2LRP_MIXINL_VOL_MASK 0x0007 /* IN2LRP_MIXINL_VOL - [2:0] */
1446#define WM8994_IN2LRP_MIXINL_VOL_SHIFT 0 /* IN2LRP_MIXINL_VOL - [2:0] */
1447#define WM8994_IN2LRP_MIXINL_VOL_WIDTH 3 /* IN2LRP_MIXINL_VOL - [2:0] */
1448
1449/*
1450 * R44 (0x2C) - Input Mixer (6)
1451 */
1452#define WM8994_IN1RP_MIXINR_VOL_MASK 0x01C0 /* IN1RP_MIXINR_VOL - [8:6] */
1453#define WM8994_IN1RP_MIXINR_VOL_SHIFT 6 /* IN1RP_MIXINR_VOL - [8:6] */
1454#define WM8994_IN1RP_MIXINR_VOL_WIDTH 3 /* IN1RP_MIXINR_VOL - [8:6] */
1455#define WM8994_IN2LRP_MIXINR_VOL_MASK 0x0007 /* IN2LRP_MIXINR_VOL - [2:0] */
1456#define WM8994_IN2LRP_MIXINR_VOL_SHIFT 0 /* IN2LRP_MIXINR_VOL - [2:0] */
1457#define WM8994_IN2LRP_MIXINR_VOL_WIDTH 3 /* IN2LRP_MIXINR_VOL - [2:0] */
1458
1459/*
1460 * R45 (0x2D) - Output Mixer (1)
1461 */
1462#define WM8994_DAC1L_TO_HPOUT1L 0x0100 /* DAC1L_TO_HPOUT1L */
1463#define WM8994_DAC1L_TO_HPOUT1L_MASK 0x0100 /* DAC1L_TO_HPOUT1L */
1464#define WM8994_DAC1L_TO_HPOUT1L_SHIFT 8 /* DAC1L_TO_HPOUT1L */
1465#define WM8994_DAC1L_TO_HPOUT1L_WIDTH 1 /* DAC1L_TO_HPOUT1L */
1466#define WM8994_MIXINR_TO_MIXOUTL 0x0080 /* MIXINR_TO_MIXOUTL */
1467#define WM8994_MIXINR_TO_MIXOUTL_MASK 0x0080 /* MIXINR_TO_MIXOUTL */
1468#define WM8994_MIXINR_TO_MIXOUTL_SHIFT 7 /* MIXINR_TO_MIXOUTL */
1469#define WM8994_MIXINR_TO_MIXOUTL_WIDTH 1 /* MIXINR_TO_MIXOUTL */
1470#define WM8994_MIXINL_TO_MIXOUTL 0x0040 /* MIXINL_TO_MIXOUTL */
1471#define WM8994_MIXINL_TO_MIXOUTL_MASK 0x0040 /* MIXINL_TO_MIXOUTL */
1472#define WM8994_MIXINL_TO_MIXOUTL_SHIFT 6 /* MIXINL_TO_MIXOUTL */
1473#define WM8994_MIXINL_TO_MIXOUTL_WIDTH 1 /* MIXINL_TO_MIXOUTL */
1474#define WM8994_IN2RN_TO_MIXOUTL 0x0020 /* IN2RN_TO_MIXOUTL */
1475#define WM8994_IN2RN_TO_MIXOUTL_MASK 0x0020 /* IN2RN_TO_MIXOUTL */
1476#define WM8994_IN2RN_TO_MIXOUTL_SHIFT 5 /* IN2RN_TO_MIXOUTL */
1477#define WM8994_IN2RN_TO_MIXOUTL_WIDTH 1 /* IN2RN_TO_MIXOUTL */
1478#define WM8994_IN2LN_TO_MIXOUTL 0x0010 /* IN2LN_TO_MIXOUTL */
1479#define WM8994_IN2LN_TO_MIXOUTL_MASK 0x0010 /* IN2LN_TO_MIXOUTL */
1480#define WM8994_IN2LN_TO_MIXOUTL_SHIFT 4 /* IN2LN_TO_MIXOUTL */
1481#define WM8994_IN2LN_TO_MIXOUTL_WIDTH 1 /* IN2LN_TO_MIXOUTL */
1482#define WM8994_IN1R_TO_MIXOUTL 0x0008 /* IN1R_TO_MIXOUTL */
1483#define WM8994_IN1R_TO_MIXOUTL_MASK 0x0008 /* IN1R_TO_MIXOUTL */
1484#define WM8994_IN1R_TO_MIXOUTL_SHIFT 3 /* IN1R_TO_MIXOUTL */
1485#define WM8994_IN1R_TO_MIXOUTL_WIDTH 1 /* IN1R_TO_MIXOUTL */
1486#define WM8994_IN1L_TO_MIXOUTL 0x0004 /* IN1L_TO_MIXOUTL */
1487#define WM8994_IN1L_TO_MIXOUTL_MASK 0x0004 /* IN1L_TO_MIXOUTL */
1488#define WM8994_IN1L_TO_MIXOUTL_SHIFT 2 /* IN1L_TO_MIXOUTL */
1489#define WM8994_IN1L_TO_MIXOUTL_WIDTH 1 /* IN1L_TO_MIXOUTL */
1490#define WM8994_IN2LP_TO_MIXOUTL 0x0002 /* IN2LP_TO_MIXOUTL */
1491#define WM8994_IN2LP_TO_MIXOUTL_MASK 0x0002 /* IN2LP_TO_MIXOUTL */
1492#define WM8994_IN2LP_TO_MIXOUTL_SHIFT 1 /* IN2LP_TO_MIXOUTL */
1493#define WM8994_IN2LP_TO_MIXOUTL_WIDTH 1 /* IN2LP_TO_MIXOUTL */
1494#define WM8994_DAC1L_TO_MIXOUTL 0x0001 /* DAC1L_TO_MIXOUTL */
1495#define WM8994_DAC1L_TO_MIXOUTL_MASK 0x0001 /* DAC1L_TO_MIXOUTL */
1496#define WM8994_DAC1L_TO_MIXOUTL_SHIFT 0 /* DAC1L_TO_MIXOUTL */
1497#define WM8994_DAC1L_TO_MIXOUTL_WIDTH 1 /* DAC1L_TO_MIXOUTL */
1498
1499/*
1500 * R46 (0x2E) - Output Mixer (2)
1501 */
1502#define WM8994_DAC1R_TO_HPOUT1R 0x0100 /* DAC1R_TO_HPOUT1R */
1503#define WM8994_DAC1R_TO_HPOUT1R_MASK 0x0100 /* DAC1R_TO_HPOUT1R */
1504#define WM8994_DAC1R_TO_HPOUT1R_SHIFT 8 /* DAC1R_TO_HPOUT1R */
1505#define WM8994_DAC1R_TO_HPOUT1R_WIDTH 1 /* DAC1R_TO_HPOUT1R */
1506#define WM8994_MIXINL_TO_MIXOUTR 0x0080 /* MIXINL_TO_MIXOUTR */
1507#define WM8994_MIXINL_TO_MIXOUTR_MASK 0x0080 /* MIXINL_TO_MIXOUTR */
1508#define WM8994_MIXINL_TO_MIXOUTR_SHIFT 7 /* MIXINL_TO_MIXOUTR */
1509#define WM8994_MIXINL_TO_MIXOUTR_WIDTH 1 /* MIXINL_TO_MIXOUTR */
1510#define WM8994_MIXINR_TO_MIXOUTR 0x0040 /* MIXINR_TO_MIXOUTR */
1511#define WM8994_MIXINR_TO_MIXOUTR_MASK 0x0040 /* MIXINR_TO_MIXOUTR */
1512#define WM8994_MIXINR_TO_MIXOUTR_SHIFT 6 /* MIXINR_TO_MIXOUTR */
1513#define WM8994_MIXINR_TO_MIXOUTR_WIDTH 1 /* MIXINR_TO_MIXOUTR */
1514#define WM8994_IN2LN_TO_MIXOUTR 0x0020 /* IN2LN_TO_MIXOUTR */
1515#define WM8994_IN2LN_TO_MIXOUTR_MASK 0x0020 /* IN2LN_TO_MIXOUTR */
1516#define WM8994_IN2LN_TO_MIXOUTR_SHIFT 5 /* IN2LN_TO_MIXOUTR */
1517#define WM8994_IN2LN_TO_MIXOUTR_WIDTH 1 /* IN2LN_TO_MIXOUTR */
1518#define WM8994_IN2RN_TO_MIXOUTR 0x0010 /* IN2RN_TO_MIXOUTR */
1519#define WM8994_IN2RN_TO_MIXOUTR_MASK 0x0010 /* IN2RN_TO_MIXOUTR */
1520#define WM8994_IN2RN_TO_MIXOUTR_SHIFT 4 /* IN2RN_TO_MIXOUTR */
1521#define WM8994_IN2RN_TO_MIXOUTR_WIDTH 1 /* IN2RN_TO_MIXOUTR */
1522#define WM8994_IN1L_TO_MIXOUTR 0x0008 /* IN1L_TO_MIXOUTR */
1523#define WM8994_IN1L_TO_MIXOUTR_MASK 0x0008 /* IN1L_TO_MIXOUTR */
1524#define WM8994_IN1L_TO_MIXOUTR_SHIFT 3 /* IN1L_TO_MIXOUTR */
1525#define WM8994_IN1L_TO_MIXOUTR_WIDTH 1 /* IN1L_TO_MIXOUTR */
1526#define WM8994_IN1R_TO_MIXOUTR 0x0004 /* IN1R_TO_MIXOUTR */
1527#define WM8994_IN1R_TO_MIXOUTR_MASK 0x0004 /* IN1R_TO_MIXOUTR */
1528#define WM8994_IN1R_TO_MIXOUTR_SHIFT 2 /* IN1R_TO_MIXOUTR */
1529#define WM8994_IN1R_TO_MIXOUTR_WIDTH 1 /* IN1R_TO_MIXOUTR */
1530#define WM8994_IN2RP_TO_MIXOUTR 0x0002 /* IN2RP_TO_MIXOUTR */
1531#define WM8994_IN2RP_TO_MIXOUTR_MASK 0x0002 /* IN2RP_TO_MIXOUTR */
1532#define WM8994_IN2RP_TO_MIXOUTR_SHIFT 1 /* IN2RP_TO_MIXOUTR */
1533#define WM8994_IN2RP_TO_MIXOUTR_WIDTH 1 /* IN2RP_TO_MIXOUTR */
1534#define WM8994_DAC1R_TO_MIXOUTR 0x0001 /* DAC1R_TO_MIXOUTR */
1535#define WM8994_DAC1R_TO_MIXOUTR_MASK 0x0001 /* DAC1R_TO_MIXOUTR */
1536#define WM8994_DAC1R_TO_MIXOUTR_SHIFT 0 /* DAC1R_TO_MIXOUTR */
1537#define WM8994_DAC1R_TO_MIXOUTR_WIDTH 1 /* DAC1R_TO_MIXOUTR */
1538
1539/*
1540 * R47 (0x2F) - Output Mixer (3)
1541 */
1542#define WM8994_IN2LP_MIXOUTL_VOL_MASK 0x0E00 /* IN2LP_MIXOUTL_VOL - [11:9] */
1543#define WM8994_IN2LP_MIXOUTL_VOL_SHIFT 9 /* IN2LP_MIXOUTL_VOL - [11:9] */
1544#define WM8994_IN2LP_MIXOUTL_VOL_WIDTH 3 /* IN2LP_MIXOUTL_VOL - [11:9] */
1545#define WM8994_IN2LN_MIXOUTL_VOL_MASK 0x01C0 /* IN2LN_MIXOUTL_VOL - [8:6] */
1546#define WM8994_IN2LN_MIXOUTL_VOL_SHIFT 6 /* IN2LN_MIXOUTL_VOL - [8:6] */
1547#define WM8994_IN2LN_MIXOUTL_VOL_WIDTH 3 /* IN2LN_MIXOUTL_VOL - [8:6] */
1548#define WM8994_IN1R_MIXOUTL_VOL_MASK 0x0038 /* IN1R_MIXOUTL_VOL - [5:3] */
1549#define WM8994_IN1R_MIXOUTL_VOL_SHIFT 3 /* IN1R_MIXOUTL_VOL - [5:3] */
1550#define WM8994_IN1R_MIXOUTL_VOL_WIDTH 3 /* IN1R_MIXOUTL_VOL - [5:3] */
1551#define WM8994_IN1L_MIXOUTL_VOL_MASK 0x0007 /* IN1L_MIXOUTL_VOL - [2:0] */
1552#define WM8994_IN1L_MIXOUTL_VOL_SHIFT 0 /* IN1L_MIXOUTL_VOL - [2:0] */
1553#define WM8994_IN1L_MIXOUTL_VOL_WIDTH 3 /* IN1L_MIXOUTL_VOL - [2:0] */
1554
1555/*
1556 * R48 (0x30) - Output Mixer (4)
1557 */
1558#define WM8994_IN2RP_MIXOUTR_VOL_MASK 0x0E00 /* IN2RP_MIXOUTR_VOL - [11:9] */
1559#define WM8994_IN2RP_MIXOUTR_VOL_SHIFT 9 /* IN2RP_MIXOUTR_VOL - [11:9] */
1560#define WM8994_IN2RP_MIXOUTR_VOL_WIDTH 3 /* IN2RP_MIXOUTR_VOL - [11:9] */
1561#define WM8994_IN2RN_MIXOUTR_VOL_MASK 0x01C0 /* IN2RN_MIXOUTR_VOL - [8:6] */
1562#define WM8994_IN2RN_MIXOUTR_VOL_SHIFT 6 /* IN2RN_MIXOUTR_VOL - [8:6] */
1563#define WM8994_IN2RN_MIXOUTR_VOL_WIDTH 3 /* IN2RN_MIXOUTR_VOL - [8:6] */
1564#define WM8994_IN1L_MIXOUTR_VOL_MASK 0x0038 /* IN1L_MIXOUTR_VOL - [5:3] */
1565#define WM8994_IN1L_MIXOUTR_VOL_SHIFT 3 /* IN1L_MIXOUTR_VOL - [5:3] */
1566#define WM8994_IN1L_MIXOUTR_VOL_WIDTH 3 /* IN1L_MIXOUTR_VOL - [5:3] */
1567#define WM8994_IN1R_MIXOUTR_VOL_MASK 0x0007 /* IN1R_MIXOUTR_VOL - [2:0] */
1568#define WM8994_IN1R_MIXOUTR_VOL_SHIFT 0 /* IN1R_MIXOUTR_VOL - [2:0] */
1569#define WM8994_IN1R_MIXOUTR_VOL_WIDTH 3 /* IN1R_MIXOUTR_VOL - [2:0] */
1570
1571/*
1572 * R49 (0x31) - Output Mixer (5)
1573 */
1574#define WM8994_DAC1L_MIXOUTL_VOL_MASK 0x0E00 /* DAC1L_MIXOUTL_VOL - [11:9] */
1575#define WM8994_DAC1L_MIXOUTL_VOL_SHIFT 9 /* DAC1L_MIXOUTL_VOL - [11:9] */
1576#define WM8994_DAC1L_MIXOUTL_VOL_WIDTH 3 /* DAC1L_MIXOUTL_VOL - [11:9] */
1577#define WM8994_IN2RN_MIXOUTL_VOL_MASK 0x01C0 /* IN2RN_MIXOUTL_VOL - [8:6] */
1578#define WM8994_IN2RN_MIXOUTL_VOL_SHIFT 6 /* IN2RN_MIXOUTL_VOL - [8:6] */
1579#define WM8994_IN2RN_MIXOUTL_VOL_WIDTH 3 /* IN2RN_MIXOUTL_VOL - [8:6] */
1580#define WM8994_MIXINR_MIXOUTL_VOL_MASK 0x0038 /* MIXINR_MIXOUTL_VOL - [5:3] */
1581#define WM8994_MIXINR_MIXOUTL_VOL_SHIFT 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
1582#define WM8994_MIXINR_MIXOUTL_VOL_WIDTH 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
1583#define WM8994_MIXINL_MIXOUTL_VOL_MASK 0x0007 /* MIXINL_MIXOUTL_VOL - [2:0] */
1584#define WM8994_MIXINL_MIXOUTL_VOL_SHIFT 0 /* MIXINL_MIXOUTL_VOL - [2:0] */
1585#define WM8994_MIXINL_MIXOUTL_VOL_WIDTH 3 /* MIXINL_MIXOUTL_VOL - [2:0] */
1586
1587/*
1588 * R50 (0x32) - Output Mixer (6)
1589 */
1590#define WM8994_DAC1R_MIXOUTR_VOL_MASK 0x0E00 /* DAC1R_MIXOUTR_VOL - [11:9] */
1591#define WM8994_DAC1R_MIXOUTR_VOL_SHIFT 9 /* DAC1R_MIXOUTR_VOL - [11:9] */
1592#define WM8994_DAC1R_MIXOUTR_VOL_WIDTH 3 /* DAC1R_MIXOUTR_VOL - [11:9] */
1593#define WM8994_IN2LN_MIXOUTR_VOL_MASK 0x01C0 /* IN2LN_MIXOUTR_VOL - [8:6] */
1594#define WM8994_IN2LN_MIXOUTR_VOL_SHIFT 6 /* IN2LN_MIXOUTR_VOL - [8:6] */
1595#define WM8994_IN2LN_MIXOUTR_VOL_WIDTH 3 /* IN2LN_MIXOUTR_VOL - [8:6] */
1596#define WM8994_MIXINL_MIXOUTR_VOL_MASK 0x0038 /* MIXINL_MIXOUTR_VOL - [5:3] */
1597#define WM8994_MIXINL_MIXOUTR_VOL_SHIFT 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
1598#define WM8994_MIXINL_MIXOUTR_VOL_WIDTH 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
1599#define WM8994_MIXINR_MIXOUTR_VOL_MASK 0x0007 /* MIXINR_MIXOUTR_VOL - [2:0] */
1600#define WM8994_MIXINR_MIXOUTR_VOL_SHIFT 0 /* MIXINR_MIXOUTR_VOL - [2:0] */
1601#define WM8994_MIXINR_MIXOUTR_VOL_WIDTH 3 /* MIXINR_MIXOUTR_VOL - [2:0] */
1602
1603/*
1604 * R51 (0x33) - HPOUT2 Mixer
1605 */
1606#define WM8994_IN2LRP_TO_HPOUT2 0x0020 /* IN2LRP_TO_HPOUT2 */
1607#define WM8994_IN2LRP_TO_HPOUT2_MASK 0x0020 /* IN2LRP_TO_HPOUT2 */
1608#define WM8994_IN2LRP_TO_HPOUT2_SHIFT 5 /* IN2LRP_TO_HPOUT2 */
1609#define WM8994_IN2LRP_TO_HPOUT2_WIDTH 1 /* IN2LRP_TO_HPOUT2 */
1610#define WM8994_MIXOUTLVOL_TO_HPOUT2 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
1611#define WM8994_MIXOUTLVOL_TO_HPOUT2_MASK 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
1612#define WM8994_MIXOUTLVOL_TO_HPOUT2_SHIFT 4 /* MIXOUTLVOL_TO_HPOUT2 */
1613#define WM8994_MIXOUTLVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTLVOL_TO_HPOUT2 */
1614#define WM8994_MIXOUTRVOL_TO_HPOUT2 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
1615#define WM8994_MIXOUTRVOL_TO_HPOUT2_MASK 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
1616#define WM8994_MIXOUTRVOL_TO_HPOUT2_SHIFT 3 /* MIXOUTRVOL_TO_HPOUT2 */
1617#define WM8994_MIXOUTRVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTRVOL_TO_HPOUT2 */
1618
1619/*
1620 * R52 (0x34) - Line Mixer (1)
1621 */
1622#define WM8994_MIXOUTL_TO_LINEOUT1N 0x0040 /* MIXOUTL_TO_LINEOUT1N */
1623#define WM8994_MIXOUTL_TO_LINEOUT1N_MASK 0x0040 /* MIXOUTL_TO_LINEOUT1N */
1624#define WM8994_MIXOUTL_TO_LINEOUT1N_SHIFT 6 /* MIXOUTL_TO_LINEOUT1N */
1625#define WM8994_MIXOUTL_TO_LINEOUT1N_WIDTH 1 /* MIXOUTL_TO_LINEOUT1N */
1626#define WM8994_MIXOUTR_TO_LINEOUT1N 0x0020 /* MIXOUTR_TO_LINEOUT1N */
1627#define WM8994_MIXOUTR_TO_LINEOUT1N_MASK 0x0020 /* MIXOUTR_TO_LINEOUT1N */
1628#define WM8994_MIXOUTR_TO_LINEOUT1N_SHIFT 5 /* MIXOUTR_TO_LINEOUT1N */
1629#define WM8994_MIXOUTR_TO_LINEOUT1N_WIDTH 1 /* MIXOUTR_TO_LINEOUT1N */
1630#define WM8994_LINEOUT1_MODE 0x0010 /* LINEOUT1_MODE */
1631#define WM8994_LINEOUT1_MODE_MASK 0x0010 /* LINEOUT1_MODE */
1632#define WM8994_LINEOUT1_MODE_SHIFT 4 /* LINEOUT1_MODE */
1633#define WM8994_LINEOUT1_MODE_WIDTH 1 /* LINEOUT1_MODE */
1634#define WM8994_IN1R_TO_LINEOUT1P 0x0004 /* IN1R_TO_LINEOUT1P */
1635#define WM8994_IN1R_TO_LINEOUT1P_MASK 0x0004 /* IN1R_TO_LINEOUT1P */
1636#define WM8994_IN1R_TO_LINEOUT1P_SHIFT 2 /* IN1R_TO_LINEOUT1P */
1637#define WM8994_IN1R_TO_LINEOUT1P_WIDTH 1 /* IN1R_TO_LINEOUT1P */
1638#define WM8994_IN1L_TO_LINEOUT1P 0x0002 /* IN1L_TO_LINEOUT1P */
1639#define WM8994_IN1L_TO_LINEOUT1P_MASK 0x0002 /* IN1L_TO_LINEOUT1P */
1640#define WM8994_IN1L_TO_LINEOUT1P_SHIFT 1 /* IN1L_TO_LINEOUT1P */
1641#define WM8994_IN1L_TO_LINEOUT1P_WIDTH 1 /* IN1L_TO_LINEOUT1P */
1642#define WM8994_MIXOUTL_TO_LINEOUT1P 0x0001 /* MIXOUTL_TO_LINEOUT1P */
1643#define WM8994_MIXOUTL_TO_LINEOUT1P_MASK 0x0001 /* MIXOUTL_TO_LINEOUT1P */
1644#define WM8994_MIXOUTL_TO_LINEOUT1P_SHIFT 0 /* MIXOUTL_TO_LINEOUT1P */
1645#define WM8994_MIXOUTL_TO_LINEOUT1P_WIDTH 1 /* MIXOUTL_TO_LINEOUT1P */
1646
1647/*
1648 * R53 (0x35) - Line Mixer (2)
1649 */
1650#define WM8994_MIXOUTR_TO_LINEOUT2N 0x0040 /* MIXOUTR_TO_LINEOUT2N */
1651#define WM8994_MIXOUTR_TO_LINEOUT2N_MASK 0x0040 /* MIXOUTR_TO_LINEOUT2N */
1652#define WM8994_MIXOUTR_TO_LINEOUT2N_SHIFT 6 /* MIXOUTR_TO_LINEOUT2N */
1653#define WM8994_MIXOUTR_TO_LINEOUT2N_WIDTH 1 /* MIXOUTR_TO_LINEOUT2N */
1654#define WM8994_MIXOUTL_TO_LINEOUT2N 0x0020 /* MIXOUTL_TO_LINEOUT2N */
1655#define WM8994_MIXOUTL_TO_LINEOUT2N_MASK 0x0020 /* MIXOUTL_TO_LINEOUT2N */
1656#define WM8994_MIXOUTL_TO_LINEOUT2N_SHIFT 5 /* MIXOUTL_TO_LINEOUT2N */
1657#define WM8994_MIXOUTL_TO_LINEOUT2N_WIDTH 1 /* MIXOUTL_TO_LINEOUT2N */
1658#define WM8994_LINEOUT2_MODE 0x0010 /* LINEOUT2_MODE */
1659#define WM8994_LINEOUT2_MODE_MASK 0x0010 /* LINEOUT2_MODE */
1660#define WM8994_LINEOUT2_MODE_SHIFT 4 /* LINEOUT2_MODE */
1661#define WM8994_LINEOUT2_MODE_WIDTH 1 /* LINEOUT2_MODE */
1662#define WM8994_IN1L_TO_LINEOUT2P 0x0004 /* IN1L_TO_LINEOUT2P */
1663#define WM8994_IN1L_TO_LINEOUT2P_MASK 0x0004 /* IN1L_TO_LINEOUT2P */
1664#define WM8994_IN1L_TO_LINEOUT2P_SHIFT 2 /* IN1L_TO_LINEOUT2P */
1665#define WM8994_IN1L_TO_LINEOUT2P_WIDTH 1 /* IN1L_TO_LINEOUT2P */
1666#define WM8994_IN1R_TO_LINEOUT2P 0x0002 /* IN1R_TO_LINEOUT2P */
1667#define WM8994_IN1R_TO_LINEOUT2P_MASK 0x0002 /* IN1R_TO_LINEOUT2P */
1668#define WM8994_IN1R_TO_LINEOUT2P_SHIFT 1 /* IN1R_TO_LINEOUT2P */
1669#define WM8994_IN1R_TO_LINEOUT2P_WIDTH 1 /* IN1R_TO_LINEOUT2P */
1670#define WM8994_MIXOUTR_TO_LINEOUT2P 0x0001 /* MIXOUTR_TO_LINEOUT2P */
1671#define WM8994_MIXOUTR_TO_LINEOUT2P_MASK 0x0001 /* MIXOUTR_TO_LINEOUT2P */
1672#define WM8994_MIXOUTR_TO_LINEOUT2P_SHIFT 0 /* MIXOUTR_TO_LINEOUT2P */
1673#define WM8994_MIXOUTR_TO_LINEOUT2P_WIDTH 1 /* MIXOUTR_TO_LINEOUT2P */
1674
1675/*
1676 * R54 (0x36) - Speaker Mixer
1677 */
1678#define WM8994_DAC2L_TO_SPKMIXL 0x0200 /* DAC2L_TO_SPKMIXL */
1679#define WM8994_DAC2L_TO_SPKMIXL_MASK 0x0200 /* DAC2L_TO_SPKMIXL */
1680#define WM8994_DAC2L_TO_SPKMIXL_SHIFT 9 /* DAC2L_TO_SPKMIXL */
1681#define WM8994_DAC2L_TO_SPKMIXL_WIDTH 1 /* DAC2L_TO_SPKMIXL */
1682#define WM8994_DAC2R_TO_SPKMIXR 0x0100 /* DAC2R_TO_SPKMIXR */
1683#define WM8994_DAC2R_TO_SPKMIXR_MASK 0x0100 /* DAC2R_TO_SPKMIXR */
1684#define WM8994_DAC2R_TO_SPKMIXR_SHIFT 8 /* DAC2R_TO_SPKMIXR */
1685#define WM8994_DAC2R_TO_SPKMIXR_WIDTH 1 /* DAC2R_TO_SPKMIXR */
1686#define WM8994_MIXINL_TO_SPKMIXL 0x0080 /* MIXINL_TO_SPKMIXL */
1687#define WM8994_MIXINL_TO_SPKMIXL_MASK 0x0080 /* MIXINL_TO_SPKMIXL */
1688#define WM8994_MIXINL_TO_SPKMIXL_SHIFT 7 /* MIXINL_TO_SPKMIXL */
1689#define WM8994_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
1690#define WM8994_MIXINR_TO_SPKMIXR 0x0040 /* MIXINR_TO_SPKMIXR */
1691#define WM8994_MIXINR_TO_SPKMIXR_MASK 0x0040 /* MIXINR_TO_SPKMIXR */
1692#define WM8994_MIXINR_TO_SPKMIXR_SHIFT 6 /* MIXINR_TO_SPKMIXR */
1693#define WM8994_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
1694#define WM8994_IN1LP_TO_SPKMIXL 0x0020 /* IN1LP_TO_SPKMIXL */
1695#define WM8994_IN1LP_TO_SPKMIXL_MASK 0x0020 /* IN1LP_TO_SPKMIXL */
1696#define WM8994_IN1LP_TO_SPKMIXL_SHIFT 5 /* IN1LP_TO_SPKMIXL */
1697#define WM8994_IN1LP_TO_SPKMIXL_WIDTH 1 /* IN1LP_TO_SPKMIXL */
1698#define WM8994_IN1RP_TO_SPKMIXR 0x0010 /* IN1RP_TO_SPKMIXR */
1699#define WM8994_IN1RP_TO_SPKMIXR_MASK 0x0010 /* IN1RP_TO_SPKMIXR */
1700#define WM8994_IN1RP_TO_SPKMIXR_SHIFT 4 /* IN1RP_TO_SPKMIXR */
1701#define WM8994_IN1RP_TO_SPKMIXR_WIDTH 1 /* IN1RP_TO_SPKMIXR */
1702#define WM8994_MIXOUTL_TO_SPKMIXL 0x0008 /* MIXOUTL_TO_SPKMIXL */
1703#define WM8994_MIXOUTL_TO_SPKMIXL_MASK 0x0008 /* MIXOUTL_TO_SPKMIXL */
1704#define WM8994_MIXOUTL_TO_SPKMIXL_SHIFT 3 /* MIXOUTL_TO_SPKMIXL */
1705#define WM8994_MIXOUTL_TO_SPKMIXL_WIDTH 1 /* MIXOUTL_TO_SPKMIXL */
1706#define WM8994_MIXOUTR_TO_SPKMIXR 0x0004 /* MIXOUTR_TO_SPKMIXR */
1707#define WM8994_MIXOUTR_TO_SPKMIXR_MASK 0x0004 /* MIXOUTR_TO_SPKMIXR */
1708#define WM8994_MIXOUTR_TO_SPKMIXR_SHIFT 2 /* MIXOUTR_TO_SPKMIXR */
1709#define WM8994_MIXOUTR_TO_SPKMIXR_WIDTH 1 /* MIXOUTR_TO_SPKMIXR */
1710#define WM8994_DAC1L_TO_SPKMIXL 0x0002 /* DAC1L_TO_SPKMIXL */
1711#define WM8994_DAC1L_TO_SPKMIXL_MASK 0x0002 /* DAC1L_TO_SPKMIXL */
1712#define WM8994_DAC1L_TO_SPKMIXL_SHIFT 1 /* DAC1L_TO_SPKMIXL */
1713#define WM8994_DAC1L_TO_SPKMIXL_WIDTH 1 /* DAC1L_TO_SPKMIXL */
1714#define WM8994_DAC1R_TO_SPKMIXR 0x0001 /* DAC1R_TO_SPKMIXR */
1715#define WM8994_DAC1R_TO_SPKMIXR_MASK 0x0001 /* DAC1R_TO_SPKMIXR */
1716#define WM8994_DAC1R_TO_SPKMIXR_SHIFT 0 /* DAC1R_TO_SPKMIXR */
1717#define WM8994_DAC1R_TO_SPKMIXR_WIDTH 1 /* DAC1R_TO_SPKMIXR */
1718
1719/*
1720 * R55 (0x37) - Additional Control
1721 */
1722#define WM8994_LINEOUT1_FB 0x0080 /* LINEOUT1_FB */
1723#define WM8994_LINEOUT1_FB_MASK 0x0080 /* LINEOUT1_FB */
1724#define WM8994_LINEOUT1_FB_SHIFT 7 /* LINEOUT1_FB */
1725#define WM8994_LINEOUT1_FB_WIDTH 1 /* LINEOUT1_FB */
1726#define WM8994_LINEOUT2_FB 0x0040 /* LINEOUT2_FB */
1727#define WM8994_LINEOUT2_FB_MASK 0x0040 /* LINEOUT2_FB */
1728#define WM8994_LINEOUT2_FB_SHIFT 6 /* LINEOUT2_FB */
1729#define WM8994_LINEOUT2_FB_WIDTH 1 /* LINEOUT2_FB */
1730#define WM8994_VROI 0x0001 /* VROI */
1731#define WM8994_VROI_MASK 0x0001 /* VROI */
1732#define WM8994_VROI_SHIFT 0 /* VROI */
1733#define WM8994_VROI_WIDTH 1 /* VROI */
1734
1735/*
1736 * R56 (0x38) - AntiPOP (1)
1737 */
1738#define WM8994_LINEOUT_VMID_BUF_ENA 0x0080 /* LINEOUT_VMID_BUF_ENA */
1739#define WM8994_LINEOUT_VMID_BUF_ENA_MASK 0x0080 /* LINEOUT_VMID_BUF_ENA */
1740#define WM8994_LINEOUT_VMID_BUF_ENA_SHIFT 7 /* LINEOUT_VMID_BUF_ENA */
1741#define WM8994_LINEOUT_VMID_BUF_ENA_WIDTH 1 /* LINEOUT_VMID_BUF_ENA */
1742#define WM8994_HPOUT2_IN_ENA 0x0040 /* HPOUT2_IN_ENA */
1743#define WM8994_HPOUT2_IN_ENA_MASK 0x0040 /* HPOUT2_IN_ENA */
1744#define WM8994_HPOUT2_IN_ENA_SHIFT 6 /* HPOUT2_IN_ENA */
1745#define WM8994_HPOUT2_IN_ENA_WIDTH 1 /* HPOUT2_IN_ENA */
1746#define WM8994_LINEOUT1_DISCH 0x0020 /* LINEOUT1_DISCH */
1747#define WM8994_LINEOUT1_DISCH_MASK 0x0020 /* LINEOUT1_DISCH */
1748#define WM8994_LINEOUT1_DISCH_SHIFT 5 /* LINEOUT1_DISCH */
1749#define WM8994_LINEOUT1_DISCH_WIDTH 1 /* LINEOUT1_DISCH */
1750#define WM8994_LINEOUT2_DISCH 0x0010 /* LINEOUT2_DISCH */
1751#define WM8994_LINEOUT2_DISCH_MASK 0x0010 /* LINEOUT2_DISCH */
1752#define WM8994_LINEOUT2_DISCH_SHIFT 4 /* LINEOUT2_DISCH */
1753#define WM8994_LINEOUT2_DISCH_WIDTH 1 /* LINEOUT2_DISCH */
1754
1755/*
1756 * R57 (0x39) - AntiPOP (2)
1757 */
1758#define WM8994_MICB2_DISCH 0x0100 /* MICB2_DISCH */
1759#define WM8994_MICB2_DISCH_MASK 0x0100 /* MICB2_DISCH */
1760#define WM8994_MICB2_DISCH_SHIFT 8 /* MICB2_DISCH */
1761#define WM8994_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1762#define WM8994_MICB1_DISCH 0x0080 /* MICB1_DISCH */
1763#define WM8994_MICB1_DISCH_MASK 0x0080 /* MICB1_DISCH */
1764#define WM8994_MICB1_DISCH_SHIFT 7 /* MICB1_DISCH */
1765#define WM8994_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1766#define WM8994_VMID_RAMP_MASK 0x0060 /* VMID_RAMP - [6:5] */
1767#define WM8994_VMID_RAMP_SHIFT 5 /* VMID_RAMP - [6:5] */
1768#define WM8994_VMID_RAMP_WIDTH 2 /* VMID_RAMP - [6:5] */
1769#define WM8994_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
1770#define WM8994_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
1771#define WM8994_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
1772#define WM8994_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
1773#define WM8994_STARTUP_BIAS_ENA 0x0004 /* STARTUP_BIAS_ENA */
1774#define WM8994_STARTUP_BIAS_ENA_MASK 0x0004 /* STARTUP_BIAS_ENA */
1775#define WM8994_STARTUP_BIAS_ENA_SHIFT 2 /* STARTUP_BIAS_ENA */
1776#define WM8994_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
1777#define WM8994_BIAS_SRC 0x0002 /* BIAS_SRC */
1778#define WM8994_BIAS_SRC_MASK 0x0002 /* BIAS_SRC */
1779#define WM8994_BIAS_SRC_SHIFT 1 /* BIAS_SRC */
1780#define WM8994_BIAS_SRC_WIDTH 1 /* BIAS_SRC */
1781#define WM8994_VMID_DISCH 0x0001 /* VMID_DISCH */
1782#define WM8994_VMID_DISCH_MASK 0x0001 /* VMID_DISCH */
1783#define WM8994_VMID_DISCH_SHIFT 0 /* VMID_DISCH */
1784#define WM8994_VMID_DISCH_WIDTH 1 /* VMID_DISCH */
1785
1786/*
1787 * R58 (0x3A) - MICBIAS
1788 */
1789#define WM8994_MICD_SCTHR_MASK 0x00C0 /* MICD_SCTHR - [7:6] */
1790#define WM8994_MICD_SCTHR_SHIFT 6 /* MICD_SCTHR - [7:6] */
1791#define WM8994_MICD_SCTHR_WIDTH 2 /* MICD_SCTHR - [7:6] */
1792#define WM8994_MICD_THR_MASK 0x0038 /* MICD_THR - [5:3] */
1793#define WM8994_MICD_THR_SHIFT 3 /* MICD_THR - [5:3] */
1794#define WM8994_MICD_THR_WIDTH 3 /* MICD_THR - [5:3] */
1795#define WM8994_MICD_ENA 0x0004 /* MICD_ENA */
1796#define WM8994_MICD_ENA_MASK 0x0004 /* MICD_ENA */
1797#define WM8994_MICD_ENA_SHIFT 2 /* MICD_ENA */
1798#define WM8994_MICD_ENA_WIDTH 1 /* MICD_ENA */
1799#define WM8994_MICB2_LVL 0x0002 /* MICB2_LVL */
1800#define WM8994_MICB2_LVL_MASK 0x0002 /* MICB2_LVL */
1801#define WM8994_MICB2_LVL_SHIFT 1 /* MICB2_LVL */
1802#define WM8994_MICB2_LVL_WIDTH 1 /* MICB2_LVL */
1803#define WM8994_MICB1_LVL 0x0001 /* MICB1_LVL */
1804#define WM8994_MICB1_LVL_MASK 0x0001 /* MICB1_LVL */
1805#define WM8994_MICB1_LVL_SHIFT 0 /* MICB1_LVL */
1806#define WM8994_MICB1_LVL_WIDTH 1 /* MICB1_LVL */
1807
1808/*
1809 * R59 (0x3B) - LDO 1
1810 */
1811#define WM8994_LDO1_VSEL_MASK 0x000E /* LDO1_VSEL - [3:1] */
1812#define WM8994_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [3:1] */
1813#define WM8994_LDO1_VSEL_WIDTH 3 /* LDO1_VSEL - [3:1] */
1814#define WM8994_LDO1_DISCH 0x0001 /* LDO1_DISCH */
1815#define WM8994_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
1816#define WM8994_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
1817#define WM8994_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
1818
1819/*
1820 * R60 (0x3C) - LDO 2
1821 */
1822#define WM8994_LDO2_VSEL_MASK 0x0006 /* LDO2_VSEL - [2:1] */
1823#define WM8994_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [2:1] */
1824#define WM8994_LDO2_VSEL_WIDTH 2 /* LDO2_VSEL - [2:1] */
1825#define WM8994_LDO2_DISCH 0x0001 /* LDO2_DISCH */
1826#define WM8994_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
1827#define WM8994_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
1828#define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1829
1830/*
1831 * R76 (0x4C) - Charge Pump (1)
1832 */
1833#define WM8994_CP_ENA 0x8000 /* CP_ENA */
1834#define WM8994_CP_ENA_MASK 0x8000 /* CP_ENA */
1835#define WM8994_CP_ENA_SHIFT 15 /* CP_ENA */
1836#define WM8994_CP_ENA_WIDTH 1 /* CP_ENA */
1837
1838/*
1839 * R81 (0x51) - Class W (1)
1840 */
1841#define WM8994_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
1842#define WM8994_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */
1843#define WM8994_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */
1844#define WM8994_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
1845#define WM8994_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
1846#define WM8994_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
1847#define WM8994_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
1848
1849/*
1850 * R84 (0x54) - DC Servo (1)
1851 */
1852#define WM8994_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1853#define WM8994_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1854#define WM8994_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1855#define WM8994_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1856#define WM8994_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1857#define WM8994_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1858#define WM8994_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1859#define WM8994_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1860#define WM8994_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1861#define WM8994_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1862#define WM8994_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1863#define WM8994_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1864#define WM8994_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1865#define WM8994_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1866#define WM8994_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1867#define WM8994_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1868#define WM8994_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1869#define WM8994_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1870#define WM8994_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1871#define WM8994_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1872#define WM8994_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1873#define WM8994_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1874#define WM8994_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1875#define WM8994_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1876#define WM8994_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
1877#define WM8994_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
1878#define WM8994_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
1879#define WM8994_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1880#define WM8994_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
1881#define WM8994_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
1882#define WM8994_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
1883#define WM8994_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1884#define WM8994_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1885#define WM8994_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1886#define WM8994_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1887#define WM8994_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1888#define WM8994_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1889#define WM8994_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1890#define WM8994_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1891#define WM8994_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1892
1893/*
1894 * R85 (0x55) - DC Servo (2)
1895 */
1896#define WM8994_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
1897#define WM8994_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
1898#define WM8994_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
1899#define WM8994_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1900#define WM8994_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1901#define WM8994_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1902
1903/*
1904 * R87 (0x57) - DC Servo (4)
1905 */
1906#define WM8994_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1907#define WM8994_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1908#define WM8994_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1909#define WM8994_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1910#define WM8994_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1911#define WM8994_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1912
1913/*
1914 * R88 (0x58) - DC Servo Readback
1915 */
1916#define WM8994_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
1917#define WM8994_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
1918#define WM8994_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
1919#define WM8994_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
1920#define WM8994_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
1921#define WM8994_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
1922#define WM8994_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
1923#define WM8994_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
1924#define WM8994_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
1925
1926/*
1927 * R96 (0x60) - Analogue HP (1)
1928 */
1929#define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1930#define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1931#define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1932#define WM8994_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1933#define WM8994_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1934#define WM8994_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1935#define WM8994_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1936#define WM8994_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1937#define WM8994_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1938#define WM8994_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1939#define WM8994_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1940#define WM8994_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1941#define WM8994_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1942#define WM8994_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1943#define WM8994_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1944#define WM8994_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1945#define WM8994_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1946#define WM8994_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1947#define WM8994_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1948#define WM8994_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1949#define WM8994_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1950#define WM8994_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1951#define WM8994_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1952#define WM8994_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1953
1954/*
1955 * R256 (0x100) - Chip Revision
1956 */
1957#define WM8994_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
1958#define WM8994_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
1959#define WM8994_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
1960
1961/*
1962 * R257 (0x101) - Control Interface
1963 */
1964#define WM8994_SPI_CONTRD 0x0040 /* SPI_CONTRD */
1965#define WM8994_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
1966#define WM8994_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
1967#define WM8994_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
1968#define WM8994_SPI_4WIRE 0x0020 /* SPI_4WIRE */
1969#define WM8994_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
1970#define WM8994_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
1971#define WM8994_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
1972#define WM8994_SPI_CFG 0x0010 /* SPI_CFG */
1973#define WM8994_SPI_CFG_MASK 0x0010 /* SPI_CFG */
1974#define WM8994_SPI_CFG_SHIFT 4 /* SPI_CFG */
1975#define WM8994_SPI_CFG_WIDTH 1 /* SPI_CFG */
1976#define WM8994_AUTO_INC 0x0004 /* AUTO_INC */
1977#define WM8994_AUTO_INC_MASK 0x0004 /* AUTO_INC */
1978#define WM8994_AUTO_INC_SHIFT 2 /* AUTO_INC */
1979#define WM8994_AUTO_INC_WIDTH 1 /* AUTO_INC */
1980
1981/*
1982 * R272 (0x110) - Write Sequencer Ctrl (1)
1983 */
1984#define WM8994_WSEQ_ENA 0x8000 /* WSEQ_ENA */
1985#define WM8994_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
1986#define WM8994_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
1987#define WM8994_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1988#define WM8994_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1989#define WM8994_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1990#define WM8994_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1991#define WM8994_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1992#define WM8994_WSEQ_START 0x0100 /* WSEQ_START */
1993#define WM8994_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1994#define WM8994_WSEQ_START_SHIFT 8 /* WSEQ_START */
1995#define WM8994_WSEQ_START_WIDTH 1 /* WSEQ_START */
1996#define WM8994_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
1997#define WM8994_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
1998#define WM8994_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
1999
2000/*
2001 * R273 (0x111) - Write Sequencer Ctrl (2)
2002 */
2003#define WM8994_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
2004#define WM8994_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
2005#define WM8994_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
2006#define WM8994_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
2007#define WM8994_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
2008#define WM8994_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
2009#define WM8994_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
2010
2011/*
2012 * R512 (0x200) - AIF1 Clocking (1)
2013 */
2014#define WM8994_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */
2015#define WM8994_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */
2016#define WM8994_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */
2017#define WM8994_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */
2018#define WM8994_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */
2019#define WM8994_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */
2020#define WM8994_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */
2021#define WM8994_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */
2022#define WM8994_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */
2023#define WM8994_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */
2024#define WM8994_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */
2025#define WM8994_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */
2026#define WM8994_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */
2027#define WM8994_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */
2028#define WM8994_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */
2029
2030/*
2031 * R513 (0x201) - AIF1 Clocking (2)
2032 */
2033#define WM8994_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */
2034#define WM8994_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */
2035#define WM8994_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */
2036#define WM8994_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */
2037#define WM8994_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */
2038#define WM8994_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */
2039
2040/*
2041 * R516 (0x204) - AIF2 Clocking (1)
2042 */
2043#define WM8994_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */
2044#define WM8994_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */
2045#define WM8994_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */
2046#define WM8994_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */
2047#define WM8994_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */
2048#define WM8994_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */
2049#define WM8994_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */
2050#define WM8994_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */
2051#define WM8994_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */
2052#define WM8994_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */
2053#define WM8994_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */
2054#define WM8994_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */
2055#define WM8994_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */
2056#define WM8994_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */
2057#define WM8994_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */
2058
2059/*
2060 * R517 (0x205) - AIF2 Clocking (2)
2061 */
2062#define WM8994_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */
2063#define WM8994_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */
2064#define WM8994_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */
2065#define WM8994_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */
2066#define WM8994_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */
2067#define WM8994_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */
2068
2069/*
2070 * R520 (0x208) - Clocking (1)
2071 */
2072#define WM8994_TOCLK_ENA 0x0010 /* TOCLK_ENA */
2073#define WM8994_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
2074#define WM8994_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
2075#define WM8994_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
2076#define WM8994_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */
2077#define WM8994_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */
2078#define WM8994_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */
2079#define WM8994_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */
2080#define WM8994_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */
2081#define WM8994_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */
2082#define WM8994_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */
2083#define WM8994_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */
2084#define WM8994_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
2085#define WM8994_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
2086#define WM8994_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
2087#define WM8994_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
2088#define WM8994_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */
2089#define WM8994_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */
2090#define WM8994_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */
2091#define WM8994_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
2092
2093/*
2094 * R521 (0x209) - Clocking (2)
2095 */
2096#define WM8994_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
2097#define WM8994_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
2098#define WM8994_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
2099#define WM8994_DBCLK_DIV_MASK 0x0070 /* DBCLK_DIV - [6:4] */
2100#define WM8994_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [6:4] */
2101#define WM8994_DBCLK_DIV_WIDTH 3 /* DBCLK_DIV - [6:4] */
2102#define WM8994_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
2103#define WM8994_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
2104#define WM8994_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
2105
2106/*
2107 * R528 (0x210) - AIF1 Rate
2108 */
2109#define WM8994_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */
2110#define WM8994_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */
2111#define WM8994_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */
2112#define WM8994_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */
2113#define WM8994_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */
2114#define WM8994_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */
2115
2116/*
2117 * R529 (0x211) - AIF2 Rate
2118 */
2119#define WM8994_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */
2120#define WM8994_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */
2121#define WM8994_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */
2122#define WM8994_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */
2123#define WM8994_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */
2124#define WM8994_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */
2125
2126/*
2127 * R530 (0x212) - Rate Status
2128 */
2129#define WM8994_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */
2130#define WM8994_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */
2131#define WM8994_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */
2132
2133/*
2134 * R544 (0x220) - FLL1 Control (1)
2135 */
2136#define WM8994_FLL1_FRAC 0x0004 /* FLL1_FRAC */
2137#define WM8994_FLL1_FRAC_MASK 0x0004 /* FLL1_FRAC */
2138#define WM8994_FLL1_FRAC_SHIFT 2 /* FLL1_FRAC */
2139#define WM8994_FLL1_FRAC_WIDTH 1 /* FLL1_FRAC */
2140#define WM8994_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */
2141#define WM8994_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */
2142#define WM8994_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */
2143#define WM8994_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */
2144#define WM8994_FLL1_ENA 0x0001 /* FLL1_ENA */
2145#define WM8994_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
2146#define WM8994_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
2147#define WM8994_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
2148
2149/*
2150 * R545 (0x221) - FLL1 Control (2)
2151 */
2152#define WM8994_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
2153#define WM8994_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
2154#define WM8994_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
2155#define WM8994_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */
2156#define WM8994_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */
2157#define WM8994_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */
2158#define WM8994_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
2159#define WM8994_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
2160#define WM8994_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
2161
2162/*
2163 * R546 (0x222) - FLL1 Control (3)
2164 */
2165#define WM8994_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */
2166#define WM8994_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */
2167#define WM8994_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */
2168
2169/*
2170 * R547 (0x223) - FLL1 Control (4)
2171 */
2172#define WM8994_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */
2173#define WM8994_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */
2174#define WM8994_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */
2175#define WM8994_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */
2176#define WM8994_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */
2177#define WM8994_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */
2178
2179/*
2180 * R548 (0x224) - FLL1 Control (5)
2181 */
2182#define WM8994_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
2183#define WM8994_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
2184#define WM8994_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
2185#define WM8994_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */
2186#define WM8994_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */
2187#define WM8994_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */
2188#define WM8994_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */
2189#define WM8994_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */
2190#define WM8994_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */
2191#define WM8994_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */
2192#define WM8994_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */
2193#define WM8994_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */
2194#define WM8994_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */
2195
2196/*
2197 * R576 (0x240) - FLL2 Control (1)
2198 */
2199#define WM8994_FLL2_FRAC 0x0004 /* FLL2_FRAC */
2200#define WM8994_FLL2_FRAC_MASK 0x0004 /* FLL2_FRAC */
2201#define WM8994_FLL2_FRAC_SHIFT 2 /* FLL2_FRAC */
2202#define WM8994_FLL2_FRAC_WIDTH 1 /* FLL2_FRAC */
2203#define WM8994_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */
2204#define WM8994_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */
2205#define WM8994_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */
2206#define WM8994_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */
2207#define WM8994_FLL2_ENA 0x0001 /* FLL2_ENA */
2208#define WM8994_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
2209#define WM8994_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
2210#define WM8994_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
2211
2212/*
2213 * R577 (0x241) - FLL2 Control (2)
2214 */
2215#define WM8994_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
2216#define WM8994_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
2217#define WM8994_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
2218#define WM8994_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */
2219#define WM8994_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */
2220#define WM8994_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */
2221#define WM8994_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
2222#define WM8994_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
2223#define WM8994_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
2224
2225/*
2226 * R578 (0x242) - FLL2 Control (3)
2227 */
2228#define WM8994_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */
2229#define WM8994_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */
2230#define WM8994_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */
2231
2232/*
2233 * R579 (0x243) - FLL2 Control (4)
2234 */
2235#define WM8994_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */
2236#define WM8994_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */
2237#define WM8994_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */
2238#define WM8994_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */
2239#define WM8994_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */
2240#define WM8994_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */
2241
2242/*
2243 * R580 (0x244) - FLL2 Control (5)
2244 */
2245#define WM8994_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
2246#define WM8994_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
2247#define WM8994_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
2248#define WM8994_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */
2249#define WM8994_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */
2250#define WM8994_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */
2251#define WM8994_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */
2252#define WM8994_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */
2253#define WM8994_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */
2254#define WM8994_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */
2255#define WM8994_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */
2256#define WM8994_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */
2257#define WM8994_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */
2258
2259/*
2260 * R768 (0x300) - AIF1 Control (1)
2261 */
2262#define WM8994_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
2263#define WM8994_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */
2264#define WM8994_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */
2265#define WM8994_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */
2266#define WM8994_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */
2267#define WM8994_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */
2268#define WM8994_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */
2269#define WM8994_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */
2270#define WM8994_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */
2271#define WM8994_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */
2272#define WM8994_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */
2273#define WM8994_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */
2274#define WM8994_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */
2275#define WM8994_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */
2276#define WM8994_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */
2277#define WM8994_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
2278#define WM8994_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */
2279#define WM8994_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */
2280#define WM8994_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */
2281#define WM8994_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
2282#define WM8994_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */
2283#define WM8994_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */
2284#define WM8994_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */
2285#define WM8994_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */
2286#define WM8994_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */
2287#define WM8994_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */
2288
2289/*
2290 * R769 (0x301) - AIF1 Control (2)
2291 */
2292#define WM8994_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */
2293#define WM8994_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */
2294#define WM8994_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */
2295#define WM8994_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */
2296#define WM8994_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */
2297#define WM8994_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */
2298#define WM8994_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */
2299#define WM8994_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */
2300#define WM8994_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */
2301#define WM8994_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */
2302#define WM8994_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */
2303#define WM8994_AIF1_MONO 0x0100 /* AIF1_MONO */
2304#define WM8994_AIF1_MONO_MASK 0x0100 /* AIF1_MONO */
2305#define WM8994_AIF1_MONO_SHIFT 8 /* AIF1_MONO */
2306#define WM8994_AIF1_MONO_WIDTH 1 /* AIF1_MONO */
2307#define WM8994_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */
2308#define WM8994_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */
2309#define WM8994_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */
2310#define WM8994_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */
2311#define WM8994_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */
2312#define WM8994_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */
2313#define WM8994_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */
2314#define WM8994_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */
2315#define WM8994_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */
2316#define WM8994_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */
2317#define WM8994_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */
2318#define WM8994_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */
2319#define WM8994_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */
2320#define WM8994_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */
2321#define WM8994_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */
2322#define WM8994_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */
2323#define WM8994_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */
2324#define WM8994_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */
2325#define WM8994_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */
2326#define WM8994_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */
2327
2328/*
2329 * R770 (0x302) - AIF1 Master/Slave
2330 */
2331#define WM8994_AIF1_TRI 0x8000 /* AIF1_TRI */
2332#define WM8994_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */
2333#define WM8994_AIF1_TRI_SHIFT 15 /* AIF1_TRI */
2334#define WM8994_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
2335#define WM8994_AIF1_MSTR 0x4000 /* AIF1_MSTR */
2336#define WM8994_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */
2337#define WM8994_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */
2338#define WM8994_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */
2339#define WM8994_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */
2340#define WM8994_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */
2341#define WM8994_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */
2342#define WM8994_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */
2343#define WM8994_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */
2344#define WM8994_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */
2345#define WM8994_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */
2346#define WM8994_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */
2347
2348/*
2349 * R771 (0x303) - AIF1 BCLK
2350 */
2351#define WM8994_AIF1_BCLK_DIV_MASK 0x01F0 /* AIF1_BCLK_DIV - [8:4] */
2352#define WM8994_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [8:4] */
2353#define WM8994_AIF1_BCLK_DIV_WIDTH 5 /* AIF1_BCLK_DIV - [8:4] */
2354
2355/*
2356 * R772 (0x304) - AIF1ADC LRCLK
2357 */
2358#define WM8994_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
2359#define WM8994_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
2360#define WM8994_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
2361#define WM8994_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */
2362#define WM8994_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */
2363#define WM8994_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */
2364#define WM8994_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */
2365
2366/*
2367 * R773 (0x305) - AIF1DAC LRCLK
2368 */
2369#define WM8994_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
2370#define WM8994_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
2371#define WM8994_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
2372#define WM8994_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */
2373#define WM8994_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */
2374#define WM8994_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */
2375#define WM8994_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */
2376
2377/*
2378 * R774 (0x306) - AIF1DAC Data
2379 */
2380#define WM8994_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */
2381#define WM8994_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */
2382#define WM8994_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */
2383#define WM8994_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */
2384#define WM8994_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */
2385#define WM8994_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */
2386#define WM8994_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */
2387#define WM8994_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */
2388
2389/*
2390 * R775 (0x307) - AIF1ADC Data
2391 */
2392#define WM8994_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */
2393#define WM8994_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */
2394#define WM8994_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */
2395#define WM8994_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */
2396#define WM8994_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */
2397#define WM8994_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */
2398#define WM8994_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */
2399#define WM8994_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */
2400
2401/*
2402 * R784 (0x310) - AIF2 Control (1)
2403 */
2404#define WM8994_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */
2405#define WM8994_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */
2406#define WM8994_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */
2407#define WM8994_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */
2408#define WM8994_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */
2409#define WM8994_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */
2410#define WM8994_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */
2411#define WM8994_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */
2412#define WM8994_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */
2413#define WM8994_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */
2414#define WM8994_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */
2415#define WM8994_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */
2416#define WM8994_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */
2417#define WM8994_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */
2418#define WM8994_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */
2419#define WM8994_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */
2420#define WM8994_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */
2421#define WM8994_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */
2422#define WM8994_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */
2423#define WM8994_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
2424#define WM8994_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */
2425#define WM8994_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */
2426#define WM8994_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */
2427#define WM8994_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */
2428#define WM8994_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */
2429#define WM8994_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */
2430#define WM8994_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */
2431#define WM8994_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */
2432#define WM8994_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */
2433#define WM8994_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */
2434
2435/*
2436 * R785 (0x311) - AIF2 Control (2)
2437 */
2438#define WM8994_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */
2439#define WM8994_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */
2440#define WM8994_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */
2441#define WM8994_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */
2442#define WM8994_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */
2443#define WM8994_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */
2444#define WM8994_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */
2445#define WM8994_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */
2446#define WM8994_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */
2447#define WM8994_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */
2448#define WM8994_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */
2449#define WM8994_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */
2450#define WM8994_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */
2451#define WM8994_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */
2452#define WM8994_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */
2453#define WM8994_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */
2454#define WM8994_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */
2455#define WM8994_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */
2456#define WM8994_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */
2457#define WM8994_AIF2_MONO 0x0100 /* AIF2_MONO */
2458#define WM8994_AIF2_MONO_MASK 0x0100 /* AIF2_MONO */
2459#define WM8994_AIF2_MONO_SHIFT 8 /* AIF2_MONO */
2460#define WM8994_AIF2_MONO_WIDTH 1 /* AIF2_MONO */
2461#define WM8994_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */
2462#define WM8994_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */
2463#define WM8994_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */
2464#define WM8994_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */
2465#define WM8994_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */
2466#define WM8994_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */
2467#define WM8994_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */
2468#define WM8994_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */
2469#define WM8994_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */
2470#define WM8994_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */
2471#define WM8994_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */
2472#define WM8994_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */
2473#define WM8994_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */
2474#define WM8994_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */
2475#define WM8994_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */
2476#define WM8994_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */
2477#define WM8994_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */
2478#define WM8994_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */
2479#define WM8994_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */
2480#define WM8994_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */
2481
2482/*
2483 * R786 (0x312) - AIF2 Master/Slave
2484 */
2485#define WM8994_AIF2_TRI 0x8000 /* AIF2_TRI */
2486#define WM8994_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */
2487#define WM8994_AIF2_TRI_SHIFT 15 /* AIF2_TRI */
2488#define WM8994_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
2489#define WM8994_AIF2_MSTR 0x4000 /* AIF2_MSTR */
2490#define WM8994_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */
2491#define WM8994_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */
2492#define WM8994_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */
2493#define WM8994_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */
2494#define WM8994_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */
2495#define WM8994_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */
2496#define WM8994_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */
2497#define WM8994_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */
2498#define WM8994_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */
2499#define WM8994_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */
2500#define WM8994_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */
2501
2502/*
2503 * R787 (0x313) - AIF2 BCLK
2504 */
2505#define WM8994_AIF2_BCLK_DIV_MASK 0x01F0 /* AIF2_BCLK_DIV - [8:4] */
2506#define WM8994_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [8:4] */
2507#define WM8994_AIF2_BCLK_DIV_WIDTH 5 /* AIF2_BCLK_DIV - [8:4] */
2508
2509/*
2510 * R788 (0x314) - AIF2ADC LRCLK
2511 */
2512#define WM8994_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */
2513#define WM8994_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */
2514#define WM8994_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */
2515#define WM8994_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */
2516#define WM8994_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */
2517#define WM8994_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */
2518#define WM8994_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */
2519
2520/*
2521 * R789 (0x315) - AIF2DAC LRCLK
2522 */
2523#define WM8994_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */
2524#define WM8994_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */
2525#define WM8994_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */
2526#define WM8994_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */
2527#define WM8994_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */
2528#define WM8994_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */
2529#define WM8994_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */
2530
2531/*
2532 * R790 (0x316) - AIF2DAC Data
2533 */
2534#define WM8994_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */
2535#define WM8994_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */
2536#define WM8994_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */
2537#define WM8994_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */
2538#define WM8994_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */
2539#define WM8994_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */
2540#define WM8994_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */
2541#define WM8994_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */
2542
2543/*
2544 * R791 (0x317) - AIF2ADC Data
2545 */
2546#define WM8994_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */
2547#define WM8994_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */
2548#define WM8994_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */
2549#define WM8994_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */
2550#define WM8994_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */
2551#define WM8994_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */
2552#define WM8994_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */
2553#define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
2554
2555/*
2556 * R1024 (0x400) - AIF1 ADC1 Left Volume
2557 */
2558#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
2559#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
2560#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
2561#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
2562#define WM8994_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */
2563#define WM8994_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */
2564#define WM8994_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */
2565
2566/*
2567 * R1025 (0x401) - AIF1 ADC1 Right Volume
2568 */
2569#define WM8994_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
2570#define WM8994_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
2571#define WM8994_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
2572#define WM8994_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
2573#define WM8994_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */
2574#define WM8994_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */
2575#define WM8994_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */
2576
2577/*
2578 * R1026 (0x402) - AIF1 DAC1 Left Volume
2579 */
2580#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
2581#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
2582#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
2583#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
2584#define WM8994_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */
2585#define WM8994_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */
2586#define WM8994_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */
2587
2588/*
2589 * R1027 (0x403) - AIF1 DAC1 Right Volume
2590 */
2591#define WM8994_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
2592#define WM8994_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
2593#define WM8994_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
2594#define WM8994_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
2595#define WM8994_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */
2596#define WM8994_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */
2597#define WM8994_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */
2598
2599/*
2600 * R1028 (0x404) - AIF1 ADC2 Left Volume
2601 */
2602#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
2603#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
2604#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
2605#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
2606#define WM8994_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */
2607#define WM8994_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */
2608#define WM8994_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */
2609
2610/*
2611 * R1029 (0x405) - AIF1 ADC2 Right Volume
2612 */
2613#define WM8994_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
2614#define WM8994_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
2615#define WM8994_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
2616#define WM8994_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
2617#define WM8994_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */
2618#define WM8994_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */
2619#define WM8994_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */
2620
2621/*
2622 * R1030 (0x406) - AIF1 DAC2 Left Volume
2623 */
2624#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
2625#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
2626#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
2627#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
2628#define WM8994_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */
2629#define WM8994_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */
2630#define WM8994_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */
2631
2632/*
2633 * R1031 (0x407) - AIF1 DAC2 Right Volume
2634 */
2635#define WM8994_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
2636#define WM8994_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
2637#define WM8994_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
2638#define WM8994_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
2639#define WM8994_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */
2640#define WM8994_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */
2641#define WM8994_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */
2642
2643/*
2644 * R1040 (0x410) - AIF1 ADC1 Filters
2645 */
2646#define WM8994_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */
2647#define WM8994_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */
2648#define WM8994_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */
2649#define WM8994_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */
2650#define WM8994_AIF1ADC1_HPF_CUT_MASK 0x6000 /* AIF1ADC1_HPF_CUT - [14:13] */
2651#define WM8994_AIF1ADC1_HPF_CUT_SHIFT 13 /* AIF1ADC1_HPF_CUT - [14:13] */
2652#define WM8994_AIF1ADC1_HPF_CUT_WIDTH 2 /* AIF1ADC1_HPF_CUT - [14:13] */
2653#define WM8994_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */
2654#define WM8994_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */
2655#define WM8994_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */
2656#define WM8994_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */
2657#define WM8994_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */
2658#define WM8994_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */
2659#define WM8994_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */
2660#define WM8994_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */
2661
2662/*
2663 * R1041 (0x411) - AIF1 ADC2 Filters
2664 */
2665#define WM8994_AIF1ADC2_HPF_CUT_MASK 0x6000 /* AIF1ADC2_HPF_CUT - [14:13] */
2666#define WM8994_AIF1ADC2_HPF_CUT_SHIFT 13 /* AIF1ADC2_HPF_CUT - [14:13] */
2667#define WM8994_AIF1ADC2_HPF_CUT_WIDTH 2 /* AIF1ADC2_HPF_CUT - [14:13] */
2668#define WM8994_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */
2669#define WM8994_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */
2670#define WM8994_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */
2671#define WM8994_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */
2672#define WM8994_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */
2673#define WM8994_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */
2674#define WM8994_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */
2675#define WM8994_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */
2676
2677/*
2678 * R1056 (0x420) - AIF1 DAC1 Filters (1)
2679 */
2680#define WM8994_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */
2681#define WM8994_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */
2682#define WM8994_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */
2683#define WM8994_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */
2684#define WM8994_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */
2685#define WM8994_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */
2686#define WM8994_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */
2687#define WM8994_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */
2688#define WM8994_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */
2689#define WM8994_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */
2690#define WM8994_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */
2691#define WM8994_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */
2692#define WM8994_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
2693#define WM8994_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
2694#define WM8994_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */
2695#define WM8994_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */
2696#define WM8994_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */
2697#define WM8994_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */
2698#define WM8994_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */
2699
2700/*
2701 * R1057 (0x421) - AIF1 DAC1 Filters (2)
2702 */
2703#define WM8994_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */
2704#define WM8994_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */
2705#define WM8994_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */
2706#define WM8994_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */
2707#define WM8994_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */
2708#define WM8994_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */
2709#define WM8994_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */
2710
2711/*
2712 * R1058 (0x422) - AIF1 DAC2 Filters (1)
2713 */
2714#define WM8994_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */
2715#define WM8994_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */
2716#define WM8994_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */
2717#define WM8994_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */
2718#define WM8994_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */
2719#define WM8994_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */
2720#define WM8994_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */
2721#define WM8994_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */
2722#define WM8994_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */
2723#define WM8994_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */
2724#define WM8994_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */
2725#define WM8994_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */
2726#define WM8994_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
2727#define WM8994_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
2728#define WM8994_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */
2729#define WM8994_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */
2730#define WM8994_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */
2731#define WM8994_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */
2732#define WM8994_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */
2733
2734/*
2735 * R1059 (0x423) - AIF1 DAC2 Filters (2)
2736 */
2737#define WM8994_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */
2738#define WM8994_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */
2739#define WM8994_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */
2740#define WM8994_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */
2741#define WM8994_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */
2742#define WM8994_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
2743#define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
2744
2745/*
2746 * R1088 (0x440) - AIF1 DRC1 (1)
2747 */
2748#define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2749#define WM8994_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2750#define WM8994_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2751#define WM8994_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2752#define WM8994_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2753#define WM8994_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2754#define WM8994_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */
2755#define WM8994_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */
2756#define WM8994_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */
2757#define WM8994_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */
2758#define WM8994_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */
2759#define WM8994_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */
2760#define WM8994_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */
2761#define WM8994_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */
2762#define WM8994_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */
2763#define WM8994_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */
2764#define WM8994_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */
2765#define WM8994_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */
2766#define WM8994_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
2767#define WM8994_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
2768#define WM8994_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */
2769#define WM8994_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */
2770#define WM8994_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */
2771#define WM8994_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */
2772#define WM8994_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */
2773#define WM8994_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */
2774#define WM8994_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */
2775#define WM8994_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */
2776#define WM8994_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */
2777#define WM8994_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */
2778#define WM8994_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */
2779#define WM8994_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */
2780#define WM8994_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */
2781#define WM8994_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */
2782#define WM8994_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */
2783#define WM8994_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */
2784#define WM8994_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */
2785#define WM8994_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */
2786#define WM8994_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */
2787#define WM8994_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */
2788#define WM8994_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */
2789#define WM8994_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */
2790
2791/*
2792 * R1089 (0x441) - AIF1 DRC1 (2)
2793 */
2794#define WM8994_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */
2795#define WM8994_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */
2796#define WM8994_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */
2797#define WM8994_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */
2798#define WM8994_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */
2799#define WM8994_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */
2800#define WM8994_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */
2801#define WM8994_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */
2802#define WM8994_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */
2803#define WM8994_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */
2804#define WM8994_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */
2805#define WM8994_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */
2806
2807/*
2808 * R1090 (0x442) - AIF1 DRC1 (3)
2809 */
2810#define WM8994_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2811#define WM8994_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2812#define WM8994_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2813#define WM8994_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */
2814#define WM8994_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */
2815#define WM8994_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */
2816#define WM8994_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */
2817#define WM8994_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */
2818#define WM8994_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */
2819#define WM8994_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */
2820#define WM8994_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */
2821#define WM8994_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */
2822#define WM8994_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */
2823#define WM8994_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */
2824#define WM8994_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */
2825#define WM8994_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */
2826#define WM8994_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */
2827#define WM8994_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */
2828
2829/*
2830 * R1091 (0x443) - AIF1 DRC1 (4)
2831 */
2832#define WM8994_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */
2833#define WM8994_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */
2834#define WM8994_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */
2835#define WM8994_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */
2836#define WM8994_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */
2837#define WM8994_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */
2838
2839/*
2840 * R1092 (0x444) - AIF1 DRC1 (5)
2841 */
2842#define WM8994_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */
2843#define WM8994_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
2844#define WM8994_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
2845#define WM8994_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */
2846#define WM8994_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */
2847#define WM8994_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */
2848
2849/*
2850 * R1104 (0x450) - AIF1 DRC2 (1)
2851 */
2852#define WM8994_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2853#define WM8994_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2854#define WM8994_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2855#define WM8994_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2856#define WM8994_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2857#define WM8994_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2858#define WM8994_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */
2859#define WM8994_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */
2860#define WM8994_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */
2861#define WM8994_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */
2862#define WM8994_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */
2863#define WM8994_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */
2864#define WM8994_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */
2865#define WM8994_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */
2866#define WM8994_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */
2867#define WM8994_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */
2868#define WM8994_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */
2869#define WM8994_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */
2870#define WM8994_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
2871#define WM8994_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
2872#define WM8994_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */
2873#define WM8994_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */
2874#define WM8994_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */
2875#define WM8994_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */
2876#define WM8994_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */
2877#define WM8994_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */
2878#define WM8994_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */
2879#define WM8994_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */
2880#define WM8994_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */
2881#define WM8994_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */
2882#define WM8994_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */
2883#define WM8994_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */
2884#define WM8994_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */
2885#define WM8994_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */
2886#define WM8994_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */
2887#define WM8994_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */
2888#define WM8994_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */
2889#define WM8994_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */
2890#define WM8994_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */
2891#define WM8994_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */
2892#define WM8994_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */
2893#define WM8994_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */
2894
2895/*
2896 * R1105 (0x451) - AIF1 DRC2 (2)
2897 */
2898#define WM8994_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */
2899#define WM8994_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */
2900#define WM8994_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */
2901#define WM8994_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */
2902#define WM8994_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */
2903#define WM8994_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */
2904#define WM8994_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */
2905#define WM8994_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */
2906#define WM8994_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */
2907#define WM8994_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */
2908#define WM8994_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */
2909#define WM8994_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */
2910
2911/*
2912 * R1106 (0x452) - AIF1 DRC2 (3)
2913 */
2914#define WM8994_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2915#define WM8994_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2916#define WM8994_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2917#define WM8994_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */
2918#define WM8994_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */
2919#define WM8994_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */
2920#define WM8994_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */
2921#define WM8994_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */
2922#define WM8994_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */
2923#define WM8994_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */
2924#define WM8994_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */
2925#define WM8994_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */
2926#define WM8994_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */
2927#define WM8994_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */
2928#define WM8994_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */
2929#define WM8994_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */
2930#define WM8994_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */
2931#define WM8994_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */
2932
2933/*
2934 * R1107 (0x453) - AIF1 DRC2 (4)
2935 */
2936#define WM8994_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */
2937#define WM8994_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */
2938#define WM8994_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */
2939#define WM8994_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */
2940#define WM8994_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */
2941#define WM8994_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */
2942
2943/*
2944 * R1108 (0x454) - AIF1 DRC2 (5)
2945 */
2946#define WM8994_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */
2947#define WM8994_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
2948#define WM8994_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
2949#define WM8994_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */
2950#define WM8994_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */
2951#define WM8994_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */
2952
2953/*
2954 * R1152 (0x480) - AIF1 DAC1 EQ Gains (1)
2955 */
2956#define WM8994_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2957#define WM8994_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2958#define WM8994_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2959#define WM8994_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2960#define WM8994_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2961#define WM8994_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2962#define WM8994_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2963#define WM8994_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2964#define WM8994_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2965#define WM8994_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */
2966#define WM8994_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */
2967#define WM8994_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */
2968#define WM8994_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */
2969
2970/*
2971 * R1153 (0x481) - AIF1 DAC1 EQ Gains (2)
2972 */
2973#define WM8994_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2974#define WM8994_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2975#define WM8994_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2976#define WM8994_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2977#define WM8994_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2978#define WM8994_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2979
2980/*
2981 * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A
2982 */
2983#define WM8994_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */
2984#define WM8994_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */
2985#define WM8994_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */
2986
2987/*
2988 * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B
2989 */
2990#define WM8994_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */
2991#define WM8994_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */
2992#define WM8994_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */
2993
2994/*
2995 * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG
2996 */
2997#define WM8994_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */
2998#define WM8994_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */
2999#define WM8994_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */
3000
3001/*
3002 * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A
3003 */
3004#define WM8994_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */
3005#define WM8994_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */
3006#define WM8994_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */
3007
3008/*
3009 * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B
3010 */
3011#define WM8994_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */
3012#define WM8994_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */
3013#define WM8994_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */
3014
3015/*
3016 * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C
3017 */
3018#define WM8994_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */
3019#define WM8994_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */
3020#define WM8994_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */
3021
3022/*
3023 * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG
3024 */
3025#define WM8994_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */
3026#define WM8994_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */
3027#define WM8994_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */
3028
3029/*
3030 * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A
3031 */
3032#define WM8994_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */
3033#define WM8994_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */
3034#define WM8994_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */
3035
3036/*
3037 * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B
3038 */
3039#define WM8994_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */
3040#define WM8994_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */
3041#define WM8994_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */
3042
3043/*
3044 * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C
3045 */
3046#define WM8994_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */
3047#define WM8994_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */
3048#define WM8994_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */
3049
3050/*
3051 * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG
3052 */
3053#define WM8994_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */
3054#define WM8994_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */
3055#define WM8994_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */
3056
3057/*
3058 * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A
3059 */
3060#define WM8994_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */
3061#define WM8994_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */
3062#define WM8994_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */
3063
3064/*
3065 * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B
3066 */
3067#define WM8994_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */
3068#define WM8994_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */
3069#define WM8994_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */
3070
3071/*
3072 * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C
3073 */
3074#define WM8994_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */
3075#define WM8994_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */
3076#define WM8994_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */
3077
3078/*
3079 * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG
3080 */
3081#define WM8994_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */
3082#define WM8994_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */
3083#define WM8994_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */
3084
3085/*
3086 * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A
3087 */
3088#define WM8994_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */
3089#define WM8994_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */
3090#define WM8994_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */
3091
3092/*
3093 * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B
3094 */
3095#define WM8994_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */
3096#define WM8994_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */
3097#define WM8994_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */
3098
3099/*
3100 * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG
3101 */
3102#define WM8994_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */
3103#define WM8994_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */
3104#define WM8994_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */
3105
3106/*
3107 * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1)
3108 */
3109#define WM8994_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
3110#define WM8994_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
3111#define WM8994_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
3112#define WM8994_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
3113#define WM8994_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
3114#define WM8994_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
3115#define WM8994_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
3116#define WM8994_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
3117#define WM8994_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
3118#define WM8994_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */
3119#define WM8994_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */
3120#define WM8994_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */
3121#define WM8994_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */
3122
3123/*
3124 * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2)
3125 */
3126#define WM8994_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
3127#define WM8994_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
3128#define WM8994_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
3129#define WM8994_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
3130#define WM8994_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
3131#define WM8994_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
3132
3133/*
3134 * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A
3135 */
3136#define WM8994_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */
3137#define WM8994_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */
3138#define WM8994_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */
3139
3140/*
3141 * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B
3142 */
3143#define WM8994_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */
3144#define WM8994_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */
3145#define WM8994_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */
3146
3147/*
3148 * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG
3149 */
3150#define WM8994_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */
3151#define WM8994_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */
3152#define WM8994_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */
3153
3154/*
3155 * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A
3156 */
3157#define WM8994_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */
3158#define WM8994_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */
3159#define WM8994_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */
3160
3161/*
3162 * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B
3163 */
3164#define WM8994_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */
3165#define WM8994_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */
3166#define WM8994_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */
3167
3168/*
3169 * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C
3170 */
3171#define WM8994_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */
3172#define WM8994_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */
3173#define WM8994_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */
3174
3175/*
3176 * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG
3177 */
3178#define WM8994_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */
3179#define WM8994_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */
3180#define WM8994_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */
3181
3182/*
3183 * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A
3184 */
3185#define WM8994_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */
3186#define WM8994_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */
3187#define WM8994_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */
3188
3189/*
3190 * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B
3191 */
3192#define WM8994_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */
3193#define WM8994_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */
3194#define WM8994_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */
3195
3196/*
3197 * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C
3198 */
3199#define WM8994_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */
3200#define WM8994_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */
3201#define WM8994_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */
3202
3203/*
3204 * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG
3205 */
3206#define WM8994_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */
3207#define WM8994_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */
3208#define WM8994_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */
3209
3210/*
3211 * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A
3212 */
3213#define WM8994_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */
3214#define WM8994_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */
3215#define WM8994_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */
3216
3217/*
3218 * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B
3219 */
3220#define WM8994_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */
3221#define WM8994_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */
3222#define WM8994_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */
3223
3224/*
3225 * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C
3226 */
3227#define WM8994_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */
3228#define WM8994_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */
3229#define WM8994_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */
3230
3231/*
3232 * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG
3233 */
3234#define WM8994_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */
3235#define WM8994_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */
3236#define WM8994_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */
3237
3238/*
3239 * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A
3240 */
3241#define WM8994_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */
3242#define WM8994_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */
3243#define WM8994_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */
3244
3245/*
3246 * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B
3247 */
3248#define WM8994_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */
3249#define WM8994_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */
3250#define WM8994_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */
3251
3252/*
3253 * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG
3254 */
3255#define WM8994_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */
3256#define WM8994_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */
3257#define WM8994_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */
3258
3259/*
3260 * R1280 (0x500) - AIF2 ADC Left Volume
3261 */
3262#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
3263#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
3264#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
3265#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
3266#define WM8994_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */
3267#define WM8994_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */
3268#define WM8994_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */
3269
3270/*
3271 * R1281 (0x501) - AIF2 ADC Right Volume
3272 */
3273#define WM8994_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
3274#define WM8994_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
3275#define WM8994_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
3276#define WM8994_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
3277#define WM8994_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */
3278#define WM8994_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */
3279#define WM8994_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */
3280
3281/*
3282 * R1282 (0x502) - AIF2 DAC Left Volume
3283 */
3284#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
3285#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
3286#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
3287#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
3288#define WM8994_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */
3289#define WM8994_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */
3290#define WM8994_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */
3291
3292/*
3293 * R1283 (0x503) - AIF2 DAC Right Volume
3294 */
3295#define WM8994_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
3296#define WM8994_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
3297#define WM8994_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
3298#define WM8994_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
3299#define WM8994_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */
3300#define WM8994_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */
3301#define WM8994_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */
3302
3303/*
3304 * R1296 (0x510) - AIF2 ADC Filters
3305 */
3306#define WM8994_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */
3307#define WM8994_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */
3308#define WM8994_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */
3309#define WM8994_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */
3310#define WM8994_AIF2ADC_HPF_CUT_MASK 0x6000 /* AIF2ADC_HPF_CUT - [14:13] */
3311#define WM8994_AIF2ADC_HPF_CUT_SHIFT 13 /* AIF2ADC_HPF_CUT - [14:13] */
3312#define WM8994_AIF2ADC_HPF_CUT_WIDTH 2 /* AIF2ADC_HPF_CUT - [14:13] */
3313#define WM8994_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */
3314#define WM8994_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */
3315#define WM8994_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */
3316#define WM8994_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */
3317#define WM8994_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */
3318#define WM8994_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */
3319#define WM8994_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */
3320#define WM8994_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */
3321
3322/*
3323 * R1312 (0x520) - AIF2 DAC Filters (1)
3324 */
3325#define WM8994_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */
3326#define WM8994_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */
3327#define WM8994_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */
3328#define WM8994_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */
3329#define WM8994_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */
3330#define WM8994_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */
3331#define WM8994_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */
3332#define WM8994_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */
3333#define WM8994_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */
3334#define WM8994_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */
3335#define WM8994_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */
3336#define WM8994_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */
3337#define WM8994_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */
3338#define WM8994_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */
3339#define WM8994_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */
3340#define WM8994_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */
3341#define WM8994_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */
3342#define WM8994_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */
3343#define WM8994_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */
3344
3345/*
3346 * R1313 (0x521) - AIF2 DAC Filters (2)
3347 */
3348#define WM8994_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */
3349#define WM8994_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */
3350#define WM8994_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */
3351#define WM8994_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */
3352#define WM8994_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */
3353#define WM8994_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
3354#define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
3355
3356/*
3357 * R1344 (0x540) - AIF2 DRC (1)
3358 */
3359#define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
3360#define WM8994_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */
3361#define WM8994_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */
3362#define WM8994_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */
3363#define WM8994_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */
3364#define WM8994_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */
3365#define WM8994_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */
3366#define WM8994_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */
3367#define WM8994_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */
3368#define WM8994_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */
3369#define WM8994_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */
3370#define WM8994_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */
3371#define WM8994_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */
3372#define WM8994_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */
3373#define WM8994_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */
3374#define WM8994_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */
3375#define WM8994_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */
3376#define WM8994_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */
3377#define WM8994_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
3378#define WM8994_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
3379#define WM8994_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */
3380#define WM8994_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */
3381#define WM8994_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */
3382#define WM8994_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */
3383#define WM8994_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */
3384#define WM8994_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */
3385#define WM8994_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */
3386#define WM8994_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */
3387#define WM8994_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */
3388#define WM8994_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */
3389#define WM8994_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */
3390#define WM8994_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */
3391#define WM8994_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */
3392#define WM8994_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */
3393#define WM8994_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */
3394#define WM8994_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */
3395#define WM8994_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */
3396#define WM8994_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */
3397#define WM8994_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */
3398#define WM8994_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */
3399#define WM8994_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */
3400#define WM8994_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */
3401
3402/*
3403 * R1345 (0x541) - AIF2 DRC (2)
3404 */
3405#define WM8994_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */
3406#define WM8994_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */
3407#define WM8994_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */
3408#define WM8994_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */
3409#define WM8994_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */
3410#define WM8994_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */
3411#define WM8994_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */
3412#define WM8994_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */
3413#define WM8994_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */
3414#define WM8994_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */
3415#define WM8994_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */
3416#define WM8994_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */
3417
3418/*
3419 * R1346 (0x542) - AIF2 DRC (3)
3420 */
3421#define WM8994_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */
3422#define WM8994_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */
3423#define WM8994_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */
3424#define WM8994_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */
3425#define WM8994_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */
3426#define WM8994_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */
3427#define WM8994_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */
3428#define WM8994_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */
3429#define WM8994_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */
3430#define WM8994_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */
3431#define WM8994_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */
3432#define WM8994_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */
3433#define WM8994_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */
3434#define WM8994_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */
3435#define WM8994_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */
3436#define WM8994_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */
3437#define WM8994_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */
3438#define WM8994_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */
3439
3440/*
3441 * R1347 (0x543) - AIF2 DRC (4)
3442 */
3443#define WM8994_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */
3444#define WM8994_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */
3445#define WM8994_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */
3446#define WM8994_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */
3447#define WM8994_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */
3448#define WM8994_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */
3449
3450/*
3451 * R1348 (0x544) - AIF2 DRC (5)
3452 */
3453#define WM8994_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */
3454#define WM8994_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */
3455#define WM8994_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */
3456#define WM8994_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */
3457#define WM8994_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */
3458#define WM8994_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */
3459
3460/*
3461 * R1408 (0x580) - AIF2 EQ Gains (1)
3462 */
3463#define WM8994_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
3464#define WM8994_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
3465#define WM8994_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
3466#define WM8994_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
3467#define WM8994_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
3468#define WM8994_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
3469#define WM8994_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */
3470#define WM8994_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
3471#define WM8994_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
3472#define WM8994_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */
3473#define WM8994_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */
3474#define WM8994_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */
3475#define WM8994_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */
3476
3477/*
3478 * R1409 (0x581) - AIF2 EQ Gains (2)
3479 */
3480#define WM8994_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
3481#define WM8994_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
3482#define WM8994_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
3483#define WM8994_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
3484#define WM8994_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
3485#define WM8994_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
3486
3487/*
3488 * R1410 (0x582) - AIF2 EQ Band 1 A
3489 */
3490#define WM8994_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */
3491#define WM8994_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */
3492#define WM8994_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */
3493
3494/*
3495 * R1411 (0x583) - AIF2 EQ Band 1 B
3496 */
3497#define WM8994_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */
3498#define WM8994_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */
3499#define WM8994_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */
3500
3501/*
3502 * R1412 (0x584) - AIF2 EQ Band 1 PG
3503 */
3504#define WM8994_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */
3505#define WM8994_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */
3506#define WM8994_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */
3507
3508/*
3509 * R1413 (0x585) - AIF2 EQ Band 2 A
3510 */
3511#define WM8994_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */
3512#define WM8994_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */
3513#define WM8994_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */
3514
3515/*
3516 * R1414 (0x586) - AIF2 EQ Band 2 B
3517 */
3518#define WM8994_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */
3519#define WM8994_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */
3520#define WM8994_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */
3521
3522/*
3523 * R1415 (0x587) - AIF2 EQ Band 2 C
3524 */
3525#define WM8994_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */
3526#define WM8994_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */
3527#define WM8994_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */
3528
3529/*
3530 * R1416 (0x588) - AIF2 EQ Band 2 PG
3531 */
3532#define WM8994_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */
3533#define WM8994_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */
3534#define WM8994_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */
3535
3536/*
3537 * R1417 (0x589) - AIF2 EQ Band 3 A
3538 */
3539#define WM8994_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */
3540#define WM8994_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */
3541#define WM8994_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */
3542
3543/*
3544 * R1418 (0x58A) - AIF2 EQ Band 3 B
3545 */
3546#define WM8994_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */
3547#define WM8994_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */
3548#define WM8994_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */
3549
3550/*
3551 * R1419 (0x58B) - AIF2 EQ Band 3 C
3552 */
3553#define WM8994_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */
3554#define WM8994_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */
3555#define WM8994_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */
3556
3557/*
3558 * R1420 (0x58C) - AIF2 EQ Band 3 PG
3559 */
3560#define WM8994_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */
3561#define WM8994_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */
3562#define WM8994_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */
3563
3564/*
3565 * R1421 (0x58D) - AIF2 EQ Band 4 A
3566 */
3567#define WM8994_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */
3568#define WM8994_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */
3569#define WM8994_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */
3570
3571/*
3572 * R1422 (0x58E) - AIF2 EQ Band 4 B
3573 */
3574#define WM8994_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */
3575#define WM8994_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */
3576#define WM8994_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */
3577
3578/*
3579 * R1423 (0x58F) - AIF2 EQ Band 4 C
3580 */
3581#define WM8994_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */
3582#define WM8994_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */
3583#define WM8994_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */
3584
3585/*
3586 * R1424 (0x590) - AIF2 EQ Band 4 PG
3587 */
3588#define WM8994_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */
3589#define WM8994_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */
3590#define WM8994_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */
3591
3592/*
3593 * R1425 (0x591) - AIF2 EQ Band 5 A
3594 */
3595#define WM8994_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */
3596#define WM8994_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */
3597#define WM8994_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */
3598
3599/*
3600 * R1426 (0x592) - AIF2 EQ Band 5 B
3601 */
3602#define WM8994_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */
3603#define WM8994_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */
3604#define WM8994_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */
3605
3606/*
3607 * R1427 (0x593) - AIF2 EQ Band 5 PG
3608 */
3609#define WM8994_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */
3610#define WM8994_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */
3611#define WM8994_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */
3612
3613/*
3614 * R1536 (0x600) - DAC1 Mixer Volumes
3615 */
3616#define WM8994_ADCR_DAC1_VOL_MASK 0x01E0 /* ADCR_DAC1_VOL - [8:5] */
3617#define WM8994_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [8:5] */
3618#define WM8994_ADCR_DAC1_VOL_WIDTH 4 /* ADCR_DAC1_VOL - [8:5] */
3619#define WM8994_ADCL_DAC1_VOL_MASK 0x000F /* ADCL_DAC1_VOL - [3:0] */
3620#define WM8994_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [3:0] */
3621#define WM8994_ADCL_DAC1_VOL_WIDTH 4 /* ADCL_DAC1_VOL - [3:0] */
3622
3623/*
3624 * R1537 (0x601) - DAC1 Left Mixer Routing
3625 */
3626#define WM8994_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
3627#define WM8994_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
3628#define WM8994_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
3629#define WM8994_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
3630#define WM8994_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
3631#define WM8994_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
3632#define WM8994_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
3633#define WM8994_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
3634#define WM8994_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */
3635#define WM8994_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */
3636#define WM8994_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */
3637#define WM8994_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */
3638#define WM8994_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */
3639#define WM8994_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */
3640#define WM8994_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */
3641#define WM8994_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */
3642#define WM8994_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */
3643#define WM8994_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */
3644#define WM8994_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */
3645#define WM8994_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */
3646
3647/*
3648 * R1538 (0x602) - DAC1 Right Mixer Routing
3649 */
3650#define WM8994_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
3651#define WM8994_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
3652#define WM8994_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
3653#define WM8994_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
3654#define WM8994_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
3655#define WM8994_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
3656#define WM8994_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
3657#define WM8994_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
3658#define WM8994_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */
3659#define WM8994_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */
3660#define WM8994_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */
3661#define WM8994_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */
3662#define WM8994_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */
3663#define WM8994_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */
3664#define WM8994_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */
3665#define WM8994_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */
3666#define WM8994_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */
3667#define WM8994_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */
3668#define WM8994_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */
3669#define WM8994_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */
3670
3671/*
3672 * R1539 (0x603) - DAC2 Mixer Volumes
3673 */
3674#define WM8994_ADCR_DAC2_VOL_MASK 0x01E0 /* ADCR_DAC2_VOL - [8:5] */
3675#define WM8994_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [8:5] */
3676#define WM8994_ADCR_DAC2_VOL_WIDTH 4 /* ADCR_DAC2_VOL - [8:5] */
3677#define WM8994_ADCL_DAC2_VOL_MASK 0x000F /* ADCL_DAC2_VOL - [3:0] */
3678#define WM8994_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [3:0] */
3679#define WM8994_ADCL_DAC2_VOL_WIDTH 4 /* ADCL_DAC2_VOL - [3:0] */
3680
3681/*
3682 * R1540 (0x604) - DAC2 Left Mixer Routing
3683 */
3684#define WM8994_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
3685#define WM8994_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
3686#define WM8994_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
3687#define WM8994_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
3688#define WM8994_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
3689#define WM8994_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
3690#define WM8994_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
3691#define WM8994_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
3692#define WM8994_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */
3693#define WM8994_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */
3694#define WM8994_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */
3695#define WM8994_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */
3696#define WM8994_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */
3697#define WM8994_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */
3698#define WM8994_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */
3699#define WM8994_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */
3700#define WM8994_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */
3701#define WM8994_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */
3702#define WM8994_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */
3703#define WM8994_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */
3704
3705/*
3706 * R1541 (0x605) - DAC2 Right Mixer Routing
3707 */
3708#define WM8994_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
3709#define WM8994_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
3710#define WM8994_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
3711#define WM8994_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
3712#define WM8994_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
3713#define WM8994_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
3714#define WM8994_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
3715#define WM8994_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
3716#define WM8994_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */
3717#define WM8994_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */
3718#define WM8994_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */
3719#define WM8994_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */
3720#define WM8994_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */
3721#define WM8994_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */
3722#define WM8994_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */
3723#define WM8994_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */
3724#define WM8994_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */
3725#define WM8994_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */
3726#define WM8994_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */
3727#define WM8994_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */
3728
3729/*
3730 * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing
3731 */
3732#define WM8994_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */
3733#define WM8994_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */
3734#define WM8994_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */
3735#define WM8994_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */
3736#define WM8994_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
3737#define WM8994_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
3738#define WM8994_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */
3739#define WM8994_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */
3740
3741/*
3742 * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing
3743 */
3744#define WM8994_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */
3745#define WM8994_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */
3746#define WM8994_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */
3747#define WM8994_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */
3748#define WM8994_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
3749#define WM8994_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
3750#define WM8994_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */
3751#define WM8994_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */
3752
3753/*
3754 * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing
3755 */
3756#define WM8994_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */
3757#define WM8994_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */
3758#define WM8994_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */
3759#define WM8994_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */
3760#define WM8994_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
3761#define WM8994_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
3762#define WM8994_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */
3763#define WM8994_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */
3764
3765/*
3766 * R1545 (0x609) - AIF1 ADC2 Right mixer Routing
3767 */
3768#define WM8994_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */
3769#define WM8994_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */
3770#define WM8994_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */
3771#define WM8994_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */
3772#define WM8994_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
3773#define WM8994_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
3774#define WM8994_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */
3775#define WM8994_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */
3776
3777/*
3778 * R1552 (0x610) - DAC1 Left Volume
3779 */
3780#define WM8994_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
3781#define WM8994_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
3782#define WM8994_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
3783#define WM8994_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
3784#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */
3785#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */
3786#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */
3787#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */
3788#define WM8994_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
3789#define WM8994_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
3790#define WM8994_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
3791
3792/*
3793 * R1553 (0x611) - DAC1 Right Volume
3794 */
3795#define WM8994_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
3796#define WM8994_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
3797#define WM8994_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
3798#define WM8994_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
3799#define WM8994_DAC1_VU 0x0100 /* DAC1_VU */
3800#define WM8994_DAC1_VU_MASK 0x0100 /* DAC1_VU */
3801#define WM8994_DAC1_VU_SHIFT 8 /* DAC1_VU */
3802#define WM8994_DAC1_VU_WIDTH 1 /* DAC1_VU */
3803#define WM8994_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
3804#define WM8994_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
3805#define WM8994_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
3806
3807/*
3808 * R1554 (0x612) - DAC2 Left Volume
3809 */
3810#define WM8994_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
3811#define WM8994_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
3812#define WM8994_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
3813#define WM8994_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
3814#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */
3815#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */
3816#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */
3817#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */
3818#define WM8994_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
3819#define WM8994_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
3820#define WM8994_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
3821
3822/*
3823 * R1555 (0x613) - DAC2 Right Volume
3824 */
3825#define WM8994_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
3826#define WM8994_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
3827#define WM8994_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
3828#define WM8994_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
3829#define WM8994_DAC2_VU 0x0100 /* DAC2_VU */
3830#define WM8994_DAC2_VU_MASK 0x0100 /* DAC2_VU */
3831#define WM8994_DAC2_VU_SHIFT 8 /* DAC2_VU */
3832#define WM8994_DAC2_VU_WIDTH 1 /* DAC2_VU */
3833#define WM8994_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
3834#define WM8994_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
3835#define WM8994_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
3836
3837/*
3838 * R1556 (0x614) - DAC Softmute
3839 */
3840#define WM8994_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
3841#define WM8994_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
3842#define WM8994_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
3843#define WM8994_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
3844#define WM8994_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
3845#define WM8994_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
3846#define WM8994_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
3847#define WM8994_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
3848
3849/*
3850 * R1568 (0x620) - Oversampling
3851 */
3852#define WM8994_ADC_OSR128 0x0002 /* ADC_OSR128 */
3853#define WM8994_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
3854#define WM8994_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
3855#define WM8994_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
3856#define WM8994_DAC_OSR128 0x0001 /* DAC_OSR128 */
3857#define WM8994_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
3858#define WM8994_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
3859#define WM8994_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
3860
3861/*
3862 * R1569 (0x621) - Sidetone
3863 */
3864#define WM8994_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
3865#define WM8994_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
3866#define WM8994_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
3867#define WM8994_ST_HPF 0x0040 /* ST_HPF */
3868#define WM8994_ST_HPF_MASK 0x0040 /* ST_HPF */
3869#define WM8994_ST_HPF_SHIFT 6 /* ST_HPF */
3870#define WM8994_ST_HPF_WIDTH 1 /* ST_HPF */
3871#define WM8994_STR_SEL 0x0002 /* STR_SEL */
3872#define WM8994_STR_SEL_MASK 0x0002 /* STR_SEL */
3873#define WM8994_STR_SEL_SHIFT 1 /* STR_SEL */
3874#define WM8994_STR_SEL_WIDTH 1 /* STR_SEL */
3875#define WM8994_STL_SEL 0x0001 /* STL_SEL */
3876#define WM8994_STL_SEL_MASK 0x0001 /* STL_SEL */
3877#define WM8994_STL_SEL_SHIFT 0 /* STL_SEL */
3878#define WM8994_STL_SEL_WIDTH 1 /* STL_SEL */
3879
3880/*
3881 * R1824 (0x720) - Pull Control (1)
3882 */
3883#define WM8994_DMICDAT2_PU 0x0800 /* DMICDAT2_PU */
3884#define WM8994_DMICDAT2_PU_MASK 0x0800 /* DMICDAT2_PU */
3885#define WM8994_DMICDAT2_PU_SHIFT 11 /* DMICDAT2_PU */
3886#define WM8994_DMICDAT2_PU_WIDTH 1 /* DMICDAT2_PU */
3887#define WM8994_DMICDAT2_PD 0x0400 /* DMICDAT2_PD */
3888#define WM8994_DMICDAT2_PD_MASK 0x0400 /* DMICDAT2_PD */
3889#define WM8994_DMICDAT2_PD_SHIFT 10 /* DMICDAT2_PD */
3890#define WM8994_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3891#define WM8994_DMICDAT1_PU 0x0200 /* DMICDAT1_PU */
3892#define WM8994_DMICDAT1_PU_MASK 0x0200 /* DMICDAT1_PU */
3893#define WM8994_DMICDAT1_PU_SHIFT 9 /* DMICDAT1_PU */
3894#define WM8994_DMICDAT1_PU_WIDTH 1 /* DMICDAT1_PU */
3895#define WM8994_DMICDAT1_PD 0x0100 /* DMICDAT1_PD */
3896#define WM8994_DMICDAT1_PD_MASK 0x0100 /* DMICDAT1_PD */
3897#define WM8994_DMICDAT1_PD_SHIFT 8 /* DMICDAT1_PD */
3898#define WM8994_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3899#define WM8994_MCLK1_PU 0x0080 /* MCLK1_PU */
3900#define WM8994_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
3901#define WM8994_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
3902#define WM8994_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
3903#define WM8994_MCLK1_PD 0x0040 /* MCLK1_PD */
3904#define WM8994_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
3905#define WM8994_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
3906#define WM8994_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3907#define WM8994_DACDAT1_PU 0x0020 /* DACDAT1_PU */
3908#define WM8994_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
3909#define WM8994_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
3910#define WM8994_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
3911#define WM8994_DACDAT1_PD 0x0010 /* DACDAT1_PD */
3912#define WM8994_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
3913#define WM8994_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
3914#define WM8994_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
3915#define WM8994_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
3916#define WM8994_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
3917#define WM8994_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
3918#define WM8994_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
3919#define WM8994_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
3920#define WM8994_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
3921#define WM8994_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
3922#define WM8994_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
3923#define WM8994_BCLK1_PU 0x0002 /* BCLK1_PU */
3924#define WM8994_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
3925#define WM8994_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
3926#define WM8994_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
3927#define WM8994_BCLK1_PD 0x0001 /* BCLK1_PD */
3928#define WM8994_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
3929#define WM8994_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
3930#define WM8994_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
3931
3932/*
3933 * R1825 (0x721) - Pull Control (2)
3934 */
3935#define WM8994_CSNADDR_PD 0x0100 /* CSNADDR_PD */
3936#define WM8994_CSNADDR_PD_MASK 0x0100 /* CSNADDR_PD */
3937#define WM8994_CSNADDR_PD_SHIFT 8 /* CSNADDR_PD */
3938#define WM8994_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */
3939#define WM8994_LDO2ENA_PD 0x0040 /* LDO2ENA_PD */
3940#define WM8994_LDO2ENA_PD_MASK 0x0040 /* LDO2ENA_PD */
3941#define WM8994_LDO2ENA_PD_SHIFT 6 /* LDO2ENA_PD */
3942#define WM8994_LDO2ENA_PD_WIDTH 1 /* LDO2ENA_PD */
3943#define WM8994_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */
3944#define WM8994_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */
3945#define WM8994_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */
3946#define WM8994_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3947#define WM8994_CIFMODE_PD 0x0004 /* CIFMODE_PD */
3948#define WM8994_CIFMODE_PD_MASK 0x0004 /* CIFMODE_PD */
3949#define WM8994_CIFMODE_PD_SHIFT 2 /* CIFMODE_PD */
3950#define WM8994_CIFMODE_PD_WIDTH 1 /* CIFMODE_PD */
3951#define WM8994_SPKMODE_PU 0x0002 /* SPKMODE_PU */
3952#define WM8994_SPKMODE_PU_MASK 0x0002 /* SPKMODE_PU */
3953#define WM8994_SPKMODE_PU_SHIFT 1 /* SPKMODE_PU */
3954#define WM8994_SPKMODE_PU_WIDTH 1 /* SPKMODE_PU */
3955
3956/*
3957 * R1840 (0x730) - Interrupt Status 1
3958 */
3959#define WM8994_GP11_EINT 0x0400 /* GP11_EINT */
3960#define WM8994_GP11_EINT_MASK 0x0400 /* GP11_EINT */
3961#define WM8994_GP11_EINT_SHIFT 10 /* GP11_EINT */
3962#define WM8994_GP11_EINT_WIDTH 1 /* GP11_EINT */
3963#define WM8994_GP10_EINT 0x0200 /* GP10_EINT */
3964#define WM8994_GP10_EINT_MASK 0x0200 /* GP10_EINT */
3965#define WM8994_GP10_EINT_SHIFT 9 /* GP10_EINT */
3966#define WM8994_GP10_EINT_WIDTH 1 /* GP10_EINT */
3967#define WM8994_GP9_EINT 0x0100 /* GP9_EINT */
3968#define WM8994_GP9_EINT_MASK 0x0100 /* GP9_EINT */
3969#define WM8994_GP9_EINT_SHIFT 8 /* GP9_EINT */
3970#define WM8994_GP9_EINT_WIDTH 1 /* GP9_EINT */
3971#define WM8994_GP8_EINT 0x0080 /* GP8_EINT */
3972#define WM8994_GP8_EINT_MASK 0x0080 /* GP8_EINT */
3973#define WM8994_GP8_EINT_SHIFT 7 /* GP8_EINT */
3974#define WM8994_GP8_EINT_WIDTH 1 /* GP8_EINT */
3975#define WM8994_GP7_EINT 0x0040 /* GP7_EINT */
3976#define WM8994_GP7_EINT_MASK 0x0040 /* GP7_EINT */
3977#define WM8994_GP7_EINT_SHIFT 6 /* GP7_EINT */
3978#define WM8994_GP7_EINT_WIDTH 1 /* GP7_EINT */
3979#define WM8994_GP6_EINT 0x0020 /* GP6_EINT */
3980#define WM8994_GP6_EINT_MASK 0x0020 /* GP6_EINT */
3981#define WM8994_GP6_EINT_SHIFT 5 /* GP6_EINT */
3982#define WM8994_GP6_EINT_WIDTH 1 /* GP6_EINT */
3983#define WM8994_GP5_EINT 0x0010 /* GP5_EINT */
3984#define WM8994_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3985#define WM8994_GP5_EINT_SHIFT 4 /* GP5_EINT */
3986#define WM8994_GP5_EINT_WIDTH 1 /* GP5_EINT */
3987#define WM8994_GP4_EINT 0x0008 /* GP4_EINT */
3988#define WM8994_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3989#define WM8994_GP4_EINT_SHIFT 3 /* GP4_EINT */
3990#define WM8994_GP4_EINT_WIDTH 1 /* GP4_EINT */
3991#define WM8994_GP3_EINT 0x0004 /* GP3_EINT */
3992#define WM8994_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3993#define WM8994_GP3_EINT_SHIFT 2 /* GP3_EINT */
3994#define WM8994_GP3_EINT_WIDTH 1 /* GP3_EINT */
3995#define WM8994_GP2_EINT 0x0002 /* GP2_EINT */
3996#define WM8994_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3997#define WM8994_GP2_EINT_SHIFT 1 /* GP2_EINT */
3998#define WM8994_GP2_EINT_WIDTH 1 /* GP2_EINT */
3999#define WM8994_GP1_EINT 0x0001 /* GP1_EINT */
4000#define WM8994_GP1_EINT_MASK 0x0001 /* GP1_EINT */
4001#define WM8994_GP1_EINT_SHIFT 0 /* GP1_EINT */
4002#define WM8994_GP1_EINT_WIDTH 1 /* GP1_EINT */
4003
4004/*
4005 * R1841 (0x731) - Interrupt Status 2
4006 */
4007#define WM8994_TEMP_WARN_EINT 0x8000 /* TEMP_WARN_EINT */
4008#define WM8994_TEMP_WARN_EINT_MASK 0x8000 /* TEMP_WARN_EINT */
4009#define WM8994_TEMP_WARN_EINT_SHIFT 15 /* TEMP_WARN_EINT */
4010#define WM8994_TEMP_WARN_EINT_WIDTH 1 /* TEMP_WARN_EINT */
4011#define WM8994_DCS_DONE_EINT 0x4000 /* DCS_DONE_EINT */
4012#define WM8994_DCS_DONE_EINT_MASK 0x4000 /* DCS_DONE_EINT */
4013#define WM8994_DCS_DONE_EINT_SHIFT 14 /* DCS_DONE_EINT */
4014#define WM8994_DCS_DONE_EINT_WIDTH 1 /* DCS_DONE_EINT */
4015#define WM8994_WSEQ_DONE_EINT 0x2000 /* WSEQ_DONE_EINT */
4016#define WM8994_WSEQ_DONE_EINT_MASK 0x2000 /* WSEQ_DONE_EINT */
4017#define WM8994_WSEQ_DONE_EINT_SHIFT 13 /* WSEQ_DONE_EINT */
4018#define WM8994_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
4019#define WM8994_FIFOS_ERR_EINT 0x1000 /* FIFOS_ERR_EINT */
4020#define WM8994_FIFOS_ERR_EINT_MASK 0x1000 /* FIFOS_ERR_EINT */
4021#define WM8994_FIFOS_ERR_EINT_SHIFT 12 /* FIFOS_ERR_EINT */
4022#define WM8994_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
4023#define WM8994_AIF2DRC_SIG_DET_EINT 0x0800 /* AIF2DRC_SIG_DET_EINT */
4024#define WM8994_AIF2DRC_SIG_DET_EINT_MASK 0x0800 /* AIF2DRC_SIG_DET_EINT */
4025#define WM8994_AIF2DRC_SIG_DET_EINT_SHIFT 11 /* AIF2DRC_SIG_DET_EINT */
4026#define WM8994_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */
4027#define WM8994_AIF1DRC2_SIG_DET_EINT 0x0400 /* AIF1DRC2_SIG_DET_EINT */
4028#define WM8994_AIF1DRC2_SIG_DET_EINT_MASK 0x0400 /* AIF1DRC2_SIG_DET_EINT */
4029#define WM8994_AIF1DRC2_SIG_DET_EINT_SHIFT 10 /* AIF1DRC2_SIG_DET_EINT */
4030#define WM8994_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */
4031#define WM8994_AIF1DRC1_SIG_DET_EINT 0x0200 /* AIF1DRC1_SIG_DET_EINT */
4032#define WM8994_AIF1DRC1_SIG_DET_EINT_MASK 0x0200 /* AIF1DRC1_SIG_DET_EINT */
4033#define WM8994_AIF1DRC1_SIG_DET_EINT_SHIFT 9 /* AIF1DRC1_SIG_DET_EINT */
4034#define WM8994_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */
4035#define WM8994_SRC2_LOCK_EINT 0x0100 /* SRC2_LOCK_EINT */
4036#define WM8994_SRC2_LOCK_EINT_MASK 0x0100 /* SRC2_LOCK_EINT */
4037#define WM8994_SRC2_LOCK_EINT_SHIFT 8 /* SRC2_LOCK_EINT */
4038#define WM8994_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */
4039#define WM8994_SRC1_LOCK_EINT 0x0080 /* SRC1_LOCK_EINT */
4040#define WM8994_SRC1_LOCK_EINT_MASK 0x0080 /* SRC1_LOCK_EINT */
4041#define WM8994_SRC1_LOCK_EINT_SHIFT 7 /* SRC1_LOCK_EINT */
4042#define WM8994_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */
4043#define WM8994_FLL2_LOCK_EINT 0x0040 /* FLL2_LOCK_EINT */
4044#define WM8994_FLL2_LOCK_EINT_MASK 0x0040 /* FLL2_LOCK_EINT */
4045#define WM8994_FLL2_LOCK_EINT_SHIFT 6 /* FLL2_LOCK_EINT */
4046#define WM8994_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
4047#define WM8994_FLL1_LOCK_EINT 0x0020 /* FLL1_LOCK_EINT */
4048#define WM8994_FLL1_LOCK_EINT_MASK 0x0020 /* FLL1_LOCK_EINT */
4049#define WM8994_FLL1_LOCK_EINT_SHIFT 5 /* FLL1_LOCK_EINT */
4050#define WM8994_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
4051#define WM8994_MIC2_SHRT_EINT 0x0010 /* MIC2_SHRT_EINT */
4052#define WM8994_MIC2_SHRT_EINT_MASK 0x0010 /* MIC2_SHRT_EINT */
4053#define WM8994_MIC2_SHRT_EINT_SHIFT 4 /* MIC2_SHRT_EINT */
4054#define WM8994_MIC2_SHRT_EINT_WIDTH 1 /* MIC2_SHRT_EINT */
4055#define WM8994_MIC2_DET_EINT 0x0008 /* MIC2_DET_EINT */
4056#define WM8994_MIC2_DET_EINT_MASK 0x0008 /* MIC2_DET_EINT */
4057#define WM8994_MIC2_DET_EINT_SHIFT 3 /* MIC2_DET_EINT */
4058#define WM8994_MIC2_DET_EINT_WIDTH 1 /* MIC2_DET_EINT */
4059#define WM8994_MIC1_SHRT_EINT 0x0004 /* MIC1_SHRT_EINT */
4060#define WM8994_MIC1_SHRT_EINT_MASK 0x0004 /* MIC1_SHRT_EINT */
4061#define WM8994_MIC1_SHRT_EINT_SHIFT 2 /* MIC1_SHRT_EINT */
4062#define WM8994_MIC1_SHRT_EINT_WIDTH 1 /* MIC1_SHRT_EINT */
4063#define WM8994_MIC1_DET_EINT 0x0002 /* MIC1_DET_EINT */
4064#define WM8994_MIC1_DET_EINT_MASK 0x0002 /* MIC1_DET_EINT */
4065#define WM8994_MIC1_DET_EINT_SHIFT 1 /* MIC1_DET_EINT */
4066#define WM8994_MIC1_DET_EINT_WIDTH 1 /* MIC1_DET_EINT */
4067#define WM8994_TEMP_SHUT_EINT 0x0001 /* TEMP_SHUT_EINT */
4068#define WM8994_TEMP_SHUT_EINT_MASK 0x0001 /* TEMP_SHUT_EINT */
4069#define WM8994_TEMP_SHUT_EINT_SHIFT 0 /* TEMP_SHUT_EINT */
4070#define WM8994_TEMP_SHUT_EINT_WIDTH 1 /* TEMP_SHUT_EINT */
4071
4072/*
4073 * R1842 (0x732) - Interrupt Raw Status 2
4074 */
4075#define WM8994_TEMP_WARN_STS 0x8000 /* TEMP_WARN_STS */
4076#define WM8994_TEMP_WARN_STS_MASK 0x8000 /* TEMP_WARN_STS */
4077#define WM8994_TEMP_WARN_STS_SHIFT 15 /* TEMP_WARN_STS */
4078#define WM8994_TEMP_WARN_STS_WIDTH 1 /* TEMP_WARN_STS */
4079#define WM8994_DCS_DONE_STS 0x4000 /* DCS_DONE_STS */
4080#define WM8994_DCS_DONE_STS_MASK 0x4000 /* DCS_DONE_STS */
4081#define WM8994_DCS_DONE_STS_SHIFT 14 /* DCS_DONE_STS */
4082#define WM8994_DCS_DONE_STS_WIDTH 1 /* DCS_DONE_STS */
4083#define WM8994_WSEQ_DONE_STS 0x2000 /* WSEQ_DONE_STS */
4084#define WM8994_WSEQ_DONE_STS_MASK 0x2000 /* WSEQ_DONE_STS */
4085#define WM8994_WSEQ_DONE_STS_SHIFT 13 /* WSEQ_DONE_STS */
4086#define WM8994_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
4087#define WM8994_FIFOS_ERR_STS 0x1000 /* FIFOS_ERR_STS */
4088#define WM8994_FIFOS_ERR_STS_MASK 0x1000 /* FIFOS_ERR_STS */
4089#define WM8994_FIFOS_ERR_STS_SHIFT 12 /* FIFOS_ERR_STS */
4090#define WM8994_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
4091#define WM8994_AIF2DRC_SIG_DET_STS 0x0800 /* AIF2DRC_SIG_DET_STS */
4092#define WM8994_AIF2DRC_SIG_DET_STS_MASK 0x0800 /* AIF2DRC_SIG_DET_STS */
4093#define WM8994_AIF2DRC_SIG_DET_STS_SHIFT 11 /* AIF2DRC_SIG_DET_STS */
4094#define WM8994_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */
4095#define WM8994_AIF1DRC2_SIG_DET_STS 0x0400 /* AIF1DRC2_SIG_DET_STS */
4096#define WM8994_AIF1DRC2_SIG_DET_STS_MASK 0x0400 /* AIF1DRC2_SIG_DET_STS */
4097#define WM8994_AIF1DRC2_SIG_DET_STS_SHIFT 10 /* AIF1DRC2_SIG_DET_STS */
4098#define WM8994_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */
4099#define WM8994_AIF1DRC1_SIG_DET_STS 0x0200 /* AIF1DRC1_SIG_DET_STS */
4100#define WM8994_AIF1DRC1_SIG_DET_STS_MASK 0x0200 /* AIF1DRC1_SIG_DET_STS */
4101#define WM8994_AIF1DRC1_SIG_DET_STS_SHIFT 9 /* AIF1DRC1_SIG_DET_STS */
4102#define WM8994_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */
4103#define WM8994_SRC2_LOCK_STS 0x0100 /* SRC2_LOCK_STS */
4104#define WM8994_SRC2_LOCK_STS_MASK 0x0100 /* SRC2_LOCK_STS */
4105#define WM8994_SRC2_LOCK_STS_SHIFT 8 /* SRC2_LOCK_STS */
4106#define WM8994_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */
4107#define WM8994_SRC1_LOCK_STS 0x0080 /* SRC1_LOCK_STS */
4108#define WM8994_SRC1_LOCK_STS_MASK 0x0080 /* SRC1_LOCK_STS */
4109#define WM8994_SRC1_LOCK_STS_SHIFT 7 /* SRC1_LOCK_STS */
4110#define WM8994_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */
4111#define WM8994_FLL2_LOCK_STS 0x0040 /* FLL2_LOCK_STS */
4112#define WM8994_FLL2_LOCK_STS_MASK 0x0040 /* FLL2_LOCK_STS */
4113#define WM8994_FLL2_LOCK_STS_SHIFT 6 /* FLL2_LOCK_STS */
4114#define WM8994_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
4115#define WM8994_FLL1_LOCK_STS 0x0020 /* FLL1_LOCK_STS */
4116#define WM8994_FLL1_LOCK_STS_MASK 0x0020 /* FLL1_LOCK_STS */
4117#define WM8994_FLL1_LOCK_STS_SHIFT 5 /* FLL1_LOCK_STS */
4118#define WM8994_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
4119#define WM8994_MIC2_SHRT_STS 0x0010 /* MIC2_SHRT_STS */
4120#define WM8994_MIC2_SHRT_STS_MASK 0x0010 /* MIC2_SHRT_STS */
4121#define WM8994_MIC2_SHRT_STS_SHIFT 4 /* MIC2_SHRT_STS */
4122#define WM8994_MIC2_SHRT_STS_WIDTH 1 /* MIC2_SHRT_STS */
4123#define WM8994_MIC2_DET_STS 0x0008 /* MIC2_DET_STS */
4124#define WM8994_MIC2_DET_STS_MASK 0x0008 /* MIC2_DET_STS */
4125#define WM8994_MIC2_DET_STS_SHIFT 3 /* MIC2_DET_STS */
4126#define WM8994_MIC2_DET_STS_WIDTH 1 /* MIC2_DET_STS */
4127#define WM8994_MIC1_SHRT_STS 0x0004 /* MIC1_SHRT_STS */
4128#define WM8994_MIC1_SHRT_STS_MASK 0x0004 /* MIC1_SHRT_STS */
4129#define WM8994_MIC1_SHRT_STS_SHIFT 2 /* MIC1_SHRT_STS */
4130#define WM8994_MIC1_SHRT_STS_WIDTH 1 /* MIC1_SHRT_STS */
4131#define WM8994_MIC1_DET_STS 0x0002 /* MIC1_DET_STS */
4132#define WM8994_MIC1_DET_STS_MASK 0x0002 /* MIC1_DET_STS */
4133#define WM8994_MIC1_DET_STS_SHIFT 1 /* MIC1_DET_STS */
4134#define WM8994_MIC1_DET_STS_WIDTH 1 /* MIC1_DET_STS */
4135#define WM8994_TEMP_SHUT_STS 0x0001 /* TEMP_SHUT_STS */
4136#define WM8994_TEMP_SHUT_STS_MASK 0x0001 /* TEMP_SHUT_STS */
4137#define WM8994_TEMP_SHUT_STS_SHIFT 0 /* TEMP_SHUT_STS */
4138#define WM8994_TEMP_SHUT_STS_WIDTH 1 /* TEMP_SHUT_STS */
4139
4140/*
4141 * R1848 (0x738) - Interrupt Status 1 Mask
4142 */
4143#define WM8994_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */
4144#define WM8994_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */
4145#define WM8994_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */
4146#define WM8994_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */
4147#define WM8994_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */
4148#define WM8994_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */
4149#define WM8994_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */
4150#define WM8994_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */
4151#define WM8994_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */
4152#define WM8994_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */
4153#define WM8994_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */
4154#define WM8994_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */
4155#define WM8994_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */
4156#define WM8994_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */
4157#define WM8994_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */
4158#define WM8994_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */
4159#define WM8994_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */
4160#define WM8994_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */
4161#define WM8994_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */
4162#define WM8994_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */
4163#define WM8994_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
4164#define WM8994_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
4165#define WM8994_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
4166#define WM8994_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
4167#define WM8994_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
4168#define WM8994_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
4169#define WM8994_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
4170#define WM8994_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
4171#define WM8994_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
4172#define WM8994_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
4173#define WM8994_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
4174#define WM8994_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
4175#define WM8994_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
4176#define WM8994_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
4177#define WM8994_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
4178#define WM8994_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
4179#define WM8994_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
4180#define WM8994_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
4181#define WM8994_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
4182#define WM8994_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
4183#define WM8994_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
4184#define WM8994_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
4185#define WM8994_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
4186#define WM8994_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
4187
4188/*
4189 * R1849 (0x739) - Interrupt Status 2 Mask
4190 */
4191#define WM8994_IM_TEMP_WARN_EINT 0x8000 /* IM_TEMP_WARN_EINT */
4192#define WM8994_IM_TEMP_WARN_EINT_MASK 0x8000 /* IM_TEMP_WARN_EINT */
4193#define WM8994_IM_TEMP_WARN_EINT_SHIFT 15 /* IM_TEMP_WARN_EINT */
4194#define WM8994_IM_TEMP_WARN_EINT_WIDTH 1 /* IM_TEMP_WARN_EINT */
4195#define WM8994_IM_DCS_DONE_EINT 0x4000 /* IM_DCS_DONE_EINT */
4196#define WM8994_IM_DCS_DONE_EINT_MASK 0x4000 /* IM_DCS_DONE_EINT */
4197#define WM8994_IM_DCS_DONE_EINT_SHIFT 14 /* IM_DCS_DONE_EINT */
4198#define WM8994_IM_DCS_DONE_EINT_WIDTH 1 /* IM_DCS_DONE_EINT */
4199#define WM8994_IM_WSEQ_DONE_EINT 0x2000 /* IM_WSEQ_DONE_EINT */
4200#define WM8994_IM_WSEQ_DONE_EINT_MASK 0x2000 /* IM_WSEQ_DONE_EINT */
4201#define WM8994_IM_WSEQ_DONE_EINT_SHIFT 13 /* IM_WSEQ_DONE_EINT */
4202#define WM8994_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
4203#define WM8994_IM_FIFOS_ERR_EINT 0x1000 /* IM_FIFOS_ERR_EINT */
4204#define WM8994_IM_FIFOS_ERR_EINT_MASK 0x1000 /* IM_FIFOS_ERR_EINT */
4205#define WM8994_IM_FIFOS_ERR_EINT_SHIFT 12 /* IM_FIFOS_ERR_EINT */
4206#define WM8994_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
4207#define WM8994_IM_AIF2DRC_SIG_DET_EINT 0x0800 /* IM_AIF2DRC_SIG_DET_EINT */
4208#define WM8994_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0800 /* IM_AIF2DRC_SIG_DET_EINT */
4209#define WM8994_IM_AIF2DRC_SIG_DET_EINT_SHIFT 11 /* IM_AIF2DRC_SIG_DET_EINT */
4210#define WM8994_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */
4211#define WM8994_IM_AIF1DRC2_SIG_DET_EINT 0x0400 /* IM_AIF1DRC2_SIG_DET_EINT */
4212#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0400 /* IM_AIF1DRC2_SIG_DET_EINT */
4213#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 10 /* IM_AIF1DRC2_SIG_DET_EINT */
4214#define WM8994_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */
4215#define WM8994_IM_AIF1DRC1_SIG_DET_EINT 0x0200 /* IM_AIF1DRC1_SIG_DET_EINT */
4216#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0200 /* IM_AIF1DRC1_SIG_DET_EINT */
4217#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 9 /* IM_AIF1DRC1_SIG_DET_EINT */
4218#define WM8994_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */
4219#define WM8994_IM_SRC2_LOCK_EINT 0x0100 /* IM_SRC2_LOCK_EINT */
4220#define WM8994_IM_SRC2_LOCK_EINT_MASK 0x0100 /* IM_SRC2_LOCK_EINT */
4221#define WM8994_IM_SRC2_LOCK_EINT_SHIFT 8 /* IM_SRC2_LOCK_EINT */
4222#define WM8994_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */
4223#define WM8994_IM_SRC1_LOCK_EINT 0x0080 /* IM_SRC1_LOCK_EINT */
4224#define WM8994_IM_SRC1_LOCK_EINT_MASK 0x0080 /* IM_SRC1_LOCK_EINT */
4225#define WM8994_IM_SRC1_LOCK_EINT_SHIFT 7 /* IM_SRC1_LOCK_EINT */
4226#define WM8994_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */
4227#define WM8994_IM_FLL2_LOCK_EINT 0x0040 /* IM_FLL2_LOCK_EINT */
4228#define WM8994_IM_FLL2_LOCK_EINT_MASK 0x0040 /* IM_FLL2_LOCK_EINT */
4229#define WM8994_IM_FLL2_LOCK_EINT_SHIFT 6 /* IM_FLL2_LOCK_EINT */
4230#define WM8994_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
4231#define WM8994_IM_FLL1_LOCK_EINT 0x0020 /* IM_FLL1_LOCK_EINT */
4232#define WM8994_IM_FLL1_LOCK_EINT_MASK 0x0020 /* IM_FLL1_LOCK_EINT */
4233#define WM8994_IM_FLL1_LOCK_EINT_SHIFT 5 /* IM_FLL1_LOCK_EINT */
4234#define WM8994_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
4235#define WM8994_IM_MIC2_SHRT_EINT 0x0010 /* IM_MIC2_SHRT_EINT */
4236#define WM8994_IM_MIC2_SHRT_EINT_MASK 0x0010 /* IM_MIC2_SHRT_EINT */
4237#define WM8994_IM_MIC2_SHRT_EINT_SHIFT 4 /* IM_MIC2_SHRT_EINT */
4238#define WM8994_IM_MIC2_SHRT_EINT_WIDTH 1 /* IM_MIC2_SHRT_EINT */
4239#define WM8994_IM_MIC2_DET_EINT 0x0008 /* IM_MIC2_DET_EINT */
4240#define WM8994_IM_MIC2_DET_EINT_MASK 0x0008 /* IM_MIC2_DET_EINT */
4241#define WM8994_IM_MIC2_DET_EINT_SHIFT 3 /* IM_MIC2_DET_EINT */
4242#define WM8994_IM_MIC2_DET_EINT_WIDTH 1 /* IM_MIC2_DET_EINT */
4243#define WM8994_IM_MIC1_SHRT_EINT 0x0004 /* IM_MIC1_SHRT_EINT */
4244#define WM8994_IM_MIC1_SHRT_EINT_MASK 0x0004 /* IM_MIC1_SHRT_EINT */
4245#define WM8994_IM_MIC1_SHRT_EINT_SHIFT 2 /* IM_MIC1_SHRT_EINT */
4246#define WM8994_IM_MIC1_SHRT_EINT_WIDTH 1 /* IM_MIC1_SHRT_EINT */
4247#define WM8994_IM_MIC1_DET_EINT 0x0002 /* IM_MIC1_DET_EINT */
4248#define WM8994_IM_MIC1_DET_EINT_MASK 0x0002 /* IM_MIC1_DET_EINT */
4249#define WM8994_IM_MIC1_DET_EINT_SHIFT 1 /* IM_MIC1_DET_EINT */
4250#define WM8994_IM_MIC1_DET_EINT_WIDTH 1 /* IM_MIC1_DET_EINT */
4251#define WM8994_IM_TEMP_SHUT_EINT 0x0001 /* IM_TEMP_SHUT_EINT */
4252#define WM8994_IM_TEMP_SHUT_EINT_MASK 0x0001 /* IM_TEMP_SHUT_EINT */
4253#define WM8994_IM_TEMP_SHUT_EINT_SHIFT 0 /* IM_TEMP_SHUT_EINT */
4254#define WM8994_IM_TEMP_SHUT_EINT_WIDTH 1 /* IM_TEMP_SHUT_EINT */
4255
4256/*
4257 * R1856 (0x740) - Interrupt Control
4258 */
4259#define WM8994_IM_IRQ 0x0001 /* IM_IRQ */
4260#define WM8994_IM_IRQ_MASK 0x0001 /* IM_IRQ */
4261#define WM8994_IM_IRQ_SHIFT 0 /* IM_IRQ */
4262#define WM8994_IM_IRQ_WIDTH 1 /* IM_IRQ */
4263
4264/*
4265 * R1864 (0x748) - IRQ Debounce
4266 */
4267#define WM8994_TEMP_WARN_DB 0x0020 /* TEMP_WARN_DB */
4268#define WM8994_TEMP_WARN_DB_MASK 0x0020 /* TEMP_WARN_DB */
4269#define WM8994_TEMP_WARN_DB_SHIFT 5 /* TEMP_WARN_DB */
4270#define WM8994_TEMP_WARN_DB_WIDTH 1 /* TEMP_WARN_DB */
4271#define WM8994_MIC2_SHRT_DB 0x0010 /* MIC2_SHRT_DB */
4272#define WM8994_MIC2_SHRT_DB_MASK 0x0010 /* MIC2_SHRT_DB */
4273#define WM8994_MIC2_SHRT_DB_SHIFT 4 /* MIC2_SHRT_DB */
4274#define WM8994_MIC2_SHRT_DB_WIDTH 1 /* MIC2_SHRT_DB */
4275#define WM8994_MIC2_DET_DB 0x0008 /* MIC2_DET_DB */
4276#define WM8994_MIC2_DET_DB_MASK 0x0008 /* MIC2_DET_DB */
4277#define WM8994_MIC2_DET_DB_SHIFT 3 /* MIC2_DET_DB */
4278#define WM8994_MIC2_DET_DB_WIDTH 1 /* MIC2_DET_DB */
4279#define WM8994_MIC1_SHRT_DB 0x0004 /* MIC1_SHRT_DB */
4280#define WM8994_MIC1_SHRT_DB_MASK 0x0004 /* MIC1_SHRT_DB */
4281#define WM8994_MIC1_SHRT_DB_SHIFT 2 /* MIC1_SHRT_DB */
4282#define WM8994_MIC1_SHRT_DB_WIDTH 1 /* MIC1_SHRT_DB */
4283#define WM8994_MIC1_DET_DB 0x0002 /* MIC1_DET_DB */
4284#define WM8994_MIC1_DET_DB_MASK 0x0002 /* MIC1_DET_DB */
4285#define WM8994_MIC1_DET_DB_SHIFT 1 /* MIC1_DET_DB */
4286#define WM8994_MIC1_DET_DB_WIDTH 1 /* MIC1_DET_DB */
4287#define WM8994_TEMP_SHUT_DB 0x0001 /* TEMP_SHUT_DB */
4288#define WM8994_TEMP_SHUT_DB_MASK 0x0001 /* TEMP_SHUT_DB */
4289#define WM8994_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */
4290#define WM8994_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */
4291
4292#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 90957f14195c..3899395a03de 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -870,6 +870,108 @@ extern int mprotect_fixup(struct vm_area_struct *vma,
870 */ 870 */
871int __get_user_pages_fast(unsigned long start, int nr_pages, int write, 871int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
872 struct page **pages); 872 struct page **pages);
873/*
874 * per-process(per-mm_struct) statistics.
875 */
876#if defined(SPLIT_RSS_COUNTING)
877/*
878 * The mm counters are not protected by its page_table_lock,
879 * so must be incremented atomically.
880 */
881static inline void set_mm_counter(struct mm_struct *mm, int member, long value)
882{
883 atomic_long_set(&mm->rss_stat.count[member], value);
884}
885
886unsigned long get_mm_counter(struct mm_struct *mm, int member);
887
888static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
889{
890 atomic_long_add(value, &mm->rss_stat.count[member]);
891}
892
893static inline void inc_mm_counter(struct mm_struct *mm, int member)
894{
895 atomic_long_inc(&mm->rss_stat.count[member]);
896}
897
898static inline void dec_mm_counter(struct mm_struct *mm, int member)
899{
900 atomic_long_dec(&mm->rss_stat.count[member]);
901}
902
903#else /* !USE_SPLIT_PTLOCKS */
904/*
905 * The mm counters are protected by its page_table_lock,
906 * so can be incremented directly.
907 */
908static inline void set_mm_counter(struct mm_struct *mm, int member, long value)
909{
910 mm->rss_stat.count[member] = value;
911}
912
913static inline unsigned long get_mm_counter(struct mm_struct *mm, int member)
914{
915 return mm->rss_stat.count[member];
916}
917
918static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
919{
920 mm->rss_stat.count[member] += value;
921}
922
923static inline void inc_mm_counter(struct mm_struct *mm, int member)
924{
925 mm->rss_stat.count[member]++;
926}
927
928static inline void dec_mm_counter(struct mm_struct *mm, int member)
929{
930 mm->rss_stat.count[member]--;
931}
932
933#endif /* !USE_SPLIT_PTLOCKS */
934
935static inline unsigned long get_mm_rss(struct mm_struct *mm)
936{
937 return get_mm_counter(mm, MM_FILEPAGES) +
938 get_mm_counter(mm, MM_ANONPAGES);
939}
940
941static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm)
942{
943 return max(mm->hiwater_rss, get_mm_rss(mm));
944}
945
946static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm)
947{
948 return max(mm->hiwater_vm, mm->total_vm);
949}
950
951static inline void update_hiwater_rss(struct mm_struct *mm)
952{
953 unsigned long _rss = get_mm_rss(mm);
954
955 if ((mm)->hiwater_rss < _rss)
956 (mm)->hiwater_rss = _rss;
957}
958
959static inline void update_hiwater_vm(struct mm_struct *mm)
960{
961 if (mm->hiwater_vm < mm->total_vm)
962 mm->hiwater_vm = mm->total_vm;
963}
964
965static inline void setmax_mm_hiwater_rss(unsigned long *maxrss,
966 struct mm_struct *mm)
967{
968 unsigned long hiwater_rss = get_mm_hiwater_rss(mm);
969
970 if (*maxrss < hiwater_rss)
971 *maxrss = hiwater_rss;
972}
973
974void sync_mm_rss(struct task_struct *task, struct mm_struct *mm);
873 975
874/* 976/*
875 * A callback you can register to apply pressure to ageable caches. 977 * A callback you can register to apply pressure to ageable caches.
@@ -1114,7 +1216,7 @@ static inline void vma_nonlinear_insert(struct vm_area_struct *vma,
1114 1216
1115/* mmap.c */ 1217/* mmap.c */
1116extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin); 1218extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin);
1117extern void vma_adjust(struct vm_area_struct *vma, unsigned long start, 1219extern int vma_adjust(struct vm_area_struct *vma, unsigned long start,
1118 unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert); 1220 unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert);
1119extern struct vm_area_struct *vma_merge(struct mm_struct *, 1221extern struct vm_area_struct *vma_merge(struct mm_struct *,
1120 struct vm_area_struct *prev, unsigned long addr, unsigned long end, 1222 struct vm_area_struct *prev, unsigned long addr, unsigned long end,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 36f96271306c..048b46270aa5 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -24,12 +24,6 @@ struct address_space;
24 24
25#define USE_SPLIT_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS) 25#define USE_SPLIT_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS)
26 26
27#if USE_SPLIT_PTLOCKS
28typedef atomic_long_t mm_counter_t;
29#else /* !USE_SPLIT_PTLOCKS */
30typedef unsigned long mm_counter_t;
31#endif /* !USE_SPLIT_PTLOCKS */
32
33/* 27/*
34 * Each physical page in the system has a struct page associated with 28 * Each physical page in the system has a struct page associated with
35 * it to keep track of whatever it is we are using the page for at the 29 * it to keep track of whatever it is we are using the page for at the
@@ -169,7 +163,8 @@ struct vm_area_struct {
169 * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack 163 * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
170 * or brk vma (with NULL file) can only be in an anon_vma list. 164 * or brk vma (with NULL file) can only be in an anon_vma list.
171 */ 165 */
172 struct list_head anon_vma_node; /* Serialized by anon_vma->lock */ 166 struct list_head anon_vma_chain; /* Serialized by mmap_sem &
167 * page_table_lock */
173 struct anon_vma *anon_vma; /* Serialized by page_table_lock */ 168 struct anon_vma *anon_vma; /* Serialized by page_table_lock */
174 169
175 /* Function pointers to deal with this struct. */ 170 /* Function pointers to deal with this struct. */
@@ -201,6 +196,29 @@ struct core_state {
201 struct completion startup; 196 struct completion startup;
202}; 197};
203 198
199enum {
200 MM_FILEPAGES,
201 MM_ANONPAGES,
202 MM_SWAPENTS,
203 NR_MM_COUNTERS
204};
205
206#if USE_SPLIT_PTLOCKS
207#define SPLIT_RSS_COUNTING
208struct mm_rss_stat {
209 atomic_long_t count[NR_MM_COUNTERS];
210};
211/* per-thread cached information, */
212struct task_rss_stat {
213 int events; /* for synchronization threshold */
214 int count[NR_MM_COUNTERS];
215};
216#else /* !USE_SPLIT_PTLOCKS */
217struct mm_rss_stat {
218 unsigned long count[NR_MM_COUNTERS];
219};
220#endif /* !USE_SPLIT_PTLOCKS */
221
204struct mm_struct { 222struct mm_struct {
205 struct vm_area_struct * mmap; /* list of VMAs */ 223 struct vm_area_struct * mmap; /* list of VMAs */
206 struct rb_root mm_rb; 224 struct rb_root mm_rb;
@@ -227,11 +245,6 @@ struct mm_struct {
227 * by mmlist_lock 245 * by mmlist_lock
228 */ 246 */
229 247
230 /* Special counters, in some configurations protected by the
231 * page_table_lock, in other configurations by being atomic.
232 */
233 mm_counter_t _file_rss;
234 mm_counter_t _anon_rss;
235 248
236 unsigned long hiwater_rss; /* High-watermark of RSS usage */ 249 unsigned long hiwater_rss; /* High-watermark of RSS usage */
237 unsigned long hiwater_vm; /* High-water virtual memory usage */ 250 unsigned long hiwater_vm; /* High-water virtual memory usage */
@@ -244,6 +257,12 @@ struct mm_struct {
244 257
245 unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ 258 unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
246 259
260 /*
261 * Special counters, in some configurations protected by the
262 * page_table_lock, in other configurations by being atomic.
263 */
264 struct mm_rss_stat rss_stat;
265
247 struct linux_binfmt *binfmt; 266 struct linux_binfmt *binfmt;
248 267
249 cpumask_t cpu_vm_mask; 268 cpumask_t cpu_vm_mask;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 2ee22e8af110..d02d2c6e0cfe 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -99,6 +99,8 @@ struct mmc_card {
99#define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */ 99#define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */
100 unsigned int quirks; /* card quirks */ 100 unsigned int quirks; /* card quirks */
101#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ 101#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
102#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
103 /* for byte mode */
102 104
103 u32 raw_cid[4]; /* raw card CID */ 105 u32 raw_cid[4]; /* raw card CID */
104 u32 raw_csd[4]; /* raw card CSD */ 106 u32 raw_csd[4]; /* raw card CSD */
@@ -139,6 +141,11 @@ static inline int mmc_card_lenient_fn0(const struct mmc_card *c)
139 return c->quirks & MMC_QUIRK_LENIENT_FN0; 141 return c->quirks & MMC_QUIRK_LENIENT_FN0;
140} 142}
141 143
144static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)
145{
146 return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
147}
148
142#define mmc_card_name(c) ((c)->cid.prod_name) 149#define mmc_card_name(c) ((c)->cid.prod_name)
143#define mmc_card_id(c) (dev_name(&(c)->dev)) 150#define mmc_card_id(c) (dev_name(&(c)->dev))
144 151
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index eaf36364b7d4..43eaf5ca5848 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -14,6 +14,7 @@
14#include <linux/sched.h> 14#include <linux/sched.h>
15 15
16#include <linux/mmc/core.h> 16#include <linux/mmc/core.h>
17#include <linux/mmc/pm.h>
17 18
18struct mmc_ios { 19struct mmc_ios {
19 unsigned int clock; /* clock rate */ 20 unsigned int clock; /* clock rate */
@@ -152,6 +153,8 @@ struct mmc_host {
152#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ 153#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */
153#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ 154#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */
154 155
156 mmc_pm_flag_t pm_caps; /* supported pm features */
157
155 /* host specific block data */ 158 /* host specific block data */
156 unsigned int max_seg_size; /* see blk_queue_max_segment_size */ 159 unsigned int max_seg_size; /* see blk_queue_max_segment_size */
157 unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */ 160 unsigned short max_hw_segs; /* see blk_queue_max_hw_segments */
@@ -197,6 +200,8 @@ struct mmc_host {
197 struct task_struct *sdio_irq_thread; 200 struct task_struct *sdio_irq_thread;
198 atomic_t sdio_irq_thread_abort; 201 atomic_t sdio_irq_thread_abort;
199 202
203 mmc_pm_flag_t pm_flags; /* requested pm features */
204
200#ifdef CONFIG_LEDS_TRIGGERS 205#ifdef CONFIG_LEDS_TRIGGERS
201 struct led_trigger *led; /* activity led */ 206 struct led_trigger *led; /* activity led */
202#endif 207#endif
diff --git a/include/linux/mmc/pm.h b/include/linux/mmc/pm.h
new file mode 100644
index 000000000000..d37aac49cf9a
--- /dev/null
+++ b/include/linux/mmc/pm.h
@@ -0,0 +1,30 @@
1/*
2 * linux/include/linux/mmc/pm.h
3 *
4 * Author: Nicolas Pitre
5 * Copyright: (C) 2009 Marvell Technology Group Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef LINUX_MMC_PM_H
13#define LINUX_MMC_PM_H
14
15/*
16 * These flags are used to describe power management features that
17 * some cards (typically SDIO cards) might wish to benefit from when
18 * the host system is being suspended. There are several layers of
19 * abstractions involved, from the host controller driver, to the MMC core
20 * code, to the SDIO core code, to finally get to the actual SDIO function
21 * driver. This file is therefore used for common definitions shared across
22 * all those layers.
23 */
24
25typedef unsigned int mmc_pm_flag_t;
26
27#define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */
28#define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */
29
30#endif
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 47ba464f5170..0ebaef577ff5 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -95,6 +95,8 @@
95#define SDIO_BUS_WIDTH_1BIT 0x00 95#define SDIO_BUS_WIDTH_1BIT 0x00
96#define SDIO_BUS_WIDTH_4BIT 0x02 96#define SDIO_BUS_WIDTH_4BIT 0x02
97 97
98#define SDIO_BUS_ASYNC_INT 0x20
99
98#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */ 100#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */
99 101
100#define SDIO_CCCR_CAPS 0x08 102#define SDIO_CCCR_CAPS 0x08
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
index ac3ab683fec6..c6c0cceba5fe 100644
--- a/include/linux/mmc/sdio_func.h
+++ b/include/linux/mmc/sdio_func.h
@@ -15,6 +15,8 @@
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/mod_devicetable.h> 16#include <linux/mod_devicetable.h>
17 17
18#include <linux/mmc/pm.h>
19
18struct mmc_card; 20struct mmc_card;
19struct sdio_func; 21struct sdio_func;
20 22
@@ -153,5 +155,8 @@ extern unsigned char sdio_f0_readb(struct sdio_func *func,
153extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b, 155extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
154 unsigned int addr, int *err_ret); 156 unsigned int addr, int *err_ret);
155 157
158extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func);
159extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);
160
156#endif 161#endif
157 162
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index a01a103341bd..bc209d8b7b5c 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -306,6 +306,7 @@ struct zone {
306 * free areas of different sizes 306 * free areas of different sizes
307 */ 307 */
308 spinlock_t lock; 308 spinlock_t lock;
309 int all_unreclaimable; /* All pages pinned */
309#ifdef CONFIG_MEMORY_HOTPLUG 310#ifdef CONFIG_MEMORY_HOTPLUG
310 /* see spanned/present_pages for more description */ 311 /* see spanned/present_pages for more description */
311 seqlock_t span_seqlock; 312 seqlock_t span_seqlock;
@@ -417,7 +418,6 @@ struct zone {
417} ____cacheline_internodealigned_in_smp; 418} ____cacheline_internodealigned_in_smp;
418 419
419typedef enum { 420typedef enum {
420 ZONE_ALL_UNRECLAIMABLE, /* all pages pinned */
421 ZONE_RECLAIM_LOCKED, /* prevents concurrent reclaim */ 421 ZONE_RECLAIM_LOCKED, /* prevents concurrent reclaim */
422 ZONE_OOM_LOCKED, /* zone is in OOM killer zonelist */ 422 ZONE_OOM_LOCKED, /* zone is in OOM killer zonelist */
423} zone_flags_t; 423} zone_flags_t;
@@ -437,11 +437,6 @@ static inline void zone_clear_flag(struct zone *zone, zone_flags_t flag)
437 clear_bit(flag, &zone->flags); 437 clear_bit(flag, &zone->flags);
438} 438}
439 439
440static inline int zone_is_all_unreclaimable(const struct zone *zone)
441{
442 return test_bit(ZONE_ALL_UNRECLAIMABLE, &zone->flags);
443}
444
445static inline int zone_is_reclaim_locked(const struct zone *zone) 440static inline int zone_is_reclaim_locked(const struct zone *zone)
446{ 441{
447 return test_bit(ZONE_RECLAIM_LOCKED, &zone->flags); 442 return test_bit(ZONE_RECLAIM_LOCKED, &zone->flags);
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 454997cccbd8..c4fa64b585ff 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -69,8 +69,6 @@
69 * int node_online(node) Is some node online? 69 * int node_online(node) Is some node online?
70 * int node_possible(node) Is some node possible? 70 * int node_possible(node) Is some node possible?
71 * 71 *
72 * int any_online_node(mask) First online node in mask
73 *
74 * node_set_online(node) set bit 'node' in node_online_map 72 * node_set_online(node) set bit 'node' in node_online_map
75 * node_set_offline(node) clear bit 'node' in node_online_map 73 * node_set_offline(node) clear bit 'node' in node_online_map
76 * 74 *
@@ -467,15 +465,6 @@ static inline int num_node_state(enum node_states state)
467#define node_online_map node_states[N_ONLINE] 465#define node_online_map node_states[N_ONLINE]
468#define node_possible_map node_states[N_POSSIBLE] 466#define node_possible_map node_states[N_POSSIBLE]
469 467
470#define any_online_node(mask) \
471({ \
472 int node; \
473 for_each_node_mask(node, (mask)) \
474 if (node_online(node)) \
475 break; \
476 node; \
477})
478
479#define num_online_nodes() num_node_state(N_ONLINE) 468#define num_online_nodes() num_node_state(N_ONLINE)
480#define num_possible_nodes() num_node_state(N_POSSIBLE) 469#define num_possible_nodes() num_node_state(N_POSSIBLE)
481#define node_online(node) node_state((node), N_ONLINE) 470#define node_online(node) node_state((node), N_ONLINE)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ec95ebe629f1..cd5809a5963e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -678,6 +678,8 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev);
678int pci_find_capability(struct pci_dev *dev, int cap); 678int pci_find_capability(struct pci_dev *dev, int cap);
679int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap); 679int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);
680int pci_find_ext_capability(struct pci_dev *dev, int cap); 680int pci_find_ext_capability(struct pci_dev *dev, int cap);
681int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
682 int cap);
681int pci_find_ht_capability(struct pci_dev *dev, int ht_cap); 683int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);
682int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap); 684int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
683struct pci_bus *pci_find_next_bus(const struct pci_bus *from); 685struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 9f2ad0aa3c39..c8f302991b66 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -507,6 +507,7 @@
507#define PCI_EXT_CAP_ID_VC 2 507#define PCI_EXT_CAP_ID_VC 2
508#define PCI_EXT_CAP_ID_DSN 3 508#define PCI_EXT_CAP_ID_DSN 3
509#define PCI_EXT_CAP_ID_PWR 4 509#define PCI_EXT_CAP_ID_PWR 4
510#define PCI_EXT_CAP_ID_VNDR 11
510#define PCI_EXT_CAP_ID_ACS 13 511#define PCI_EXT_CAP_ID_ACS 13
511#define PCI_EXT_CAP_ID_ARI 14 512#define PCI_EXT_CAP_ID_ARI 14
512#define PCI_EXT_CAP_ID_ATS 15 513#define PCI_EXT_CAP_ID_ATS 15
diff --git a/include/linux/pm.h b/include/linux/pm.h
index e80df06ad22a..8e258c727971 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -215,20 +215,59 @@ struct dev_pm_ops {
215 int (*runtime_idle)(struct device *dev); 215 int (*runtime_idle)(struct device *dev);
216}; 216};
217 217
218#ifdef CONFIG_PM_SLEEP
219#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
220 .suspend = suspend_fn, \
221 .resume = resume_fn, \
222 .freeze = suspend_fn, \
223 .thaw = resume_fn, \
224 .poweroff = suspend_fn, \
225 .restore = resume_fn,
226#else
227#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
228#endif
229
230#ifdef CONFIG_PM_RUNTIME
231#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
232 .runtime_suspend = suspend_fn, \
233 .runtime_resume = resume_fn, \
234 .runtime_idle = idle_fn,
235#else
236#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn)
237#endif
238
218/* 239/*
219 * Use this if you want to use the same suspend and resume callbacks for suspend 240 * Use this if you want to use the same suspend and resume callbacks for suspend
220 * to RAM and hibernation. 241 * to RAM and hibernation.
221 */ 242 */
222#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ 243#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
223const struct dev_pm_ops name = { \ 244const struct dev_pm_ops name = { \
224 .suspend = suspend_fn, \ 245 SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
225 .resume = resume_fn, \ 246}
226 .freeze = suspend_fn, \ 247
227 .thaw = resume_fn, \ 248/*
228 .poweroff = suspend_fn, \ 249 * Use this for defining a set of PM operations to be used in all situations
229 .restore = resume_fn, \ 250 * (sustem suspend, hibernation or runtime PM).
251 */
252#define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
253const struct dev_pm_ops name = { \
254 SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
255 SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
230} 256}
231 257
258/*
259 * Use this for subsystems (bus types, device types, device classes) that don't
260 * need any special suspend/resume handling in addition to invoking the PM
261 * callbacks provided by device drivers supporting both the system sleep PM and
262 * runtime PM, make the pm member point to generic_subsys_pm_ops.
263 */
264#ifdef CONFIG_PM_OPS
265extern struct dev_pm_ops generic_subsys_pm_ops;
266#define GENERIC_SUBSYS_PM_OPS (&generic_subsys_pm_ops)
267#else
268#define GENERIC_SUBSYS_PM_OPS NULL
269#endif
270
232/** 271/**
233 * PM_EVENT_ messages 272 * PM_EVENT_ messages
234 * 273 *
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 7d773aac5314..b776db737244 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -62,6 +62,11 @@ static inline void device_set_run_wake(struct device *dev, bool enable)
62 dev->power.run_wake = enable; 62 dev->power.run_wake = enable;
63} 63}
64 64
65static inline bool pm_runtime_suspended(struct device *dev)
66{
67 return dev->power.runtime_status == RPM_SUSPENDED;
68}
69
65#else /* !CONFIG_PM_RUNTIME */ 70#else /* !CONFIG_PM_RUNTIME */
66 71
67static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; } 72static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; }
@@ -89,6 +94,7 @@ static inline void pm_runtime_get_noresume(struct device *dev) {}
89static inline void pm_runtime_put_noidle(struct device *dev) {} 94static inline void pm_runtime_put_noidle(struct device *dev) {}
90static inline bool device_run_wake(struct device *dev) { return false; } 95static inline bool device_run_wake(struct device *dev) { return false; }
91static inline void device_set_run_wake(struct device *dev, bool enable) {} 96static inline void device_set_run_wake(struct device *dev, bool enable) {}
97static inline bool pm_runtime_suspended(struct device *dev) { return false; }
92 98
93#endif /* !CONFIG_PM_RUNTIME */ 99#endif /* !CONFIG_PM_RUNTIME */
94 100
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index b019ae64e2ab..d25bd224d370 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -37,7 +37,27 @@ struct anon_vma {
37 * is serialized by a system wide lock only visible to 37 * is serialized by a system wide lock only visible to
38 * mm_take_all_locks() (mm_all_locks_mutex). 38 * mm_take_all_locks() (mm_all_locks_mutex).
39 */ 39 */
40 struct list_head head; /* List of private "related" vmas */ 40 struct list_head head; /* Chain of private "related" vmas */
41};
42
43/*
44 * The copy-on-write semantics of fork mean that an anon_vma
45 * can become associated with multiple processes. Furthermore,
46 * each child process will have its own anon_vma, where new
47 * pages for that process are instantiated.
48 *
49 * This structure allows us to find the anon_vmas associated
50 * with a VMA, or the VMAs associated with an anon_vma.
51 * The "same_vma" list contains the anon_vma_chains linking
52 * all the anon_vmas associated with this VMA.
53 * The "same_anon_vma" list contains the anon_vma_chains
54 * which link all the VMAs associated with this anon_vma.
55 */
56struct anon_vma_chain {
57 struct vm_area_struct *vma;
58 struct anon_vma *anon_vma;
59 struct list_head same_vma; /* locked by mmap_sem & page_table_lock */
60 struct list_head same_anon_vma; /* locked by anon_vma->lock */
41}; 61};
42 62
43#ifdef CONFIG_MMU 63#ifdef CONFIG_MMU
@@ -89,15 +109,23 @@ static inline void anon_vma_unlock(struct vm_area_struct *vma)
89 */ 109 */
90void anon_vma_init(void); /* create anon_vma_cachep */ 110void anon_vma_init(void); /* create anon_vma_cachep */
91int anon_vma_prepare(struct vm_area_struct *); 111int anon_vma_prepare(struct vm_area_struct *);
92void __anon_vma_merge(struct vm_area_struct *, struct vm_area_struct *); 112void unlink_anon_vmas(struct vm_area_struct *);
93void anon_vma_unlink(struct vm_area_struct *); 113int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
94void anon_vma_link(struct vm_area_struct *); 114int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
95void __anon_vma_link(struct vm_area_struct *); 115void __anon_vma_link(struct vm_area_struct *);
96void anon_vma_free(struct anon_vma *); 116void anon_vma_free(struct anon_vma *);
97 117
118static inline void anon_vma_merge(struct vm_area_struct *vma,
119 struct vm_area_struct *next)
120{
121 VM_BUG_ON(vma->anon_vma != next->anon_vma);
122 unlink_anon_vmas(next);
123}
124
98/* 125/*
99 * rmap interfaces called when adding or removing pte of page 126 * rmap interfaces called when adding or removing pte of page
100 */ 127 */
128void page_move_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
101void page_add_anon_rmap(struct page *, struct vm_area_struct *, unsigned long); 129void page_add_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
102void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned long); 130void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
103void page_add_file_rmap(struct page *); 131void page_add_file_rmap(struct page *);
@@ -181,7 +209,7 @@ static inline int page_referenced(struct page *page, int is_locked,
181 unsigned long *vm_flags) 209 unsigned long *vm_flags)
182{ 210{
183 *vm_flags = 0; 211 *vm_flags = 0;
184 return TestClearPageReferenced(page); 212 return 0;
185} 213}
186 214
187#define try_to_unmap(page, refs) SWAP_FAIL 215#define try_to_unmap(page, refs) SWAP_FAIL
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4b1753f7e48e..46c6f8d5dc06 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -396,60 +396,6 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
396static inline void arch_pick_mmap_layout(struct mm_struct *mm) {} 396static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
397#endif 397#endif
398 398
399#if USE_SPLIT_PTLOCKS
400/*
401 * The mm counters are not protected by its page_table_lock,
402 * so must be incremented atomically.
403 */
404#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
405#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
406#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
407#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
408#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
409
410#else /* !USE_SPLIT_PTLOCKS */
411/*
412 * The mm counters are protected by its page_table_lock,
413 * so can be incremented directly.
414 */
415#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
416#define get_mm_counter(mm, member) ((mm)->_##member)
417#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
418#define inc_mm_counter(mm, member) (mm)->_##member++
419#define dec_mm_counter(mm, member) (mm)->_##member--
420
421#endif /* !USE_SPLIT_PTLOCKS */
422
423#define get_mm_rss(mm) \
424 (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
425#define update_hiwater_rss(mm) do { \
426 unsigned long _rss = get_mm_rss(mm); \
427 if ((mm)->hiwater_rss < _rss) \
428 (mm)->hiwater_rss = _rss; \
429} while (0)
430#define update_hiwater_vm(mm) do { \
431 if ((mm)->hiwater_vm < (mm)->total_vm) \
432 (mm)->hiwater_vm = (mm)->total_vm; \
433} while (0)
434
435static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm)
436{
437 return max(mm->hiwater_rss, get_mm_rss(mm));
438}
439
440static inline void setmax_mm_hiwater_rss(unsigned long *maxrss,
441 struct mm_struct *mm)
442{
443 unsigned long hiwater_rss = get_mm_hiwater_rss(mm);
444
445 if (*maxrss < hiwater_rss)
446 *maxrss = hiwater_rss;
447}
448
449static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm)
450{
451 return max(mm->hiwater_vm, mm->total_vm);
452}
453 399
454extern void set_dumpable(struct mm_struct *mm, int value); 400extern void set_dumpable(struct mm_struct *mm, int value);
455extern int get_dumpable(struct mm_struct *mm); 401extern int get_dumpable(struct mm_struct *mm);
@@ -1274,7 +1220,9 @@ struct task_struct {
1274 struct plist_node pushable_tasks; 1220 struct plist_node pushable_tasks;
1275 1221
1276 struct mm_struct *mm, *active_mm; 1222 struct mm_struct *mm, *active_mm;
1277 1223#if defined(SPLIT_RSS_COUNTING)
1224 struct task_rss_stat rss_stat;
1225#endif
1278/* task state */ 1226/* task state */
1279 int exit_state; 1227 int exit_state;
1280 int exit_code, exit_signal; 1228 int exit_code, exit_signal;
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index 1c297ddc9d5a..1b177d29a7f0 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -2,6 +2,7 @@
2#define __LINUX_SERIAL_SCI_H 2#define __LINUX_SERIAL_SCI_H
3 3
4#include <linux/serial_core.h> 4#include <linux/serial_core.h>
5#include <asm/dmaengine.h>
5 6
6/* 7/*
7 * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) 8 * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
@@ -16,6 +17,8 @@ enum {
16 SCIx_NR_IRQS, 17 SCIx_NR_IRQS,
17}; 18};
18 19
20struct device;
21
19/* 22/*
20 * Platform device specific platform_data struct 23 * Platform device specific platform_data struct
21 */ 24 */
@@ -26,6 +29,9 @@ struct plat_sci_port {
26 unsigned int type; /* SCI / SCIF / IRDA */ 29 unsigned int type; /* SCI / SCIF / IRDA */
27 upf_t flags; /* UPF_* flags */ 30 upf_t flags; /* UPF_* flags */
28 char *clk; /* clock string */ 31 char *clk; /* clock string */
32 struct device *dma_dev;
33 enum sh_dmae_slave_chan_id dma_slave_tx;
34 enum sh_dmae_slave_chan_id dma_slave_rx;
29}; 35};
30 36
31#endif /* __LINUX_SERIAL_SCI_H */ 37#endif /* __LINUX_SERIAL_SCI_H */
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 7a0570e6a596..cfa2d20e35f1 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -154,7 +154,7 @@ smp_call_function_any(const struct cpumask *mask, void (*func)(void *info),
154/* 154/*
155 * smp_processor_id(): get the current CPU ID. 155 * smp_processor_id(): get the current CPU ID.
156 * 156 *
157 * if DEBUG_PREEMPT is enabled the we check whether it is 157 * if DEBUG_PREEMPT is enabled then we check whether it is
158 * used in a preemption-safe way. (smp_processor_id() is safe 158 * used in a preemption-safe way. (smp_processor_id() is safe
159 * if it's used in a preemption-off critical section, or in 159 * if it's used in a preemption-off critical section, or in
160 * a thread that is bound to the current CPU.) 160 * a thread that is bound to the current CPU.)
diff --git a/include/linux/spi/max7301.h b/include/linux/spi/max7301.h
index 6dfd83f19b4b..34af0a3477bf 100644
--- a/include/linux/spi/max7301.h
+++ b/include/linux/spi/max7301.h
@@ -1,9 +1,27 @@
1#ifndef LINUX_SPI_MAX7301_H 1#ifndef LINUX_SPI_MAX7301_H
2#define LINUX_SPI_MAX7301_H 2#define LINUX_SPI_MAX7301_H
3 3
4#include <linux/gpio.h>
5
6/*
7 * Some registers must be read back to modify.
8 * To save time we cache them here in memory
9 */
10struct max7301 {
11 struct mutex lock;
12 u8 port_config[8]; /* field 0 is unused */
13 u32 out_level; /* cached output levels */
14 struct gpio_chip chip;
15 struct device *dev;
16 int (*write)(struct device *dev, unsigned int reg, unsigned int val);
17 int (*read)(struct device *dev, unsigned int reg);
18};
19
4struct max7301_platform_data { 20struct max7301_platform_data {
5 /* number assigned to the first GPIO */ 21 /* number assigned to the first GPIO */
6 unsigned base; 22 unsigned base;
7}; 23};
8 24
25extern int __max730x_remove(struct device *dev);
26extern int __max730x_probe(struct max7301 *ts);
9#endif 27#endif
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h
index 6bb293684eb8..4d3e450e2b03 100644
--- a/include/linux/usb/audio.h
+++ b/include/linux/usb/audio.h
@@ -269,8 +269,8 @@ struct uac_format_type_i_ext_descriptor {
269 __u8 bLength; 269 __u8 bLength;
270 __u8 bDescriptorType; 270 __u8 bDescriptorType;
271 __u8 bDescriptorSubtype; 271 __u8 bDescriptorSubtype;
272 __u8 bSubslotSize;
273 __u8 bFormatType; 272 __u8 bFormatType;
273 __u8 bSubslotSize;
274 __u8 bBitResolution; 274 __u8 bBitResolution;
275 __u8 bHeaderLength; 275 __u8 bHeaderLength;
276 __u8 bControlSize; 276 __u8 bControlSize;
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 1f57bb92eb5a..098595500632 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -544,7 +544,7 @@ struct snd_rawmidi_status {
544 * Timer section - /dev/snd/timer 544 * Timer section - /dev/snd/timer
545 */ 545 */
546 546
547#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 5) 547#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
548 548
549enum { 549enum {
550 SNDRV_TIMER_CLASS_NONE = -1, 550 SNDRV_TIMER_CLASS_NONE = -1,
diff --git a/init/initramfs.c b/init/initramfs.c
index b37d34beb90b..37d3859b1b32 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -525,7 +525,7 @@ static void __init clean_rootfs(void)
525 int fd; 525 int fd;
526 void *buf; 526 void *buf;
527 struct linux_dirent64 *dirp; 527 struct linux_dirent64 *dirp;
528 int count; 528 int num;
529 529
530 fd = sys_open("/", O_RDONLY, 0); 530 fd = sys_open("/", O_RDONLY, 0);
531 WARN_ON(fd < 0); 531 WARN_ON(fd < 0);
@@ -539,9 +539,9 @@ static void __init clean_rootfs(void)
539 } 539 }
540 540
541 dirp = buf; 541 dirp = buf;
542 count = sys_getdents64(fd, dirp, BUF_SIZE); 542 num = sys_getdents64(fd, dirp, BUF_SIZE);
543 while (count > 0) { 543 while (num > 0) {
544 while (count > 0) { 544 while (num > 0) {
545 struct stat st; 545 struct stat st;
546 int ret; 546 int ret;
547 547
@@ -554,12 +554,12 @@ static void __init clean_rootfs(void)
554 sys_unlink(dirp->d_name); 554 sys_unlink(dirp->d_name);
555 } 555 }
556 556
557 count -= dirp->d_reclen; 557 num -= dirp->d_reclen;
558 dirp = (void *)dirp + dirp->d_reclen; 558 dirp = (void *)dirp + dirp->d_reclen;
559 } 559 }
560 dirp = buf; 560 dirp = buf;
561 memset(buf, 0, BUF_SIZE); 561 memset(buf, 0, BUF_SIZE);
562 count = sys_getdents64(fd, dirp, BUF_SIZE); 562 num = sys_getdents64(fd, dirp, BUF_SIZE);
563 } 563 }
564 564
565 sys_close(fd); 565 sys_close(fd);
diff --git a/init/main.c b/init/main.c
index 40aaa020cd68..a1ab78ceb4b6 100644
--- a/init/main.c
+++ b/init/main.c
@@ -174,7 +174,7 @@ static int __init maxcpus(char *str)
174 174
175early_param("maxcpus", maxcpus); 175early_param("maxcpus", maxcpus);
176#else 176#else
177const unsigned int setup_max_cpus = NR_CPUS; 177static const unsigned int setup_max_cpus = NR_CPUS;
178#endif 178#endif
179 179
180/* 180/*
@@ -618,7 +618,7 @@ asmlinkage void __init start_kernel(void)
618 local_irq_enable(); 618 local_irq_enable();
619 619
620 /* Interrupts are enabled now so all GFP allocations are safe. */ 620 /* Interrupts are enabled now so all GFP allocations are safe. */
621 set_gfp_allowed_mask(__GFP_BITS_MASK); 621 gfp_allowed_mask = __GFP_BITS_MASK;
622 622
623 kmem_cache_init_late(); 623 kmem_cache_init_late();
624 624
@@ -847,7 +847,8 @@ static noinline int init_post(void)
847 run_init_process("/bin/init"); 847 run_init_process("/bin/init");
848 run_init_process("/bin/sh"); 848 run_init_process("/bin/sh");
849 849
850 panic("No init found. Try passing init= option to kernel."); 850 panic("No init found. Try passing init= option to kernel. "
851 "See Linux Documentation/init.txt for guidance.");
851} 852}
852 853
853static int __init kernel_init(void * unused) 854static int __init kernel_init(void * unused)
diff --git a/kernel/Makefile b/kernel/Makefile
index 7b974699f8c2..a987aa1676b5 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -91,6 +91,9 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
91obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o 91obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
92obj-$(CONFIG_TRACEPOINTS) += tracepoint.o 92obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
93obj-$(CONFIG_LATENCYTOP) += latencytop.o 93obj-$(CONFIG_LATENCYTOP) += latencytop.o
94obj-$(CONFIG_BINFMT_ELF) += elfcore.o
95obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o
96obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o
94obj-$(CONFIG_FUNCTION_TRACER) += trace/ 97obj-$(CONFIG_FUNCTION_TRACER) += trace/
95obj-$(CONFIG_TRACING) += trace/ 98obj-$(CONFIG_TRACING) += trace/
96obj-$(CONFIG_X86_DS) += trace/ 99obj-$(CONFIG_X86_DS) += trace/
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 677f25376a38..f8cced2692b3 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -338,7 +338,7 @@ int __cpuinit cpu_up(unsigned int cpu)
338 if (!cpu_possible(cpu)) { 338 if (!cpu_possible(cpu)) {
339 printk(KERN_ERR "can't online cpu %d because it is not " 339 printk(KERN_ERR "can't online cpu %d because it is not "
340 "configured as may-hotadd at boot time\n", cpu); 340 "configured as may-hotadd at boot time\n", cpu);
341#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) 341#if defined(CONFIG_IA64)
342 printk(KERN_ERR "please check additional_cpus= boot " 342 printk(KERN_ERR "please check additional_cpus= boot "
343 "parameter\n"); 343 "parameter\n");
344#endif 344#endif
diff --git a/kernel/elfcore.c b/kernel/elfcore.c
new file mode 100644
index 000000000000..ff915efef66d
--- /dev/null
+++ b/kernel/elfcore.c
@@ -0,0 +1,28 @@
1#include <linux/elf.h>
2#include <linux/fs.h>
3#include <linux/mm.h>
4
5#include <asm/elf.h>
6
7
8Elf_Half __weak elf_core_extra_phdrs(void)
9{
10 return 0;
11}
12
13int __weak elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
14 unsigned long limit)
15{
16 return 1;
17}
18
19int __weak elf_core_write_extra_data(struct file *file, size_t *size,
20 unsigned long limit)
21{
22 return 1;
23}
24
25size_t __weak elf_core_extra_data_size(void)
26{
27 return 0;
28}
diff --git a/kernel/exit.c b/kernel/exit.c
index 45ed043b8bf5..ce1e48c2d93d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -952,7 +952,8 @@ NORET_TYPE void do_exit(long code)
952 preempt_count()); 952 preempt_count());
953 953
954 acct_update_integrals(tsk); 954 acct_update_integrals(tsk);
955 955 /* sync mm's RSS info before statistics gathering */
956 sync_mm_rss(tsk, tsk->mm);
956 group_dead = atomic_dec_and_test(&tsk->signal->live); 957 group_dead = atomic_dec_and_test(&tsk->signal->live);
957 if (group_dead) { 958 if (group_dead) {
958 hrtimer_cancel(&tsk->signal->real_timer); 959 hrtimer_cancel(&tsk->signal->real_timer);
@@ -1188,7 +1189,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
1188 1189
1189 if (unlikely(wo->wo_flags & WNOWAIT)) { 1190 if (unlikely(wo->wo_flags & WNOWAIT)) {
1190 int exit_code = p->exit_code; 1191 int exit_code = p->exit_code;
1191 int why, status; 1192 int why;
1192 1193
1193 get_task_struct(p); 1194 get_task_struct(p);
1194 read_unlock(&tasklist_lock); 1195 read_unlock(&tasklist_lock);
diff --git a/kernel/fork.c b/kernel/fork.c
index 17bbf093356d..b0ec34abc0bb 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -329,15 +329,17 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
329 if (!tmp) 329 if (!tmp)
330 goto fail_nomem; 330 goto fail_nomem;
331 *tmp = *mpnt; 331 *tmp = *mpnt;
332 INIT_LIST_HEAD(&tmp->anon_vma_chain);
332 pol = mpol_dup(vma_policy(mpnt)); 333 pol = mpol_dup(vma_policy(mpnt));
333 retval = PTR_ERR(pol); 334 retval = PTR_ERR(pol);
334 if (IS_ERR(pol)) 335 if (IS_ERR(pol))
335 goto fail_nomem_policy; 336 goto fail_nomem_policy;
336 vma_set_policy(tmp, pol); 337 vma_set_policy(tmp, pol);
338 if (anon_vma_fork(tmp, mpnt))
339 goto fail_nomem_anon_vma_fork;
337 tmp->vm_flags &= ~VM_LOCKED; 340 tmp->vm_flags &= ~VM_LOCKED;
338 tmp->vm_mm = mm; 341 tmp->vm_mm = mm;
339 tmp->vm_next = NULL; 342 tmp->vm_next = NULL;
340 anon_vma_link(tmp);
341 file = tmp->vm_file; 343 file = tmp->vm_file;
342 if (file) { 344 if (file) {
343 struct inode *inode = file->f_path.dentry->d_inode; 345 struct inode *inode = file->f_path.dentry->d_inode;
@@ -392,6 +394,8 @@ out:
392 flush_tlb_mm(oldmm); 394 flush_tlb_mm(oldmm);
393 up_write(&oldmm->mmap_sem); 395 up_write(&oldmm->mmap_sem);
394 return retval; 396 return retval;
397fail_nomem_anon_vma_fork:
398 mpol_put(pol);
395fail_nomem_policy: 399fail_nomem_policy:
396 kmem_cache_free(vm_area_cachep, tmp); 400 kmem_cache_free(vm_area_cachep, tmp);
397fail_nomem: 401fail_nomem:
@@ -455,8 +459,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
455 (current->mm->flags & MMF_INIT_MASK) : default_dump_filter; 459 (current->mm->flags & MMF_INIT_MASK) : default_dump_filter;
456 mm->core_state = NULL; 460 mm->core_state = NULL;
457 mm->nr_ptes = 0; 461 mm->nr_ptes = 0;
458 set_mm_counter(mm, file_rss, 0); 462 memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
459 set_mm_counter(mm, anon_rss, 0);
460 spin_lock_init(&mm->page_table_lock); 463 spin_lock_init(&mm->page_table_lock);
461 mm->free_area_cache = TASK_UNMAPPED_BASE; 464 mm->free_area_cache = TASK_UNMAPPED_BASE;
462 mm->cached_hole_size = ~0UL; 465 mm->cached_hole_size = ~0UL;
@@ -825,6 +828,8 @@ void __cleanup_sighand(struct sighand_struct *sighand)
825 */ 828 */
826static void posix_cpu_timers_init_group(struct signal_struct *sig) 829static void posix_cpu_timers_init_group(struct signal_struct *sig)
827{ 830{
831 unsigned long cpu_limit;
832
828 /* Thread group counters. */ 833 /* Thread group counters. */
829 thread_group_cputime_init(sig); 834 thread_group_cputime_init(sig);
830 835
@@ -839,9 +844,9 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
839 sig->cputime_expires.virt_exp = cputime_zero; 844 sig->cputime_expires.virt_exp = cputime_zero;
840 sig->cputime_expires.sched_exp = 0; 845 sig->cputime_expires.sched_exp = 0;
841 846
842 if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { 847 cpu_limit = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
843 sig->cputime_expires.prof_exp = 848 if (cpu_limit != RLIM_INFINITY) {
844 secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); 849 sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit);
845 sig->cputimer.running = 1; 850 sig->cputimer.running = 1;
846 } 851 }
847 852
@@ -1034,7 +1039,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1034#endif 1039#endif
1035 retval = -EAGAIN; 1040 retval = -EAGAIN;
1036 if (atomic_read(&p->real_cred->user->processes) >= 1041 if (atomic_read(&p->real_cred->user->processes) >=
1037 p->signal->rlim[RLIMIT_NPROC].rlim_cur) { 1042 task_rlimit(p, RLIMIT_NPROC)) {
1038 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && 1043 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
1039 p->real_cred->user != INIT_USER) 1044 p->real_cred->user != INIT_USER)
1040 goto bad_fork_free; 1045 goto bad_fork_free;
diff --git a/kernel/panic.c b/kernel/panic.c
index c787333282b8..13d966b4c14a 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -36,15 +36,36 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
36 36
37EXPORT_SYMBOL(panic_notifier_list); 37EXPORT_SYMBOL(panic_notifier_list);
38 38
39static long no_blink(long time)
40{
41 return 0;
42}
43
44/* Returns how long it waited in ms */ 39/* Returns how long it waited in ms */
45long (*panic_blink)(long time); 40long (*panic_blink)(long time);
46EXPORT_SYMBOL(panic_blink); 41EXPORT_SYMBOL(panic_blink);
47 42
43static void panic_blink_one_second(void)
44{
45 static long i = 0, end;
46
47 if (panic_blink) {
48 end = i + MSEC_PER_SEC;
49
50 while (i < end) {
51 i += panic_blink(i);
52 mdelay(1);
53 i++;
54 }
55 } else {
56 /*
57 * When running under a hypervisor a small mdelay may get
58 * rounded up to the hypervisor timeslice. For example, with
59 * a 1ms in 10ms hypervisor timeslice we might inflate a
60 * mdelay(1) loop by 10x.
61 *
62 * If we have nothing to blink, spin on 1 second calls to
63 * mdelay to avoid this.
64 */
65 mdelay(MSEC_PER_SEC);
66 }
67}
68
48/** 69/**
49 * panic - halt the system 70 * panic - halt the system
50 * @fmt: The text string to print 71 * @fmt: The text string to print
@@ -95,9 +116,6 @@ NORET_TYPE void panic(const char * fmt, ...)
95 116
96 bust_spinlocks(0); 117 bust_spinlocks(0);
97 118
98 if (!panic_blink)
99 panic_blink = no_blink;
100
101 if (panic_timeout > 0) { 119 if (panic_timeout > 0) {
102 /* 120 /*
103 * Delay timeout seconds before rebooting the machine. 121 * Delay timeout seconds before rebooting the machine.
@@ -105,11 +123,9 @@ NORET_TYPE void panic(const char * fmt, ...)
105 */ 123 */
106 printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout); 124 printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout);
107 125
108 for (i = 0; i < panic_timeout*1000; ) { 126 for (i = 0; i < panic_timeout; i++) {
109 touch_nmi_watchdog(); 127 touch_nmi_watchdog();
110 i += panic_blink(i); 128 panic_blink_one_second();
111 mdelay(1);
112 i++;
113 } 129 }
114 /* 130 /*
115 * This will not be a clean reboot, with everything 131 * This will not be a clean reboot, with everything
@@ -135,11 +151,9 @@ NORET_TYPE void panic(const char * fmt, ...)
135 } 151 }
136#endif 152#endif
137 local_irq_enable(); 153 local_irq_enable();
138 for (i = 0; ; ) { 154 while (1) {
139 touch_softlockup_watchdog(); 155 touch_softlockup_watchdog();
140 i += panic_blink(i); 156 panic_blink_one_second();
141 mdelay(1);
142 i++;
143 } 157 }
144} 158}
145 159
diff --git a/kernel/params.c b/kernel/params.c
index cf1b69183127..8d95f5451b22 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -24,7 +24,6 @@
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <linux/string.h>
28 27
29#if 0 28#if 0
30#define DEBUGP printk 29#define DEBUGP printk
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index a661e7991865..8e352c756ba7 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -2610,7 +2610,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
2610 if (user_locked > user_lock_limit) 2610 if (user_locked > user_lock_limit)
2611 extra = user_locked - user_lock_limit; 2611 extra = user_locked - user_lock_limit;
2612 2612
2613 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 2613 lock_limit = rlimit(RLIMIT_MEMLOCK);
2614 lock_limit >>= PAGE_SHIFT; 2614 lock_limit >>= PAGE_SHIFT;
2615 locked = vma->vm_mm->locked_vm + extra; 2615 locked = vma->vm_mm->locked_vm + extra;
2616 2616
diff --git a/kernel/pid.c b/kernel/pid.c
index b08e697cd83f..86b296943e5f 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -376,7 +376,7 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type)
376EXPORT_SYMBOL(pid_task); 376EXPORT_SYMBOL(pid_task);
377 377
378/* 378/*
379 * Must be called under rcu_read_lock() or with tasklist_lock read-held. 379 * Must be called under rcu_read_lock().
380 */ 380 */
381struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) 381struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
382{ 382{
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 438ff4523513..1a22dfd42df9 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -982,6 +982,7 @@ static void check_thread_timers(struct task_struct *tsk,
982 int maxfire; 982 int maxfire;
983 struct list_head *timers = tsk->cpu_timers; 983 struct list_head *timers = tsk->cpu_timers;
984 struct signal_struct *const sig = tsk->signal; 984 struct signal_struct *const sig = tsk->signal;
985 unsigned long soft;
985 986
986 maxfire = 20; 987 maxfire = 20;
987 tsk->cputime_expires.prof_exp = cputime_zero; 988 tsk->cputime_expires.prof_exp = cputime_zero;
@@ -1030,9 +1031,10 @@ static void check_thread_timers(struct task_struct *tsk,
1030 /* 1031 /*
1031 * Check for the special case thread timers. 1032 * Check for the special case thread timers.
1032 */ 1033 */
1033 if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) { 1034 soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur);
1034 unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max; 1035 if (soft != RLIM_INFINITY) {
1035 unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur; 1036 unsigned long hard =
1037 ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_max);
1036 1038
1037 if (hard != RLIM_INFINITY && 1039 if (hard != RLIM_INFINITY &&
1038 tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) { 1040 tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
@@ -1043,14 +1045,13 @@ static void check_thread_timers(struct task_struct *tsk,
1043 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); 1045 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
1044 return; 1046 return;
1045 } 1047 }
1046 if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) { 1048 if (tsk->rt.timeout > DIV_ROUND_UP(soft, USEC_PER_SEC/HZ)) {
1047 /* 1049 /*
1048 * At the soft limit, send a SIGXCPU every second. 1050 * At the soft limit, send a SIGXCPU every second.
1049 */ 1051 */
1050 if (sig->rlim[RLIMIT_RTTIME].rlim_cur 1052 if (soft < hard) {
1051 < sig->rlim[RLIMIT_RTTIME].rlim_max) { 1053 soft += USEC_PER_SEC;
1052 sig->rlim[RLIMIT_RTTIME].rlim_cur += 1054 sig->rlim[RLIMIT_RTTIME].rlim_cur = soft;
1053 USEC_PER_SEC;
1054 } 1055 }
1055 printk(KERN_INFO 1056 printk(KERN_INFO
1056 "RT Watchdog Timeout: %s[%d]\n", 1057 "RT Watchdog Timeout: %s[%d]\n",
@@ -1121,6 +1122,7 @@ static void check_process_timers(struct task_struct *tsk,
1121 unsigned long long sum_sched_runtime, sched_expires; 1122 unsigned long long sum_sched_runtime, sched_expires;
1122 struct list_head *timers = sig->cpu_timers; 1123 struct list_head *timers = sig->cpu_timers;
1123 struct task_cputime cputime; 1124 struct task_cputime cputime;
1125 unsigned long soft;
1124 1126
1125 /* 1127 /*
1126 * Don't sample the current process CPU clocks if there are no timers. 1128 * Don't sample the current process CPU clocks if there are no timers.
@@ -1193,11 +1195,13 @@ static void check_process_timers(struct task_struct *tsk,
1193 SIGPROF); 1195 SIGPROF);
1194 check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime, 1196 check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime,
1195 SIGVTALRM); 1197 SIGVTALRM);
1196 1198 soft = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
1197 if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { 1199 if (soft != RLIM_INFINITY) {
1198 unsigned long psecs = cputime_to_secs(ptime); 1200 unsigned long psecs = cputime_to_secs(ptime);
1201 unsigned long hard =
1202 ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
1199 cputime_t x; 1203 cputime_t x;
1200 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) { 1204 if (psecs >= hard) {
1201 /* 1205 /*
1202 * At the hard limit, we just die. 1206 * At the hard limit, we just die.
1203 * No need to calculate anything else now. 1207 * No need to calculate anything else now.
@@ -1205,17 +1209,17 @@ static void check_process_timers(struct task_struct *tsk,
1205 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); 1209 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
1206 return; 1210 return;
1207 } 1211 }
1208 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) { 1212 if (psecs >= soft) {
1209 /* 1213 /*
1210 * At the soft limit, send a SIGXCPU every second. 1214 * At the soft limit, send a SIGXCPU every second.
1211 */ 1215 */
1212 __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk); 1216 __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
1213 if (sig->rlim[RLIMIT_CPU].rlim_cur 1217 if (soft < hard) {
1214 < sig->rlim[RLIMIT_CPU].rlim_max) { 1218 soft++;
1215 sig->rlim[RLIMIT_CPU].rlim_cur++; 1219 sig->rlim[RLIMIT_CPU].rlim_cur = soft;
1216 } 1220 }
1217 } 1221 }
1218 x = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); 1222 x = secs_to_cputime(soft);
1219 if (cputime_eq(prof_expires, cputime_zero) || 1223 if (cputime_eq(prof_expires, cputime_zero) ||
1220 cputime_lt(x, prof_expires)) { 1224 cputime_lt(x, prof_expires)) {
1221 prof_expires = x; 1225 prof_expires = x;
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index bbfe472d7524..da5288ec2392 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -323,6 +323,7 @@ static int create_image(int platform_mode)
323int hibernation_snapshot(int platform_mode) 323int hibernation_snapshot(int platform_mode)
324{ 324{
325 int error; 325 int error;
326 gfp_t saved_mask;
326 327
327 error = platform_begin(platform_mode); 328 error = platform_begin(platform_mode);
328 if (error) 329 if (error)
@@ -334,6 +335,7 @@ int hibernation_snapshot(int platform_mode)
334 goto Close; 335 goto Close;
335 336
336 suspend_console(); 337 suspend_console();
338 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
337 error = dpm_suspend_start(PMSG_FREEZE); 339 error = dpm_suspend_start(PMSG_FREEZE);
338 if (error) 340 if (error)
339 goto Recover_platform; 341 goto Recover_platform;
@@ -351,6 +353,7 @@ int hibernation_snapshot(int platform_mode)
351 353
352 dpm_resume_end(in_suspend ? 354 dpm_resume_end(in_suspend ?
353 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 355 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
356 set_gfp_allowed_mask(saved_mask);
354 resume_console(); 357 resume_console();
355 Close: 358 Close:
356 platform_end(platform_mode); 359 platform_end(platform_mode);
@@ -445,14 +448,17 @@ static int resume_target_kernel(bool platform_mode)
445int hibernation_restore(int platform_mode) 448int hibernation_restore(int platform_mode)
446{ 449{
447 int error; 450 int error;
451 gfp_t saved_mask;
448 452
449 pm_prepare_console(); 453 pm_prepare_console();
450 suspend_console(); 454 suspend_console();
455 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
451 error = dpm_suspend_start(PMSG_QUIESCE); 456 error = dpm_suspend_start(PMSG_QUIESCE);
452 if (!error) { 457 if (!error) {
453 error = resume_target_kernel(platform_mode); 458 error = resume_target_kernel(platform_mode);
454 dpm_resume_end(PMSG_RECOVER); 459 dpm_resume_end(PMSG_RECOVER);
455 } 460 }
461 set_gfp_allowed_mask(saved_mask);
456 resume_console(); 462 resume_console();
457 pm_restore_console(); 463 pm_restore_console();
458 return error; 464 return error;
@@ -466,6 +472,7 @@ int hibernation_restore(int platform_mode)
466int hibernation_platform_enter(void) 472int hibernation_platform_enter(void)
467{ 473{
468 int error; 474 int error;
475 gfp_t saved_mask;
469 476
470 if (!hibernation_ops) 477 if (!hibernation_ops)
471 return -ENOSYS; 478 return -ENOSYS;
@@ -481,6 +488,7 @@ int hibernation_platform_enter(void)
481 488
482 entering_platform_hibernation = true; 489 entering_platform_hibernation = true;
483 suspend_console(); 490 suspend_console();
491 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
484 error = dpm_suspend_start(PMSG_HIBERNATE); 492 error = dpm_suspend_start(PMSG_HIBERNATE);
485 if (error) { 493 if (error) {
486 if (hibernation_ops->recover) 494 if (hibernation_ops->recover)
@@ -518,6 +526,7 @@ int hibernation_platform_enter(void)
518 Resume_devices: 526 Resume_devices:
519 entering_platform_hibernation = false; 527 entering_platform_hibernation = false;
520 dpm_resume_end(PMSG_RESTORE); 528 dpm_resume_end(PMSG_RESTORE);
529 set_gfp_allowed_mask(saved_mask);
521 resume_console(); 530 resume_console();
522 531
523 Close: 532 Close:
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 6f10dfc2d3e9..44cce10b582d 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -189,6 +189,7 @@ static int suspend_enter(suspend_state_t state)
189int suspend_devices_and_enter(suspend_state_t state) 189int suspend_devices_and_enter(suspend_state_t state)
190{ 190{
191 int error; 191 int error;
192 gfp_t saved_mask;
192 193
193 if (!suspend_ops) 194 if (!suspend_ops)
194 return -ENOSYS; 195 return -ENOSYS;
@@ -199,6 +200,7 @@ int suspend_devices_and_enter(suspend_state_t state)
199 goto Close; 200 goto Close;
200 } 201 }
201 suspend_console(); 202 suspend_console();
203 saved_mask = clear_gfp_allowed_mask(GFP_IOFS);
202 suspend_test_start(); 204 suspend_test_start();
203 error = dpm_suspend_start(PMSG_SUSPEND); 205 error = dpm_suspend_start(PMSG_SUSPEND);
204 if (error) { 206 if (error) {
@@ -215,6 +217,7 @@ int suspend_devices_and_enter(suspend_state_t state)
215 suspend_test_start(); 217 suspend_test_start();
216 dpm_resume_end(PMSG_RESUME); 218 dpm_resume_end(PMSG_RESUME);
217 suspend_test_finish("resume devices"); 219 suspend_test_finish("resume devices");
220 set_gfp_allowed_mask(saved_mask);
218 resume_console(); 221 resume_console();
219 Close: 222 Close:
220 if (suspend_ops->end) 223 if (suspend_ops->end)
diff --git a/kernel/printk.c b/kernel/printk.c
index 40674122ecf2..75077ad0b537 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -70,8 +70,6 @@ int console_printk[4] = {
70 DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ 70 DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
71}; 71};
72 72
73static int saved_console_loglevel = -1;
74
75/* 73/*
76 * Low level drivers may need that to know if they can schedule in 74 * Low level drivers may need that to know if they can schedule in
77 * their unblank() callback or not. So let's export it. 75 * their unblank() callback or not. So let's export it.
@@ -146,6 +144,7 @@ static char __log_buf[__LOG_BUF_LEN];
146static char *log_buf = __log_buf; 144static char *log_buf = __log_buf;
147static int log_buf_len = __LOG_BUF_LEN; 145static int log_buf_len = __LOG_BUF_LEN;
148static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ 146static unsigned logged_chars; /* Number of chars produced since last read+clear operation */
147static int saved_console_loglevel = -1;
149 148
150#ifdef CONFIG_KEXEC 149#ifdef CONFIG_KEXEC
151/* 150/*
diff --git a/kernel/relay.c b/kernel/relay.c
index c705a41b4ba3..3d97f2821611 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -1215,14 +1215,14 @@ static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i)
1215/* 1215/*
1216 * subbuf_splice_actor - splice up to one subbuf's worth of data 1216 * subbuf_splice_actor - splice up to one subbuf's worth of data
1217 */ 1217 */
1218static int subbuf_splice_actor(struct file *in, 1218static ssize_t subbuf_splice_actor(struct file *in,
1219 loff_t *ppos, 1219 loff_t *ppos,
1220 struct pipe_inode_info *pipe, 1220 struct pipe_inode_info *pipe,
1221 size_t len, 1221 size_t len,
1222 unsigned int flags, 1222 unsigned int flags,
1223 int *nonpad_ret) 1223 int *nonpad_ret)
1224{ 1224{
1225 unsigned int pidx, poff, total_len, subbuf_pages, nr_pages, ret; 1225 unsigned int pidx, poff, total_len, subbuf_pages, nr_pages;
1226 struct rchan_buf *rbuf = in->private_data; 1226 struct rchan_buf *rbuf = in->private_data;
1227 unsigned int subbuf_size = rbuf->chan->subbuf_size; 1227 unsigned int subbuf_size = rbuf->chan->subbuf_size;
1228 uint64_t pos = (uint64_t) *ppos; 1228 uint64_t pos = (uint64_t) *ppos;
@@ -1241,6 +1241,7 @@ static int subbuf_splice_actor(struct file *in,
1241 .ops = &relay_pipe_buf_ops, 1241 .ops = &relay_pipe_buf_ops,
1242 .spd_release = relay_page_release, 1242 .spd_release = relay_page_release,
1243 }; 1243 };
1244 ssize_t ret;
1244 1245
1245 if (rbuf->subbufs_produced == rbuf->subbufs_consumed) 1246 if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
1246 return 0; 1247 return 0;
diff --git a/kernel/sched.c b/kernel/sched.c
index abb36b16b93b..b47ceeec1a91 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4353,7 +4353,7 @@ int can_nice(const struct task_struct *p, const int nice)
4353 /* convert nice value [19,-20] to rlimit style value [1,40] */ 4353 /* convert nice value [19,-20] to rlimit style value [1,40] */
4354 int nice_rlim = 20 - nice; 4354 int nice_rlim = 20 - nice;
4355 4355
4356 return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || 4356 return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
4357 capable(CAP_SYS_NICE)); 4357 capable(CAP_SYS_NICE));
4358} 4358}
4359 4359
@@ -4530,7 +4530,7 @@ recheck:
4530 4530
4531 if (!lock_task_sighand(p, &flags)) 4531 if (!lock_task_sighand(p, &flags))
4532 return -ESRCH; 4532 return -ESRCH;
4533 rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur; 4533 rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO);
4534 unlock_task_sighand(p, &flags); 4534 unlock_task_sighand(p, &flags);
4535 4535
4536 /* can't set/change the rt policy */ 4536 /* can't set/change the rt policy */
diff --git a/kernel/sched_cpupri.c b/kernel/sched_cpupri.c
index eeb3506c4834..82095bf2099f 100644
--- a/kernel/sched_cpupri.c
+++ b/kernel/sched_cpupri.c
@@ -47,7 +47,7 @@ static int convert_prio(int prio)
47} 47}
48 48
49#define for_each_cpupri_active(array, idx) \ 49#define for_each_cpupri_active(array, idx) \
50 for_each_bit(idx, array, CPUPRI_NR_PRIORITIES) 50 for_each_set_bit(idx, array, CPUPRI_NR_PRIORITIES)
51 51
52/** 52/**
53 * cpupri_find - find the best (lowest-pri) CPU in the system 53 * cpupri_find - find the best (lowest-pri) CPU in the system
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index bf3e38fdbe6d..5a6ed1f0990a 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -1662,8 +1662,9 @@ static void watchdog(struct rq *rq, struct task_struct *p)
1662 if (!p->signal) 1662 if (!p->signal)
1663 return; 1663 return;
1664 1664
1665 soft = p->signal->rlim[RLIMIT_RTTIME].rlim_cur; 1665 /* max may change after cur was read, this will be fixed next tick */
1666 hard = p->signal->rlim[RLIMIT_RTTIME].rlim_max; 1666 soft = task_rlimit(p, RLIMIT_RTTIME);
1667 hard = task_rlimit_max(p, RLIMIT_RTTIME);
1667 1668
1668 if (soft != RLIM_INFINITY) { 1669 if (soft != RLIM_INFINITY) {
1669 unsigned long next; 1670 unsigned long next;
diff --git a/kernel/signal.c b/kernel/signal.c
index 5bb9baffa4f1..dbd7fe073c55 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -245,7 +245,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
245 245
246 if (override_rlimit || 246 if (override_rlimit ||
247 atomic_read(&user->sigpending) <= 247 atomic_read(&user->sigpending) <=
248 t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) { 248 task_rlimit(t, RLIMIT_SIGPENDING)) {
249 q = kmem_cache_alloc(sigqueue_cachep, flags); 249 q = kmem_cache_alloc(sigqueue_cachep, flags);
250 } else { 250 } else {
251 print_dropped_signal(sig); 251 print_dropped_signal(sig);
diff --git a/kernel/sys.c b/kernel/sys.c
index 877fe4f8e05e..9814e43fb23b 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -571,8 +571,7 @@ static int set_user(struct cred *new)
571 if (!new_user) 571 if (!new_user)
572 return -EAGAIN; 572 return -EAGAIN;
573 573
574 if (atomic_read(&new_user->processes) >= 574 if (atomic_read(&new_user->processes) >= rlimit(RLIMIT_NPROC) &&
575 current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
576 new_user != INIT_USER) { 575 new_user != INIT_USER) {
577 free_uid(new_user); 576 free_uid(new_user);
578 return -EAGAIN; 577 return -EAGAIN;
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index 00d59d048edf..0a67e041edf8 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -21,6 +21,7 @@
21#include <linux/tsacct_kern.h> 21#include <linux/tsacct_kern.h>
22#include <linux/acct.h> 22#include <linux/acct.h>
23#include <linux/jiffies.h> 23#include <linux/jiffies.h>
24#include <linux/mm.h>
24 25
25/* 26/*
26 * fill in basic accounting fields 27 * fill in basic accounting fields
diff --git a/lib/Kconfig b/lib/Kconfig
index 97b136ff117e..170d8ca901d8 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -160,6 +160,9 @@ config TEXTSEARCH_BM
160config TEXTSEARCH_FSM 160config TEXTSEARCH_FSM
161 tristate 161 tristate
162 162
163config BTREE
164 boolean
165
163config HAS_IOMEM 166config HAS_IOMEM
164 boolean 167 boolean
165 depends on !NO_IOMEM 168 depends on !NO_IOMEM
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 5e3407d997b2..b520ec1f33c5 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -864,8 +864,7 @@ config DEBUG_FORCE_WEAK_PER_CPU
864 864
865config LKDTM 865config LKDTM
866 tristate "Linux Kernel Dump Test Tool Module" 866 tristate "Linux Kernel Dump Test Tool Module"
867 depends on DEBUG_KERNEL 867 depends on DEBUG_FS
868 depends on KPROBES
869 depends on BLOCK 868 depends on BLOCK
870 default n 869 default n
871 help 870 help
@@ -876,7 +875,7 @@ config LKDTM
876 called lkdtm. 875 called lkdtm.
877 876
878 Documentation on how to use the module can be found in 877 Documentation on how to use the module can be found in
879 drivers/misc/lkdtm.c 878 Documentation/fault-injection/provoke-crashes.txt
880 879
881config FAULT_INJECTION 880config FAULT_INJECTION
882 bool "Fault-injection framework" 881 bool "Fault-injection framework"
diff --git a/lib/Makefile b/lib/Makefile
index 3b0b4a696db9..2e152aed7198 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -41,6 +41,7 @@ lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
41obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o 41obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o
42obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o 42obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
43obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o 43obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
44obj-$(CONFIG_BTREE) += btree.o
44obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o 45obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
45obj-$(CONFIG_DEBUG_LIST) += list_debug.o 46obj-$(CONFIG_DEBUG_LIST) += list_debug.o
46obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o 47obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 11bf49750583..ffb78c916ccd 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -487,7 +487,7 @@ int __bitmap_parse(const char *buf, unsigned int buflen,
487EXPORT_SYMBOL(__bitmap_parse); 487EXPORT_SYMBOL(__bitmap_parse);
488 488
489/** 489/**
490 * bitmap_parse_user() 490 * bitmap_parse_user - convert an ASCII hex string in a user buffer into a bitmap
491 * 491 *
492 * @ubuf: pointer to user buffer containing string. 492 * @ubuf: pointer to user buffer containing string.
493 * @ulen: buffer size in bytes. If string is smaller than this 493 * @ulen: buffer size in bytes. If string is smaller than this
@@ -619,7 +619,7 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits)
619EXPORT_SYMBOL(bitmap_parselist); 619EXPORT_SYMBOL(bitmap_parselist);
620 620
621/** 621/**
622 * bitmap_pos_to_ord(buf, pos, bits) 622 * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
623 * @buf: pointer to a bitmap 623 * @buf: pointer to a bitmap
624 * @pos: a bit position in @buf (0 <= @pos < @bits) 624 * @pos: a bit position in @buf (0 <= @pos < @bits)
625 * @bits: number of valid bit positions in @buf 625 * @bits: number of valid bit positions in @buf
@@ -655,7 +655,7 @@ static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
655} 655}
656 656
657/** 657/**
658 * bitmap_ord_to_pos(buf, ord, bits) 658 * bitmap_ord_to_pos - find position of n-th set bit in bitmap
659 * @buf: pointer to bitmap 659 * @buf: pointer to bitmap
660 * @ord: ordinal bit position (n-th set bit, n >= 0) 660 * @ord: ordinal bit position (n-th set bit, n >= 0)
661 * @bits: number of valid bit positions in @buf 661 * @bits: number of valid bit positions in @buf
@@ -733,10 +733,9 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src,
733 bitmap_zero(dst, bits); 733 bitmap_zero(dst, bits);
734 734
735 w = bitmap_weight(new, bits); 735 w = bitmap_weight(new, bits);
736 for (oldbit = find_first_bit(src, bits); 736 for_each_set_bit(oldbit, src, bits) {
737 oldbit < bits;
738 oldbit = find_next_bit(src, bits, oldbit + 1)) {
739 int n = bitmap_pos_to_ord(old, oldbit, bits); 737 int n = bitmap_pos_to_ord(old, oldbit, bits);
738
740 if (n < 0 || w == 0) 739 if (n < 0 || w == 0)
741 set_bit(oldbit, dst); /* identity map */ 740 set_bit(oldbit, dst); /* identity map */
742 else 741 else
@@ -903,9 +902,7 @@ void bitmap_onto(unsigned long *dst, const unsigned long *orig,
903 */ 902 */
904 903
905 m = 0; 904 m = 0;
906 for (n = find_first_bit(relmap, bits); 905 for_each_set_bit(n, relmap, bits) {
907 n < bits;
908 n = find_next_bit(relmap, bits, n + 1)) {
909 /* m == bitmap_pos_to_ord(relmap, n, bits) */ 906 /* m == bitmap_pos_to_ord(relmap, n, bits) */
910 if (test_bit(m, orig)) 907 if (test_bit(m, orig))
911 set_bit(n, dst); 908 set_bit(n, dst);
@@ -934,9 +931,7 @@ void bitmap_fold(unsigned long *dst, const unsigned long *orig,
934 return; 931 return;
935 bitmap_zero(dst, bits); 932 bitmap_zero(dst, bits);
936 933
937 for (oldbit = find_first_bit(orig, bits); 934 for_each_set_bit(oldbit, orig, bits)
938 oldbit < bits;
939 oldbit = find_next_bit(orig, bits, oldbit + 1))
940 set_bit(oldbit % sz, dst); 935 set_bit(oldbit % sz, dst);
941} 936}
942EXPORT_SYMBOL(bitmap_fold); 937EXPORT_SYMBOL(bitmap_fold);
diff --git a/lib/btree.c b/lib/btree.c
new file mode 100644
index 000000000000..41859a820218
--- /dev/null
+++ b/lib/btree.c
@@ -0,0 +1,797 @@
1/*
2 * lib/btree.c - Simple In-memory B+Tree
3 *
4 * As should be obvious for Linux kernel code, license is GPLv2
5 *
6 * Copyright (c) 2007-2008 Joern Engel <joern@logfs.org>
7 * Bits and pieces stolen from Peter Zijlstra's code, which is
8 * Copyright 2007, Red Hat Inc. Peter Zijlstra <pzijlstr@redhat.com>
9 * GPLv2
10 *
11 * see http://programming.kicks-ass.net/kernel-patches/vma_lookup/btree.patch
12 *
13 * A relatively simple B+Tree implementation. I have written it as a learning
14 * excercise to understand how B+Trees work. Turned out to be useful as well.
15 *
16 * B+Trees can be used similar to Linux radix trees (which don't have anything
17 * in common with textbook radix trees, beware). Prerequisite for them working
18 * well is that access to a random tree node is much faster than a large number
19 * of operations within each node.
20 *
21 * Disks have fulfilled the prerequisite for a long time. More recently DRAM
22 * has gained similar properties, as memory access times, when measured in cpu
23 * cycles, have increased. Cacheline sizes have increased as well, which also
24 * helps B+Trees.
25 *
26 * Compared to radix trees, B+Trees are more efficient when dealing with a
27 * sparsely populated address space. Between 25% and 50% of the memory is
28 * occupied with valid pointers. When densely populated, radix trees contain
29 * ~98% pointers - hard to beat. Very sparse radix trees contain only ~2%
30 * pointers.
31 *
32 * This particular implementation stores pointers identified by a long value.
33 * Storing NULL pointers is illegal, lookup will return NULL when no entry
34 * was found.
35 *
36 * A tricks was used that is not commonly found in textbooks. The lowest
37 * values are to the right, not to the left. All used slots within a node
38 * are on the left, all unused slots contain NUL values. Most operations
39 * simply loop once over all slots and terminate on the first NUL.
40 */
41
42#include <linux/btree.h>
43#include <linux/cache.h>
44#include <linux/kernel.h>
45#include <linux/slab.h>
46#include <linux/module.h>
47
48#define MAX(a, b) ((a) > (b) ? (a) : (b))
49#define NODESIZE MAX(L1_CACHE_BYTES, 128)
50
51struct btree_geo {
52 int keylen;
53 int no_pairs;
54 int no_longs;
55};
56
57struct btree_geo btree_geo32 = {
58 .keylen = 1,
59 .no_pairs = NODESIZE / sizeof(long) / 2,
60 .no_longs = NODESIZE / sizeof(long) / 2,
61};
62EXPORT_SYMBOL_GPL(btree_geo32);
63
64#define LONG_PER_U64 (64 / BITS_PER_LONG)
65struct btree_geo btree_geo64 = {
66 .keylen = LONG_PER_U64,
67 .no_pairs = NODESIZE / sizeof(long) / (1 + LONG_PER_U64),
68 .no_longs = LONG_PER_U64 * (NODESIZE / sizeof(long) / (1 + LONG_PER_U64)),
69};
70EXPORT_SYMBOL_GPL(btree_geo64);
71
72struct btree_geo btree_geo128 = {
73 .keylen = 2 * LONG_PER_U64,
74 .no_pairs = NODESIZE / sizeof(long) / (1 + 2 * LONG_PER_U64),
75 .no_longs = 2 * LONG_PER_U64 * (NODESIZE / sizeof(long) / (1 + 2 * LONG_PER_U64)),
76};
77EXPORT_SYMBOL_GPL(btree_geo128);
78
79static struct kmem_cache *btree_cachep;
80
81void *btree_alloc(gfp_t gfp_mask, void *pool_data)
82{
83 return kmem_cache_alloc(btree_cachep, gfp_mask);
84}
85EXPORT_SYMBOL_GPL(btree_alloc);
86
87void btree_free(void *element, void *pool_data)
88{
89 kmem_cache_free(btree_cachep, element);
90}
91EXPORT_SYMBOL_GPL(btree_free);
92
93static unsigned long *btree_node_alloc(struct btree_head *head, gfp_t gfp)
94{
95 unsigned long *node;
96
97 node = mempool_alloc(head->mempool, gfp);
98 memset(node, 0, NODESIZE);
99 return node;
100}
101
102static int longcmp(const unsigned long *l1, const unsigned long *l2, size_t n)
103{
104 size_t i;
105
106 for (i = 0; i < n; i++) {
107 if (l1[i] < l2[i])
108 return -1;
109 if (l1[i] > l2[i])
110 return 1;
111 }
112 return 0;
113}
114
115static unsigned long *longcpy(unsigned long *dest, const unsigned long *src,
116 size_t n)
117{
118 size_t i;
119
120 for (i = 0; i < n; i++)
121 dest[i] = src[i];
122 return dest;
123}
124
125static unsigned long *longset(unsigned long *s, unsigned long c, size_t n)
126{
127 size_t i;
128
129 for (i = 0; i < n; i++)
130 s[i] = c;
131 return s;
132}
133
134static void dec_key(struct btree_geo *geo, unsigned long *key)
135{
136 unsigned long val;
137 int i;
138
139 for (i = geo->keylen - 1; i >= 0; i--) {
140 val = key[i];
141 key[i] = val - 1;
142 if (val)
143 break;
144 }
145}
146
147static unsigned long *bkey(struct btree_geo *geo, unsigned long *node, int n)
148{
149 return &node[n * geo->keylen];
150}
151
152static void *bval(struct btree_geo *geo, unsigned long *node, int n)
153{
154 return (void *)node[geo->no_longs + n];
155}
156
157static void setkey(struct btree_geo *geo, unsigned long *node, int n,
158 unsigned long *key)
159{
160 longcpy(bkey(geo, node, n), key, geo->keylen);
161}
162
163static void setval(struct btree_geo *geo, unsigned long *node, int n,
164 void *val)
165{
166 node[geo->no_longs + n] = (unsigned long) val;
167}
168
169static void clearpair(struct btree_geo *geo, unsigned long *node, int n)
170{
171 longset(bkey(geo, node, n), 0, geo->keylen);
172 node[geo->no_longs + n] = 0;
173}
174
175static inline void __btree_init(struct btree_head *head)
176{
177 head->node = NULL;
178 head->height = 0;
179}
180
181void btree_init_mempool(struct btree_head *head, mempool_t *mempool)
182{
183 __btree_init(head);
184 head->mempool = mempool;
185}
186EXPORT_SYMBOL_GPL(btree_init_mempool);
187
188int btree_init(struct btree_head *head)
189{
190 __btree_init(head);
191 head->mempool = mempool_create(0, btree_alloc, btree_free, NULL);
192 if (!head->mempool)
193 return -ENOMEM;
194 return 0;
195}
196EXPORT_SYMBOL_GPL(btree_init);
197
198void btree_destroy(struct btree_head *head)
199{
200 mempool_destroy(head->mempool);
201 head->mempool = NULL;
202}
203EXPORT_SYMBOL_GPL(btree_destroy);
204
205void *btree_last(struct btree_head *head, struct btree_geo *geo,
206 unsigned long *key)
207{
208 int height = head->height;
209 unsigned long *node = head->node;
210
211 if (height == 0)
212 return NULL;
213
214 for ( ; height > 1; height--)
215 node = bval(geo, node, 0);
216
217 longcpy(key, bkey(geo, node, 0), geo->keylen);
218 return bval(geo, node, 0);
219}
220EXPORT_SYMBOL_GPL(btree_last);
221
222static int keycmp(struct btree_geo *geo, unsigned long *node, int pos,
223 unsigned long *key)
224{
225 return longcmp(bkey(geo, node, pos), key, geo->keylen);
226}
227
228static int keyzero(struct btree_geo *geo, unsigned long *key)
229{
230 int i;
231
232 for (i = 0; i < geo->keylen; i++)
233 if (key[i])
234 return 0;
235
236 return 1;
237}
238
239void *btree_lookup(struct btree_head *head, struct btree_geo *geo,
240 unsigned long *key)
241{
242 int i, height = head->height;
243 unsigned long *node = head->node;
244
245 if (height == 0)
246 return NULL;
247
248 for ( ; height > 1; height--) {
249 for (i = 0; i < geo->no_pairs; i++)
250 if (keycmp(geo, node, i, key) <= 0)
251 break;
252 if (i == geo->no_pairs)
253 return NULL;
254 node = bval(geo, node, i);
255 if (!node)
256 return NULL;
257 }
258
259 if (!node)
260 return NULL;
261
262 for (i = 0; i < geo->no_pairs; i++)
263 if (keycmp(geo, node, i, key) == 0)
264 return bval(geo, node, i);
265 return NULL;
266}
267EXPORT_SYMBOL_GPL(btree_lookup);
268
269int btree_update(struct btree_head *head, struct btree_geo *geo,
270 unsigned long *key, void *val)
271{
272 int i, height = head->height;
273 unsigned long *node = head->node;
274
275 if (height == 0)
276 return -ENOENT;
277
278 for ( ; height > 1; height--) {
279 for (i = 0; i < geo->no_pairs; i++)
280 if (keycmp(geo, node, i, key) <= 0)
281 break;
282 if (i == geo->no_pairs)
283 return -ENOENT;
284 node = bval(geo, node, i);
285 if (!node)
286 return -ENOENT;
287 }
288
289 if (!node)
290 return -ENOENT;
291
292 for (i = 0; i < geo->no_pairs; i++)
293 if (keycmp(geo, node, i, key) == 0) {
294 setval(geo, node, i, val);
295 return 0;
296 }
297 return -ENOENT;
298}
299EXPORT_SYMBOL_GPL(btree_update);
300
301/*
302 * Usually this function is quite similar to normal lookup. But the key of
303 * a parent node may be smaller than the smallest key of all its siblings.
304 * In such a case we cannot just return NULL, as we have only proven that no
305 * key smaller than __key, but larger than this parent key exists.
306 * So we set __key to the parent key and retry. We have to use the smallest
307 * such parent key, which is the last parent key we encountered.
308 */
309void *btree_get_prev(struct btree_head *head, struct btree_geo *geo,
310 unsigned long *__key)
311{
312 int i, height;
313 unsigned long *node, *oldnode;
314 unsigned long *retry_key = NULL, key[geo->keylen];
315
316 if (keyzero(geo, __key))
317 return NULL;
318
319 if (head->height == 0)
320 return NULL;
321retry:
322 longcpy(key, __key, geo->keylen);
323 dec_key(geo, key);
324
325 node = head->node;
326 for (height = head->height ; height > 1; height--) {
327 for (i = 0; i < geo->no_pairs; i++)
328 if (keycmp(geo, node, i, key) <= 0)
329 break;
330 if (i == geo->no_pairs)
331 goto miss;
332 oldnode = node;
333 node = bval(geo, node, i);
334 if (!node)
335 goto miss;
336 retry_key = bkey(geo, oldnode, i);
337 }
338
339 if (!node)
340 goto miss;
341
342 for (i = 0; i < geo->no_pairs; i++) {
343 if (keycmp(geo, node, i, key) <= 0) {
344 if (bval(geo, node, i)) {
345 longcpy(__key, bkey(geo, node, i), geo->keylen);
346 return bval(geo, node, i);
347 } else
348 goto miss;
349 }
350 }
351miss:
352 if (retry_key) {
353 __key = retry_key;
354 retry_key = NULL;
355 goto retry;
356 }
357 return NULL;
358}
359
360static int getpos(struct btree_geo *geo, unsigned long *node,
361 unsigned long *key)
362{
363 int i;
364
365 for (i = 0; i < geo->no_pairs; i++) {
366 if (keycmp(geo, node, i, key) <= 0)
367 break;
368 }
369 return i;
370}
371
372static int getfill(struct btree_geo *geo, unsigned long *node, int start)
373{
374 int i;
375
376 for (i = start; i < geo->no_pairs; i++)
377 if (!bval(geo, node, i))
378 break;
379 return i;
380}
381
382/*
383 * locate the correct leaf node in the btree
384 */
385static unsigned long *find_level(struct btree_head *head, struct btree_geo *geo,
386 unsigned long *key, int level)
387{
388 unsigned long *node = head->node;
389 int i, height;
390
391 for (height = head->height; height > level; height--) {
392 for (i = 0; i < geo->no_pairs; i++)
393 if (keycmp(geo, node, i, key) <= 0)
394 break;
395
396 if ((i == geo->no_pairs) || !bval(geo, node, i)) {
397 /* right-most key is too large, update it */
398 /* FIXME: If the right-most key on higher levels is
399 * always zero, this wouldn't be necessary. */
400 i--;
401 setkey(geo, node, i, key);
402 }
403 BUG_ON(i < 0);
404 node = bval(geo, node, i);
405 }
406 BUG_ON(!node);
407 return node;
408}
409
410static int btree_grow(struct btree_head *head, struct btree_geo *geo,
411 gfp_t gfp)
412{
413 unsigned long *node;
414 int fill;
415
416 node = btree_node_alloc(head, gfp);
417 if (!node)
418 return -ENOMEM;
419 if (head->node) {
420 fill = getfill(geo, head->node, 0);
421 setkey(geo, node, 0, bkey(geo, head->node, fill - 1));
422 setval(geo, node, 0, head->node);
423 }
424 head->node = node;
425 head->height++;
426 return 0;
427}
428
429static void btree_shrink(struct btree_head *head, struct btree_geo *geo)
430{
431 unsigned long *node;
432 int fill;
433
434 if (head->height <= 1)
435 return;
436
437 node = head->node;
438 fill = getfill(geo, node, 0);
439 BUG_ON(fill > 1);
440 head->node = bval(geo, node, 0);
441 head->height--;
442 mempool_free(node, head->mempool);
443}
444
445static int btree_insert_level(struct btree_head *head, struct btree_geo *geo,
446 unsigned long *key, void *val, int level,
447 gfp_t gfp)
448{
449 unsigned long *node;
450 int i, pos, fill, err;
451
452 BUG_ON(!val);
453 if (head->height < level) {
454 err = btree_grow(head, geo, gfp);
455 if (err)
456 return err;
457 }
458
459retry:
460 node = find_level(head, geo, key, level);
461 pos = getpos(geo, node, key);
462 fill = getfill(geo, node, pos);
463 /* two identical keys are not allowed */
464 BUG_ON(pos < fill && keycmp(geo, node, pos, key) == 0);
465
466 if (fill == geo->no_pairs) {
467 /* need to split node */
468 unsigned long *new;
469
470 new = btree_node_alloc(head, gfp);
471 if (!new)
472 return -ENOMEM;
473 err = btree_insert_level(head, geo,
474 bkey(geo, node, fill / 2 - 1),
475 new, level + 1, gfp);
476 if (err) {
477 mempool_free(new, head->mempool);
478 return err;
479 }
480 for (i = 0; i < fill / 2; i++) {
481 setkey(geo, new, i, bkey(geo, node, i));
482 setval(geo, new, i, bval(geo, node, i));
483 setkey(geo, node, i, bkey(geo, node, i + fill / 2));
484 setval(geo, node, i, bval(geo, node, i + fill / 2));
485 clearpair(geo, node, i + fill / 2);
486 }
487 if (fill & 1) {
488 setkey(geo, node, i, bkey(geo, node, fill - 1));
489 setval(geo, node, i, bval(geo, node, fill - 1));
490 clearpair(geo, node, fill - 1);
491 }
492 goto retry;
493 }
494 BUG_ON(fill >= geo->no_pairs);
495
496 /* shift and insert */
497 for (i = fill; i > pos; i--) {
498 setkey(geo, node, i, bkey(geo, node, i - 1));
499 setval(geo, node, i, bval(geo, node, i - 1));
500 }
501 setkey(geo, node, pos, key);
502 setval(geo, node, pos, val);
503
504 return 0;
505}
506
507int btree_insert(struct btree_head *head, struct btree_geo *geo,
508 unsigned long *key, void *val, gfp_t gfp)
509{
510 return btree_insert_level(head, geo, key, val, 1, gfp);
511}
512EXPORT_SYMBOL_GPL(btree_insert);
513
514static void *btree_remove_level(struct btree_head *head, struct btree_geo *geo,
515 unsigned long *key, int level);
516static void merge(struct btree_head *head, struct btree_geo *geo, int level,
517 unsigned long *left, int lfill,
518 unsigned long *right, int rfill,
519 unsigned long *parent, int lpos)
520{
521 int i;
522
523 for (i = 0; i < rfill; i++) {
524 /* Move all keys to the left */
525 setkey(geo, left, lfill + i, bkey(geo, right, i));
526 setval(geo, left, lfill + i, bval(geo, right, i));
527 }
528 /* Exchange left and right child in parent */
529 setval(geo, parent, lpos, right);
530 setval(geo, parent, lpos + 1, left);
531 /* Remove left (formerly right) child from parent */
532 btree_remove_level(head, geo, bkey(geo, parent, lpos), level + 1);
533 mempool_free(right, head->mempool);
534}
535
536static void rebalance(struct btree_head *head, struct btree_geo *geo,
537 unsigned long *key, int level, unsigned long *child, int fill)
538{
539 unsigned long *parent, *left = NULL, *right = NULL;
540 int i, no_left, no_right;
541
542 if (fill == 0) {
543 /* Because we don't steal entries from a neigbour, this case
544 * can happen. Parent node contains a single child, this
545 * node, so merging with a sibling never happens.
546 */
547 btree_remove_level(head, geo, key, level + 1);
548 mempool_free(child, head->mempool);
549 return;
550 }
551
552 parent = find_level(head, geo, key, level + 1);
553 i = getpos(geo, parent, key);
554 BUG_ON(bval(geo, parent, i) != child);
555
556 if (i > 0) {
557 left = bval(geo, parent, i - 1);
558 no_left = getfill(geo, left, 0);
559 if (fill + no_left <= geo->no_pairs) {
560 merge(head, geo, level,
561 left, no_left,
562 child, fill,
563 parent, i - 1);
564 return;
565 }
566 }
567 if (i + 1 < getfill(geo, parent, i)) {
568 right = bval(geo, parent, i + 1);
569 no_right = getfill(geo, right, 0);
570 if (fill + no_right <= geo->no_pairs) {
571 merge(head, geo, level,
572 child, fill,
573 right, no_right,
574 parent, i);
575 return;
576 }
577 }
578 /*
579 * We could also try to steal one entry from the left or right
580 * neighbor. By not doing so we changed the invariant from
581 * "all nodes are at least half full" to "no two neighboring
582 * nodes can be merged". Which means that the average fill of
583 * all nodes is still half or better.
584 */
585}
586
587static void *btree_remove_level(struct btree_head *head, struct btree_geo *geo,
588 unsigned long *key, int level)
589{
590 unsigned long *node;
591 int i, pos, fill;
592 void *ret;
593
594 if (level > head->height) {
595 /* we recursed all the way up */
596 head->height = 0;
597 head->node = NULL;
598 return NULL;
599 }
600
601 node = find_level(head, geo, key, level);
602 pos = getpos(geo, node, key);
603 fill = getfill(geo, node, pos);
604 if ((level == 1) && (keycmp(geo, node, pos, key) != 0))
605 return NULL;
606 ret = bval(geo, node, pos);
607
608 /* remove and shift */
609 for (i = pos; i < fill - 1; i++) {
610 setkey(geo, node, i, bkey(geo, node, i + 1));
611 setval(geo, node, i, bval(geo, node, i + 1));
612 }
613 clearpair(geo, node, fill - 1);
614
615 if (fill - 1 < geo->no_pairs / 2) {
616 if (level < head->height)
617 rebalance(head, geo, key, level, node, fill - 1);
618 else if (fill - 1 == 1)
619 btree_shrink(head, geo);
620 }
621
622 return ret;
623}
624
625void *btree_remove(struct btree_head *head, struct btree_geo *geo,
626 unsigned long *key)
627{
628 if (head->height == 0)
629 return NULL;
630
631 return btree_remove_level(head, geo, key, 1);
632}
633EXPORT_SYMBOL_GPL(btree_remove);
634
635int btree_merge(struct btree_head *target, struct btree_head *victim,
636 struct btree_geo *geo, gfp_t gfp)
637{
638 unsigned long key[geo->keylen];
639 unsigned long dup[geo->keylen];
640 void *val;
641 int err;
642
643 BUG_ON(target == victim);
644
645 if (!(target->node)) {
646 /* target is empty, just copy fields over */
647 target->node = victim->node;
648 target->height = victim->height;
649 __btree_init(victim);
650 return 0;
651 }
652
653 /* TODO: This needs some optimizations. Currently we do three tree
654 * walks to remove a single object from the victim.
655 */
656 for (;;) {
657 if (!btree_last(victim, geo, key))
658 break;
659 val = btree_lookup(victim, geo, key);
660 err = btree_insert(target, geo, key, val, gfp);
661 if (err)
662 return err;
663 /* We must make a copy of the key, as the original will get
664 * mangled inside btree_remove. */
665 longcpy(dup, key, geo->keylen);
666 btree_remove(victim, geo, dup);
667 }
668 return 0;
669}
670EXPORT_SYMBOL_GPL(btree_merge);
671
672static size_t __btree_for_each(struct btree_head *head, struct btree_geo *geo,
673 unsigned long *node, unsigned long opaque,
674 void (*func)(void *elem, unsigned long opaque,
675 unsigned long *key, size_t index,
676 void *func2),
677 void *func2, int reap, int height, size_t count)
678{
679 int i;
680 unsigned long *child;
681
682 for (i = 0; i < geo->no_pairs; i++) {
683 child = bval(geo, node, i);
684 if (!child)
685 break;
686 if (height > 1)
687 count = __btree_for_each(head, geo, child, opaque,
688 func, func2, reap, height - 1, count);
689 else
690 func(child, opaque, bkey(geo, node, i), count++,
691 func2);
692 }
693 if (reap)
694 mempool_free(node, head->mempool);
695 return count;
696}
697
698static void empty(void *elem, unsigned long opaque, unsigned long *key,
699 size_t index, void *func2)
700{
701}
702
703void visitorl(void *elem, unsigned long opaque, unsigned long *key,
704 size_t index, void *__func)
705{
706 visitorl_t func = __func;
707
708 func(elem, opaque, *key, index);
709}
710EXPORT_SYMBOL_GPL(visitorl);
711
712void visitor32(void *elem, unsigned long opaque, unsigned long *__key,
713 size_t index, void *__func)
714{
715 visitor32_t func = __func;
716 u32 *key = (void *)__key;
717
718 func(elem, opaque, *key, index);
719}
720EXPORT_SYMBOL_GPL(visitor32);
721
722void visitor64(void *elem, unsigned long opaque, unsigned long *__key,
723 size_t index, void *__func)
724{
725 visitor64_t func = __func;
726 u64 *key = (void *)__key;
727
728 func(elem, opaque, *key, index);
729}
730EXPORT_SYMBOL_GPL(visitor64);
731
732void visitor128(void *elem, unsigned long opaque, unsigned long *__key,
733 size_t index, void *__func)
734{
735 visitor128_t func = __func;
736 u64 *key = (void *)__key;
737
738 func(elem, opaque, key[0], key[1], index);
739}
740EXPORT_SYMBOL_GPL(visitor128);
741
742size_t btree_visitor(struct btree_head *head, struct btree_geo *geo,
743 unsigned long opaque,
744 void (*func)(void *elem, unsigned long opaque,
745 unsigned long *key,
746 size_t index, void *func2),
747 void *func2)
748{
749 size_t count = 0;
750
751 if (!func2)
752 func = empty;
753 if (head->node)
754 count = __btree_for_each(head, geo, head->node, opaque, func,
755 func2, 0, head->height, 0);
756 return count;
757}
758EXPORT_SYMBOL_GPL(btree_visitor);
759
760size_t btree_grim_visitor(struct btree_head *head, struct btree_geo *geo,
761 unsigned long opaque,
762 void (*func)(void *elem, unsigned long opaque,
763 unsigned long *key,
764 size_t index, void *func2),
765 void *func2)
766{
767 size_t count = 0;
768
769 if (!func2)
770 func = empty;
771 if (head->node)
772 count = __btree_for_each(head, geo, head->node, opaque, func,
773 func2, 1, head->height, 0);
774 __btree_init(head);
775 return count;
776}
777EXPORT_SYMBOL_GPL(btree_grim_visitor);
778
779static int __init btree_module_init(void)
780{
781 btree_cachep = kmem_cache_create("btree_node", NODESIZE, 0,
782 SLAB_HWCACHE_ALIGN, NULL);
783 return 0;
784}
785
786static void __exit btree_module_exit(void)
787{
788 kmem_cache_destroy(btree_cachep);
789}
790
791/* If core code starts using btree, initialization should happen even earlier */
792module_init(btree_module_init);
793module_exit(btree_module_exit);
794
795MODULE_AUTHOR("Joern Engel <joern@logfs.org>");
796MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
797MODULE_LICENSE("GPL");
diff --git a/lib/crc32.c b/lib/crc32.c
index 02e3b31b3a79..0f45fbff34cb 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -30,11 +30,15 @@
30#include <asm/atomic.h> 30#include <asm/atomic.h>
31#include "crc32defs.h" 31#include "crc32defs.h"
32#if CRC_LE_BITS == 8 32#if CRC_LE_BITS == 8
33#define tole(x) __constant_cpu_to_le32(x) 33# define tole(x) __constant_cpu_to_le32(x)
34#define tobe(x) __constant_cpu_to_be32(x)
35#else 34#else
36#define tole(x) (x) 35# define tole(x) (x)
37#define tobe(x) (x) 36#endif
37
38#if CRC_BE_BITS == 8
39# define tobe(x) __constant_cpu_to_be32(x)
40#else
41# define tobe(x) (x)
38#endif 42#endif
39#include "crc32table.h" 43#include "crc32table.h"
40 44
@@ -52,20 +56,19 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab)
52# else 56# else
53# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) 57# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
54# endif 58# endif
55 const u32 *b = (const u32 *)buf; 59 const u32 *b;
56 size_t rem_len; 60 size_t rem_len;
57 61
58 /* Align it */ 62 /* Align it */
59 if (unlikely((long)b & 3 && len)) { 63 if (unlikely((long)buf & 3 && len)) {
60 u8 *p = (u8 *)b;
61 do { 64 do {
62 DO_CRC(*p++); 65 DO_CRC(*buf++);
63 } while ((--len) && ((long)p)&3); 66 } while ((--len) && ((long)buf)&3);
64 b = (u32 *)p;
65 } 67 }
66 rem_len = len & 3; 68 rem_len = len & 3;
67 /* load data 32 bits wide, xor data 32 bits wide. */ 69 /* load data 32 bits wide, xor data 32 bits wide. */
68 len = len >> 2; 70 len = len >> 2;
71 b = (const u32 *)buf;
69 for (--b; len; --len) { 72 for (--b; len; --len) {
70 crc ^= *++b; /* use pre increment for speed */ 73 crc ^= *++b; /* use pre increment for speed */
71 DO_CRC(0); 74 DO_CRC(0);
@@ -82,6 +85,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab)
82 } while (--len); 85 } while (--len);
83 } 86 }
84 return crc; 87 return crc;
88#undef DO_CRC
85} 89}
86#endif 90#endif
87/** 91/**
@@ -119,9 +123,6 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
119 crc = __cpu_to_le32(crc); 123 crc = __cpu_to_le32(crc);
120 crc = crc32_body(crc, p, len, tab); 124 crc = crc32_body(crc, p, len, tab);
121 return __le32_to_cpu(crc); 125 return __le32_to_cpu(crc);
122#undef ENDIAN_SHIFT
123#undef DO_CRC
124
125# elif CRC_LE_BITS == 4 126# elif CRC_LE_BITS == 4
126 while (len--) { 127 while (len--) {
127 crc ^= *p++; 128 crc ^= *p++;
@@ -179,9 +180,6 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
179 crc = __cpu_to_be32(crc); 180 crc = __cpu_to_be32(crc);
180 crc = crc32_body(crc, p, len, tab); 181 crc = crc32_body(crc, p, len, tab);
181 return __be32_to_cpu(crc); 182 return __be32_to_cpu(crc);
182#undef ENDIAN_SHIFT
183#undef DO_CRC
184
185# elif CRC_BE_BITS == 4 183# elif CRC_BE_BITS == 4
186 while (len--) { 184 while (len--) {
187 crc ^= *p++ << 24; 185 crc ^= *p++ << 24;
diff --git a/lib/list_sort.c b/lib/list_sort.c
index 19d11e0bb958..4b5cb794c38b 100644
--- a/lib/list_sort.c
+++ b/lib/list_sort.c
@@ -4,99 +4,214 @@
4#include <linux/slab.h> 4#include <linux/slab.h>
5#include <linux/list.h> 5#include <linux/list.h>
6 6
7#define MAX_LIST_LENGTH_BITS 20
8
9/*
10 * Returns a list organized in an intermediate format suited
11 * to chaining of merge() calls: null-terminated, no reserved or
12 * sentinel head node, "prev" links not maintained.
13 */
14static struct list_head *merge(void *priv,
15 int (*cmp)(void *priv, struct list_head *a,
16 struct list_head *b),
17 struct list_head *a, struct list_head *b)
18{
19 struct list_head head, *tail = &head;
20
21 while (a && b) {
22 /* if equal, take 'a' -- important for sort stability */
23 if ((*cmp)(priv, a, b) <= 0) {
24 tail->next = a;
25 a = a->next;
26 } else {
27 tail->next = b;
28 b = b->next;
29 }
30 tail = tail->next;
31 }
32 tail->next = a?:b;
33 return head.next;
34}
35
36/*
37 * Combine final list merge with restoration of standard doubly-linked
38 * list structure. This approach duplicates code from merge(), but
39 * runs faster than the tidier alternatives of either a separate final
40 * prev-link restoration pass, or maintaining the prev links
41 * throughout.
42 */
43static void merge_and_restore_back_links(void *priv,
44 int (*cmp)(void *priv, struct list_head *a,
45 struct list_head *b),
46 struct list_head *head,
47 struct list_head *a, struct list_head *b)
48{
49 struct list_head *tail = head;
50
51 while (a && b) {
52 /* if equal, take 'a' -- important for sort stability */
53 if ((*cmp)(priv, a, b) <= 0) {
54 tail->next = a;
55 a->prev = tail;
56 a = a->next;
57 } else {
58 tail->next = b;
59 b->prev = tail;
60 b = b->next;
61 }
62 tail = tail->next;
63 }
64 tail->next = a ? : b;
65
66 do {
67 /*
68 * In worst cases this loop may run many iterations.
69 * Continue callbacks to the client even though no
70 * element comparison is needed, so the client's cmp()
71 * routine can invoke cond_resched() periodically.
72 */
73 (*cmp)(priv, tail, tail);
74
75 tail->next->prev = tail;
76 tail = tail->next;
77 } while (tail->next);
78
79 tail->next = head;
80 head->prev = tail;
81}
82
7/** 83/**
8 * list_sort - sort a list. 84 * list_sort - sort a list
9 * @priv: private data, passed to @cmp 85 * @priv: private data, opaque to list_sort(), passed to @cmp
10 * @head: the list to sort 86 * @head: the list to sort
11 * @cmp: the elements comparison function 87 * @cmp: the elements comparison function
12 * 88 *
13 * This function has been implemented by Mark J Roberts <mjr@znex.org>. It 89 * This function implements "merge sort", which has O(nlog(n))
14 * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted 90 * complexity.
15 * in ascending order.
16 * 91 *
17 * The comparison function @cmp is supposed to return a negative value if @a is 92 * The comparison function @cmp must return a negative value if @a
18 * less than @b, and a positive value if @a is greater than @b. If @a and @b 93 * should sort before @b, and a positive value if @a should sort after
19 * are equivalent, then it does not matter what this function returns. 94 * @b. If @a and @b are equivalent, and their original relative
95 * ordering is to be preserved, @cmp must return 0.
20 */ 96 */
21void list_sort(void *priv, struct list_head *head, 97void list_sort(void *priv, struct list_head *head,
22 int (*cmp)(void *priv, struct list_head *a, 98 int (*cmp)(void *priv, struct list_head *a,
23 struct list_head *b)) 99 struct list_head *b))
24{ 100{
25 struct list_head *p, *q, *e, *list, *tail, *oldhead; 101 struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
26 int insize, nmerges, psize, qsize, i; 102 -- last slot is a sentinel */
103 int lev; /* index into part[] */
104 int max_lev = 0;
105 struct list_head *list;
27 106
28 if (list_empty(head)) 107 if (list_empty(head))
29 return; 108 return;
30 109
110 memset(part, 0, sizeof(part));
111
112 head->prev->next = NULL;
31 list = head->next; 113 list = head->next;
32 list_del(head);
33 insize = 1;
34 for (;;) {
35 p = oldhead = list;
36 list = tail = NULL;
37 nmerges = 0;
38
39 while (p) {
40 nmerges++;
41 q = p;
42 psize = 0;
43 for (i = 0; i < insize; i++) {
44 psize++;
45 q = q->next == oldhead ? NULL : q->next;
46 if (!q)
47 break;
48 }
49 114
50 qsize = insize; 115 while (list) {
51 while (psize > 0 || (qsize > 0 && q)) { 116 struct list_head *cur = list;
52 if (!psize) { 117 list = list->next;
53 e = q; 118 cur->next = NULL;
54 q = q->next; 119
55 qsize--; 120 for (lev = 0; part[lev]; lev++) {
56 if (q == oldhead) 121 cur = merge(priv, cmp, part[lev], cur);
57 q = NULL; 122 part[lev] = NULL;
58 } else if (!qsize || !q) { 123 }
59 e = p; 124 if (lev > max_lev) {
60 p = p->next; 125 if (unlikely(lev >= ARRAY_SIZE(part)-1)) {
61 psize--; 126 printk_once(KERN_DEBUG "list passed to"
62 if (p == oldhead) 127 " list_sort() too long for"
63 p = NULL; 128 " efficiency\n");
64 } else if (cmp(priv, p, q) <= 0) { 129 lev--;
65 e = p;
66 p = p->next;
67 psize--;
68 if (p == oldhead)
69 p = NULL;
70 } else {
71 e = q;
72 q = q->next;
73 qsize--;
74 if (q == oldhead)
75 q = NULL;
76 }
77 if (tail)
78 tail->next = e;
79 else
80 list = e;
81 e->prev = tail;
82 tail = e;
83 } 130 }
84 p = q; 131 max_lev = lev;
85 } 132 }
133 part[lev] = cur;
134 }
86 135
87 tail->next = list; 136 for (lev = 0; lev < max_lev; lev++)
88 list->prev = tail; 137 if (part[lev])
138 list = merge(priv, cmp, part[lev], list);
89 139
90 if (nmerges <= 1) 140 merge_and_restore_back_links(priv, cmp, head, part[max_lev], list);
91 break; 141}
142EXPORT_SYMBOL(list_sort);
92 143
93 insize *= 2; 144#ifdef DEBUG_LIST_SORT
94 } 145struct debug_el {
146 struct list_head l_h;
147 int value;
148 unsigned serial;
149};
95 150
96 head->next = list; 151static int cmp(void *priv, struct list_head *a, struct list_head *b)
97 head->prev = list->prev; 152{
98 list->prev->next = head; 153 return container_of(a, struct debug_el, l_h)->value
99 list->prev = head; 154 - container_of(b, struct debug_el, l_h)->value;
100} 155}
101 156
102EXPORT_SYMBOL(list_sort); 157/*
158 * The pattern of set bits in the list length determines which cases
159 * are hit in list_sort().
160 */
161#define LIST_SORT_TEST_LENGTH (512+128+2) /* not including head */
162
163static int __init list_sort_test(void)
164{
165 int i, r = 1, count;
166 struct list_head *head = kmalloc(sizeof(*head), GFP_KERNEL);
167 struct list_head *cur;
168
169 printk(KERN_WARNING "testing list_sort()\n");
170
171 cur = head;
172 for (i = 0; i < LIST_SORT_TEST_LENGTH; i++) {
173 struct debug_el *el = kmalloc(sizeof(*el), GFP_KERNEL);
174 BUG_ON(!el);
175 /* force some equivalencies */
176 el->value = (r = (r * 725861) % 6599) % (LIST_SORT_TEST_LENGTH/3);
177 el->serial = i;
178
179 el->l_h.prev = cur;
180 cur->next = &el->l_h;
181 cur = cur->next;
182 }
183 head->prev = cur;
184
185 list_sort(NULL, head, cmp);
186
187 count = 1;
188 for (cur = head->next; cur->next != head; cur = cur->next) {
189 struct debug_el *el = container_of(cur, struct debug_el, l_h);
190 int cmp_result = cmp(NULL, cur, cur->next);
191 if (cur->next->prev != cur) {
192 printk(KERN_EMERG "list_sort() returned "
193 "a corrupted list!\n");
194 return 1;
195 } else if (cmp_result > 0) {
196 printk(KERN_EMERG "list_sort() failed to sort!\n");
197 return 1;
198 } else if (cmp_result == 0 &&
199 el->serial >= container_of(cur->next,
200 struct debug_el, l_h)->serial) {
201 printk(KERN_EMERG "list_sort() failed to preserve order"
202 " of equivalent elements!\n");
203 return 1;
204 }
205 kfree(cur->prev);
206 count++;
207 }
208 kfree(cur);
209 if (count != LIST_SORT_TEST_LENGTH) {
210 printk(KERN_EMERG "list_sort() returned list of"
211 "different length!\n");
212 return 1;
213 }
214 return 0;
215}
216module_init(list_sort_test);
217#endif
diff --git a/lib/show_mem.c b/lib/show_mem.c
index 238e72a18ce1..fdc77c82f922 100644
--- a/lib/show_mem.c
+++ b/lib/show_mem.c
@@ -15,7 +15,7 @@ void show_mem(void)
15 unsigned long total = 0, reserved = 0, shared = 0, 15 unsigned long total = 0, reserved = 0, shared = 0,
16 nonshared = 0, highmem = 0; 16 nonshared = 0, highmem = 0;
17 17
18 printk(KERN_INFO "Mem-Info:\n"); 18 printk("Mem-Info:\n");
19 show_free_areas(); 19 show_free_areas();
20 20
21 for_each_online_pgdat(pgdat) { 21 for_each_online_pgdat(pgdat) {
@@ -49,15 +49,15 @@ void show_mem(void)
49 pgdat_resize_unlock(pgdat, &flags); 49 pgdat_resize_unlock(pgdat, &flags);
50 } 50 }
51 51
52 printk(KERN_INFO "%lu pages RAM\n", total); 52 printk("%lu pages RAM\n", total);
53#ifdef CONFIG_HIGHMEM 53#ifdef CONFIG_HIGHMEM
54 printk(KERN_INFO "%lu pages HighMem\n", highmem); 54 printk("%lu pages HighMem\n", highmem);
55#endif 55#endif
56 printk(KERN_INFO "%lu pages reserved\n", reserved); 56 printk("%lu pages reserved\n", reserved);
57 printk(KERN_INFO "%lu pages shared\n", shared); 57 printk("%lu pages shared\n", shared);
58 printk(KERN_INFO "%lu pages non-shared\n", nonshared); 58 printk("%lu pages non-shared\n", nonshared);
59#ifdef CONFIG_QUICKLIST 59#ifdef CONFIG_QUICKLIST
60 printk(KERN_INFO "%lu pages in pagetable cache\n", 60 printk("%lu pages in pagetable cache\n",
61 quicklist_total_size()); 61 quicklist_total_size());
62#endif 62#endif
63} 63}
diff --git a/lib/string.c b/lib/string.c
index a1cdcfcc42d0..f71bead1be3e 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -36,25 +36,21 @@ int strnicmp(const char *s1, const char *s2, size_t len)
36 /* Yes, Virginia, it had better be unsigned */ 36 /* Yes, Virginia, it had better be unsigned */
37 unsigned char c1, c2; 37 unsigned char c1, c2;
38 38
39 c1 = c2 = 0; 39 if (!len)
40 if (len) { 40 return 0;
41 do { 41
42 c1 = *s1; 42 do {
43 c2 = *s2; 43 c1 = *s1++;
44 s1++; 44 c2 = *s2++;
45 s2++; 45 if (!c1 || !c2)
46 if (!c1) 46 break;
47 break; 47 if (c1 == c2)
48 if (!c2) 48 continue;
49 break; 49 c1 = tolower(c1);
50 if (c1 == c2) 50 c2 = tolower(c2);
51 continue; 51 if (c1 != c2)
52 c1 = tolower(c1); 52 break;
53 c2 = tolower(c2); 53 } while (--len);
54 if (c1 != c2)
55 break;
56 } while (--len);
57 }
58 return (int)c1 - (int)c2; 54 return (int)c1 - (int)c2;
59} 55}
60EXPORT_SYMBOL(strnicmp); 56EXPORT_SYMBOL(strnicmp);
@@ -693,13 +689,13 @@ EXPORT_SYMBOL(strstr);
693 */ 689 */
694char *strnstr(const char *s1, const char *s2, size_t len) 690char *strnstr(const char *s1, const char *s2, size_t len)
695{ 691{
696 size_t l1 = len, l2; 692 size_t l2;
697 693
698 l2 = strlen(s2); 694 l2 = strlen(s2);
699 if (!l2) 695 if (!l2)
700 return (char *)s1; 696 return (char *)s1;
701 while (l1 >= l2) { 697 while (len >= l2) {
702 l1--; 698 len--;
703 if (!memcmp(s1, s2, l2)) 699 if (!memcmp(s1, s2, l2))
704 return (char *)s1; 700 return (char *)s1;
705 s1++; 701 s1++;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index af4aaa6c36f3..0d461c7c14db 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -381,8 +381,8 @@ static noinline char *put_dec(char *buf, unsigned long long num)
381#define PLUS 4 /* show plus */ 381#define PLUS 4 /* show plus */
382#define SPACE 8 /* space if plus */ 382#define SPACE 8 /* space if plus */
383#define LEFT 16 /* left justified */ 383#define LEFT 16 /* left justified */
384#define SMALL 32 /* Must be 32 == 0x20 */ 384#define SMALL 32 /* use lowercase in hex (must be 32 == 0x20) */
385#define SPECIAL 64 /* 0x */ 385#define SPECIAL 64 /* prefix hex with "0x", octal with "0" */
386 386
387enum format_type { 387enum format_type {
388 FORMAT_TYPE_NONE, /* Just a string part */ 388 FORMAT_TYPE_NONE, /* Just a string part */
@@ -408,12 +408,12 @@ enum format_type {
408}; 408};
409 409
410struct printf_spec { 410struct printf_spec {
411 enum format_type type; 411 u16 type;
412 int flags; /* flags to number() */ 412 s16 field_width; /* width of output field */
413 int field_width; /* width of output field */ 413 u8 flags; /* flags to number() */
414 int base; 414 u8 base;
415 int precision; /* # of digits/chars */ 415 s8 precision; /* # of digits/chars */
416 int qualifier; 416 u8 qualifier;
417}; 417};
418 418
419static char *number(char *buf, char *end, unsigned long long num, 419static char *number(char *buf, char *end, unsigned long long num,
@@ -597,22 +597,29 @@ static char *resource_string(char *buf, char *end, struct resource *res,
597#ifndef MEM_RSRC_PRINTK_SIZE 597#ifndef MEM_RSRC_PRINTK_SIZE
598#define MEM_RSRC_PRINTK_SIZE 10 598#define MEM_RSRC_PRINTK_SIZE 10
599#endif 599#endif
600 struct printf_spec hex_spec = { 600 static const struct printf_spec io_spec = {
601 .base = 16, 601 .base = 16,
602 .field_width = IO_RSRC_PRINTK_SIZE,
602 .precision = -1, 603 .precision = -1,
603 .flags = SPECIAL | SMALL | ZEROPAD, 604 .flags = SPECIAL | SMALL | ZEROPAD,
604 }; 605 };
605 struct printf_spec dec_spec = { 606 static const struct printf_spec mem_spec = {
607 .base = 16,
608 .field_width = MEM_RSRC_PRINTK_SIZE,
609 .precision = -1,
610 .flags = SPECIAL | SMALL | ZEROPAD,
611 };
612 static const struct printf_spec dec_spec = {
606 .base = 10, 613 .base = 10,
607 .precision = -1, 614 .precision = -1,
608 .flags = 0, 615 .flags = 0,
609 }; 616 };
610 struct printf_spec str_spec = { 617 static const struct printf_spec str_spec = {
611 .field_width = -1, 618 .field_width = -1,
612 .precision = 10, 619 .precision = 10,
613 .flags = LEFT, 620 .flags = LEFT,
614 }; 621 };
615 struct printf_spec flag_spec = { 622 static const struct printf_spec flag_spec = {
616 .base = 16, 623 .base = 16,
617 .precision = -1, 624 .precision = -1,
618 .flags = SPECIAL | SMALL, 625 .flags = SPECIAL | SMALL,
@@ -628,35 +635,31 @@ static char *resource_string(char *buf, char *end, struct resource *res,
628 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; 635 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
629 636
630 char *p = sym, *pend = sym + sizeof(sym); 637 char *p = sym, *pend = sym + sizeof(sym);
631 int size = -1, addr = 0;
632 int decode = (fmt[0] == 'R') ? 1 : 0; 638 int decode = (fmt[0] == 'R') ? 1 : 0;
633 639 const struct printf_spec *specp;
634 if (res->flags & IORESOURCE_IO) {
635 size = IO_RSRC_PRINTK_SIZE;
636 addr = 1;
637 } else if (res->flags & IORESOURCE_MEM) {
638 size = MEM_RSRC_PRINTK_SIZE;
639 addr = 1;
640 }
641 640
642 *p++ = '['; 641 *p++ = '[';
643 if (res->flags & IORESOURCE_IO) 642 if (res->flags & IORESOURCE_IO) {
644 p = string(p, pend, "io ", str_spec); 643 p = string(p, pend, "io ", str_spec);
645 else if (res->flags & IORESOURCE_MEM) 644 specp = &io_spec;
645 } else if (res->flags & IORESOURCE_MEM) {
646 p = string(p, pend, "mem ", str_spec); 646 p = string(p, pend, "mem ", str_spec);
647 else if (res->flags & IORESOURCE_IRQ) 647 specp = &mem_spec;
648 } else if (res->flags & IORESOURCE_IRQ) {
648 p = string(p, pend, "irq ", str_spec); 649 p = string(p, pend, "irq ", str_spec);
649 else if (res->flags & IORESOURCE_DMA) 650 specp = &dec_spec;
651 } else if (res->flags & IORESOURCE_DMA) {
650 p = string(p, pend, "dma ", str_spec); 652 p = string(p, pend, "dma ", str_spec);
651 else { 653 specp = &dec_spec;
654 } else {
652 p = string(p, pend, "??? ", str_spec); 655 p = string(p, pend, "??? ", str_spec);
656 specp = &mem_spec;
653 decode = 0; 657 decode = 0;
654 } 658 }
655 hex_spec.field_width = size; 659 p = number(p, pend, res->start, *specp);
656 p = number(p, pend, res->start, addr ? hex_spec : dec_spec);
657 if (res->start != res->end) { 660 if (res->start != res->end) {
658 *p++ = '-'; 661 *p++ = '-';
659 p = number(p, pend, res->end, addr ? hex_spec : dec_spec); 662 p = number(p, pend, res->end, *specp);
660 } 663 }
661 if (decode) { 664 if (decode) {
662 if (res->flags & IORESOURCE_MEM_64) 665 if (res->flags & IORESOURCE_MEM_64)
@@ -1333,7 +1336,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
1333 break; 1336 break;
1334 1337
1335 case FORMAT_TYPE_NRCHARS: { 1338 case FORMAT_TYPE_NRCHARS: {
1336 int qualifier = spec.qualifier; 1339 u8 qualifier = spec.qualifier;
1337 1340
1338 if (qualifier == 'l') { 1341 if (qualifier == 'l') {
1339 long *ip = va_arg(args, long *); 1342 long *ip = va_arg(args, long *);
@@ -1619,7 +1622,7 @@ do { \
1619 1622
1620 case FORMAT_TYPE_NRCHARS: { 1623 case FORMAT_TYPE_NRCHARS: {
1621 /* skip %n 's argument */ 1624 /* skip %n 's argument */
1622 int qualifier = spec.qualifier; 1625 u8 qualifier = spec.qualifier;
1623 void *skip_arg; 1626 void *skip_arg;
1624 if (qualifier == 'l') 1627 if (qualifier == 'l')
1625 skip_arg = va_arg(args, long *); 1628 skip_arg = va_arg(args, long *);
@@ -1885,7 +1888,9 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
1885 char *next; 1888 char *next;
1886 char digit; 1889 char digit;
1887 int num = 0; 1890 int num = 0;
1888 int qualifier, base, field_width; 1891 u8 qualifier;
1892 u8 base;
1893 s16 field_width;
1889 bool is_sign; 1894 bool is_sign;
1890 1895
1891 while (*fmt && *str) { 1896 while (*fmt && *str) {
@@ -1963,7 +1968,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
1963 { 1968 {
1964 char *s = (char *)va_arg(args, char *); 1969 char *s = (char *)va_arg(args, char *);
1965 if (field_width == -1) 1970 if (field_width == -1)
1966 field_width = INT_MAX; 1971 field_width = SHORT_MAX;
1967 /* first, skip leading white space in buffer */ 1972 /* first, skip leading white space in buffer */
1968 str = skip_spaces(str); 1973 str = skip_spaces(str);
1969 1974
diff --git a/mm/fadvise.c b/mm/fadvise.c
index e43359214f6f..8d723c9e8b75 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -77,12 +77,20 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
77 switch (advice) { 77 switch (advice) {
78 case POSIX_FADV_NORMAL: 78 case POSIX_FADV_NORMAL:
79 file->f_ra.ra_pages = bdi->ra_pages; 79 file->f_ra.ra_pages = bdi->ra_pages;
80 spin_lock(&file->f_lock);
81 file->f_mode &= ~FMODE_RANDOM;
82 spin_unlock(&file->f_lock);
80 break; 83 break;
81 case POSIX_FADV_RANDOM: 84 case POSIX_FADV_RANDOM:
82 file->f_ra.ra_pages = 0; 85 spin_lock(&file->f_lock);
86 file->f_mode |= FMODE_RANDOM;
87 spin_unlock(&file->f_lock);
83 break; 88 break;
84 case POSIX_FADV_SEQUENTIAL: 89 case POSIX_FADV_SEQUENTIAL:
85 file->f_ra.ra_pages = bdi->ra_pages * 2; 90 file->f_ra.ra_pages = bdi->ra_pages * 2;
91 spin_lock(&file->f_lock);
92 file->f_mode &= ~FMODE_RANDOM;
93 spin_unlock(&file->f_lock);
86 break; 94 break;
87 case POSIX_FADV_WILLNEED: 95 case POSIX_FADV_WILLNEED:
88 if (!mapping->a_ops->readpage) { 96 if (!mapping->a_ops->readpage) {
diff --git a/mm/filemap.c b/mm/filemap.c
index 148b52a5bb7e..045b31c37653 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1986,7 +1986,7 @@ EXPORT_SYMBOL(iov_iter_single_seg_count);
1986inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk) 1986inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk)
1987{ 1987{
1988 struct inode *inode = file->f_mapping->host; 1988 struct inode *inode = file->f_mapping->host;
1989 unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; 1989 unsigned long limit = rlimit(RLIMIT_FSIZE);
1990 1990
1991 if (unlikely(*pos < 0)) 1991 if (unlikely(*pos < 0))
1992 return -EINVAL; 1992 return -EINVAL;
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 1888b2d71bb8..78b94f0b6d5d 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -194,7 +194,7 @@ retry:
194 flush_cache_page(vma, address, pte_pfn(*pte)); 194 flush_cache_page(vma, address, pte_pfn(*pte));
195 pteval = ptep_clear_flush_notify(vma, address, pte); 195 pteval = ptep_clear_flush_notify(vma, address, pte);
196 page_remove_rmap(page); 196 page_remove_rmap(page);
197 dec_mm_counter(mm, file_rss); 197 dec_mm_counter(mm, MM_FILEPAGES);
198 BUG_ON(pte_dirty(pteval)); 198 BUG_ON(pte_dirty(pteval));
199 pte_unmap_unlock(pte, ptl); 199 pte_unmap_unlock(pte, ptl);
200 page_cache_release(page); 200 page_cache_release(page);
diff --git a/mm/fremap.c b/mm/fremap.c
index b6ec85abbb39..46f5dacf90a2 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -40,7 +40,7 @@ static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
40 page_remove_rmap(page); 40 page_remove_rmap(page);
41 page_cache_release(page); 41 page_cache_release(page);
42 update_hiwater_rss(mm); 42 update_hiwater_rss(mm);
43 dec_mm_counter(mm, file_rss); 43 dec_mm_counter(mm, MM_FILEPAGES);
44 } 44 }
45 } else { 45 } else {
46 if (!pte_file(pte)) 46 if (!pte_file(pte))
diff --git a/mm/ksm.c b/mm/ksm.c
index 56a0da1f9979..a93f1b7f508c 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1563,10 +1563,12 @@ int page_referenced_ksm(struct page *page, struct mem_cgroup *memcg,
1563again: 1563again:
1564 hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) { 1564 hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
1565 struct anon_vma *anon_vma = rmap_item->anon_vma; 1565 struct anon_vma *anon_vma = rmap_item->anon_vma;
1566 struct anon_vma_chain *vmac;
1566 struct vm_area_struct *vma; 1567 struct vm_area_struct *vma;
1567 1568
1568 spin_lock(&anon_vma->lock); 1569 spin_lock(&anon_vma->lock);
1569 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { 1570 list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
1571 vma = vmac->vma;
1570 if (rmap_item->address < vma->vm_start || 1572 if (rmap_item->address < vma->vm_start ||
1571 rmap_item->address >= vma->vm_end) 1573 rmap_item->address >= vma->vm_end)
1572 continue; 1574 continue;
@@ -1614,10 +1616,12 @@ int try_to_unmap_ksm(struct page *page, enum ttu_flags flags)
1614again: 1616again:
1615 hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) { 1617 hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
1616 struct anon_vma *anon_vma = rmap_item->anon_vma; 1618 struct anon_vma *anon_vma = rmap_item->anon_vma;
1619 struct anon_vma_chain *vmac;
1617 struct vm_area_struct *vma; 1620 struct vm_area_struct *vma;
1618 1621
1619 spin_lock(&anon_vma->lock); 1622 spin_lock(&anon_vma->lock);
1620 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { 1623 list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
1624 vma = vmac->vma;
1621 if (rmap_item->address < vma->vm_start || 1625 if (rmap_item->address < vma->vm_start ||
1622 rmap_item->address >= vma->vm_end) 1626 rmap_item->address >= vma->vm_end)
1623 continue; 1627 continue;
@@ -1664,10 +1668,12 @@ int rmap_walk_ksm(struct page *page, int (*rmap_one)(struct page *,
1664again: 1668again:
1665 hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) { 1669 hlist_for_each_entry(rmap_item, hlist, &stable_node->hlist, hlist) {
1666 struct anon_vma *anon_vma = rmap_item->anon_vma; 1670 struct anon_vma *anon_vma = rmap_item->anon_vma;
1671 struct anon_vma_chain *vmac;
1667 struct vm_area_struct *vma; 1672 struct vm_area_struct *vma;
1668 1673
1669 spin_lock(&anon_vma->lock); 1674 spin_lock(&anon_vma->lock);
1670 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { 1675 list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
1676 vma = vmac->vma;
1671 if (rmap_item->address < vma->vm_start || 1677 if (rmap_item->address < vma->vm_start ||
1672 rmap_item->address >= vma->vm_end) 1678 rmap_item->address >= vma->vm_end)
1673 continue; 1679 continue;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 954032b80bed..d813823ab08f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2545,7 +2545,7 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *mem,
2545 pc = list_entry(list->prev, struct page_cgroup, lru); 2545 pc = list_entry(list->prev, struct page_cgroup, lru);
2546 if (busy == pc) { 2546 if (busy == pc) {
2547 list_move(&pc->lru, list); 2547 list_move(&pc->lru, list);
2548 busy = 0; 2548 busy = NULL;
2549 spin_unlock_irqrestore(&zone->lru_lock, flags); 2549 spin_unlock_irqrestore(&zone->lru_lock, flags);
2550 continue; 2550 continue;
2551 } 2551 }
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 17299fd4577c..d1f335162976 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -383,9 +383,12 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
383 if (av == NULL) /* Not actually mapped anymore */ 383 if (av == NULL) /* Not actually mapped anymore */
384 goto out; 384 goto out;
385 for_each_process (tsk) { 385 for_each_process (tsk) {
386 struct anon_vma_chain *vmac;
387
386 if (!task_early_kill(tsk)) 388 if (!task_early_kill(tsk))
387 continue; 389 continue;
388 list_for_each_entry (vma, &av->head, anon_vma_node) { 390 list_for_each_entry(vmac, &av->head, same_anon_vma) {
391 vma = vmac->vma;
389 if (!page_mapped_in_vma(page, vma)) 392 if (!page_mapped_in_vma(page, vma))
390 continue; 393 continue;
391 if (vma->vm_mm == tsk->mm) 394 if (vma->vm_mm == tsk->mm)
diff --git a/mm/memory.c b/mm/memory.c
index 72fb5f39bccc..d1153e37e9ba 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -121,6 +121,80 @@ static int __init init_zero_pfn(void)
121} 121}
122core_initcall(init_zero_pfn); 122core_initcall(init_zero_pfn);
123 123
124
125#if defined(SPLIT_RSS_COUNTING)
126
127void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm)
128{
129 int i;
130
131 for (i = 0; i < NR_MM_COUNTERS; i++) {
132 if (task->rss_stat.count[i]) {
133 add_mm_counter(mm, i, task->rss_stat.count[i]);
134 task->rss_stat.count[i] = 0;
135 }
136 }
137 task->rss_stat.events = 0;
138}
139
140static void add_mm_counter_fast(struct mm_struct *mm, int member, int val)
141{
142 struct task_struct *task = current;
143
144 if (likely(task->mm == mm))
145 task->rss_stat.count[member] += val;
146 else
147 add_mm_counter(mm, member, val);
148}
149#define inc_mm_counter_fast(mm, member) add_mm_counter_fast(mm, member, 1)
150#define dec_mm_counter_fast(mm, member) add_mm_counter_fast(mm, member, -1)
151
152/* sync counter once per 64 page faults */
153#define TASK_RSS_EVENTS_THRESH (64)
154static void check_sync_rss_stat(struct task_struct *task)
155{
156 if (unlikely(task != current))
157 return;
158 if (unlikely(task->rss_stat.events++ > TASK_RSS_EVENTS_THRESH))
159 __sync_task_rss_stat(task, task->mm);
160}
161
162unsigned long get_mm_counter(struct mm_struct *mm, int member)
163{
164 long val = 0;
165
166 /*
167 * Don't use task->mm here...for avoiding to use task_get_mm()..
168 * The caller must guarantee task->mm is not invalid.
169 */
170 val = atomic_long_read(&mm->rss_stat.count[member]);
171 /*
172 * counter is updated in asynchronous manner and may go to minus.
173 * But it's never be expected number for users.
174 */
175 if (val < 0)
176 return 0;
177 return (unsigned long)val;
178}
179
180void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
181{
182 __sync_task_rss_stat(task, mm);
183}
184#else
185
186#define inc_mm_counter_fast(mm, member) inc_mm_counter(mm, member)
187#define dec_mm_counter_fast(mm, member) dec_mm_counter(mm, member)
188
189static void check_sync_rss_stat(struct task_struct *task)
190{
191}
192
193void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
194{
195}
196#endif
197
124/* 198/*
125 * If a p?d_bad entry is found while walking page tables, report 199 * If a p?d_bad entry is found while walking page tables, report
126 * the error, before resetting entry to p?d_none. Usually (but 200 * the error, before resetting entry to p?d_none. Usually (but
@@ -300,7 +374,7 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *vma,
300 * Hide vma from rmap and truncate_pagecache before freeing 374 * Hide vma from rmap and truncate_pagecache before freeing
301 * pgtables 375 * pgtables
302 */ 376 */
303 anon_vma_unlink(vma); 377 unlink_anon_vmas(vma);
304 unlink_file_vma(vma); 378 unlink_file_vma(vma);
305 379
306 if (is_vm_hugetlb_page(vma)) { 380 if (is_vm_hugetlb_page(vma)) {
@@ -314,7 +388,7 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *vma,
314 && !is_vm_hugetlb_page(next)) { 388 && !is_vm_hugetlb_page(next)) {
315 vma = next; 389 vma = next;
316 next = vma->vm_next; 390 next = vma->vm_next;
317 anon_vma_unlink(vma); 391 unlink_anon_vmas(vma);
318 unlink_file_vma(vma); 392 unlink_file_vma(vma);
319 } 393 }
320 free_pgd_range(tlb, addr, vma->vm_end, 394 free_pgd_range(tlb, addr, vma->vm_end,
@@ -376,12 +450,20 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
376 return 0; 450 return 0;
377} 451}
378 452
379static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss) 453static inline void init_rss_vec(int *rss)
380{ 454{
381 if (file_rss) 455 memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
382 add_mm_counter(mm, file_rss, file_rss); 456}
383 if (anon_rss) 457
384 add_mm_counter(mm, anon_rss, anon_rss); 458static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
459{
460 int i;
461
462 if (current->mm == mm)
463 sync_mm_rss(current, mm);
464 for (i = 0; i < NR_MM_COUNTERS; i++)
465 if (rss[i])
466 add_mm_counter(mm, i, rss[i]);
385} 467}
386 468
387/* 469/*
@@ -597,7 +679,9 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
597 &src_mm->mmlist); 679 &src_mm->mmlist);
598 spin_unlock(&mmlist_lock); 680 spin_unlock(&mmlist_lock);
599 } 681 }
600 if (is_write_migration_entry(entry) && 682 if (likely(!non_swap_entry(entry)))
683 rss[MM_SWAPENTS]++;
684 else if (is_write_migration_entry(entry) &&
601 is_cow_mapping(vm_flags)) { 685 is_cow_mapping(vm_flags)) {
602 /* 686 /*
603 * COW mappings require pages in both parent 687 * COW mappings require pages in both parent
@@ -632,7 +716,10 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
632 if (page) { 716 if (page) {
633 get_page(page); 717 get_page(page);
634 page_dup_rmap(page); 718 page_dup_rmap(page);
635 rss[PageAnon(page)]++; 719 if (PageAnon(page))
720 rss[MM_ANONPAGES]++;
721 else
722 rss[MM_FILEPAGES]++;
636 } 723 }
637 724
638out_set_pte: 725out_set_pte:
@@ -648,11 +735,12 @@ static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm,
648 pte_t *src_pte, *dst_pte; 735 pte_t *src_pte, *dst_pte;
649 spinlock_t *src_ptl, *dst_ptl; 736 spinlock_t *src_ptl, *dst_ptl;
650 int progress = 0; 737 int progress = 0;
651 int rss[2]; 738 int rss[NR_MM_COUNTERS];
652 swp_entry_t entry = (swp_entry_t){0}; 739 swp_entry_t entry = (swp_entry_t){0};
653 740
654again: 741again:
655 rss[1] = rss[0] = 0; 742 init_rss_vec(rss);
743
656 dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl); 744 dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
657 if (!dst_pte) 745 if (!dst_pte)
658 return -ENOMEM; 746 return -ENOMEM;
@@ -688,7 +776,7 @@ again:
688 arch_leave_lazy_mmu_mode(); 776 arch_leave_lazy_mmu_mode();
689 spin_unlock(src_ptl); 777 spin_unlock(src_ptl);
690 pte_unmap_nested(orig_src_pte); 778 pte_unmap_nested(orig_src_pte);
691 add_mm_rss(dst_mm, rss[0], rss[1]); 779 add_mm_rss_vec(dst_mm, rss);
692 pte_unmap_unlock(orig_dst_pte, dst_ptl); 780 pte_unmap_unlock(orig_dst_pte, dst_ptl);
693 cond_resched(); 781 cond_resched();
694 782
@@ -816,8 +904,9 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
816 struct mm_struct *mm = tlb->mm; 904 struct mm_struct *mm = tlb->mm;
817 pte_t *pte; 905 pte_t *pte;
818 spinlock_t *ptl; 906 spinlock_t *ptl;
819 int file_rss = 0; 907 int rss[NR_MM_COUNTERS];
820 int anon_rss = 0; 908
909 init_rss_vec(rss);
821 910
822 pte = pte_offset_map_lock(mm, pmd, addr, &ptl); 911 pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
823 arch_enter_lazy_mmu_mode(); 912 arch_enter_lazy_mmu_mode();
@@ -863,14 +952,14 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
863 set_pte_at(mm, addr, pte, 952 set_pte_at(mm, addr, pte,
864 pgoff_to_pte(page->index)); 953 pgoff_to_pte(page->index));
865 if (PageAnon(page)) 954 if (PageAnon(page))
866 anon_rss--; 955 rss[MM_ANONPAGES]--;
867 else { 956 else {
868 if (pte_dirty(ptent)) 957 if (pte_dirty(ptent))
869 set_page_dirty(page); 958 set_page_dirty(page);
870 if (pte_young(ptent) && 959 if (pte_young(ptent) &&
871 likely(!VM_SequentialReadHint(vma))) 960 likely(!VM_SequentialReadHint(vma)))
872 mark_page_accessed(page); 961 mark_page_accessed(page);
873 file_rss--; 962 rss[MM_FILEPAGES]--;
874 } 963 }
875 page_remove_rmap(page); 964 page_remove_rmap(page);
876 if (unlikely(page_mapcount(page) < 0)) 965 if (unlikely(page_mapcount(page) < 0))
@@ -887,13 +976,18 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
887 if (pte_file(ptent)) { 976 if (pte_file(ptent)) {
888 if (unlikely(!(vma->vm_flags & VM_NONLINEAR))) 977 if (unlikely(!(vma->vm_flags & VM_NONLINEAR)))
889 print_bad_pte(vma, addr, ptent, NULL); 978 print_bad_pte(vma, addr, ptent, NULL);
890 } else if 979 } else {
891 (unlikely(!free_swap_and_cache(pte_to_swp_entry(ptent)))) 980 swp_entry_t entry = pte_to_swp_entry(ptent);
892 print_bad_pte(vma, addr, ptent, NULL); 981
982 if (!non_swap_entry(entry))
983 rss[MM_SWAPENTS]--;
984 if (unlikely(!free_swap_and_cache(entry)))
985 print_bad_pte(vma, addr, ptent, NULL);
986 }
893 pte_clear_not_present_full(mm, addr, pte, tlb->fullmm); 987 pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
894 } while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0)); 988 } while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));
895 989
896 add_mm_rss(mm, file_rss, anon_rss); 990 add_mm_rss_vec(mm, rss);
897 arch_leave_lazy_mmu_mode(); 991 arch_leave_lazy_mmu_mode();
898 pte_unmap_unlock(pte - 1, ptl); 992 pte_unmap_unlock(pte - 1, ptl);
899 993
@@ -1527,7 +1621,7 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
1527 1621
1528 /* Ok, finally just insert the thing.. */ 1622 /* Ok, finally just insert the thing.. */
1529 get_page(page); 1623 get_page(page);
1530 inc_mm_counter(mm, file_rss); 1624 inc_mm_counter_fast(mm, MM_FILEPAGES);
1531 page_add_file_rmap(page); 1625 page_add_file_rmap(page);
1532 set_pte_at(mm, addr, pte, mk_pte(page, prot)); 1626 set_pte_at(mm, addr, pte, mk_pte(page, prot));
1533 1627
@@ -2044,6 +2138,13 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
2044 page_cache_release(old_page); 2138 page_cache_release(old_page);
2045 } 2139 }
2046 reuse = reuse_swap_page(old_page); 2140 reuse = reuse_swap_page(old_page);
2141 if (reuse)
2142 /*
2143 * The page is all ours. Move it to our anon_vma so
2144 * the rmap code will not search our parent or siblings.
2145 * Protected against the rmap code by the page lock.
2146 */
2147 page_move_anon_rmap(old_page, vma, address);
2047 unlock_page(old_page); 2148 unlock_page(old_page);
2048 } else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) == 2149 } else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
2049 (VM_WRITE|VM_SHARED))) { 2150 (VM_WRITE|VM_SHARED))) {
@@ -2163,11 +2264,11 @@ gotten:
2163 if (likely(pte_same(*page_table, orig_pte))) { 2264 if (likely(pte_same(*page_table, orig_pte))) {
2164 if (old_page) { 2265 if (old_page) {
2165 if (!PageAnon(old_page)) { 2266 if (!PageAnon(old_page)) {
2166 dec_mm_counter(mm, file_rss); 2267 dec_mm_counter_fast(mm, MM_FILEPAGES);
2167 inc_mm_counter(mm, anon_rss); 2268 inc_mm_counter_fast(mm, MM_ANONPAGES);
2168 } 2269 }
2169 } else 2270 } else
2170 inc_mm_counter(mm, anon_rss); 2271 inc_mm_counter_fast(mm, MM_ANONPAGES);
2171 flush_cache_page(vma, address, pte_pfn(orig_pte)); 2272 flush_cache_page(vma, address, pte_pfn(orig_pte));
2172 entry = mk_pte(new_page, vma->vm_page_prot); 2273 entry = mk_pte(new_page, vma->vm_page_prot);
2173 entry = maybe_mkwrite(pte_mkdirty(entry), vma); 2274 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
@@ -2604,7 +2705,8 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
2604 * discarded at swap_free(). 2705 * discarded at swap_free().
2605 */ 2706 */
2606 2707
2607 inc_mm_counter(mm, anon_rss); 2708 inc_mm_counter_fast(mm, MM_ANONPAGES);
2709 dec_mm_counter_fast(mm, MM_SWAPENTS);
2608 pte = mk_pte(page, vma->vm_page_prot); 2710 pte = mk_pte(page, vma->vm_page_prot);
2609 if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) { 2711 if ((flags & FAULT_FLAG_WRITE) && reuse_swap_page(page)) {
2610 pte = maybe_mkwrite(pte_mkdirty(pte), vma); 2712 pte = maybe_mkwrite(pte_mkdirty(pte), vma);
@@ -2688,7 +2790,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
2688 if (!pte_none(*page_table)) 2790 if (!pte_none(*page_table))
2689 goto release; 2791 goto release;
2690 2792
2691 inc_mm_counter(mm, anon_rss); 2793 inc_mm_counter_fast(mm, MM_ANONPAGES);
2692 page_add_new_anon_rmap(page, vma, address); 2794 page_add_new_anon_rmap(page, vma, address);
2693setpte: 2795setpte:
2694 set_pte_at(mm, address, page_table, entry); 2796 set_pte_at(mm, address, page_table, entry);
@@ -2842,10 +2944,10 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2842 if (flags & FAULT_FLAG_WRITE) 2944 if (flags & FAULT_FLAG_WRITE)
2843 entry = maybe_mkwrite(pte_mkdirty(entry), vma); 2945 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
2844 if (anon) { 2946 if (anon) {
2845 inc_mm_counter(mm, anon_rss); 2947 inc_mm_counter_fast(mm, MM_ANONPAGES);
2846 page_add_new_anon_rmap(page, vma, address); 2948 page_add_new_anon_rmap(page, vma, address);
2847 } else { 2949 } else {
2848 inc_mm_counter(mm, file_rss); 2950 inc_mm_counter_fast(mm, MM_FILEPAGES);
2849 page_add_file_rmap(page); 2951 page_add_file_rmap(page);
2850 if (flags & FAULT_FLAG_WRITE) { 2952 if (flags & FAULT_FLAG_WRITE) {
2851 dirty_page = page; 2953 dirty_page = page;
@@ -3023,6 +3125,9 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
3023 3125
3024 count_vm_event(PGFAULT); 3126 count_vm_event(PGFAULT);
3025 3127
3128 /* do counter updates before entering really critical section. */
3129 check_sync_rss_stat(current);
3130
3026 if (unlikely(is_vm_hugetlb_page(vma))) 3131 if (unlikely(is_vm_hugetlb_page(vma)))
3027 return hugetlb_fault(mm, vma, address, flags); 3132 return hugetlb_fault(mm, vma, address, flags);
3028 3133
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 030ce8a5bb0e..78e34e63c7b8 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -28,6 +28,7 @@
28#include <linux/pfn.h> 28#include <linux/pfn.h>
29#include <linux/suspend.h> 29#include <linux/suspend.h>
30#include <linux/mm_inline.h> 30#include <linux/mm_inline.h>
31#include <linux/firmware-map.h>
31 32
32#include <asm/tlbflush.h> 33#include <asm/tlbflush.h>
33 34
@@ -523,6 +524,9 @@ int __ref add_memory(int nid, u64 start, u64 size)
523 BUG_ON(ret); 524 BUG_ON(ret);
524 } 525 }
525 526
527 /* create new memmap entry */
528 firmware_map_add_hotplug(start, start + size, "System RAM");
529
526 goto out; 530 goto out;
527 531
528error: 532error:
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 290fb5bf0440..bda230e52acd 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -563,24 +563,50 @@ static int policy_vma(struct vm_area_struct *vma, struct mempolicy *new)
563} 563}
564 564
565/* Step 2: apply policy to a range and do splits. */ 565/* Step 2: apply policy to a range and do splits. */
566static int mbind_range(struct vm_area_struct *vma, unsigned long start, 566static int mbind_range(struct mm_struct *mm, unsigned long start,
567 unsigned long end, struct mempolicy *new) 567 unsigned long end, struct mempolicy *new_pol)
568{ 568{
569 struct vm_area_struct *next; 569 struct vm_area_struct *next;
570 int err; 570 struct vm_area_struct *prev;
571 struct vm_area_struct *vma;
572 int err = 0;
573 pgoff_t pgoff;
574 unsigned long vmstart;
575 unsigned long vmend;
571 576
572 err = 0; 577 vma = find_vma_prev(mm, start, &prev);
573 for (; vma && vma->vm_start < end; vma = next) { 578 if (!vma || vma->vm_start > start)
579 return -EFAULT;
580
581 for (; vma && vma->vm_start < end; prev = vma, vma = next) {
574 next = vma->vm_next; 582 next = vma->vm_next;
575 if (vma->vm_start < start) 583 vmstart = max(start, vma->vm_start);
576 err = split_vma(vma->vm_mm, vma, start, 1); 584 vmend = min(end, vma->vm_end);
577 if (!err && vma->vm_end > end) 585
578 err = split_vma(vma->vm_mm, vma, end, 0); 586 pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
579 if (!err) 587 prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
580 err = policy_vma(vma, new); 588 vma->anon_vma, vma->vm_file, pgoff, new_pol);
589 if (prev) {
590 vma = prev;
591 next = vma->vm_next;
592 continue;
593 }
594 if (vma->vm_start != vmstart) {
595 err = split_vma(vma->vm_mm, vma, vmstart, 1);
596 if (err)
597 goto out;
598 }
599 if (vma->vm_end != vmend) {
600 err = split_vma(vma->vm_mm, vma, vmend, 0);
601 if (err)
602 goto out;
603 }
604 err = policy_vma(vma, new_pol);
581 if (err) 605 if (err)
582 break; 606 goto out;
583 } 607 }
608
609 out:
584 return err; 610 return err;
585} 611}
586 612
@@ -862,36 +888,36 @@ int do_migrate_pages(struct mm_struct *mm,
862 if (err) 888 if (err)
863 goto out; 889 goto out;
864 890
865/* 891 /*
866 * Find a 'source' bit set in 'tmp' whose corresponding 'dest' 892 * Find a 'source' bit set in 'tmp' whose corresponding 'dest'
867 * bit in 'to' is not also set in 'tmp'. Clear the found 'source' 893 * bit in 'to' is not also set in 'tmp'. Clear the found 'source'
868 * bit in 'tmp', and return that <source, dest> pair for migration. 894 * bit in 'tmp', and return that <source, dest> pair for migration.
869 * The pair of nodemasks 'to' and 'from' define the map. 895 * The pair of nodemasks 'to' and 'from' define the map.
870 * 896 *
871 * If no pair of bits is found that way, fallback to picking some 897 * If no pair of bits is found that way, fallback to picking some
872 * pair of 'source' and 'dest' bits that are not the same. If the 898 * pair of 'source' and 'dest' bits that are not the same. If the
873 * 'source' and 'dest' bits are the same, this represents a node 899 * 'source' and 'dest' bits are the same, this represents a node
874 * that will be migrating to itself, so no pages need move. 900 * that will be migrating to itself, so no pages need move.
875 * 901 *
876 * If no bits are left in 'tmp', or if all remaining bits left 902 * If no bits are left in 'tmp', or if all remaining bits left
877 * in 'tmp' correspond to the same bit in 'to', return false 903 * in 'tmp' correspond to the same bit in 'to', return false
878 * (nothing left to migrate). 904 * (nothing left to migrate).
879 * 905 *
880 * This lets us pick a pair of nodes to migrate between, such that 906 * This lets us pick a pair of nodes to migrate between, such that
881 * if possible the dest node is not already occupied by some other 907 * if possible the dest node is not already occupied by some other
882 * source node, minimizing the risk of overloading the memory on a 908 * source node, minimizing the risk of overloading the memory on a
883 * node that would happen if we migrated incoming memory to a node 909 * node that would happen if we migrated incoming memory to a node
884 * before migrating outgoing memory source that same node. 910 * before migrating outgoing memory source that same node.
885 * 911 *
886 * A single scan of tmp is sufficient. As we go, we remember the 912 * A single scan of tmp is sufficient. As we go, we remember the
887 * most recent <s, d> pair that moved (s != d). If we find a pair 913 * most recent <s, d> pair that moved (s != d). If we find a pair
888 * that not only moved, but what's better, moved to an empty slot 914 * that not only moved, but what's better, moved to an empty slot
889 * (d is not set in tmp), then we break out then, with that pair. 915 * (d is not set in tmp), then we break out then, with that pair.
890 * Otherwise when we finish scannng from_tmp, we at least have the 916 * Otherwise when we finish scannng from_tmp, we at least have the
891 * most recent <s, d> pair that moved. If we get all the way through 917 * most recent <s, d> pair that moved. If we get all the way through
892 * the scan of tmp without finding any node that moved, much less 918 * the scan of tmp without finding any node that moved, much less
893 * moved to an empty node, then there is nothing left worth migrating. 919 * moved to an empty node, then there is nothing left worth migrating.
894 */ 920 */
895 921
896 tmp = *from_nodes; 922 tmp = *from_nodes;
897 while (!nodes_empty(tmp)) { 923 while (!nodes_empty(tmp)) {
@@ -1047,7 +1073,7 @@ static long do_mbind(unsigned long start, unsigned long len,
1047 if (!IS_ERR(vma)) { 1073 if (!IS_ERR(vma)) {
1048 int nr_failed = 0; 1074 int nr_failed = 0;
1049 1075
1050 err = mbind_range(vma, start, end, new); 1076 err = mbind_range(mm, start, end, new);
1051 1077
1052 if (!list_empty(&pagelist)) 1078 if (!list_empty(&pagelist))
1053 nr_failed = migrate_pages(&pagelist, new_vma_page, 1079 nr_failed = migrate_pages(&pagelist, new_vma_page,
diff --git a/mm/migrate.c b/mm/migrate.c
index edb6101ed774..88000b89fc9a 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -275,8 +275,6 @@ static int migrate_page_move_mapping(struct address_space *mapping,
275 */ 275 */
276static void migrate_page_copy(struct page *newpage, struct page *page) 276static void migrate_page_copy(struct page *newpage, struct page *page)
277{ 277{
278 int anon;
279
280 copy_highpage(newpage, page); 278 copy_highpage(newpage, page);
281 279
282 if (PageError(page)) 280 if (PageError(page))
@@ -313,8 +311,6 @@ static void migrate_page_copy(struct page *newpage, struct page *page)
313 ClearPageSwapCache(page); 311 ClearPageSwapCache(page);
314 ClearPagePrivate(page); 312 ClearPagePrivate(page);
315 set_page_private(page, 0); 313 set_page_private(page, 0);
316 /* page->mapping contains a flag for PageAnon() */
317 anon = PageAnon(page);
318 page->mapping = NULL; 314 page->mapping = NULL;
319 315
320 /* 316 /*
diff --git a/mm/mlock.c b/mm/mlock.c
index 2b8335a89400..8f4e2dfceec1 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -25,7 +25,7 @@ int can_do_mlock(void)
25{ 25{
26 if (capable(CAP_IPC_LOCK)) 26 if (capable(CAP_IPC_LOCK))
27 return 1; 27 return 1;
28 if (current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur != 0) 28 if (rlimit(RLIMIT_MEMLOCK) != 0)
29 return 1; 29 return 1;
30 return 0; 30 return 0;
31} 31}
@@ -487,7 +487,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
487 locked = len >> PAGE_SHIFT; 487 locked = len >> PAGE_SHIFT;
488 locked += current->mm->locked_vm; 488 locked += current->mm->locked_vm;
489 489
490 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 490 lock_limit = rlimit(RLIMIT_MEMLOCK);
491 lock_limit >>= PAGE_SHIFT; 491 lock_limit >>= PAGE_SHIFT;
492 492
493 /* check against resource limits */ 493 /* check against resource limits */
@@ -550,7 +550,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
550 550
551 down_write(&current->mm->mmap_sem); 551 down_write(&current->mm->mmap_sem);
552 552
553 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 553 lock_limit = rlimit(RLIMIT_MEMLOCK);
554 lock_limit >>= PAGE_SHIFT; 554 lock_limit >>= PAGE_SHIFT;
555 555
556 ret = -ENOMEM; 556 ret = -ENOMEM;
@@ -584,7 +584,7 @@ int user_shm_lock(size_t size, struct user_struct *user)
584 int allowed = 0; 584 int allowed = 0;
585 585
586 locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 586 locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
587 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 587 lock_limit = rlimit(RLIMIT_MEMLOCK);
588 if (lock_limit == RLIM_INFINITY) 588 if (lock_limit == RLIM_INFINITY)
589 allowed = 1; 589 allowed = 1;
590 lock_limit >>= PAGE_SHIFT; 590 lock_limit >>= PAGE_SHIFT;
@@ -618,12 +618,12 @@ int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
618 618
619 down_write(&mm->mmap_sem); 619 down_write(&mm->mmap_sem);
620 620
621 lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; 621 lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT;
622 vm = mm->total_vm + pgsz; 622 vm = mm->total_vm + pgsz;
623 if (lim < vm) 623 if (lim < vm)
624 goto out; 624 goto out;
625 625
626 lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; 626 lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT;
627 vm = mm->locked_vm + pgsz; 627 vm = mm->locked_vm + pgsz;
628 if (lim < vm) 628 if (lim < vm)
629 goto out; 629 goto out;
diff --git a/mm/mmap.c b/mm/mmap.c
index ee2298936fe6..f1b4448626bf 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -265,7 +265,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
265 * segment grow beyond its set limit the in case where the limit is 265 * segment grow beyond its set limit the in case where the limit is
266 * not page aligned -Ram Gupta 266 * not page aligned -Ram Gupta
267 */ 267 */
268 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 268 rlim = rlimit(RLIMIT_DATA);
269 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) + 269 if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
270 (mm->end_data - mm->start_data) > rlim) 270 (mm->end_data - mm->start_data) > rlim)
271 goto out; 271 goto out;
@@ -437,7 +437,6 @@ __vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
437{ 437{
438 __vma_link_list(mm, vma, prev, rb_parent); 438 __vma_link_list(mm, vma, prev, rb_parent);
439 __vma_link_rb(mm, vma, rb_link, rb_parent); 439 __vma_link_rb(mm, vma, rb_link, rb_parent);
440 __anon_vma_link(vma);
441} 440}
442 441
443static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma, 442static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -499,7 +498,7 @@ __vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma,
499 * are necessary. The "insert" vma (if any) is to be inserted 498 * are necessary. The "insert" vma (if any) is to be inserted
500 * before we drop the necessary locks. 499 * before we drop the necessary locks.
501 */ 500 */
502void vma_adjust(struct vm_area_struct *vma, unsigned long start, 501int vma_adjust(struct vm_area_struct *vma, unsigned long start,
503 unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert) 502 unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert)
504{ 503{
505 struct mm_struct *mm = vma->vm_mm; 504 struct mm_struct *mm = vma->vm_mm;
@@ -542,6 +541,26 @@ again: remove_next = 1 + (end > next->vm_end);
542 } 541 }
543 } 542 }
544 543
544 /*
545 * When changing only vma->vm_end, we don't really need anon_vma lock.
546 */
547 if (vma->anon_vma && (insert || importer || start != vma->vm_start))
548 anon_vma = vma->anon_vma;
549 if (anon_vma) {
550 /*
551 * Easily overlooked: when mprotect shifts the boundary,
552 * make sure the expanding vma has anon_vma set if the
553 * shrinking vma had, to cover any anon pages imported.
554 */
555 if (importer && !importer->anon_vma) {
556 /* Block reverse map lookups until things are set up. */
557 if (anon_vma_clone(importer, vma)) {
558 return -ENOMEM;
559 }
560 importer->anon_vma = anon_vma;
561 }
562 }
563
545 if (file) { 564 if (file) {
546 mapping = file->f_mapping; 565 mapping = file->f_mapping;
547 if (!(vma->vm_flags & VM_NONLINEAR)) 566 if (!(vma->vm_flags & VM_NONLINEAR))
@@ -567,25 +586,6 @@ again: remove_next = 1 + (end > next->vm_end);
567 } 586 }
568 } 587 }
569 588
570 /*
571 * When changing only vma->vm_end, we don't really need
572 * anon_vma lock.
573 */
574 if (vma->anon_vma && (insert || importer || start != vma->vm_start))
575 anon_vma = vma->anon_vma;
576 if (anon_vma) {
577 spin_lock(&anon_vma->lock);
578 /*
579 * Easily overlooked: when mprotect shifts the boundary,
580 * make sure the expanding vma has anon_vma set if the
581 * shrinking vma had, to cover any anon pages imported.
582 */
583 if (importer && !importer->anon_vma) {
584 importer->anon_vma = anon_vma;
585 __anon_vma_link(importer);
586 }
587 }
588
589 if (root) { 589 if (root) {
590 flush_dcache_mmap_lock(mapping); 590 flush_dcache_mmap_lock(mapping);
591 vma_prio_tree_remove(vma, root); 591 vma_prio_tree_remove(vma, root);
@@ -616,8 +616,6 @@ again: remove_next = 1 + (end > next->vm_end);
616 __vma_unlink(mm, next, vma); 616 __vma_unlink(mm, next, vma);
617 if (file) 617 if (file)
618 __remove_shared_vm_struct(next, file, mapping); 618 __remove_shared_vm_struct(next, file, mapping);
619 if (next->anon_vma)
620 __anon_vma_merge(vma, next);
621 } else if (insert) { 619 } else if (insert) {
622 /* 620 /*
623 * split_vma has split insert from vma, and needs 621 * split_vma has split insert from vma, and needs
@@ -627,8 +625,6 @@ again: remove_next = 1 + (end > next->vm_end);
627 __insert_vm_struct(mm, insert); 625 __insert_vm_struct(mm, insert);
628 } 626 }
629 627
630 if (anon_vma)
631 spin_unlock(&anon_vma->lock);
632 if (mapping) 628 if (mapping)
633 spin_unlock(&mapping->i_mmap_lock); 629 spin_unlock(&mapping->i_mmap_lock);
634 630
@@ -638,6 +634,8 @@ again: remove_next = 1 + (end > next->vm_end);
638 if (next->vm_flags & VM_EXECUTABLE) 634 if (next->vm_flags & VM_EXECUTABLE)
639 removed_exe_file_vma(mm); 635 removed_exe_file_vma(mm);
640 } 636 }
637 if (next->anon_vma)
638 anon_vma_merge(vma, next);
641 mm->map_count--; 639 mm->map_count--;
642 mpol_put(vma_policy(next)); 640 mpol_put(vma_policy(next));
643 kmem_cache_free(vm_area_cachep, next); 641 kmem_cache_free(vm_area_cachep, next);
@@ -653,6 +651,8 @@ again: remove_next = 1 + (end > next->vm_end);
653 } 651 }
654 652
655 validate_mm(mm); 653 validate_mm(mm);
654
655 return 0;
656} 656}
657 657
658/* 658/*
@@ -759,6 +759,7 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
759{ 759{
760 pgoff_t pglen = (end - addr) >> PAGE_SHIFT; 760 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
761 struct vm_area_struct *area, *next; 761 struct vm_area_struct *area, *next;
762 int err;
762 763
763 /* 764 /*
764 * We later require that vma->vm_flags == vm_flags, 765 * We later require that vma->vm_flags == vm_flags,
@@ -792,11 +793,13 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
792 is_mergeable_anon_vma(prev->anon_vma, 793 is_mergeable_anon_vma(prev->anon_vma,
793 next->anon_vma)) { 794 next->anon_vma)) {
794 /* cases 1, 6 */ 795 /* cases 1, 6 */
795 vma_adjust(prev, prev->vm_start, 796 err = vma_adjust(prev, prev->vm_start,
796 next->vm_end, prev->vm_pgoff, NULL); 797 next->vm_end, prev->vm_pgoff, NULL);
797 } else /* cases 2, 5, 7 */ 798 } else /* cases 2, 5, 7 */
798 vma_adjust(prev, prev->vm_start, 799 err = vma_adjust(prev, prev->vm_start,
799 end, prev->vm_pgoff, NULL); 800 end, prev->vm_pgoff, NULL);
801 if (err)
802 return NULL;
800 return prev; 803 return prev;
801 } 804 }
802 805
@@ -808,11 +811,13 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
808 can_vma_merge_before(next, vm_flags, 811 can_vma_merge_before(next, vm_flags,
809 anon_vma, file, pgoff+pglen)) { 812 anon_vma, file, pgoff+pglen)) {
810 if (prev && addr < prev->vm_end) /* case 4 */ 813 if (prev && addr < prev->vm_end) /* case 4 */
811 vma_adjust(prev, prev->vm_start, 814 err = vma_adjust(prev, prev->vm_start,
812 addr, prev->vm_pgoff, NULL); 815 addr, prev->vm_pgoff, NULL);
813 else /* cases 3, 8 */ 816 else /* cases 3, 8 */
814 vma_adjust(area, addr, next->vm_end, 817 err = vma_adjust(area, addr, next->vm_end,
815 next->vm_pgoff - pglen, NULL); 818 next->vm_pgoff - pglen, NULL);
819 if (err)
820 return NULL;
816 return area; 821 return area;
817 } 822 }
818 823
@@ -967,7 +972,7 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
967 unsigned long locked, lock_limit; 972 unsigned long locked, lock_limit;
968 locked = len >> PAGE_SHIFT; 973 locked = len >> PAGE_SHIFT;
969 locked += mm->locked_vm; 974 locked += mm->locked_vm;
970 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 975 lock_limit = rlimit(RLIMIT_MEMLOCK);
971 lock_limit >>= PAGE_SHIFT; 976 lock_limit >>= PAGE_SHIFT;
972 if (locked > lock_limit && !capable(CAP_IPC_LOCK)) 977 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
973 return -EAGAIN; 978 return -EAGAIN;
@@ -1205,6 +1210,7 @@ munmap_back:
1205 vma->vm_flags = vm_flags; 1210 vma->vm_flags = vm_flags;
1206 vma->vm_page_prot = vm_get_page_prot(vm_flags); 1211 vma->vm_page_prot = vm_get_page_prot(vm_flags);
1207 vma->vm_pgoff = pgoff; 1212 vma->vm_pgoff = pgoff;
1213 INIT_LIST_HEAD(&vma->anon_vma_chain);
1208 1214
1209 if (file) { 1215 if (file) {
1210 error = -EINVAL; 1216 error = -EINVAL;
@@ -1265,13 +1271,8 @@ out:
1265 mm->total_vm += len >> PAGE_SHIFT; 1271 mm->total_vm += len >> PAGE_SHIFT;
1266 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); 1272 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
1267 if (vm_flags & VM_LOCKED) { 1273 if (vm_flags & VM_LOCKED) {
1268 /* 1274 if (!mlock_vma_pages_range(vma, addr, addr + len))
1269 * makes pages present; downgrades, drops, reacquires mmap_sem 1275 mm->locked_vm += (len >> PAGE_SHIFT);
1270 */
1271 long nr_pages = mlock_vma_pages_range(vma, addr, addr + len);
1272 if (nr_pages < 0)
1273 return nr_pages; /* vma gone! */
1274 mm->locked_vm += (len >> PAGE_SHIFT) - nr_pages;
1275 } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) 1276 } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
1276 make_pages_present(addr, addr + len); 1277 make_pages_present(addr, addr + len);
1277 return addr; 1278 return addr;
@@ -1599,7 +1600,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
1599 return -ENOMEM; 1600 return -ENOMEM;
1600 1601
1601 /* Stack limit test */ 1602 /* Stack limit test */
1602 if (size > rlim[RLIMIT_STACK].rlim_cur) 1603 if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
1603 return -ENOMEM; 1604 return -ENOMEM;
1604 1605
1605 /* mlock limit tests */ 1606 /* mlock limit tests */
@@ -1607,7 +1608,8 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
1607 unsigned long locked; 1608 unsigned long locked;
1608 unsigned long limit; 1609 unsigned long limit;
1609 locked = mm->locked_vm + grow; 1610 locked = mm->locked_vm + grow;
1610 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; 1611 limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur);
1612 limit >>= PAGE_SHIFT;
1611 if (locked > limit && !capable(CAP_IPC_LOCK)) 1613 if (locked > limit && !capable(CAP_IPC_LOCK))
1612 return -ENOMEM; 1614 return -ENOMEM;
1613 } 1615 }
@@ -1754,8 +1756,7 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
1754 if (!prev || expand_stack(prev, addr)) 1756 if (!prev || expand_stack(prev, addr))
1755 return NULL; 1757 return NULL;
1756 if (prev->vm_flags & VM_LOCKED) { 1758 if (prev->vm_flags & VM_LOCKED) {
1757 if (mlock_vma_pages_range(prev, addr, prev->vm_end) < 0) 1759 mlock_vma_pages_range(prev, addr, prev->vm_end);
1758 return NULL; /* vma gone! */
1759 } 1760 }
1760 return prev; 1761 return prev;
1761} 1762}
@@ -1783,8 +1784,7 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr)
1783 if (expand_stack(vma, addr)) 1784 if (expand_stack(vma, addr))
1784 return NULL; 1785 return NULL;
1785 if (vma->vm_flags & VM_LOCKED) { 1786 if (vma->vm_flags & VM_LOCKED) {
1786 if (mlock_vma_pages_range(vma, addr, start) < 0) 1787 mlock_vma_pages_range(vma, addr, start);
1787 return NULL; /* vma gone! */
1788 } 1788 }
1789 return vma; 1789 return vma;
1790} 1790}
@@ -1871,6 +1871,7 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
1871{ 1871{
1872 struct mempolicy *pol; 1872 struct mempolicy *pol;
1873 struct vm_area_struct *new; 1873 struct vm_area_struct *new;
1874 int err = -ENOMEM;
1874 1875
1875 if (is_vm_hugetlb_page(vma) && (addr & 1876 if (is_vm_hugetlb_page(vma) && (addr &
1876 ~(huge_page_mask(hstate_vma(vma))))) 1877 ~(huge_page_mask(hstate_vma(vma)))))
@@ -1878,11 +1879,13 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
1878 1879
1879 new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); 1880 new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
1880 if (!new) 1881 if (!new)
1881 return -ENOMEM; 1882 goto out_err;
1882 1883
1883 /* most fields are the same, copy all, and then fixup */ 1884 /* most fields are the same, copy all, and then fixup */
1884 *new = *vma; 1885 *new = *vma;
1885 1886
1887 INIT_LIST_HEAD(&new->anon_vma_chain);
1888
1886 if (new_below) 1889 if (new_below)
1887 new->vm_end = addr; 1890 new->vm_end = addr;
1888 else { 1891 else {
@@ -1892,11 +1895,14 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
1892 1895
1893 pol = mpol_dup(vma_policy(vma)); 1896 pol = mpol_dup(vma_policy(vma));
1894 if (IS_ERR(pol)) { 1897 if (IS_ERR(pol)) {
1895 kmem_cache_free(vm_area_cachep, new); 1898 err = PTR_ERR(pol);
1896 return PTR_ERR(pol); 1899 goto out_free_vma;
1897 } 1900 }
1898 vma_set_policy(new, pol); 1901 vma_set_policy(new, pol);
1899 1902
1903 if (anon_vma_clone(new, vma))
1904 goto out_free_mpol;
1905
1900 if (new->vm_file) { 1906 if (new->vm_file) {
1901 get_file(new->vm_file); 1907 get_file(new->vm_file);
1902 if (vma->vm_flags & VM_EXECUTABLE) 1908 if (vma->vm_flags & VM_EXECUTABLE)
@@ -1907,12 +1913,28 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
1907 new->vm_ops->open(new); 1913 new->vm_ops->open(new);
1908 1914
1909 if (new_below) 1915 if (new_below)
1910 vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff + 1916 err = vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
1911 ((addr - new->vm_start) >> PAGE_SHIFT), new); 1917 ((addr - new->vm_start) >> PAGE_SHIFT), new);
1912 else 1918 else
1913 vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); 1919 err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
1914 1920
1915 return 0; 1921 /* Success. */
1922 if (!err)
1923 return 0;
1924
1925 /* Clean everything up if vma_adjust failed. */
1926 new->vm_ops->close(new);
1927 if (new->vm_file) {
1928 if (vma->vm_flags & VM_EXECUTABLE)
1929 removed_exe_file_vma(mm);
1930 fput(new->vm_file);
1931 }
1932 out_free_mpol:
1933 mpol_put(pol);
1934 out_free_vma:
1935 kmem_cache_free(vm_area_cachep, new);
1936 out_err:
1937 return err;
1916} 1938}
1917 1939
1918/* 1940/*
@@ -2074,7 +2096,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
2074 unsigned long locked, lock_limit; 2096 unsigned long locked, lock_limit;
2075 locked = len >> PAGE_SHIFT; 2097 locked = len >> PAGE_SHIFT;
2076 locked += mm->locked_vm; 2098 locked += mm->locked_vm;
2077 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 2099 lock_limit = rlimit(RLIMIT_MEMLOCK);
2078 lock_limit >>= PAGE_SHIFT; 2100 lock_limit >>= PAGE_SHIFT;
2079 if (locked > lock_limit && !capable(CAP_IPC_LOCK)) 2101 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
2080 return -EAGAIN; 2102 return -EAGAIN;
@@ -2122,6 +2144,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
2122 return -ENOMEM; 2144 return -ENOMEM;
2123 } 2145 }
2124 2146
2147 INIT_LIST_HEAD(&vma->anon_vma_chain);
2125 vma->vm_mm = mm; 2148 vma->vm_mm = mm;
2126 vma->vm_start = addr; 2149 vma->vm_start = addr;
2127 vma->vm_end = addr + len; 2150 vma->vm_end = addr + len;
@@ -2258,10 +2281,11 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
2258 if (new_vma) { 2281 if (new_vma) {
2259 *new_vma = *vma; 2282 *new_vma = *vma;
2260 pol = mpol_dup(vma_policy(vma)); 2283 pol = mpol_dup(vma_policy(vma));
2261 if (IS_ERR(pol)) { 2284 if (IS_ERR(pol))
2262 kmem_cache_free(vm_area_cachep, new_vma); 2285 goto out_free_vma;
2263 return NULL; 2286 INIT_LIST_HEAD(&new_vma->anon_vma_chain);
2264 } 2287 if (anon_vma_clone(new_vma, vma))
2288 goto out_free_mempol;
2265 vma_set_policy(new_vma, pol); 2289 vma_set_policy(new_vma, pol);
2266 new_vma->vm_start = addr; 2290 new_vma->vm_start = addr;
2267 new_vma->vm_end = addr + len; 2291 new_vma->vm_end = addr + len;
@@ -2277,6 +2301,12 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
2277 } 2301 }
2278 } 2302 }
2279 return new_vma; 2303 return new_vma;
2304
2305 out_free_mempol:
2306 mpol_put(pol);
2307 out_free_vma:
2308 kmem_cache_free(vm_area_cachep, new_vma);
2309 return NULL;
2280} 2310}
2281 2311
2282/* 2312/*
@@ -2288,7 +2318,7 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
2288 unsigned long cur = mm->total_vm; /* pages */ 2318 unsigned long cur = mm->total_vm; /* pages */
2289 unsigned long lim; 2319 unsigned long lim;
2290 2320
2291 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; 2321 lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;
2292 2322
2293 if (cur + npages > lim) 2323 if (cur + npages > lim)
2294 return 0; 2324 return 0;
@@ -2354,6 +2384,7 @@ int install_special_mapping(struct mm_struct *mm,
2354 if (unlikely(vma == NULL)) 2384 if (unlikely(vma == NULL))
2355 return -ENOMEM; 2385 return -ENOMEM;
2356 2386
2387 INIT_LIST_HEAD(&vma->anon_vma_chain);
2357 vma->vm_mm = mm; 2388 vma->vm_mm = mm;
2358 vma->vm_start = addr; 2389 vma->vm_start = addr;
2359 vma->vm_end = addr + len; 2390 vma->vm_end = addr + len;
@@ -2454,6 +2485,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
2454int mm_take_all_locks(struct mm_struct *mm) 2485int mm_take_all_locks(struct mm_struct *mm)
2455{ 2486{
2456 struct vm_area_struct *vma; 2487 struct vm_area_struct *vma;
2488 struct anon_vma_chain *avc;
2457 int ret = -EINTR; 2489 int ret = -EINTR;
2458 2490
2459 BUG_ON(down_read_trylock(&mm->mmap_sem)); 2491 BUG_ON(down_read_trylock(&mm->mmap_sem));
@@ -2471,7 +2503,8 @@ int mm_take_all_locks(struct mm_struct *mm)
2471 if (signal_pending(current)) 2503 if (signal_pending(current))
2472 goto out_unlock; 2504 goto out_unlock;
2473 if (vma->anon_vma) 2505 if (vma->anon_vma)
2474 vm_lock_anon_vma(mm, vma->anon_vma); 2506 list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
2507 vm_lock_anon_vma(mm, avc->anon_vma);
2475 } 2508 }
2476 2509
2477 ret = 0; 2510 ret = 0;
@@ -2526,13 +2559,15 @@ static void vm_unlock_mapping(struct address_space *mapping)
2526void mm_drop_all_locks(struct mm_struct *mm) 2559void mm_drop_all_locks(struct mm_struct *mm)
2527{ 2560{
2528 struct vm_area_struct *vma; 2561 struct vm_area_struct *vma;
2562 struct anon_vma_chain *avc;
2529 2563
2530 BUG_ON(down_read_trylock(&mm->mmap_sem)); 2564 BUG_ON(down_read_trylock(&mm->mmap_sem));
2531 BUG_ON(!mutex_is_locked(&mm_all_locks_mutex)); 2565 BUG_ON(!mutex_is_locked(&mm_all_locks_mutex));
2532 2566
2533 for (vma = mm->mmap; vma; vma = vma->vm_next) { 2567 for (vma = mm->mmap; vma; vma = vma->vm_next) {
2534 if (vma->anon_vma) 2568 if (vma->anon_vma)
2535 vm_unlock_anon_vma(vma->anon_vma); 2569 list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
2570 vm_unlock_anon_vma(avc->anon_vma);
2536 if (vma->vm_file && vma->vm_file->f_mapping) 2571 if (vma->vm_file && vma->vm_file->f_mapping)
2537 vm_unlock_mapping(vma->vm_file->f_mapping); 2572 vm_unlock_mapping(vma->vm_file->f_mapping);
2538 } 2573 }
diff --git a/mm/mremap.c b/mm/mremap.c
index 845190898d59..e9c75efce609 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -285,7 +285,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
285 if (vma->vm_flags & VM_LOCKED) { 285 if (vma->vm_flags & VM_LOCKED) {
286 unsigned long locked, lock_limit; 286 unsigned long locked, lock_limit;
287 locked = mm->locked_vm << PAGE_SHIFT; 287 locked = mm->locked_vm << PAGE_SHIFT;
288 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; 288 lock_limit = rlimit(RLIMIT_MEMLOCK);
289 locked += new_len - old_len; 289 locked += new_len - old_len;
290 if (locked > lock_limit && !capable(CAP_IPC_LOCK)) 290 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
291 goto Eagain; 291 goto Eagain;
@@ -460,8 +460,11 @@ unsigned long do_mremap(unsigned long addr,
460 if (vma_expandable(vma, new_len - old_len)) { 460 if (vma_expandable(vma, new_len - old_len)) {
461 int pages = (new_len - old_len) >> PAGE_SHIFT; 461 int pages = (new_len - old_len) >> PAGE_SHIFT;
462 462
463 vma_adjust(vma, vma->vm_start, 463 if (vma_adjust(vma, vma->vm_start, addr + new_len,
464 addr + new_len, vma->vm_pgoff, NULL); 464 vma->vm_pgoff, NULL)) {
465 ret = -ENOMEM;
466 goto out;
467 }
465 468
466 mm->total_vm += pages; 469 mm->total_vm += pages;
467 vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages); 470 vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
diff --git a/mm/nommu.c b/mm/nommu.c
index 48a2ecfaf059..b9b5cceb1b68 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -146,7 +146,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
146 (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); 146 (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
147 147
148 for (i = 0; i < nr_pages; i++) { 148 for (i = 0; i < nr_pages; i++) {
149 vma = find_vma(mm, start); 149 vma = find_extend_vma(mm, start);
150 if (!vma) 150 if (!vma)
151 goto finish_or_fault; 151 goto finish_or_fault;
152 152
@@ -764,7 +764,7 @@ EXPORT_SYMBOL(find_vma);
764 */ 764 */
765struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr) 765struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
766{ 766{
767 return find_vma(mm, addr); 767 return find_vma(mm, addr & PAGE_MASK);
768} 768}
769 769
770/* 770/*
@@ -1209,7 +1209,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1209 region->vm_flags = vm_flags; 1209 region->vm_flags = vm_flags;
1210 region->vm_pgoff = pgoff; 1210 region->vm_pgoff = pgoff;
1211 1211
1212 INIT_LIST_HEAD(&vma->anon_vma_node); 1212 INIT_LIST_HEAD(&vma->anon_vma_chain);
1213 vma->vm_flags = vm_flags; 1213 vma->vm_flags = vm_flags;
1214 vma->vm_pgoff = pgoff; 1214 vma->vm_pgoff = pgoff;
1215 1215
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 237050478f28..35755a4156d6 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -401,8 +401,8 @@ static void __oom_kill_task(struct task_struct *p, int verbose)
401 "vsz:%lukB, anon-rss:%lukB, file-rss:%lukB\n", 401 "vsz:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
402 task_pid_nr(p), p->comm, 402 task_pid_nr(p), p->comm,
403 K(p->mm->total_vm), 403 K(p->mm->total_vm),
404 K(get_mm_counter(p->mm, anon_rss)), 404 K(get_mm_counter(p->mm, MM_ANONPAGES)),
405 K(get_mm_counter(p->mm, file_rss))); 405 K(get_mm_counter(p->mm, MM_FILEPAGES)));
406 task_unlock(p); 406 task_unlock(p);
407 407
408 /* 408 /*
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a6b17aa4740b..a8182c89de59 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -76,6 +76,31 @@ unsigned long totalreserve_pages __read_mostly;
76int percpu_pagelist_fraction; 76int percpu_pagelist_fraction;
77gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK; 77gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
78 78
79#ifdef CONFIG_PM_SLEEP
80/*
81 * The following functions are used by the suspend/hibernate code to temporarily
82 * change gfp_allowed_mask in order to avoid using I/O during memory allocations
83 * while devices are suspended. To avoid races with the suspend/hibernate code,
84 * they should always be called with pm_mutex held (gfp_allowed_mask also should
85 * only be modified with pm_mutex held, unless the suspend/hibernate code is
86 * guaranteed not to run in parallel with that modification).
87 */
88void set_gfp_allowed_mask(gfp_t mask)
89{
90 WARN_ON(!mutex_is_locked(&pm_mutex));
91 gfp_allowed_mask = mask;
92}
93
94gfp_t clear_gfp_allowed_mask(gfp_t mask)
95{
96 gfp_t ret = gfp_allowed_mask;
97
98 WARN_ON(!mutex_is_locked(&pm_mutex));
99 gfp_allowed_mask &= ~mask;
100 return ret;
101}
102#endif /* CONFIG_PM_SLEEP */
103
79#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE 104#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
80int pageblock_order __read_mostly; 105int pageblock_order __read_mostly;
81#endif 106#endif
@@ -530,7 +555,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
530 int batch_free = 0; 555 int batch_free = 0;
531 556
532 spin_lock(&zone->lock); 557 spin_lock(&zone->lock);
533 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); 558 zone->all_unreclaimable = 0;
534 zone->pages_scanned = 0; 559 zone->pages_scanned = 0;
535 560
536 __mod_zone_page_state(zone, NR_FREE_PAGES, count); 561 __mod_zone_page_state(zone, NR_FREE_PAGES, count);
@@ -568,7 +593,7 @@ static void free_one_page(struct zone *zone, struct page *page, int order,
568 int migratetype) 593 int migratetype)
569{ 594{
570 spin_lock(&zone->lock); 595 spin_lock(&zone->lock);
571 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE); 596 zone->all_unreclaimable = 0;
572 zone->pages_scanned = 0; 597 zone->pages_scanned = 0;
573 598
574 __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order); 599 __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
@@ -583,6 +608,7 @@ static void __free_pages_ok(struct page *page, unsigned int order)
583 int bad = 0; 608 int bad = 0;
584 int wasMlocked = __TestClearPageMlocked(page); 609 int wasMlocked = __TestClearPageMlocked(page);
585 610
611 trace_mm_page_free_direct(page, order);
586 kmemcheck_free_shadow(page, order); 612 kmemcheck_free_shadow(page, order);
587 613
588 for (i = 0 ; i < (1 << order) ; ++i) 614 for (i = 0 ; i < (1 << order) ; ++i)
@@ -1073,8 +1099,9 @@ void mark_free_pages(struct zone *zone)
1073 1099
1074/* 1100/*
1075 * Free a 0-order page 1101 * Free a 0-order page
1102 * cold == 1 ? free a cold page : free a hot page
1076 */ 1103 */
1077static void free_hot_cold_page(struct page *page, int cold) 1104void free_hot_cold_page(struct page *page, int cold)
1078{ 1105{
1079 struct zone *zone = page_zone(page); 1106 struct zone *zone = page_zone(page);
1080 struct per_cpu_pages *pcp; 1107 struct per_cpu_pages *pcp;
@@ -1082,6 +1109,7 @@ static void free_hot_cold_page(struct page *page, int cold)
1082 int migratetype; 1109 int migratetype;
1083 int wasMlocked = __TestClearPageMlocked(page); 1110 int wasMlocked = __TestClearPageMlocked(page);
1084 1111
1112 trace_mm_page_free_direct(page, 0);
1085 kmemcheck_free_shadow(page, 0); 1113 kmemcheck_free_shadow(page, 0);
1086 1114
1087 if (PageAnon(page)) 1115 if (PageAnon(page))
@@ -1133,12 +1161,6 @@ out:
1133 local_irq_restore(flags); 1161 local_irq_restore(flags);
1134} 1162}
1135 1163
1136void free_hot_page(struct page *page)
1137{
1138 trace_mm_page_free_direct(page, 0);
1139 free_hot_cold_page(page, 0);
1140}
1141
1142/* 1164/*
1143 * split_page takes a non-compound higher-order page, and splits it into 1165 * split_page takes a non-compound higher-order page, and splits it into
1144 * n (1<<order) sub-pages: page[0..n] 1166 * n (1<<order) sub-pages: page[0..n]
@@ -2008,9 +2030,8 @@ void __pagevec_free(struct pagevec *pvec)
2008void __free_pages(struct page *page, unsigned int order) 2030void __free_pages(struct page *page, unsigned int order)
2009{ 2031{
2010 if (put_page_testzero(page)) { 2032 if (put_page_testzero(page)) {
2011 trace_mm_page_free_direct(page, order);
2012 if (order == 0) 2033 if (order == 0)
2013 free_hot_page(page); 2034 free_hot_cold_page(page, 0);
2014 else 2035 else
2015 __free_pages_ok(page, order); 2036 __free_pages_ok(page, order);
2016 } 2037 }
@@ -2266,7 +2287,7 @@ void show_free_areas(void)
2266 K(zone_page_state(zone, NR_BOUNCE)), 2287 K(zone_page_state(zone, NR_BOUNCE)),
2267 K(zone_page_state(zone, NR_WRITEBACK_TEMP)), 2288 K(zone_page_state(zone, NR_WRITEBACK_TEMP)),
2268 zone->pages_scanned, 2289 zone->pages_scanned,
2269 (zone_is_all_unreclaimable(zone) ? "yes" : "no") 2290 (zone->all_unreclaimable ? "yes" : "no")
2270 ); 2291 );
2271 printk("lowmem_reserve[]:"); 2292 printk("lowmem_reserve[]:");
2272 for (i = 0; i < MAX_NR_ZONES; i++) 2293 for (i = 0; i < MAX_NR_ZONES; i++)
@@ -4371,8 +4392,12 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
4371 for (i = 0; i < MAX_NR_ZONES; i++) { 4392 for (i = 0; i < MAX_NR_ZONES; i++) {
4372 if (i == ZONE_MOVABLE) 4393 if (i == ZONE_MOVABLE)
4373 continue; 4394 continue;
4374 printk(" %-8s %0#10lx -> %0#10lx\n", 4395 printk(" %-8s ", zone_names[i]);
4375 zone_names[i], 4396 if (arch_zone_lowest_possible_pfn[i] ==
4397 arch_zone_highest_possible_pfn[i])
4398 printk("empty\n");
4399 else
4400 printk("%0#10lx -> %0#10lx\n",
4376 arch_zone_lowest_possible_pfn[i], 4401 arch_zone_lowest_possible_pfn[i],
4377 arch_zone_highest_possible_pfn[i]); 4402 arch_zone_highest_possible_pfn[i]);
4378 } 4403 }
diff --git a/mm/readahead.c b/mm/readahead.c
index 033bc135a41f..337b20e946f6 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -501,6 +501,12 @@ void page_cache_sync_readahead(struct address_space *mapping,
501 if (!ra->ra_pages) 501 if (!ra->ra_pages)
502 return; 502 return;
503 503
504 /* be dumb */
505 if (filp->f_mode & FMODE_RANDOM) {
506 force_page_cache_readahead(mapping, filp, offset, req_size);
507 return;
508 }
509
504 /* do read-ahead */ 510 /* do read-ahead */
505 ondemand_readahead(mapping, ra, filp, false, offset, req_size); 511 ondemand_readahead(mapping, ra, filp, false, offset, req_size);
506} 512}
diff --git a/mm/rmap.c b/mm/rmap.c
index 278cd277bdec..fcd593c9c997 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -62,6 +62,7 @@
62#include "internal.h" 62#include "internal.h"
63 63
64static struct kmem_cache *anon_vma_cachep; 64static struct kmem_cache *anon_vma_cachep;
65static struct kmem_cache *anon_vma_chain_cachep;
65 66
66static inline struct anon_vma *anon_vma_alloc(void) 67static inline struct anon_vma *anon_vma_alloc(void)
67{ 68{
@@ -73,6 +74,16 @@ void anon_vma_free(struct anon_vma *anon_vma)
73 kmem_cache_free(anon_vma_cachep, anon_vma); 74 kmem_cache_free(anon_vma_cachep, anon_vma);
74} 75}
75 76
77static inline struct anon_vma_chain *anon_vma_chain_alloc(void)
78{
79 return kmem_cache_alloc(anon_vma_chain_cachep, GFP_KERNEL);
80}
81
82void anon_vma_chain_free(struct anon_vma_chain *anon_vma_chain)
83{
84 kmem_cache_free(anon_vma_chain_cachep, anon_vma_chain);
85}
86
76/** 87/**
77 * anon_vma_prepare - attach an anon_vma to a memory region 88 * anon_vma_prepare - attach an anon_vma to a memory region
78 * @vma: the memory region in question 89 * @vma: the memory region in question
@@ -103,18 +114,23 @@ void anon_vma_free(struct anon_vma *anon_vma)
103int anon_vma_prepare(struct vm_area_struct *vma) 114int anon_vma_prepare(struct vm_area_struct *vma)
104{ 115{
105 struct anon_vma *anon_vma = vma->anon_vma; 116 struct anon_vma *anon_vma = vma->anon_vma;
117 struct anon_vma_chain *avc;
106 118
107 might_sleep(); 119 might_sleep();
108 if (unlikely(!anon_vma)) { 120 if (unlikely(!anon_vma)) {
109 struct mm_struct *mm = vma->vm_mm; 121 struct mm_struct *mm = vma->vm_mm;
110 struct anon_vma *allocated; 122 struct anon_vma *allocated;
111 123
124 avc = anon_vma_chain_alloc();
125 if (!avc)
126 goto out_enomem;
127
112 anon_vma = find_mergeable_anon_vma(vma); 128 anon_vma = find_mergeable_anon_vma(vma);
113 allocated = NULL; 129 allocated = NULL;
114 if (!anon_vma) { 130 if (!anon_vma) {
115 anon_vma = anon_vma_alloc(); 131 anon_vma = anon_vma_alloc();
116 if (unlikely(!anon_vma)) 132 if (unlikely(!anon_vma))
117 return -ENOMEM; 133 goto out_enomem_free_avc;
118 allocated = anon_vma; 134 allocated = anon_vma;
119 } 135 }
120 spin_lock(&anon_vma->lock); 136 spin_lock(&anon_vma->lock);
@@ -123,53 +139,113 @@ int anon_vma_prepare(struct vm_area_struct *vma)
123 spin_lock(&mm->page_table_lock); 139 spin_lock(&mm->page_table_lock);
124 if (likely(!vma->anon_vma)) { 140 if (likely(!vma->anon_vma)) {
125 vma->anon_vma = anon_vma; 141 vma->anon_vma = anon_vma;
126 list_add_tail(&vma->anon_vma_node, &anon_vma->head); 142 avc->anon_vma = anon_vma;
143 avc->vma = vma;
144 list_add(&avc->same_vma, &vma->anon_vma_chain);
145 list_add(&avc->same_anon_vma, &anon_vma->head);
127 allocated = NULL; 146 allocated = NULL;
128 } 147 }
129 spin_unlock(&mm->page_table_lock); 148 spin_unlock(&mm->page_table_lock);
130 149
131 spin_unlock(&anon_vma->lock); 150 spin_unlock(&anon_vma->lock);
132 if (unlikely(allocated)) 151 if (unlikely(allocated)) {
133 anon_vma_free(allocated); 152 anon_vma_free(allocated);
153 anon_vma_chain_free(avc);
154 }
134 } 155 }
135 return 0; 156 return 0;
157
158 out_enomem_free_avc:
159 anon_vma_chain_free(avc);
160 out_enomem:
161 return -ENOMEM;
136} 162}
137 163
138void __anon_vma_merge(struct vm_area_struct *vma, struct vm_area_struct *next) 164static void anon_vma_chain_link(struct vm_area_struct *vma,
165 struct anon_vma_chain *avc,
166 struct anon_vma *anon_vma)
139{ 167{
140 BUG_ON(vma->anon_vma != next->anon_vma); 168 avc->vma = vma;
141 list_del(&next->anon_vma_node); 169 avc->anon_vma = anon_vma;
170 list_add(&avc->same_vma, &vma->anon_vma_chain);
171
172 spin_lock(&anon_vma->lock);
173 list_add_tail(&avc->same_anon_vma, &anon_vma->head);
174 spin_unlock(&anon_vma->lock);
142} 175}
143 176
144void __anon_vma_link(struct vm_area_struct *vma) 177/*
178 * Attach the anon_vmas from src to dst.
179 * Returns 0 on success, -ENOMEM on failure.
180 */
181int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
145{ 182{
146 struct anon_vma *anon_vma = vma->anon_vma; 183 struct anon_vma_chain *avc, *pavc;
147 184
148 if (anon_vma) 185 list_for_each_entry(pavc, &src->anon_vma_chain, same_vma) {
149 list_add_tail(&vma->anon_vma_node, &anon_vma->head); 186 avc = anon_vma_chain_alloc();
187 if (!avc)
188 goto enomem_failure;
189 anon_vma_chain_link(dst, avc, pavc->anon_vma);
190 }
191 return 0;
192
193 enomem_failure:
194 unlink_anon_vmas(dst);
195 return -ENOMEM;
150} 196}
151 197
152void anon_vma_link(struct vm_area_struct *vma) 198/*
199 * Attach vma to its own anon_vma, as well as to the anon_vmas that
200 * the corresponding VMA in the parent process is attached to.
201 * Returns 0 on success, non-zero on failure.
202 */
203int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
153{ 204{
154 struct anon_vma *anon_vma = vma->anon_vma; 205 struct anon_vma_chain *avc;
206 struct anon_vma *anon_vma;
155 207
156 if (anon_vma) { 208 /* Don't bother if the parent process has no anon_vma here. */
157 spin_lock(&anon_vma->lock); 209 if (!pvma->anon_vma)
158 list_add_tail(&vma->anon_vma_node, &anon_vma->head); 210 return 0;
159 spin_unlock(&anon_vma->lock); 211
160 } 212 /*
213 * First, attach the new VMA to the parent VMA's anon_vmas,
214 * so rmap can find non-COWed pages in child processes.
215 */
216 if (anon_vma_clone(vma, pvma))
217 return -ENOMEM;
218
219 /* Then add our own anon_vma. */
220 anon_vma = anon_vma_alloc();
221 if (!anon_vma)
222 goto out_error;
223 avc = anon_vma_chain_alloc();
224 if (!avc)
225 goto out_error_free_anon_vma;
226 anon_vma_chain_link(vma, avc, anon_vma);
227 /* Mark this anon_vma as the one where our new (COWed) pages go. */
228 vma->anon_vma = anon_vma;
229
230 return 0;
231
232 out_error_free_anon_vma:
233 anon_vma_free(anon_vma);
234 out_error:
235 return -ENOMEM;
161} 236}
162 237
163void anon_vma_unlink(struct vm_area_struct *vma) 238static void anon_vma_unlink(struct anon_vma_chain *anon_vma_chain)
164{ 239{
165 struct anon_vma *anon_vma = vma->anon_vma; 240 struct anon_vma *anon_vma = anon_vma_chain->anon_vma;
166 int empty; 241 int empty;
167 242
243 /* If anon_vma_fork fails, we can get an empty anon_vma_chain. */
168 if (!anon_vma) 244 if (!anon_vma)
169 return; 245 return;
170 246
171 spin_lock(&anon_vma->lock); 247 spin_lock(&anon_vma->lock);
172 list_del(&vma->anon_vma_node); 248 list_del(&anon_vma_chain->same_anon_vma);
173 249
174 /* We must garbage collect the anon_vma if it's empty */ 250 /* We must garbage collect the anon_vma if it's empty */
175 empty = list_empty(&anon_vma->head) && !ksm_refcount(anon_vma); 251 empty = list_empty(&anon_vma->head) && !ksm_refcount(anon_vma);
@@ -179,6 +255,18 @@ void anon_vma_unlink(struct vm_area_struct *vma)
179 anon_vma_free(anon_vma); 255 anon_vma_free(anon_vma);
180} 256}
181 257
258void unlink_anon_vmas(struct vm_area_struct *vma)
259{
260 struct anon_vma_chain *avc, *next;
261
262 /* Unlink each anon_vma chained to the VMA. */
263 list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
264 anon_vma_unlink(avc);
265 list_del(&avc->same_vma);
266 anon_vma_chain_free(avc);
267 }
268}
269
182static void anon_vma_ctor(void *data) 270static void anon_vma_ctor(void *data)
183{ 271{
184 struct anon_vma *anon_vma = data; 272 struct anon_vma *anon_vma = data;
@@ -192,6 +280,7 @@ void __init anon_vma_init(void)
192{ 280{
193 anon_vma_cachep = kmem_cache_create("anon_vma", sizeof(struct anon_vma), 281 anon_vma_cachep = kmem_cache_create("anon_vma", sizeof(struct anon_vma),
194 0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, anon_vma_ctor); 282 0, SLAB_DESTROY_BY_RCU|SLAB_PANIC, anon_vma_ctor);
283 anon_vma_chain_cachep = KMEM_CACHE(anon_vma_chain, SLAB_PANIC);
195} 284}
196 285
197/* 286/*
@@ -396,7 +485,7 @@ static int page_referenced_anon(struct page *page,
396{ 485{
397 unsigned int mapcount; 486 unsigned int mapcount;
398 struct anon_vma *anon_vma; 487 struct anon_vma *anon_vma;
399 struct vm_area_struct *vma; 488 struct anon_vma_chain *avc;
400 int referenced = 0; 489 int referenced = 0;
401 490
402 anon_vma = page_lock_anon_vma(page); 491 anon_vma = page_lock_anon_vma(page);
@@ -404,7 +493,8 @@ static int page_referenced_anon(struct page *page,
404 return referenced; 493 return referenced;
405 494
406 mapcount = page_mapcount(page); 495 mapcount = page_mapcount(page);
407 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { 496 list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
497 struct vm_area_struct *vma = avc->vma;
408 unsigned long address = vma_address(page, vma); 498 unsigned long address = vma_address(page, vma);
409 if (address == -EFAULT) 499 if (address == -EFAULT)
410 continue; 500 continue;
@@ -511,9 +601,6 @@ int page_referenced(struct page *page,
511 int referenced = 0; 601 int referenced = 0;
512 int we_locked = 0; 602 int we_locked = 0;
513 603
514 if (TestClearPageReferenced(page))
515 referenced++;
516
517 *vm_flags = 0; 604 *vm_flags = 0;
518 if (page_mapped(page) && page_rmapping(page)) { 605 if (page_mapped(page) && page_rmapping(page)) {
519 if (!is_locked && (!PageAnon(page) || PageKsm(page))) { 606 if (!is_locked && (!PageAnon(page) || PageKsm(page))) {
@@ -614,6 +701,30 @@ int page_mkclean(struct page *page)
614EXPORT_SYMBOL_GPL(page_mkclean); 701EXPORT_SYMBOL_GPL(page_mkclean);
615 702
616/** 703/**
704 * page_move_anon_rmap - move a page to our anon_vma
705 * @page: the page to move to our anon_vma
706 * @vma: the vma the page belongs to
707 * @address: the user virtual address mapped
708 *
709 * When a page belongs exclusively to one process after a COW event,
710 * that page can be moved into the anon_vma that belongs to just that
711 * process, so the rmap code will not search the parent or sibling
712 * processes.
713 */
714void page_move_anon_rmap(struct page *page,
715 struct vm_area_struct *vma, unsigned long address)
716{
717 struct anon_vma *anon_vma = vma->anon_vma;
718
719 VM_BUG_ON(!PageLocked(page));
720 VM_BUG_ON(!anon_vma);
721 VM_BUG_ON(page->index != linear_page_index(vma, address));
722
723 anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
724 page->mapping = (struct address_space *) anon_vma;
725}
726
727/**
617 * __page_set_anon_rmap - setup new anonymous rmap 728 * __page_set_anon_rmap - setup new anonymous rmap
618 * @page: the page to add the mapping to 729 * @page: the page to add the mapping to
619 * @vma: the vm area in which the mapping is added 730 * @vma: the vm area in which the mapping is added
@@ -652,9 +763,6 @@ static void __page_check_anon_rmap(struct page *page,
652 * are initially only visible via the pagetables, and the pte is locked 763 * are initially only visible via the pagetables, and the pte is locked
653 * over the call to page_add_new_anon_rmap. 764 * over the call to page_add_new_anon_rmap.
654 */ 765 */
655 struct anon_vma *anon_vma = vma->anon_vma;
656 anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
657 BUG_ON(page->mapping != (struct address_space *)anon_vma);
658 BUG_ON(page->index != linear_page_index(vma, address)); 766 BUG_ON(page->index != linear_page_index(vma, address));
659#endif 767#endif
660} 768}
@@ -815,9 +923,9 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
815 923
816 if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) { 924 if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
817 if (PageAnon(page)) 925 if (PageAnon(page))
818 dec_mm_counter(mm, anon_rss); 926 dec_mm_counter(mm, MM_ANONPAGES);
819 else 927 else
820 dec_mm_counter(mm, file_rss); 928 dec_mm_counter(mm, MM_FILEPAGES);
821 set_pte_at(mm, address, pte, 929 set_pte_at(mm, address, pte,
822 swp_entry_to_pte(make_hwpoison_entry(page))); 930 swp_entry_to_pte(make_hwpoison_entry(page)));
823 } else if (PageAnon(page)) { 931 } else if (PageAnon(page)) {
@@ -839,7 +947,8 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
839 list_add(&mm->mmlist, &init_mm.mmlist); 947 list_add(&mm->mmlist, &init_mm.mmlist);
840 spin_unlock(&mmlist_lock); 948 spin_unlock(&mmlist_lock);
841 } 949 }
842 dec_mm_counter(mm, anon_rss); 950 dec_mm_counter(mm, MM_ANONPAGES);
951 inc_mm_counter(mm, MM_SWAPENTS);
843 } else if (PAGE_MIGRATION) { 952 } else if (PAGE_MIGRATION) {
844 /* 953 /*
845 * Store the pfn of the page in a special migration 954 * Store the pfn of the page in a special migration
@@ -857,7 +966,7 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
857 entry = make_migration_entry(page, pte_write(pteval)); 966 entry = make_migration_entry(page, pte_write(pteval));
858 set_pte_at(mm, address, pte, swp_entry_to_pte(entry)); 967 set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
859 } else 968 } else
860 dec_mm_counter(mm, file_rss); 969 dec_mm_counter(mm, MM_FILEPAGES);
861 970
862 page_remove_rmap(page); 971 page_remove_rmap(page);
863 page_cache_release(page); 972 page_cache_release(page);
@@ -996,7 +1105,7 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
996 1105
997 page_remove_rmap(page); 1106 page_remove_rmap(page);
998 page_cache_release(page); 1107 page_cache_release(page);
999 dec_mm_counter(mm, file_rss); 1108 dec_mm_counter(mm, MM_FILEPAGES);
1000 (*mapcount)--; 1109 (*mapcount)--;
1001 } 1110 }
1002 pte_unmap_unlock(pte - 1, ptl); 1111 pte_unmap_unlock(pte - 1, ptl);
@@ -1024,14 +1133,15 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
1024static int try_to_unmap_anon(struct page *page, enum ttu_flags flags) 1133static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
1025{ 1134{
1026 struct anon_vma *anon_vma; 1135 struct anon_vma *anon_vma;
1027 struct vm_area_struct *vma; 1136 struct anon_vma_chain *avc;
1028 int ret = SWAP_AGAIN; 1137 int ret = SWAP_AGAIN;
1029 1138
1030 anon_vma = page_lock_anon_vma(page); 1139 anon_vma = page_lock_anon_vma(page);
1031 if (!anon_vma) 1140 if (!anon_vma)
1032 return ret; 1141 return ret;
1033 1142
1034 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { 1143 list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
1144 struct vm_area_struct *vma = avc->vma;
1035 unsigned long address = vma_address(page, vma); 1145 unsigned long address = vma_address(page, vma);
1036 if (address == -EFAULT) 1146 if (address == -EFAULT)
1037 continue; 1147 continue;
@@ -1222,7 +1332,7 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *,
1222 struct vm_area_struct *, unsigned long, void *), void *arg) 1332 struct vm_area_struct *, unsigned long, void *), void *arg)
1223{ 1333{
1224 struct anon_vma *anon_vma; 1334 struct anon_vma *anon_vma;
1225 struct vm_area_struct *vma; 1335 struct anon_vma_chain *avc;
1226 int ret = SWAP_AGAIN; 1336 int ret = SWAP_AGAIN;
1227 1337
1228 /* 1338 /*
@@ -1237,7 +1347,8 @@ static int rmap_walk_anon(struct page *page, int (*rmap_one)(struct page *,
1237 if (!anon_vma) 1347 if (!anon_vma)
1238 return ret; 1348 return ret;
1239 spin_lock(&anon_vma->lock); 1349 spin_lock(&anon_vma->lock);
1240 list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { 1350 list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
1351 struct vm_area_struct *vma = avc->vma;
1241 unsigned long address = vma_address(page, vma); 1352 unsigned long address = vma_address(page, vma);
1242 if (address == -EFAULT) 1353 if (address == -EFAULT)
1243 continue; 1354 continue;
diff --git a/mm/swap.c b/mm/swap.c
index 308e57d8d7ed..9036b89813ac 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -55,7 +55,7 @@ static void __page_cache_release(struct page *page)
55 del_page_from_lru(zone, page); 55 del_page_from_lru(zone, page);
56 spin_unlock_irqrestore(&zone->lru_lock, flags); 56 spin_unlock_irqrestore(&zone->lru_lock, flags);
57 } 57 }
58 free_hot_page(page); 58 free_hot_cold_page(page, 0);
59} 59}
60 60
61static void put_compound_page(struct page *page) 61static void put_compound_page(struct page *page)
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 6c0585b16418..84374d8cf814 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -840,7 +840,8 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
840 goto out; 840 goto out;
841 } 841 }
842 842
843 inc_mm_counter(vma->vm_mm, anon_rss); 843 dec_mm_counter(vma->vm_mm, MM_SWAPENTS);
844 inc_mm_counter(vma->vm_mm, MM_ANONPAGES);
844 get_page(page); 845 get_page(page);
845 set_pte_at(vma->vm_mm, addr, pte, 846 set_pte_at(vma->vm_mm, addr, pte,
846 pte_mkold(mk_pte(page, vma->vm_page_prot))); 847 pte_mkold(mk_pte(page, vma->vm_page_prot)));
@@ -1759,11 +1760,11 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1759 unsigned int type; 1760 unsigned int type;
1760 int i, prev; 1761 int i, prev;
1761 int error; 1762 int error;
1762 union swap_header *swap_header = NULL; 1763 union swap_header *swap_header;
1763 unsigned int nr_good_pages = 0; 1764 unsigned int nr_good_pages;
1764 int nr_extents = 0; 1765 int nr_extents = 0;
1765 sector_t span; 1766 sector_t span;
1766 unsigned long maxpages = 1; 1767 unsigned long maxpages;
1767 unsigned long swapfilepages; 1768 unsigned long swapfilepages;
1768 unsigned char *swap_map = NULL; 1769 unsigned char *swap_map = NULL;
1769 struct page *page = NULL; 1770 struct page *page = NULL;
@@ -1922,9 +1923,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1922 * swap pte. 1923 * swap pte.
1923 */ 1924 */
1924 maxpages = swp_offset(pte_to_swp_entry( 1925 maxpages = swp_offset(pte_to_swp_entry(
1925 swp_entry_to_pte(swp_entry(0, ~0UL)))) - 1; 1926 swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1;
1926 if (maxpages > swap_header->info.last_page) 1927 if (maxpages > swap_header->info.last_page) {
1927 maxpages = swap_header->info.last_page; 1928 maxpages = swap_header->info.last_page + 1;
1929 /* p->max is an unsigned int: don't overflow it */
1930 if ((unsigned int)maxpages == 0)
1931 maxpages = UINT_MAX;
1932 }
1928 p->highest_bit = maxpages - 1; 1933 p->highest_bit = maxpages - 1;
1929 1934
1930 error = -EINVAL; 1935 error = -EINVAL;
@@ -1948,23 +1953,24 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1948 } 1953 }
1949 1954
1950 memset(swap_map, 0, maxpages); 1955 memset(swap_map, 0, maxpages);
1956 nr_good_pages = maxpages - 1; /* omit header page */
1957
1951 for (i = 0; i < swap_header->info.nr_badpages; i++) { 1958 for (i = 0; i < swap_header->info.nr_badpages; i++) {
1952 int page_nr = swap_header->info.badpages[i]; 1959 unsigned int page_nr = swap_header->info.badpages[i];
1953 if (page_nr <= 0 || page_nr >= swap_header->info.last_page) { 1960 if (page_nr == 0 || page_nr > swap_header->info.last_page) {
1954 error = -EINVAL; 1961 error = -EINVAL;
1955 goto bad_swap; 1962 goto bad_swap;
1956 } 1963 }
1957 swap_map[page_nr] = SWAP_MAP_BAD; 1964 if (page_nr < maxpages) {
1965 swap_map[page_nr] = SWAP_MAP_BAD;
1966 nr_good_pages--;
1967 }
1958 } 1968 }
1959 1969
1960 error = swap_cgroup_swapon(type, maxpages); 1970 error = swap_cgroup_swapon(type, maxpages);
1961 if (error) 1971 if (error)
1962 goto bad_swap; 1972 goto bad_swap;
1963 1973
1964 nr_good_pages = swap_header->info.last_page -
1965 swap_header->info.nr_badpages -
1966 1 /* header page */;
1967
1968 if (nr_good_pages) { 1974 if (nr_good_pages) {
1969 swap_map[0] = SWAP_MAP_BAD; 1975 swap_map[0] = SWAP_MAP_BAD;
1970 p->max = maxpages; 1976 p->max = maxpages;
@@ -2155,7 +2161,11 @@ void swap_shmem_alloc(swp_entry_t entry)
2155} 2161}
2156 2162
2157/* 2163/*
2158 * increase reference count of swap entry by 1. 2164 * Increase reference count of swap entry by 1.
2165 * Returns 0 for success, or -ENOMEM if a swap_count_continuation is required
2166 * but could not be atomically allocated. Returns 0, just as if it succeeded,
2167 * if __swap_duplicate() fails for another reason (-EINVAL or -ENOENT), which
2168 * might occur if a page table entry has got corrupted.
2159 */ 2169 */
2160int swap_duplicate(swp_entry_t entry) 2170int swap_duplicate(swp_entry_t entry)
2161{ 2171{
diff --git a/mm/vmscan.c b/mm/vmscan.c
index c26986c85ce0..79c809895fba 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -262,27 +262,6 @@ unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
262 return ret; 262 return ret;
263} 263}
264 264
265/* Called without lock on whether page is mapped, so answer is unstable */
266static inline int page_mapping_inuse(struct page *page)
267{
268 struct address_space *mapping;
269
270 /* Page is in somebody's page tables. */
271 if (page_mapped(page))
272 return 1;
273
274 /* Be more reluctant to reclaim swapcache than pagecache */
275 if (PageSwapCache(page))
276 return 1;
277
278 mapping = page_mapping(page);
279 if (!mapping)
280 return 0;
281
282 /* File is mmap'd by somebody? */
283 return mapping_mapped(mapping);
284}
285
286static inline int is_page_cache_freeable(struct page *page) 265static inline int is_page_cache_freeable(struct page *page)
287{ 266{
288 /* 267 /*
@@ -579,6 +558,65 @@ redo:
579 put_page(page); /* drop ref from isolate */ 558 put_page(page); /* drop ref from isolate */
580} 559}
581 560
561enum page_references {
562 PAGEREF_RECLAIM,
563 PAGEREF_RECLAIM_CLEAN,
564 PAGEREF_KEEP,
565 PAGEREF_ACTIVATE,
566};
567
568static enum page_references page_check_references(struct page *page,
569 struct scan_control *sc)
570{
571 int referenced_ptes, referenced_page;
572 unsigned long vm_flags;
573
574 referenced_ptes = page_referenced(page, 1, sc->mem_cgroup, &vm_flags);
575 referenced_page = TestClearPageReferenced(page);
576
577 /* Lumpy reclaim - ignore references */
578 if (sc->order > PAGE_ALLOC_COSTLY_ORDER)
579 return PAGEREF_RECLAIM;
580
581 /*
582 * Mlock lost the isolation race with us. Let try_to_unmap()
583 * move the page to the unevictable list.
584 */
585 if (vm_flags & VM_LOCKED)
586 return PAGEREF_RECLAIM;
587
588 if (referenced_ptes) {
589 if (PageAnon(page))
590 return PAGEREF_ACTIVATE;
591 /*
592 * All mapped pages start out with page table
593 * references from the instantiating fault, so we need
594 * to look twice if a mapped file page is used more
595 * than once.
596 *
597 * Mark it and spare it for another trip around the
598 * inactive list. Another page table reference will
599 * lead to its activation.
600 *
601 * Note: the mark is set for activated pages as well
602 * so that recently deactivated but used pages are
603 * quickly recovered.
604 */
605 SetPageReferenced(page);
606
607 if (referenced_page)
608 return PAGEREF_ACTIVATE;
609
610 return PAGEREF_KEEP;
611 }
612
613 /* Reclaim if clean, defer dirty pages to writeback */
614 if (referenced_page)
615 return PAGEREF_RECLAIM_CLEAN;
616
617 return PAGEREF_RECLAIM;
618}
619
582/* 620/*
583 * shrink_page_list() returns the number of reclaimed pages 621 * shrink_page_list() returns the number of reclaimed pages
584 */ 622 */
@@ -590,16 +628,15 @@ static unsigned long shrink_page_list(struct list_head *page_list,
590 struct pagevec freed_pvec; 628 struct pagevec freed_pvec;
591 int pgactivate = 0; 629 int pgactivate = 0;
592 unsigned long nr_reclaimed = 0; 630 unsigned long nr_reclaimed = 0;
593 unsigned long vm_flags;
594 631
595 cond_resched(); 632 cond_resched();
596 633
597 pagevec_init(&freed_pvec, 1); 634 pagevec_init(&freed_pvec, 1);
598 while (!list_empty(page_list)) { 635 while (!list_empty(page_list)) {
636 enum page_references references;
599 struct address_space *mapping; 637 struct address_space *mapping;
600 struct page *page; 638 struct page *page;
601 int may_enter_fs; 639 int may_enter_fs;
602 int referenced;
603 640
604 cond_resched(); 641 cond_resched();
605 642
@@ -641,17 +678,16 @@ static unsigned long shrink_page_list(struct list_head *page_list,
641 goto keep_locked; 678 goto keep_locked;
642 } 679 }
643 680
644 referenced = page_referenced(page, 1, 681 references = page_check_references(page, sc);
645 sc->mem_cgroup, &vm_flags); 682 switch (references) {
646 /* 683 case PAGEREF_ACTIVATE:
647 * In active use or really unfreeable? Activate it.
648 * If page which have PG_mlocked lost isoltation race,
649 * try_to_unmap moves it to unevictable list
650 */
651 if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
652 referenced && page_mapping_inuse(page)
653 && !(vm_flags & VM_LOCKED))
654 goto activate_locked; 684 goto activate_locked;
685 case PAGEREF_KEEP:
686 goto keep_locked;
687 case PAGEREF_RECLAIM:
688 case PAGEREF_RECLAIM_CLEAN:
689 ; /* try to reclaim the page below */
690 }
655 691
656 /* 692 /*
657 * Anonymous process memory has backing store? 693 * Anonymous process memory has backing store?
@@ -685,7 +721,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
685 } 721 }
686 722
687 if (PageDirty(page)) { 723 if (PageDirty(page)) {
688 if (sc->order <= PAGE_ALLOC_COSTLY_ORDER && referenced) 724 if (references == PAGEREF_RECLAIM_CLEAN)
689 goto keep_locked; 725 goto keep_locked;
690 if (!may_enter_fs) 726 if (!may_enter_fs)
691 goto keep_locked; 727 goto keep_locked;
@@ -1350,9 +1386,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
1350 continue; 1386 continue;
1351 } 1387 }
1352 1388
1353 /* page_referenced clears PageReferenced */ 1389 if (page_referenced(page, 0, sc->mem_cgroup, &vm_flags)) {
1354 if (page_mapping_inuse(page) &&
1355 page_referenced(page, 0, sc->mem_cgroup, &vm_flags)) {
1356 nr_rotated++; 1390 nr_rotated++;
1357 /* 1391 /*
1358 * Identify referenced, file-backed active pages and 1392 * Identify referenced, file-backed active pages and
@@ -1501,6 +1535,13 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc,
1501 unsigned long ap, fp; 1535 unsigned long ap, fp;
1502 struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); 1536 struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
1503 1537
1538 /* If we have no swap space, do not bother scanning anon pages. */
1539 if (!sc->may_swap || (nr_swap_pages <= 0)) {
1540 percent[0] = 0;
1541 percent[1] = 100;
1542 return;
1543 }
1544
1504 anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) + 1545 anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) +
1505 zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON); 1546 zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON);
1506 file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) + 1547 file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) +
@@ -1598,22 +1639,20 @@ static void shrink_zone(int priority, struct zone *zone,
1598 unsigned long nr_reclaimed = sc->nr_reclaimed; 1639 unsigned long nr_reclaimed = sc->nr_reclaimed;
1599 unsigned long nr_to_reclaim = sc->nr_to_reclaim; 1640 unsigned long nr_to_reclaim = sc->nr_to_reclaim;
1600 struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc); 1641 struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
1601 int noswap = 0;
1602 1642
1603 /* If we have no swap space, do not bother scanning anon pages. */ 1643 get_scan_ratio(zone, sc, percent);
1604 if (!sc->may_swap || (nr_swap_pages <= 0)) {
1605 noswap = 1;
1606 percent[0] = 0;
1607 percent[1] = 100;
1608 } else
1609 get_scan_ratio(zone, sc, percent);
1610 1644
1611 for_each_evictable_lru(l) { 1645 for_each_evictable_lru(l) {
1612 int file = is_file_lru(l); 1646 int file = is_file_lru(l);
1613 unsigned long scan; 1647 unsigned long scan;
1614 1648
1649 if (percent[file] == 0) {
1650 nr[l] = 0;
1651 continue;
1652 }
1653
1615 scan = zone_nr_lru_pages(zone, sc, l); 1654 scan = zone_nr_lru_pages(zone, sc, l);
1616 if (priority || noswap) { 1655 if (priority) {
1617 scan >>= priority; 1656 scan >>= priority;
1618 scan = (scan * percent[file]) / 100; 1657 scan = (scan * percent[file]) / 100;
1619 } 1658 }
@@ -1694,8 +1733,7 @@ static void shrink_zones(int priority, struct zonelist *zonelist,
1694 continue; 1733 continue;
1695 note_zone_scanning_priority(zone, priority); 1734 note_zone_scanning_priority(zone, priority);
1696 1735
1697 if (zone_is_all_unreclaimable(zone) && 1736 if (zone->all_unreclaimable && priority != DEF_PRIORITY)
1698 priority != DEF_PRIORITY)
1699 continue; /* Let kswapd poll it */ 1737 continue; /* Let kswapd poll it */
1700 sc->all_unreclaimable = 0; 1738 sc->all_unreclaimable = 0;
1701 } else { 1739 } else {
@@ -1922,7 +1960,7 @@ static int sleeping_prematurely(pg_data_t *pgdat, int order, long remaining)
1922 if (!populated_zone(zone)) 1960 if (!populated_zone(zone))
1923 continue; 1961 continue;
1924 1962
1925 if (zone_is_all_unreclaimable(zone)) 1963 if (zone->all_unreclaimable)
1926 continue; 1964 continue;
1927 1965
1928 if (!zone_watermark_ok(zone, order, high_wmark_pages(zone), 1966 if (!zone_watermark_ok(zone, order, high_wmark_pages(zone),
@@ -2012,8 +2050,7 @@ loop_again:
2012 if (!populated_zone(zone)) 2050 if (!populated_zone(zone))
2013 continue; 2051 continue;
2014 2052
2015 if (zone_is_all_unreclaimable(zone) && 2053 if (zone->all_unreclaimable && priority != DEF_PRIORITY)
2016 priority != DEF_PRIORITY)
2017 continue; 2054 continue;
2018 2055
2019 /* 2056 /*
@@ -2056,13 +2093,9 @@ loop_again:
2056 if (!populated_zone(zone)) 2093 if (!populated_zone(zone))
2057 continue; 2094 continue;
2058 2095
2059 if (zone_is_all_unreclaimable(zone) && 2096 if (zone->all_unreclaimable && priority != DEF_PRIORITY)
2060 priority != DEF_PRIORITY)
2061 continue; 2097 continue;
2062 2098
2063 if (!zone_watermark_ok(zone, order,
2064 high_wmark_pages(zone), end_zone, 0))
2065 all_zones_ok = 0;
2066 temp_priority[i] = priority; 2099 temp_priority[i] = priority;
2067 sc.nr_scanned = 0; 2100 sc.nr_scanned = 0;
2068 note_zone_scanning_priority(zone, priority); 2101 note_zone_scanning_priority(zone, priority);
@@ -2087,12 +2120,11 @@ loop_again:
2087 lru_pages); 2120 lru_pages);
2088 sc.nr_reclaimed += reclaim_state->reclaimed_slab; 2121 sc.nr_reclaimed += reclaim_state->reclaimed_slab;
2089 total_scanned += sc.nr_scanned; 2122 total_scanned += sc.nr_scanned;
2090 if (zone_is_all_unreclaimable(zone)) 2123 if (zone->all_unreclaimable)
2091 continue; 2124 continue;
2092 if (nr_slab == 0 && zone->pages_scanned >= 2125 if (nr_slab == 0 &&
2093 (zone_reclaimable_pages(zone) * 6)) 2126 zone->pages_scanned >= (zone_reclaimable_pages(zone) * 6))
2094 zone_set_flag(zone, 2127 zone->all_unreclaimable = 1;
2095 ZONE_ALL_UNRECLAIMABLE);
2096 /* 2128 /*
2097 * If we've done a decent amount of scanning and 2129 * If we've done a decent amount of scanning and
2098 * the reclaim ratio is low, start doing writepage 2130 * the reclaim ratio is low, start doing writepage
@@ -2102,13 +2134,18 @@ loop_again:
2102 total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2) 2134 total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
2103 sc.may_writepage = 1; 2135 sc.may_writepage = 1;
2104 2136
2105 /* 2137 if (!zone_watermark_ok(zone, order,
2106 * We are still under min water mark. it mean we have 2138 high_wmark_pages(zone), end_zone, 0)) {
2107 * GFP_ATOMIC allocation failure risk. Hurry up! 2139 all_zones_ok = 0;
2108 */ 2140 /*
2109 if (!zone_watermark_ok(zone, order, min_wmark_pages(zone), 2141 * We are still under min water mark. This
2110 end_zone, 0)) 2142 * means that we have a GFP_ATOMIC allocation
2111 has_under_min_watermark_zone = 1; 2143 * failure risk. Hurry up!
2144 */
2145 if (!zone_watermark_ok(zone, order,
2146 min_wmark_pages(zone), end_zone, 0))
2147 has_under_min_watermark_zone = 1;
2148 }
2112 2149
2113 } 2150 }
2114 if (all_zones_ok) 2151 if (all_zones_ok)
@@ -2550,6 +2587,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
2550 * and RECLAIM_SWAP. 2587 * and RECLAIM_SWAP.
2551 */ 2588 */
2552 p->flags |= PF_MEMALLOC | PF_SWAPWRITE; 2589 p->flags |= PF_MEMALLOC | PF_SWAPWRITE;
2590 lockdep_set_current_reclaim_state(gfp_mask);
2553 reclaim_state.reclaimed_slab = 0; 2591 reclaim_state.reclaimed_slab = 0;
2554 p->reclaim_state = &reclaim_state; 2592 p->reclaim_state = &reclaim_state;
2555 2593
@@ -2593,6 +2631,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
2593 2631
2594 p->reclaim_state = NULL; 2632 p->reclaim_state = NULL;
2595 current->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE); 2633 current->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE);
2634 lockdep_clear_current_reclaim_state();
2596 return sc.nr_reclaimed >= nr_pages; 2635 return sc.nr_reclaimed >= nr_pages;
2597} 2636}
2598 2637
@@ -2615,7 +2654,7 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
2615 zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages) 2654 zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages)
2616 return ZONE_RECLAIM_FULL; 2655 return ZONE_RECLAIM_FULL;
2617 2656
2618 if (zone_is_all_unreclaimable(zone)) 2657 if (zone->all_unreclaimable)
2619 return ZONE_RECLAIM_FULL; 2658 return ZONE_RECLAIM_FULL;
2620 2659
2621 /* 2660 /*
diff --git a/mm/vmstat.c b/mm/vmstat.c
index fc5aa183bc45..7f760cbc73f3 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -763,7 +763,7 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
763 "\n prev_priority: %i" 763 "\n prev_priority: %i"
764 "\n start_pfn: %lu" 764 "\n start_pfn: %lu"
765 "\n inactive_ratio: %u", 765 "\n inactive_ratio: %u",
766 zone_is_all_unreclaimable(zone), 766 zone->all_unreclaimable,
767 zone->prev_priority, 767 zone->prev_priority,
768 zone->zone_start_pfn, 768 zone->zone_start_pfn,
769 zone->inactive_ratio); 769 zone->inactive_ratio);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 6dcf8c9c784c..8420a4205b76 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -133,7 +133,7 @@ svc_pool_map_choose_mode(void)
133 return SVC_POOL_PERNODE; 133 return SVC_POOL_PERNODE;
134 } 134 }
135 135
136 node = any_online_node(node_online_map); 136 node = first_online_node;
137 if (nr_cpus_node(node) > 2) { 137 if (nr_cpus_node(node) > 2) {
138 /* 138 /*
139 * Non-trivial SMP, or CONFIG_NUMA on 139 * Non-trivial SMP, or CONFIG_NUMA on
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 7d1f9e928f69..8f0f1fb3dc52 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -173,11 +173,13 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
173 .sin_addr.s_addr = htonl(INADDR_ANY), 173 .sin_addr.s_addr = htonl(INADDR_ANY),
174 .sin_port = htons(port), 174 .sin_port = htons(port),
175 }; 175 };
176#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
176 struct sockaddr_in6 sin6 = { 177 struct sockaddr_in6 sin6 = {
177 .sin6_family = AF_INET6, 178 .sin6_family = AF_INET6,
178 .sin6_addr = IN6ADDR_ANY_INIT, 179 .sin6_addr = IN6ADDR_ANY_INIT,
179 .sin6_port = htons(port), 180 .sin6_port = htons(port),
180 }; 181 };
182#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
181 struct sockaddr *sap; 183 struct sockaddr *sap;
182 size_t len; 184 size_t len;
183 185
@@ -186,10 +188,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
186 sap = (struct sockaddr *)&sin; 188 sap = (struct sockaddr *)&sin;
187 len = sizeof(sin); 189 len = sizeof(sin);
188 break; 190 break;
191#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
189 case PF_INET6: 192 case PF_INET6:
190 sap = (struct sockaddr *)&sin6; 193 sap = (struct sockaddr *)&sin6;
191 len = sizeof(sin6); 194 len = sizeof(sin6);
192 break; 195 break;
196#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
193 default: 197 default:
194 return ERR_PTR(-EAFNOSUPPORT); 198 return ERR_PTR(-EAFNOSUPPORT);
195 } 199 }
@@ -231,7 +235,10 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
231 err: 235 err:
232 spin_unlock(&svc_xprt_class_lock); 236 spin_unlock(&svc_xprt_class_lock);
233 dprintk("svc: transport %s not found\n", xprt_name); 237 dprintk("svc: transport %s not found\n", xprt_name);
234 return -ENOENT; 238
239 /* This errno is exposed to user space. Provide a reasonable
240 * perror msg for a bad transport. */
241 return -EPROTONOSUPPORT;
235} 242}
236EXPORT_SYMBOL_GPL(svc_create_xprt); 243EXPORT_SYMBOL_GPL(svc_create_xprt);
237 244
@@ -699,8 +706,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
699 spin_unlock_bh(&pool->sp_lock); 706 spin_unlock_bh(&pool->sp_lock);
700 707
701 len = 0; 708 len = 0;
702 if (test_bit(XPT_LISTENER, &xprt->xpt_flags) && 709 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
703 !test_bit(XPT_CLOSE, &xprt->xpt_flags)) { 710 dprintk("svc_recv: found XPT_CLOSE\n");
711 svc_delete_xprt(xprt);
712 } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
704 struct svc_xprt *newxpt; 713 struct svc_xprt *newxpt;
705 newxpt = xprt->xpt_ops->xpo_accept(xprt); 714 newxpt = xprt->xpt_ops->xpo_accept(xprt);
706 if (newxpt) { 715 if (newxpt) {
@@ -726,7 +735,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
726 svc_xprt_received(newxpt); 735 svc_xprt_received(newxpt);
727 } 736 }
728 svc_xprt_received(xprt); 737 svc_xprt_received(xprt);
729 } else if (!test_bit(XPT_CLOSE, &xprt->xpt_flags)) { 738 } else {
730 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", 739 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
731 rqstp, pool->sp_id, xprt, 740 rqstp, pool->sp_id, xprt,
732 atomic_read(&xprt->xpt_ref.refcount)); 741 atomic_read(&xprt->xpt_ref.refcount));
@@ -739,11 +748,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
739 dprintk("svc: got len=%d\n", len); 748 dprintk("svc: got len=%d\n", len);
740 } 749 }
741 750
742 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
743 dprintk("svc_recv: found XPT_CLOSE\n");
744 svc_delete_xprt(xprt);
745 }
746
747 /* No data, incomplete (TCP) read, or accept() */ 751 /* No data, incomplete (TCP) read, or accept() */
748 if (len == 0 || len == -EAGAIN) { 752 if (len == 0 || len == -EAGAIN) {
749 rqstp->rq_res.len = 0; 753 rqstp->rq_res.len = 0;
@@ -889,11 +893,8 @@ void svc_delete_xprt(struct svc_xprt *xprt)
889 if (test_bit(XPT_TEMP, &xprt->xpt_flags)) 893 if (test_bit(XPT_TEMP, &xprt->xpt_flags))
890 serv->sv_tmpcnt--; 894 serv->sv_tmpcnt--;
891 895
892 for (dr = svc_deferred_dequeue(xprt); dr; 896 while ((dr = svc_deferred_dequeue(xprt)) != NULL)
893 dr = svc_deferred_dequeue(xprt)) {
894 svc_xprt_put(xprt);
895 kfree(dr); 897 kfree(dr);
896 }
897 898
898 svc_xprt_put(xprt); 899 svc_xprt_put(xprt);
899 spin_unlock_bh(&serv->sv_lock); 900 spin_unlock_bh(&serv->sv_lock);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index d8c041114497..afdcb0459a83 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#define RPCDBG_FACILITY RPCDBG_AUTH 16#define RPCDBG_FACILITY RPCDBG_AUTH
17 17
18#include <linux/sunrpc/clnt.h>
18 19
19/* 20/*
20 * AUTHUNIX and AUTHNULL credentials are both handled here. 21 * AUTHUNIX and AUTHNULL credentials are both handled here.
@@ -187,10 +188,13 @@ static int ip_map_parse(struct cache_detail *cd,
187 * for scratch: */ 188 * for scratch: */
188 char *buf = mesg; 189 char *buf = mesg;
189 int len; 190 int len;
190 int b1, b2, b3, b4, b5, b6, b7, b8;
191 char c;
192 char class[8]; 191 char class[8];
193 struct in6_addr addr; 192 union {
193 struct sockaddr sa;
194 struct sockaddr_in s4;
195 struct sockaddr_in6 s6;
196 } address;
197 struct sockaddr_in6 sin6;
194 int err; 198 int err;
195 199
196 struct ip_map *ipmp; 200 struct ip_map *ipmp;
@@ -209,24 +213,24 @@ static int ip_map_parse(struct cache_detail *cd,
209 len = qword_get(&mesg, buf, mlen); 213 len = qword_get(&mesg, buf, mlen);
210 if (len <= 0) return -EINVAL; 214 if (len <= 0) return -EINVAL;
211 215
212 if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) == 4) { 216 if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0)
213 addr.s6_addr32[0] = 0;
214 addr.s6_addr32[1] = 0;
215 addr.s6_addr32[2] = htonl(0xffff);
216 addr.s6_addr32[3] =
217 htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
218 } else if (sscanf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c",
219 &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
220 addr.s6_addr16[0] = htons(b1);
221 addr.s6_addr16[1] = htons(b2);
222 addr.s6_addr16[2] = htons(b3);
223 addr.s6_addr16[3] = htons(b4);
224 addr.s6_addr16[4] = htons(b5);
225 addr.s6_addr16[5] = htons(b6);
226 addr.s6_addr16[6] = htons(b7);
227 addr.s6_addr16[7] = htons(b8);
228 } else
229 return -EINVAL; 217 return -EINVAL;
218 switch (address.sa.sa_family) {
219 case AF_INET:
220 /* Form a mapped IPv4 address in sin6 */
221 memset(&sin6, 0, sizeof(sin6));
222 sin6.sin6_family = AF_INET6;
223 sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
224 sin6.sin6_addr.s6_addr32[3] = address.s4.sin_addr.s_addr;
225 break;
226#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
227 case AF_INET6:
228 memcpy(&sin6, &address.s6, sizeof(sin6));
229 break;
230#endif
231 default:
232 return -EINVAL;
233 }
230 234
231 expiry = get_expiry(&mesg); 235 expiry = get_expiry(&mesg);
232 if (expiry ==0) 236 if (expiry ==0)
@@ -243,7 +247,8 @@ static int ip_map_parse(struct cache_detail *cd,
243 } else 247 } else
244 dom = NULL; 248 dom = NULL;
245 249
246 ipmp = ip_map_lookup(class, &addr); 250 /* IPv6 scope IDs are ignored for now */
251 ipmp = ip_map_lookup(class, &sin6.sin6_addr);
247 if (ipmp) { 252 if (ipmp) {
248 err = ip_map_update(ipmp, 253 err = ip_map_update(ipmp,
249 container_of(dom, struct unix_domain, h), 254 container_of(dom, struct unix_domain, h),
@@ -619,7 +624,7 @@ static int unix_gid_show(struct seq_file *m,
619 else 624 else
620 glen = 0; 625 glen = 0;
621 626
622 seq_printf(m, "%d %d:", ug->uid, glen); 627 seq_printf(m, "%u %d:", ug->uid, glen);
623 for (i = 0; i < glen; i++) 628 for (i = 0; i < glen; i++)
624 seq_printf(m, " %d", GROUP_AT(ug->gi, i)); 629 seq_printf(m, " %d", GROUP_AT(ug->gi, i));
625 seq_printf(m, "\n"); 630 seq_printf(m, "\n");
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 870929e08e5d..a29f259204e6 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -968,6 +968,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
968 return len; 968 return len;
969 err_delete: 969 err_delete:
970 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 970 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
971 svc_xprt_received(&svsk->sk_xprt);
971 err_again: 972 err_again:
972 return -EAGAIN; 973 return -EAGAIN;
973} 974}
@@ -1357,7 +1358,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return,
1357 1358
1358 if (!so) 1359 if (!so)
1359 return err; 1360 return err;
1360 if (so->sk->sk_family != AF_INET) 1361 if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6))
1361 err = -EAFNOSUPPORT; 1362 err = -EAFNOSUPPORT;
1362 else if (so->sk->sk_protocol != IPPROTO_TCP && 1363 else if (so->sk->sk_protocol != IPPROTO_TCP &&
1363 so->sk->sk_protocol != IPPROTO_UDP) 1364 so->sk->sk_protocol != IPPROTO_UDP)
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3257d3d96767..a4d74344d805 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -145,11 +145,14 @@ our $Sparse = qr{
145 __kprobes| 145 __kprobes|
146 __ref 146 __ref
147 }x; 147 }x;
148
149# Notes to $Attribute:
150# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
148our $Attribute = qr{ 151our $Attribute = qr{
149 const| 152 const|
150 __read_mostly| 153 __read_mostly|
151 __kprobes| 154 __kprobes|
152 __(?:mem|cpu|dev|)(?:initdata|init)| 155 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
153 ____cacheline_aligned| 156 ____cacheline_aligned|
154 ____cacheline_aligned_in_smp| 157 ____cacheline_aligned_in_smp|
155 ____cacheline_internodealigned_in_smp| 158 ____cacheline_internodealigned_in_smp|
@@ -189,6 +192,14 @@ our $typeTypedefs = qr{(?x:
189 atomic_t 192 atomic_t
190)}; 193)};
191 194
195our $logFunctions = qr{(?x:
196 printk|
197 pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)|
198 dev_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
199 WARN|
200 panic
201)};
202
192our @typeList = ( 203our @typeList = (
193 qr{void}, 204 qr{void},
194 qr{(?:unsigned\s+)?char}, 205 qr{(?:unsigned\s+)?char},
@@ -1377,12 +1388,17 @@ sub process {
1377#80 column limit 1388#80 column limit
1378 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 1389 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1379 $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 1390 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
1380 $line !~ /^\+\s*printk\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ && 1391 $line !~ /^\+\s*$logFunctions\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ &&
1381 $length > 80) 1392 $length > 80)
1382 { 1393 {
1383 WARN("line over 80 characters\n" . $herecurr); 1394 WARN("line over 80 characters\n" . $herecurr);
1384 } 1395 }
1385 1396
1397# check for spaces before a quoted newline
1398 if ($rawline =~ /^.*\".*\s\\n/) {
1399 WARN("unnecessary whitespace before a quoted newline\n" . $herecurr);
1400 }
1401
1386# check for adding lines without a newline. 1402# check for adding lines without a newline.
1387 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 1403 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
1388 WARN("adding a line without newline at end of file\n" . $herecurr); 1404 WARN("adding a line without newline at end of file\n" . $herecurr);
@@ -1411,6 +1427,12 @@ sub process {
1411 ERROR("code indent should use tabs where possible\n" . $herevet); 1427 ERROR("code indent should use tabs where possible\n" . $herevet);
1412 } 1428 }
1413 1429
1430# check for space before tabs.
1431 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
1432 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1433 WARN("please, no space before tabs\n" . $herevet);
1434 }
1435
1414# check we are in a valid C source file if not then ignore this hunk 1436# check we are in a valid C source file if not then ignore this hunk
1415 next if ($realfile !~ /\.(h|c)$/); 1437 next if ($realfile !~ /\.(h|c)$/);
1416 1438
@@ -2182,8 +2204,10 @@ sub process {
2182 # Find out how long the conditional actually is. 2204 # Find out how long the conditional actually is.
2183 my @newlines = ($c =~ /\n/gs); 2205 my @newlines = ($c =~ /\n/gs);
2184 my $cond_lines = 1 + $#newlines; 2206 my $cond_lines = 1 + $#newlines;
2207 my $stat_real = '';
2185 2208
2186 my $stat_real = raw_line($linenr, $cond_lines); 2209 $stat_real = raw_line($linenr, $cond_lines)
2210 . "\n" if ($cond_lines);
2187 if (defined($stat_real) && $cond_lines > 1) { 2211 if (defined($stat_real) && $cond_lines > 1) {
2188 $stat_real = "[...]\n$stat_real"; 2212 $stat_real = "[...]\n$stat_real";
2189 } 2213 }
@@ -2348,6 +2372,8 @@ sub process {
2348 DECLARE_PER_CPU| 2372 DECLARE_PER_CPU|
2349 DEFINE_PER_CPU| 2373 DEFINE_PER_CPU|
2350 __typeof__\(| 2374 __typeof__\(|
2375 union|
2376 struct|
2351 \.$Ident\s*=\s*| 2377 \.$Ident\s*=\s*|
2352 ^\"|\"$ 2378 ^\"|\"$
2353 }x; 2379 }x;
@@ -2572,6 +2598,11 @@ sub process {
2572 WARN("plain inline is preferred over $1\n" . $herecurr); 2598 WARN("plain inline is preferred over $1\n" . $herecurr);
2573 } 2599 }
2574 2600
2601# check for sizeof(&)
2602 if ($line =~ /\bsizeof\s*\(\s*\&/) {
2603 WARN("sizeof(& should be avoided\n" . $herecurr);
2604 }
2605
2575# check for new externs in .c files. 2606# check for new externs in .c files.
2576 if ($realfile =~ /\.c$/ && defined $stat && 2607 if ($realfile =~ /\.c$/ && defined $stat &&
2577 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 2608 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
@@ -2634,9 +2665,46 @@ sub process {
2634 if ($line =~ /^.\s*__initcall\s*\(/) { 2665 if ($line =~ /^.\s*__initcall\s*\(/) {
2635 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr); 2666 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
2636 } 2667 }
2637# check for struct file_operations, ensure they are const. 2668# check for various ops structs, ensure they are const.
2669 my $struct_ops = qr{acpi_dock_ops|
2670 address_space_operations|
2671 backlight_ops|
2672 block_device_operations|
2673 dentry_operations|
2674 dev_pm_ops|
2675 dma_map_ops|
2676 extent_io_ops|
2677 file_lock_operations|
2678 file_operations|
2679 hv_ops|
2680 ide_dma_ops|
2681 intel_dvo_dev_ops|
2682 item_operations|
2683 iwl_ops|
2684 kgdb_arch|
2685 kgdb_io|
2686 kset_uevent_ops|
2687 lock_manager_operations|
2688 microcode_ops|
2689 mtrr_ops|
2690 neigh_ops|
2691 nlmsvc_binding|
2692 pci_raw_ops|
2693 pipe_buf_operations|
2694 platform_hibernation_ops|
2695 platform_suspend_ops|
2696 proto_ops|
2697 rpc_pipe_ops|
2698 seq_operations|
2699 snd_ac97_build_ops|
2700 soc_pcmcia_socket_ops|
2701 stacktrace_ops|
2702 sysfs_ops|
2703 tty_operations|
2704 usb_mon_operations|
2705 wd_ops}x;
2638 if ($line !~ /\bconst\b/ && 2706 if ($line !~ /\bconst\b/ &&
2639 $line =~ /\bstruct\s+(file_operations|seq_operations)\b/) { 2707 $line =~ /\bstruct\s+($struct_ops)\b/) {
2640 WARN("struct $1 should normally be const\n" . 2708 WARN("struct $1 should normally be const\n" .
2641 $herecurr); 2709 $herecurr);
2642 } 2710 }
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index 2f3230db7ffb..f76f3d13276d 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -41,6 +41,8 @@ my $web = 0;
41my $subsystem = 0; 41my $subsystem = 0;
42my $status = 0; 42my $status = 0;
43my $keywords = 1; 43my $keywords = 1;
44my $sections = 0;
45my $file_emails = 0;
44my $from_filename = 0; 46my $from_filename = 0;
45my $pattern_depth = 0; 47my $pattern_depth = 0;
46my $version = 0; 48my $version = 0;
@@ -120,9 +122,11 @@ if (!GetOptions(
120 'web!' => \$web, 122 'web!' => \$web,
121 'pattern-depth=i' => \$pattern_depth, 123 'pattern-depth=i' => \$pattern_depth,
122 'k|keywords!' => \$keywords, 124 'k|keywords!' => \$keywords,
125 'sections!' => \$sections,
126 'fe|file-emails!' => \$file_emails,
123 'f|file' => \$from_filename, 127 'f|file' => \$from_filename,
124 'v|version' => \$version, 128 'v|version' => \$version,
125 'h|help' => \$help, 129 'h|help|usage' => \$help,
126 )) { 130 )) {
127 die "$P: invalid argument - use --help if necessary\n"; 131 die "$P: invalid argument - use --help if necessary\n";
128} 132}
@@ -137,9 +141,9 @@ if ($version != 0) {
137 exit 0; 141 exit 0;
138} 142}
139 143
140if ($#ARGV < 0) { 144if (-t STDIN && !@ARGV) {
141 usage(); 145 # We're talking to a terminal, but have no command line arguments.
142 die "$P: argument missing: patchfile or -f file please\n"; 146 die "$P: missing patchfile or -f file - use --help if necessary\n";
143} 147}
144 148
145if ($output_separator ne ", ") { 149if ($output_separator ne ", ") {
@@ -150,16 +154,24 @@ if ($output_rolestats) {
150 $output_roles = 1; 154 $output_roles = 1;
151} 155}
152 156
153my $selections = $email + $scm + $status + $subsystem + $web; 157if ($sections) {
154if ($selections == 0) { 158 $email = 0;
155 usage(); 159 $email_list = 0;
156 die "$P: Missing required option: email, scm, status, subsystem or web\n"; 160 $scm = 0;
161 $status = 0;
162 $subsystem = 0;
163 $web = 0;
164 $keywords = 0;
165} else {
166 my $selections = $email + $scm + $status + $subsystem + $web;
167 if ($selections == 0) {
168 die "$P: Missing required option: email, scm, status, subsystem or web\n";
169 }
157} 170}
158 171
159if ($email && 172if ($email &&
160 ($email_maintainer + $email_list + $email_subscriber_list + 173 ($email_maintainer + $email_list + $email_subscriber_list +
161 $email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) { 174 $email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) {
162 usage();
163 die "$P: Please select at least 1 email option\n"; 175 die "$P: Please select at least 1 email option\n";
164} 176}
165 177
@@ -173,8 +185,9 @@ if (!top_of_kernel_tree($lk_path)) {
173my @typevalue = (); 185my @typevalue = ();
174my %keyword_hash; 186my %keyword_hash;
175 187
176open(MAINT, "<${lk_path}MAINTAINERS") || die "$P: Can't open MAINTAINERS\n"; 188open (my $maint, '<', "${lk_path}MAINTAINERS")
177while (<MAINT>) { 189 or die "$P: Can't open MAINTAINERS: $!\n";
190while (<$maint>) {
178 my $line = $_; 191 my $line = $_;
179 192
180 if ($line =~ m/^(\C):\s*(.*)/) { 193 if ($line =~ m/^(\C):\s*(.*)/) {
@@ -199,13 +212,14 @@ while (<MAINT>) {
199 push(@typevalue, $line); 212 push(@typevalue, $line);
200 } 213 }
201} 214}
202close(MAINT); 215close($maint);
203 216
204my %mailmap; 217my %mailmap;
205 218
206if ($email_remove_duplicates) { 219if ($email_remove_duplicates) {
207 open(MAILMAP, "<${lk_path}.mailmap") || warn "$P: Can't open .mailmap\n"; 220 open(my $mailmap, '<', "${lk_path}.mailmap")
208 while (<MAILMAP>) { 221 or warn "$P: Can't open .mailmap: $!\n";
222 while (<$mailmap>) {
209 my $line = $_; 223 my $line = $_;
210 224
211 next if ($line =~ m/^\s*#/); 225 next if ($line =~ m/^\s*#/);
@@ -224,7 +238,7 @@ if ($email_remove_duplicates) {
224 $mailmap{$name} = \@arr; 238 $mailmap{$name} = \@arr;
225 } 239 }
226 } 240 }
227 close(MAILMAP); 241 close($mailmap);
228} 242}
229 243
230## use the filenames on the command line or find the filenames in the patchfiles 244## use the filenames on the command line or find the filenames in the patchfiles
@@ -232,31 +246,47 @@ if ($email_remove_duplicates) {
232my @files = (); 246my @files = ();
233my @range = (); 247my @range = ();
234my @keyword_tvi = (); 248my @keyword_tvi = ();
249my @file_emails = ();
250
251if (!@ARGV) {
252 push(@ARGV, "&STDIN");
253}
235 254
236foreach my $file (@ARGV) { 255foreach my $file (@ARGV) {
237 ##if $file is a directory and it lacks a trailing slash, add one 256 if ($file ne "&STDIN") {
238 if ((-d $file)) { 257 ##if $file is a directory and it lacks a trailing slash, add one
239 $file =~ s@([^/])$@$1/@; 258 if ((-d $file)) {
240 } elsif (!(-f $file)) { 259 $file =~ s@([^/])$@$1/@;
241 die "$P: file '${file}' not found\n"; 260 } elsif (!(-f $file)) {
261 die "$P: file '${file}' not found\n";
262 }
242 } 263 }
243 if ($from_filename) { 264 if ($from_filename) {
244 push(@files, $file); 265 push(@files, $file);
245 if (-f $file && $keywords) { 266 if (-f $file && ($keywords || $file_emails)) {
246 open(FILE, "<$file") or die "$P: Can't open ${file}\n"; 267 open(my $f, '<', $file)
247 my $text = do { local($/) ; <FILE> }; 268 or die "$P: Can't open $file: $!\n";
248 foreach my $line (keys %keyword_hash) { 269 my $text = do { local($/) ; <$f> };
249 if ($text =~ m/$keyword_hash{$line}/x) { 270 close($f);
250 push(@keyword_tvi, $line); 271 if ($keywords) {
272 foreach my $line (keys %keyword_hash) {
273 if ($text =~ m/$keyword_hash{$line}/x) {
274 push(@keyword_tvi, $line);
275 }
251 } 276 }
252 } 277 }
253 close(FILE); 278 if ($file_emails) {
279 my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
280 push(@file_emails, clean_file_emails(@poss_addr));
281 }
254 } 282 }
255 } else { 283 } else {
256 my $file_cnt = @files; 284 my $file_cnt = @files;
257 my $lastfile; 285 my $lastfile;
258 open(PATCH, "<$file") or die "$P: Can't open ${file}\n"; 286
259 while (<PATCH>) { 287 open(my $patch, '<', $file)
288 or die "$P: Can't open $file: $!\n";
289 while (<$patch>) {
260 my $patch_line = $_; 290 my $patch_line = $_;
261 if (m/^\+\+\+\s+(\S+)/) { 291 if (m/^\+\+\+\s+(\S+)/) {
262 my $filename = $1; 292 my $filename = $1;
@@ -276,7 +306,8 @@ foreach my $file (@ARGV) {
276 } 306 }
277 } 307 }
278 } 308 }
279 close(PATCH); 309 close($patch);
310
280 if ($file_cnt == @files) { 311 if ($file_cnt == @files) {
281 warn "$P: file '${file}' doesn't appear to be a patch. " 312 warn "$P: file '${file}' doesn't appear to be a patch. "
282 . "Add -f to options?\n"; 313 . "Add -f to options?\n";
@@ -285,6 +316,8 @@ foreach my $file (@ARGV) {
285 } 316 }
286} 317}
287 318
319@file_emails = uniq(@file_emails);
320
288my @email_to = (); 321my @email_to = ();
289my @list_to = (); 322my @list_to = ();
290my @scm = (); 323my @scm = ();
@@ -314,6 +347,7 @@ foreach my $file (@files) {
314 if ($type eq 'X') { 347 if ($type eq 'X') {
315 if (file_match_pattern($file, $value)) { 348 if (file_match_pattern($file, $value)) {
316 $exclude = 1; 349 $exclude = 1;
350 last;
317 } 351 }
318 } 352 }
319 } 353 }
@@ -340,12 +374,28 @@ foreach my $file (@files) {
340 } 374 }
341 } 375 }
342 376
343 $tvi += ($end - $start); 377 $tvi = $end + 1;
344
345 } 378 }
346 379
347 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) { 380 foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
348 add_categories($line); 381 add_categories($line);
382 if ($sections) {
383 my $i;
384 my $start = find_starting_index($line);
385 my $end = find_ending_index($line);
386 for ($i = $start; $i < $end; $i++) {
387 my $line = $typevalue[$i];
388 if ($line =~ /^[FX]:/) { ##Restore file patterns
389 $line =~ s/([^\\])\.([^\*])/$1\?$2/g;
390 $line =~ s/([^\\])\.$/$1\?/g; ##Convert . back to ?
391 $line =~ s/\\\./\./g; ##Convert \. to .
392 $line =~ s/\.\*/\*/g; ##Convert .* to *
393 }
394 $line =~ s/^([A-Z]):/$1:\t/g;
395 print("$line\n");
396 }
397 print("\n");
398 }
349 } 399 }
350 400
351 if ($email && $email_git) { 401 if ($email && $email_git) {
@@ -377,6 +427,14 @@ if ($email) {
377 } 427 }
378 } 428 }
379 } 429 }
430
431 foreach my $email (@file_emails) {
432 my ($name, $address) = parse_email($email);
433
434 my $tmp_email = format_email($name, $address, $email_usename);
435 push_email_address($tmp_email, '');
436 add_role($tmp_email, 'in file');
437 }
380} 438}
381 439
382if ($email || $email_list) { 440if ($email || $email_list) {
@@ -453,6 +511,7 @@ MAINTAINER field selection options:
453 --remove-duplicates => minimize duplicate email names/addresses 511 --remove-duplicates => minimize duplicate email names/addresses
454 --roles => show roles (status:subsystem, git-signer, list, etc...) 512 --roles => show roles (status:subsystem, git-signer, list, etc...)
455 --rolestats => show roles and statistics (commits/total_commits, %) 513 --rolestats => show roles and statistics (commits/total_commits, %)
514 --file-emails => add email addresses found in -f file (default: 0 (off))
456 --scm => print SCM tree(s) if any 515 --scm => print SCM tree(s) if any
457 --status => print status if any 516 --status => print status if any
458 --subsystem => print subsystem name if any 517 --subsystem => print subsystem name if any
@@ -466,6 +525,7 @@ Output type options:
466Other options: 525Other options:
467 --pattern-depth => Number of pattern directory traversals (default: 0 (all)) 526 --pattern-depth => Number of pattern directory traversals (default: 0 (all))
468 --keywords => scan patch for keywords (default: 1 (on)) 527 --keywords => scan patch for keywords (default: 1 (on))
528 --sections => print the entire subsystem sections with pattern matches
469 --version => show version 529 --version => show version
470 --help => show this help information 530 --help => show this help information
471 531
@@ -545,7 +605,7 @@ sub parse_email {
545 $name =~ s/^\"|\"$//g; 605 $name =~ s/^\"|\"$//g;
546 $address =~ s/^\s+|\s+$//g; 606 $address =~ s/^\s+|\s+$//g;
547 607
548 if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars 608 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
549 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 609 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
550 $name = "\"$name\""; 610 $name = "\"$name\"";
551 } 611 }
@@ -562,7 +622,7 @@ sub format_email {
562 $name =~ s/^\"|\"$//g; 622 $name =~ s/^\"|\"$//g;
563 $address =~ s/^\s+|\s+$//g; 623 $address =~ s/^\s+|\s+$//g;
564 624
565 if ($name =~ /[^a-z0-9 \.\-]/i) { ##has "must quote" chars 625 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
566 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 626 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
567 $name = "\"$name\""; 627 $name = "\"$name\"";
568 } 628 }
@@ -811,7 +871,9 @@ sub add_role {
811 foreach my $entry (@email_to) { 871 foreach my $entry (@email_to) {
812 if ($email_remove_duplicates) { 872 if ($email_remove_duplicates) {
813 my ($entry_name, $entry_address) = parse_email($entry->[0]); 873 my ($entry_name, $entry_address) = parse_email($entry->[0]);
814 if ($name eq $entry_name || $address eq $entry_address) { 874 if (($name eq $entry_name || $address eq $entry_address)
875 && ($role eq "" || !($entry->[1] =~ m/$role/))
876 ) {
815 if ($entry->[1] eq "") { 877 if ($entry->[1] eq "") {
816 $entry->[1] = "$role"; 878 $entry->[1] = "$role";
817 } else { 879 } else {
@@ -819,7 +881,9 @@ sub add_role {
819 } 881 }
820 } 882 }
821 } else { 883 } else {
822 if ($email eq $entry->[0]) { 884 if ($email eq $entry->[0]
885 && ($role eq "" || !($entry->[1] =~ m/$role/))
886 ) {
823 if ($entry->[1] eq "") { 887 if ($entry->[1] eq "") {
824 $entry->[1] = "$role"; 888 $entry->[1] = "$role";
825 } else { 889 } else {
@@ -1099,6 +1163,51 @@ sub sort_and_uniq {
1099 return @parms; 1163 return @parms;
1100} 1164}
1101 1165
1166sub clean_file_emails {
1167 my (@file_emails) = @_;
1168 my @fmt_emails = ();
1169
1170 foreach my $email (@file_emails) {
1171 $email =~ s/[\(\<\{]{0,1}([A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+)[\)\>\}]{0,1}/\<$1\>/g;
1172 my ($name, $address) = parse_email($email);
1173 if ($name eq '"[,\.]"') {
1174 $name = "";
1175 }
1176
1177 my @nw = split(/[^A-Za-zÀ-ÿ\'\,\.\+-]/, $name);
1178 if (@nw > 2) {
1179 my $first = $nw[@nw - 3];
1180 my $middle = $nw[@nw - 2];
1181 my $last = $nw[@nw - 1];
1182
1183 if (((length($first) == 1 && $first =~ m/[A-Za-z]/) ||
1184 (length($first) == 2 && substr($first, -1) eq ".")) ||
1185 (length($middle) == 1 ||
1186 (length($middle) == 2 && substr($middle, -1) eq "."))) {
1187 $name = "$first $middle $last";
1188 } else {
1189 $name = "$middle $last";
1190 }
1191 }
1192
1193 if (substr($name, -1) =~ /[,\.]/) {
1194 $name = substr($name, 0, length($name) - 1);
1195 } elsif (substr($name, -2) =~ /[,\.]"/) {
1196 $name = substr($name, 0, length($name) - 2) . '"';
1197 }
1198
1199 if (substr($name, 0, 1) =~ /[,\.]/) {
1200 $name = substr($name, 1, length($name) - 1);
1201 } elsif (substr($name, 0, 2) =~ /"[,\.]/) {
1202 $name = '"' . substr($name, 2, length($name) - 2);
1203 }
1204
1205 my $fmt_email = format_email($name, $address, $email_usename);
1206 push(@fmt_emails, $fmt_email);
1207 }
1208 return @fmt_emails;
1209}
1210
1102sub merge_email { 1211sub merge_email {
1103 my @lines; 1212 my @lines;
1104 my %saw; 1213 my %saw;
@@ -1183,7 +1292,7 @@ sub rfc822_strip_comments {
1183 1292
1184# valid: returns true if the parameter is an RFC822 valid address 1293# valid: returns true if the parameter is an RFC822 valid address
1185# 1294#
1186sub rfc822_valid ($) { 1295sub rfc822_valid {
1187 my $s = rfc822_strip_comments(shift); 1296 my $s = rfc822_strip_comments(shift);
1188 1297
1189 if (!$rfc822re) { 1298 if (!$rfc822re) {
@@ -1203,7 +1312,7 @@ sub rfc822_valid ($) {
1203# from success with no addresses found, because an empty string is 1312# from success with no addresses found, because an empty string is
1204# a valid list. 1313# a valid list.
1205 1314
1206sub rfc822_validlist ($) { 1315sub rfc822_validlist {
1207 my $s = rfc822_strip_comments(shift); 1316 my $s = rfc822_strip_comments(shift);
1208 1317
1209 if (!$rfc822re) { 1318 if (!$rfc822re) {
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 8f8b17ac074d..73943651caed 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -393,7 +393,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
393 event == SNDRV_TIMER_EVENT_CONTINUE) 393 event == SNDRV_TIMER_EVENT_CONTINUE)
394 resolution = snd_timer_resolution(ti); 394 resolution = snd_timer_resolution(ti);
395 if (ti->ccallback) 395 if (ti->ccallback)
396 ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); 396 ti->ccallback(ti, event, &tstamp, resolution);
397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE) 397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
398 return; 398 return;
399 timer = ti->timer; 399 timer = ti->timer;
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index b865e45a8f9b..5913717c1be6 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1558,7 +1558,7 @@ static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
1558 1558
1559 err = pnp_activate_dev(devmc); 1559 err = pnp_activate_dev(devmc);
1560 if (err < 0) { 1560 if (err < 0) {
1561 snd_printk(KERN_ERR "OPL syntg pnp configure failure: %d\n", 1561 snd_printk(KERN_ERR "MC pnp configure failure: %d\n",
1562 err); 1562 err);
1563 return err; 1563 return err;
1564 } 1564 }
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index a4af53b5c1cf..becd90d7536d 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -144,12 +144,8 @@ struct snd_opti9xx {
144 144
145 spinlock_t lock; 145 spinlock_t lock;
146 146
147 long wss_base;
147 int irq; 148 int irq;
148
149#ifdef CONFIG_PNP
150 struct pnp_dev *dev;
151 struct pnp_dev *devmpu;
152#endif /* CONFIG_PNP */
153}; 149};
154 150
155static int snd_opti9xx_pnp_is_probed; 151static int snd_opti9xx_pnp_is_probed;
@@ -159,12 +155,17 @@ static int snd_opti9xx_pnp_is_probed;
159static struct pnp_card_device_id snd_opti9xx_pnpids[] = { 155static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
160#ifndef OPTi93X 156#ifndef OPTi93X
161 /* OPTi 82C924 */ 157 /* OPTi 82C924 */
162 { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 }, 158 { .id = "OPT0924",
159 .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
160 .driver_data = 0x0924 },
163 /* OPTi 82C925 */ 161 /* OPTi 82C925 */
164 { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 }, 162 { .id = "OPT0925",
163 .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
164 .driver_data = 0x0925 },
165#else 165#else
166 /* OPTi 82C931/3 */ 166 /* OPTi 82C931/3 */
167 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 }, 167 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
168 .driver_data = 0x0931 },
168#endif /* OPTi93X */ 169#endif /* OPTi93X */
169 { .id = "" } 170 { .id = "" }
170}; 171};
@@ -207,24 +208,34 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
207 chip->hardware = hardware; 208 chip->hardware = hardware;
208 strcpy(chip->name, snd_opti9xx_names[hardware]); 209 strcpy(chip->name, snd_opti9xx_names[hardware]);
209 210
210 chip->mc_base_size = opti9xx_mc_size[hardware];
211
212 spin_lock_init(&chip->lock); 211 spin_lock_init(&chip->lock);
213 212
214 chip->irq = -1; 213 chip->irq = -1;
215 214
215#ifndef OPTi93X
216#ifdef CONFIG_PNP
217 if (isapnp && chip->mc_base)
218 /* PnP resource gives the least 10 bits */
219 chip->mc_base |= 0xc00;
220#endif /* CONFIG_PNP */
221 else {
222 chip->mc_base = 0xf8c;
223 chip->mc_base_size = opti9xx_mc_size[hardware];
224 }
225#else
226 chip->mc_base_size = opti9xx_mc_size[hardware];
227#endif
228
216 switch (hardware) { 229 switch (hardware) {
217#ifndef OPTi93X 230#ifndef OPTi93X
218 case OPTi9XX_HW_82C928: 231 case OPTi9XX_HW_82C928:
219 case OPTi9XX_HW_82C929: 232 case OPTi9XX_HW_82C929:
220 chip->mc_base = 0xf8c;
221 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; 233 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
222 chip->pwd_reg = 3; 234 chip->pwd_reg = 3;
223 break; 235 break;
224 236
225 case OPTi9XX_HW_82C924: 237 case OPTi9XX_HW_82C924:
226 case OPTi9XX_HW_82C925: 238 case OPTi9XX_HW_82C925:
227 chip->mc_base = 0xf8c;
228 chip->password = 0xe5; 239 chip->password = 0xe5;
229 chip->pwd_reg = 3; 240 chip->pwd_reg = 3;
230 break; 241 break;
@@ -292,7 +303,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
292 spin_unlock_irqrestore(&chip->lock, flags); 303 spin_unlock_irqrestore(&chip->lock, flags);
293 return retval; 304 return retval;
294} 305}
295 306
296static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, 307static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
297 unsigned char value) 308 unsigned char value)
298{ 309{
@@ -341,7 +352,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
341 352
342 353
343static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, 354static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
344 long wss_base, 355 long port,
345 int irq, int dma1, int dma2, 356 int irq, int dma1, int dma2,
346 long mpu_port, int mpu_irq) 357 long mpu_port, int mpu_irq)
347{ 358{
@@ -354,16 +365,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
354 switch (chip->hardware) { 365 switch (chip->hardware) {
355#ifndef OPTi93X 366#ifndef OPTi93X
356 case OPTi9XX_HW_82C924: 367 case OPTi9XX_HW_82C924:
368 /* opti 929 mode (?), OPL3 clock output, audio enable */
357 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); 369 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
370 /* enable wave audio */
358 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); 371 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
359 372
360 case OPTi9XX_HW_82C925: 373 case OPTi9XX_HW_82C925:
374 /* enable WSS mode */
361 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); 375 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
376 /* OPL3 FM synthesis */
362 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20); 377 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
378 /* disable Sound Blaster IRQ and DMA */
363 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); 379 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
364#ifdef CS4231 380#ifdef CS4231
381 /* cs4231/4248 fix enabled */
365 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); 382 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
366#else 383#else
384 /* cs4231/4248 fix disabled */
367 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02); 385 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
368#endif /* CS4231 */ 386#endif /* CS4231 */
369 break; 387 break;
@@ -411,21 +429,26 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
411 return -EINVAL; 429 return -EINVAL;
412 } 430 }
413 431
414 switch (wss_base) { 432 /* PnP resource says it decodes only 10 bits of address */
415 case 0x530: 433 switch (port & 0x3ff) {
434 case 0x130:
435 chip->wss_base = 0x530;
416 wss_base_bits = 0x00; 436 wss_base_bits = 0x00;
417 break; 437 break;
418 case 0x604: 438 case 0x204:
439 chip->wss_base = 0x604;
419 wss_base_bits = 0x03; 440 wss_base_bits = 0x03;
420 break; 441 break;
421 case 0xe80: 442 case 0x280:
443 chip->wss_base = 0xe80;
422 wss_base_bits = 0x01; 444 wss_base_bits = 0x01;
423 break; 445 break;
424 case 0xf40: 446 case 0x340:
447 chip->wss_base = 0xf40;
425 wss_base_bits = 0x02; 448 wss_base_bits = 0x02;
426 break; 449 break;
427 default: 450 default:
428 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base); 451 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
429 goto __skip_base; 452 goto __skip_base;
430 } 453 }
431 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); 454 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
@@ -487,7 +510,7 @@ __skip_base:
487#endif /* CS4231 || OPTi93X */ 510#endif /* CS4231 || OPTi93X */
488 511
489#ifndef OPTi93X 512#ifndef OPTi93X
490 outb(irq_bits << 3 | dma_bits, wss_base); 513 outb(irq_bits << 3 | dma_bits, chip->wss_base);
491#else /* OPTi93X */ 514#else /* OPTi93X */
492 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); 515 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
493#endif /* OPTi93X */ 516#endif /* OPTi93X */
@@ -729,15 +752,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
729{ 752{
730 struct pnp_dev *pdev; 753 struct pnp_dev *pdev;
731 int err; 754 int err;
755 struct pnp_dev *devmpu;
756#ifndef OPTi93X
757 struct pnp_dev *devmc;
758#endif
732 759
733 chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); 760 pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
734 if (chip->dev == NULL) 761 if (pdev == NULL)
735 return -EBUSY; 762 return -EBUSY;
736 763
737 chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
738
739 pdev = chip->dev;
740
741 err = pnp_activate_dev(pdev); 764 err = pnp_activate_dev(pdev);
742 if (err < 0) { 765 if (err < 0) {
743 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err); 766 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
@@ -750,9 +773,24 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
750 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; 773 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
751 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; 774 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
752#else 775#else
753 if (pid->driver_data != 0x0924) 776 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
754 port = pnp_port_start(pdev, 1); 777 if (devmc == NULL)
778 return -EBUSY;
779
780 err = pnp_activate_dev(devmc);
781 if (err < 0) {
782 snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
783 return err;
784 }
785
786 port = pnp_port_start(pdev, 1);
755 fm_port = pnp_port_start(pdev, 2) + 8; 787 fm_port = pnp_port_start(pdev, 2) + 8;
788 /*
789 * The MC(0) is never accessed and card does not
790 * include it in the PnP resource range. OPTI93x include it.
791 */
792 chip->mc_base = pnp_port_start(devmc, 0) - 1;
793 chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
756#endif /* OPTi93X */ 794#endif /* OPTi93X */
757 irq = pnp_irq(pdev, 0); 795 irq = pnp_irq(pdev, 0);
758 dma1 = pnp_dma(pdev, 0); 796 dma1 = pnp_dma(pdev, 0);
@@ -760,16 +798,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
760 dma2 = pnp_dma(pdev, 1); 798 dma2 = pnp_dma(pdev, 1);
761#endif /* CS4231 || OPTi93X */ 799#endif /* CS4231 || OPTi93X */
762 800
763 pdev = chip->devmpu; 801 devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
764 if (pdev && mpu_port > 0) { 802
765 err = pnp_activate_dev(pdev); 803 if (devmpu && mpu_port > 0) {
804 err = pnp_activate_dev(devmpu);
766 if (err < 0) { 805 if (err < 0) {
767 snd_printk(KERN_ERR "AUDIO pnp configure failure\n"); 806 snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
768 mpu_port = -1; 807 mpu_port = -1;
769 chip->devmpu = NULL;
770 } else { 808 } else {
771 mpu_port = pnp_port_start(pdev, 0); 809 mpu_port = pnp_port_start(devmpu, 0);
772 mpu_irq = pnp_irq(pdev, 0); 810 mpu_irq = pnp_irq(devmpu, 0);
773 } 811 }
774 } 812 }
775 return pid->driver_data; 813 return pid->driver_data;
@@ -824,7 +862,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
824 if (error) 862 if (error)
825 return error; 863 return error;
826 864
827 error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2, 865 error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
828#ifdef OPTi93X 866#ifdef OPTi93X
829 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, 867 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
830#else 868#else
@@ -865,10 +903,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
865 sprintf(card->shortname, "OPTi %s", card->driver); 903 sprintf(card->shortname, "OPTi %s", card->driver);
866#if defined(CS4231) || defined(OPTi93X) 904#if defined(CS4231) || defined(OPTi93X)
867 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 905 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
868 card->shortname, pcm->name, port + 4, irq, dma1, xdma2); 906 card->shortname, pcm->name,
907 chip->wss_base + 4, irq, dma1, xdma2);
869#else 908#else
870 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", 909 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
871 card->shortname, pcm->name, port + 4, irq, dma1); 910 card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
872#endif /* CS4231 || OPTi93X */ 911#endif /* CS4231 || OPTi93X */
873 912
874 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) 913 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
@@ -1062,9 +1101,6 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
1062 snd_card_free(card); 1101 snd_card_free(card);
1063 return error; 1102 return error;
1064 } 1103 }
1065 if (hw <= OPTi9XX_HW_82C930)
1066 chip->mc_base -= 0x80;
1067
1068 error = snd_opti9xx_read_check(chip); 1104 error = snd_opti9xx_read_check(chip);
1069 if (error) { 1105 if (error) {
1070 snd_printk(KERN_ERR "OPTI chip not found\n"); 1106 snd_printk(KERN_ERR "OPTI chip not found\n");
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 8d21a3feda3a..8ccbcddf08e1 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -14,6 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/delay.h>
17#include <asm/dma.h> 18#include <asm/dma.h>
18#include <linux/isa.h> 19#include <linux/isa.h>
19#include <sound/core.h> 20#include <sound/core.h>
diff --git a/sound/oss/coproc.h b/sound/oss/coproc.h
index 7306346e9ac4..7bec21bbdd88 100644
--- a/sound/oss/coproc.h
+++ b/sound/oss/coproc.h
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6/* 6/*
7 * Coprocessor access types 7 * Coprocessor access types
8 */ 8 */
9#define COPR_CUSTOM 0x0001 /* Custom applications */ 9#define COPR_CUSTOM 0x0001 /* Custom applications */
10#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */ 10#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */
diff --git a/sound/oss/v_midi.h b/sound/oss/v_midi.h
index 1b86cb45c607..08e2185ee816 100644
--- a/sound/oss/v_midi.h
+++ b/sound/oss/v_midi.h
@@ -2,9 +2,9 @@ typedef struct vmidi_devc {
2 int dev; 2 int dev;
3 3
4 /* State variables */ 4 /* State variables */
5 int opened; 5 int opened;
6 spinlock_t lock; 6 spinlock_t lock;
7 7
8 /* MIDI fields */ 8 /* MIDI fields */
9 int my_mididev; 9 int my_mididev;
10 int pair_mididev; 10 int pair_mididev;
@@ -12,4 +12,3 @@ typedef struct vmidi_devc {
12 int intr_active; 12 int intr_active;
13 void (*midi_input_intr) (int dev, unsigned char data); 13 void (*midi_input_intr) (int dev, unsigned char data);
14 } vmidi_devc; 14 } vmidi_devc;
15
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 556cff937be7..567348b05b5a 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -157,7 +157,7 @@ config SND_HDA_CODEC_INTELHDMI
157 157
158config SND_HDA_ELD 158config SND_HDA_ELD
159 def_bool y 159 def_bool y
160 depends on SND_HDA_CODEC_INTELHDMI 160 depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
161 161
162config SND_HDA_CODEC_CIRRUS 162config SND_HDA_CODEC_CIRRUS
163 bool "Build Cirrus Logic codec support" 163 bool "Build Cirrus Logic codec support"
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 315a1c4f8998..24bc195b02da 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,7 @@ snd-hda-intel-objs := hda_intel.o
3snd-hda-codec-y := hda_codec.o 3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o 5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o 6snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o 8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9 9
@@ -18,7 +18,7 @@ snd-hda-codec-ca0110-objs := patch_ca0110.o
18snd-hda-codec-conexant-objs := patch_conexant.o 18snd-hda-codec-conexant-objs := patch_conexant.o
19snd-hda-codec-via-objs := patch_via.o 19snd-hda-codec-via-objs := patch_via.o
20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o 20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o 21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
22 22
23# common driver 23# common driver
24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o 24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 76d3c4c049db..5bd7cf45f3a5 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -978,8 +978,9 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
978 * 978 *
979 * Returns 0 if successful, or a negative error code. 979 * Returns 0 if successful, or a negative error code.
980 */ 980 */
981int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 981int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
982 struct hda_codec **codecp) 982 unsigned int codec_addr,
983 struct hda_codec **codecp)
983{ 984{
984 struct hda_codec *codec; 985 struct hda_codec *codec;
985 char component[31]; 986 char component[31];
@@ -1186,7 +1187,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
1186 */ 1187 */
1187 1188
1188/* FIXME: more better hash key? */ 1189/* FIXME: more better hash key? */
1189#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) 1190#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
1190#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) 1191#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
1191#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) 1192#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
1192#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) 1193#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
@@ -1356,7 +1357,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
1356 if (!codec->no_trigger_sense) { 1357 if (!codec->no_trigger_sense) {
1357 pincap = snd_hda_query_pin_caps(codec, nid); 1358 pincap = snd_hda_query_pin_caps(codec, nid);
1358 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ 1359 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1359 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); 1360 snd_hda_codec_read(codec, nid, 0,
1361 AC_VERB_SET_PIN_SENSE, 0);
1360 } 1362 }
1361 return snd_hda_codec_read(codec, nid, 0, 1363 return snd_hda_codec_read(codec, nid, 0,
1362 AC_VERB_GET_PIN_SENSE, 0); 1364 AC_VERB_GET_PIN_SENSE, 0);
@@ -1372,8 +1374,8 @@ EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
1372 */ 1374 */
1373int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 1375int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
1374{ 1376{
1375 u32 sense = snd_hda_pin_sense(codec, nid); 1377 u32 sense = snd_hda_pin_sense(codec, nid);
1376 return !!(sense & AC_PINSENSE_PRESENCE); 1378 return !!(sense & AC_PINSENSE_PRESENCE);
1377} 1379}
1378EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 1380EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
1379 1381
@@ -1952,7 +1954,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1952 err = snd_hda_ctl_add(codec, 0, kctl); 1954 err = snd_hda_ctl_add(codec, 0, kctl);
1953 if (err < 0) 1955 if (err < 0)
1954 return err; 1956 return err;
1955 1957
1956 for (s = slaves; *s; s++) { 1958 for (s = slaves; *s; s++) {
1957 struct snd_kcontrol *sctl; 1959 struct snd_kcontrol *sctl;
1958 int i = 0; 1960 int i = 0;
@@ -2439,27 +2441,27 @@ static struct snd_kcontrol_new dig_mixes[] = {
2439 { 2441 {
2440 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2442 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2442 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 2444 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
2443 .info = snd_hda_spdif_mask_info, 2445 .info = snd_hda_spdif_mask_info,
2444 .get = snd_hda_spdif_cmask_get, 2446 .get = snd_hda_spdif_cmask_get,
2445 }, 2447 },
2446 { 2448 {
2447 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2449 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2448 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2449 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), 2451 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
2450 .info = snd_hda_spdif_mask_info, 2452 .info = snd_hda_spdif_mask_info,
2451 .get = snd_hda_spdif_pmask_get, 2453 .get = snd_hda_spdif_pmask_get,
2452 }, 2454 },
2453 { 2455 {
2454 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2455 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2457 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
2456 .info = snd_hda_spdif_mask_info, 2458 .info = snd_hda_spdif_mask_info,
2457 .get = snd_hda_spdif_default_get, 2459 .get = snd_hda_spdif_default_get,
2458 .put = snd_hda_spdif_default_put, 2460 .put = snd_hda_spdif_default_put,
2459 }, 2461 },
2460 { 2462 {
2461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2462 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2464 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
2463 .info = snd_hda_spdif_out_switch_info, 2465 .info = snd_hda_spdif_out_switch_info,
2464 .get = snd_hda_spdif_out_switch_get, 2466 .get = snd_hda_spdif_out_switch_get,
2465 .put = snd_hda_spdif_out_switch_put, 2467 .put = snd_hda_spdif_out_switch_put,
@@ -2610,7 +2612,7 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2610static struct snd_kcontrol_new dig_in_ctls[] = { 2612static struct snd_kcontrol_new dig_in_ctls[] = {
2611 { 2613 {
2612 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2613 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 2615 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
2614 .info = snd_hda_spdif_in_switch_info, 2616 .info = snd_hda_spdif_in_switch_info,
2615 .get = snd_hda_spdif_in_switch_get, 2617 .get = snd_hda_spdif_in_switch_get,
2616 .put = snd_hda_spdif_in_switch_put, 2618 .put = snd_hda_spdif_in_switch_put,
@@ -2618,7 +2620,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
2618 { 2620 {
2619 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2621 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2620 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2622 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2621 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 2623 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
2622 .info = snd_hda_spdif_mask_info, 2624 .info = snd_hda_spdif_mask_info,
2623 .get = snd_hda_spdif_in_status_get, 2625 .get = snd_hda_spdif_in_status_get,
2624 }, 2626 },
@@ -2883,7 +2885,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
2883 int err = snd_hda_codec_build_controls(codec); 2885 int err = snd_hda_codec_build_controls(codec);
2884 if (err < 0) { 2886 if (err < 0) {
2885 printk(KERN_ERR "hda_codec: cannot build controls" 2887 printk(KERN_ERR "hda_codec: cannot build controls"
2886 "for #%d (error %d)\n", codec->addr, err); 2888 "for #%d (error %d)\n", codec->addr, err);
2887 err = snd_hda_codec_reset(codec); 2889 err = snd_hda_codec_reset(codec);
2888 if (err < 0) { 2890 if (err < 0) {
2889 printk(KERN_ERR 2891 printk(KERN_ERR
@@ -2979,8 +2981,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2979 val |= channels - 1; 2981 val |= channels - 1;
2980 2982
2981 switch (snd_pcm_format_width(format)) { 2983 switch (snd_pcm_format_width(format)) {
2982 case 8: val |= 0x00; break; 2984 case 8:
2983 case 16: val |= 0x10; break; 2985 val |= 0x00;
2986 break;
2987 case 16:
2988 val |= 0x10;
2989 break;
2984 case 20: 2990 case 20:
2985 case 24: 2991 case 24:
2986 case 32: 2992 case 32:
@@ -3298,7 +3304,8 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type)
3298 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) 3304 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3299 return audio_idx[type][i]; 3305 return audio_idx[type][i];
3300 3306
3301 snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]); 3307 snd_printk(KERN_WARNING "Too many %s devices\n",
3308 snd_hda_pcm_type_name[type]);
3302 return -EAGAIN; 3309 return -EAGAIN;
3303} 3310}
3304 3311
@@ -3336,7 +3343,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
3336 err = codec->patch_ops.build_pcms(codec); 3343 err = codec->patch_ops.build_pcms(codec);
3337 if (err < 0) { 3344 if (err < 0) {
3338 printk(KERN_ERR "hda_codec: cannot build PCMs" 3345 printk(KERN_ERR "hda_codec: cannot build PCMs"
3339 "for #%d (error %d)\n", codec->addr, err); 3346 "for #%d (error %d)\n", codec->addr, err);
3340 err = snd_hda_codec_reset(codec); 3347 err = snd_hda_codec_reset(codec);
3341 if (err < 0) { 3348 if (err < 0) {
3342 printk(KERN_ERR 3349 printk(KERN_ERR
@@ -3466,8 +3473,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
3466 3473
3467/** 3474/**
3468 * snd_hda_check_board_codec_sid_config - compare the current codec 3475 * snd_hda_check_board_codec_sid_config - compare the current codec
3469 subsystem ID with the 3476 subsystem ID with the
3470 config table 3477 config table
3471 3478
3472 This is important for Gateway notebooks with SB450 HDA Audio 3479 This is important for Gateway notebooks with SB450 HDA Audio
3473 where the vendor ID of the PCI device is: 3480 where the vendor ID of the PCI device is:
@@ -3607,7 +3614,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
3607 * 3614 *
3608 * Increment the power-up counter and power up the hardware really when 3615 * Increment the power-up counter and power up the hardware really when
3609 * not turned on yet. 3616 * not turned on yet.
3610 */ 3617 */
3611void snd_hda_power_up(struct hda_codec *codec) 3618void snd_hda_power_up(struct hda_codec *codec)
3612{ 3619{
3613 struct hda_bus *bus = codec->bus; 3620 struct hda_bus *bus = codec->bus;
@@ -3636,7 +3643,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up);
3636 * 3643 *
3637 * Decrement the power-up counter and schedules the power-off work if 3644 * Decrement the power-up counter and schedules the power-off work if
3638 * the counter rearches to zero. 3645 * the counter rearches to zero.
3639 */ 3646 */
3640void snd_hda_power_down(struct hda_codec *codec) 3647void snd_hda_power_down(struct hda_codec *codec)
3641{ 3648{
3642 --codec->power_count; 3649 --codec->power_count;
@@ -3662,7 +3669,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_down);
3662 * 3669 *
3663 * This function is supposed to be set or called from the check_power_status 3670 * This function is supposed to be set or called from the check_power_status
3664 * patch ops. 3671 * patch ops.
3665 */ 3672 */
3666int snd_hda_check_amp_list_power(struct hda_codec *codec, 3673int snd_hda_check_amp_list_power(struct hda_codec *codec,
3667 struct hda_loopback_check *check, 3674 struct hda_loopback_check *check,
3668 hda_nid_t nid) 3675 hda_nid_t nid)
@@ -3830,7 +3837,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
3830{ 3837{
3831 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 3838 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
3832 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 3839 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3833 set_dig_out_convert(codec, nid, 3840 set_dig_out_convert(codec, nid,
3834 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 3841 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
3835 -1); 3842 -1);
3836 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 3843 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -4089,13 +4096,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
4089/* 4096/*
4090 * Sort an associated group of pins according to their sequence numbers. 4097 * Sort an associated group of pins according to their sequence numbers.
4091 */ 4098 */
4092static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, 4099static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
4093 int num_pins) 4100 int num_pins)
4094{ 4101{
4095 int i, j; 4102 int i, j;
4096 short seq; 4103 short seq;
4097 hda_nid_t nid; 4104 hda_nid_t nid;
4098 4105
4099 for (i = 0; i < num_pins; i++) { 4106 for (i = 0; i < num_pins; i++) {
4100 for (j = i + 1; j < num_pins; j++) { 4107 for (j = i + 1; j < num_pins; j++) {
4101 if (sequences[i] > sequences[j]) { 4108 if (sequences[i] > sequences[j]) {
@@ -4123,7 +4130,7 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
4123 * is detected, one of speaker of HP pins is assigned as the primary 4130 * is detected, one of speaker of HP pins is assigned as the primary
4124 * output, i.e. to line_out_pins[0]. So, line_outs is always positive 4131 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
4125 * if any analog output exists. 4132 * if any analog output exists.
4126 * 4133 *
4127 * The analog input pins are assigned to input_pins array. 4134 * The analog input pins are assigned to input_pins array.
4128 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, 4135 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4129 * respectively. 4136 * respectively.
@@ -4186,9 +4193,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4186 case AC_JACK_SPEAKER: 4193 case AC_JACK_SPEAKER:
4187 seq = get_defcfg_sequence(def_conf); 4194 seq = get_defcfg_sequence(def_conf);
4188 assoc = get_defcfg_association(def_conf); 4195 assoc = get_defcfg_association(def_conf);
4189 if (! assoc) 4196 if (!assoc)
4190 continue; 4197 continue;
4191 if (! assoc_speaker) 4198 if (!assoc_speaker)
4192 assoc_speaker = assoc; 4199 assoc_speaker = assoc;
4193 else if (assoc_speaker != assoc) 4200 else if (assoc_speaker != assoc)
4194 continue; 4201 continue;
@@ -4286,7 +4293,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4286 cfg->speaker_outs); 4293 cfg->speaker_outs);
4287 sort_pins_by_sequence(cfg->hp_pins, sequences_hp, 4294 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
4288 cfg->hp_outs); 4295 cfg->hp_outs);
4289 4296
4290 /* if we have only one mic, make it AUTO_PIN_MIC */ 4297 /* if we have only one mic, make it AUTO_PIN_MIC */
4291 if (!cfg->input_pins[AUTO_PIN_MIC] && 4298 if (!cfg->input_pins[AUTO_PIN_MIC] &&
4292 cfg->input_pins[AUTO_PIN_FRONT_MIC]) { 4299 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
@@ -4436,7 +4443,7 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
4436/** 4443/**
4437 * snd_array_new - get a new element from the given array 4444 * snd_array_new - get a new element from the given array
4438 * @array: the array object 4445 * @array: the array object
4439 * 4446 *
4440 * Get a new element from the given array. If it exceeds the 4447 * Get a new element from the given array. If it exceeds the
4441 * pre-allocated array size, re-allocate the array. 4448 * pre-allocated array size, re-allocate the array.
4442 * 4449 *
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 4228f2fe5956..dcd22446cfc7 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -331,6 +331,7 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
331 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, 331 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
332 AC_DIPSIZE_ELD_BUF); 332 AC_DIPSIZE_ELD_BUF);
333} 333}
334EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
334 335
335int snd_hdmi_get_eld(struct hdmi_eld *eld, 336int snd_hdmi_get_eld(struct hdmi_eld *eld,
336 struct hda_codec *codec, hda_nid_t nid) 337 struct hda_codec *codec, hda_nid_t nid)
@@ -366,6 +367,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
366 kfree(buf); 367 kfree(buf);
367 return ret; 368 return ret;
368} 369}
370EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
369 371
370static void hdmi_show_short_audio_desc(struct cea_sad *a) 372static void hdmi_show_short_audio_desc(struct cea_sad *a)
371{ 373{
@@ -404,6 +406,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
404 } 406 }
405 buf[j] = '\0'; /* necessary when j == 0 */ 407 buf[j] = '\0'; /* necessary when j == 0 */
406} 408}
409EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
407 410
408void snd_hdmi_show_eld(struct hdmi_eld *e) 411void snd_hdmi_show_eld(struct hdmi_eld *e)
409{ 412{
@@ -422,6 +425,7 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
422 for (i = 0; i < e->sad_count; i++) 425 for (i = 0; i < e->sad_count; i++)
423 hdmi_show_short_audio_desc(e->sad + i); 426 hdmi_show_short_audio_desc(e->sad + i);
424} 427}
428EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
425 429
426#ifdef CONFIG_PROC_FS 430#ifdef CONFIG_PROC_FS
427 431
@@ -580,6 +584,7 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
580 584
581 return 0; 585 return 0;
582} 586}
587EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
583 588
584void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) 589void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
585{ 590{
@@ -588,5 +593,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
588 eld->proc_entry = NULL; 593 eld->proc_entry = NULL;
589 } 594 }
590} 595}
596EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
591 597
592#endif /* CONFIG_PROC_FS */ 598#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index d5c93ad852ee..43b7cfb7cffd 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -267,7 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
267#define RIRB_INT_MASK 0x05 267#define RIRB_INT_MASK 0x05
268 268
269/* STATESTS int mask: S3,SD2,SD1,SD0 */ 269/* STATESTS int mask: S3,SD2,SD1,SD0 */
270#define AZX_MAX_CODECS 4 270#define AZX_MAX_CODECS 8
271#define AZX_DEFAULT_CODECS 4
271#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1) 272#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
272 273
273/* SD_CTL bits */ 274/* SD_CTL bits */
@@ -1367,6 +1368,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1367 1368
1368/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */ 1369/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
1369static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { 1370static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1371 [AZX_DRIVER_NVIDIA] = 8,
1370 [AZX_DRIVER_TERA] = 1, 1372 [AZX_DRIVER_TERA] = 1,
1371}; 1373};
1372 1374
@@ -1399,7 +1401,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1399 codecs = 0; 1401 codecs = 0;
1400 max_slots = azx_max_codecs[chip->driver_type]; 1402 max_slots = azx_max_codecs[chip->driver_type];
1401 if (!max_slots) 1403 if (!max_slots)
1402 max_slots = AZX_MAX_CODECS; 1404 max_slots = AZX_DEFAULT_CODECS;
1403 1405
1404 /* First try to probe all given codec slots */ 1406 /* First try to probe all given codec slots */
1405 for (c = 0; c < max_slots; c++) { 1407 for (c = 0; c < max_slots; c++) {
@@ -2263,10 +2265,12 @@ static int azx_dev_free(struct snd_device *device)
2263static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2265static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2264 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2266 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2265 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2267 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2268 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2266 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2269 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2267 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), 2270 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2268 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2271 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2269 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2272 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2273 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2270 {} 2274 {}
2271}; 2275};
2272 2276
@@ -2354,6 +2358,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2354static struct snd_pci_quirk msi_black_list[] __devinitdata = { 2358static struct snd_pci_quirk msi_black_list[] __devinitdata = {
2355 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ 2359 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
2356 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ 2360 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
2361 SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
2357 {} 2362 {}
2358}; 2363};
2359 2364
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
new file mode 100644
index 000000000000..2c2bafbf0258
--- /dev/null
+++ b/sound/pci/hda/patch_hdmi.c
@@ -0,0 +1,849 @@
1/*
2 *
3 * patch_hdmi.c - routines for HDMI/DisplayPort codecs
4 *
5 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Wu Fengguang <wfg@linux.intel.com>
9 *
10 * Maintained by:
11 * Wu Fengguang <wfg@linux.intel.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28
29struct hdmi_spec {
30 int num_cvts;
31 int num_pins;
32 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */
33 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */
34
35 /*
36 * source connection for each pin
37 */
38 hda_nid_t pin_cvt[MAX_HDMI_PINS+1];
39
40 /*
41 * HDMI sink attached to each pin
42 */
43 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
44
45 /*
46 * export one pcm per pipe
47 */
48 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
49
50 /*
51 * nvhdmi specific
52 */
53 struct hda_multi_out multiout;
54 unsigned int codec_type;
55};
56
57
58struct hdmi_audio_infoframe {
59 u8 type; /* 0x84 */
60 u8 ver; /* 0x01 */
61 u8 len; /* 0x0a */
62
63 u8 checksum; /* PB0 */
64 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
65 u8 SS01_SF24;
66 u8 CXT04;
67 u8 CA;
68 u8 LFEPBL01_LSV36_DM_INH7;
69 u8 reserved[5]; /* PB6 - PB10 */
70};
71
72/*
73 * CEA speaker placement:
74 *
75 * FLH FCH FRH
76 * FLW FL FLC FC FRC FR FRW
77 *
78 * LFE
79 * TC
80 *
81 * RL RLC RC RRC RR
82 *
83 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
84 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
85 */
86enum cea_speaker_placement {
87 FL = (1 << 0), /* Front Left */
88 FC = (1 << 1), /* Front Center */
89 FR = (1 << 2), /* Front Right */
90 FLC = (1 << 3), /* Front Left Center */
91 FRC = (1 << 4), /* Front Right Center */
92 RL = (1 << 5), /* Rear Left */
93 RC = (1 << 6), /* Rear Center */
94 RR = (1 << 7), /* Rear Right */
95 RLC = (1 << 8), /* Rear Left Center */
96 RRC = (1 << 9), /* Rear Right Center */
97 LFE = (1 << 10), /* Low Frequency Effect */
98 FLW = (1 << 11), /* Front Left Wide */
99 FRW = (1 << 12), /* Front Right Wide */
100 FLH = (1 << 13), /* Front Left High */
101 FCH = (1 << 14), /* Front Center High */
102 FRH = (1 << 15), /* Front Right High */
103 TC = (1 << 16), /* Top Center */
104};
105
106/*
107 * ELD SA bits in the CEA Speaker Allocation data block
108 */
109static int eld_speaker_allocation_bits[] = {
110 [0] = FL | FR,
111 [1] = LFE,
112 [2] = FC,
113 [3] = RL | RR,
114 [4] = RC,
115 [5] = FLC | FRC,
116 [6] = RLC | RRC,
117 /* the following are not defined in ELD yet */
118 [7] = FLW | FRW,
119 [8] = FLH | FRH,
120 [9] = TC,
121 [10] = FCH,
122};
123
124struct cea_channel_speaker_allocation {
125 int ca_index;
126 int speakers[8];
127
128 /* derived values, just for convenience */
129 int channels;
130 int spk_mask;
131};
132
133/*
134 * ALSA sequence is:
135 *
136 * surround40 surround41 surround50 surround51 surround71
137 * ch0 front left = = = =
138 * ch1 front right = = = =
139 * ch2 rear left = = = =
140 * ch3 rear right = = = =
141 * ch4 LFE center center center
142 * ch5 LFE LFE
143 * ch6 side left
144 * ch7 side right
145 *
146 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
147 */
148static int hdmi_channel_mapping[0x32][8] = {
149 /* stereo */
150 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
151 /* 2.1 */
152 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
153 /* Dolby Surround */
154 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
155 /* surround40 */
156 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
157 /* 4ch */
158 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
159 /* surround41 */
160 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
161 /* surround50 */
162 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
163 /* surround51 */
164 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
165 /* 7.1 */
166 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
167};
168
169/*
170 * This is an ordered list!
171 *
172 * The preceding ones have better chances to be selected by
173 * hdmi_setup_channel_allocation().
174 */
175static struct cea_channel_speaker_allocation channel_allocations[] = {
176/* channel: 7 6 5 4 3 2 1 0 */
177{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
178 /* 2.1 */
179{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
180 /* Dolby Surround */
181{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
182 /* surround40 */
183{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
184 /* surround41 */
185{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
186 /* surround50 */
187{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
188 /* surround51 */
189{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
190 /* 6.1 */
191{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
192 /* surround71 */
193{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
194
195{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
196{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
197{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
198{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
199{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
200{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
201{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
202{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
203{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
204{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
205{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
206{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
207{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
208{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
209{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
210{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
211{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
212{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
213{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
214{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
215{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
216{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
217{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
218{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
219{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
220{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
222{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
223{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
224{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
225{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
226{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
227{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
228{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
229{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
230{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
231{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
232{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
233{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
234{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
235{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
236};
237
238
239/*
240 * HDMI routines
241 */
242
243static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
244{
245 int i;
246
247 for (i = 0; nids[i]; i++)
248 if (nids[i] == nid)
249 return i;
250
251 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
252 return -EINVAL;
253}
254
255static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
256 struct hdmi_eld *eld)
257{
258 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
259 snd_hdmi_show_eld(eld);
260}
261
262#ifdef BE_PARANOID
263static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
264 int *packet_index, int *byte_index)
265{
266 int val;
267
268 val = snd_hda_codec_read(codec, pin_nid, 0,
269 AC_VERB_GET_HDMI_DIP_INDEX, 0);
270
271 *packet_index = val >> 5;
272 *byte_index = val & 0x1f;
273}
274#endif
275
276static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
277 int packet_index, int byte_index)
278{
279 int val;
280
281 val = (packet_index << 5) | (byte_index & 0x1f);
282
283 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
284}
285
286static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
287 unsigned char val)
288{
289 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
290}
291
292static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
293{
294 /* Unmute */
295 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
296 snd_hda_codec_write(codec, pin_nid, 0,
297 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
298 /* Enable pin out */
299 snd_hda_codec_write(codec, pin_nid, 0,
300 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
301}
302
303static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
304{
305 return 1 + snd_hda_codec_read(codec, nid, 0,
306 AC_VERB_GET_CVT_CHAN_COUNT, 0);
307}
308
309static void hdmi_set_channel_count(struct hda_codec *codec,
310 hda_nid_t nid, int chs)
311{
312 if (chs != hdmi_get_channel_count(codec, nid))
313 snd_hda_codec_write(codec, nid, 0,
314 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
315}
316
317
318/*
319 * Channel mapping routines
320 */
321
322/*
323 * Compute derived values in channel_allocations[].
324 */
325static void init_channel_allocations(void)
326{
327 int i, j;
328 struct cea_channel_speaker_allocation *p;
329
330 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
331 p = channel_allocations + i;
332 p->channels = 0;
333 p->spk_mask = 0;
334 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
335 if (p->speakers[j]) {
336 p->channels++;
337 p->spk_mask |= p->speakers[j];
338 }
339 }
340}
341
342/*
343 * The transformation takes two steps:
344 *
345 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
346 * spk_mask => (channel_allocations[]) => ai->CA
347 *
348 * TODO: it could select the wrong CA from multiple candidates.
349*/
350static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
351 struct hdmi_audio_infoframe *ai)
352{
353 struct hdmi_spec *spec = codec->spec;
354 struct hdmi_eld *eld;
355 int i;
356 int spk_mask = 0;
357 int channels = 1 + (ai->CC02_CT47 & 0x7);
358 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
359
360 /*
361 * CA defaults to 0 for basic stereo audio
362 */
363 if (channels <= 2)
364 return 0;
365
366 i = hda_node_index(spec->pin_cvt, nid);
367 if (i < 0)
368 return 0;
369 eld = &spec->sink_eld[i];
370
371 /*
372 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
373 * in console or for audio devices. Assume the highest speakers
374 * configuration, to _not_ prohibit multi-channel audio playback.
375 */
376 if (!eld->spk_alloc)
377 eld->spk_alloc = 0xffff;
378
379 /*
380 * expand ELD's speaker allocation mask
381 *
382 * ELD tells the speaker mask in a compact(paired) form,
383 * expand ELD's notions to match the ones used by Audio InfoFrame.
384 */
385 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
386 if (eld->spk_alloc & (1 << i))
387 spk_mask |= eld_speaker_allocation_bits[i];
388 }
389
390 /* search for the first working match in the CA table */
391 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
392 if (channels == channel_allocations[i].channels &&
393 (spk_mask & channel_allocations[i].spk_mask) ==
394 channel_allocations[i].spk_mask) {
395 ai->CA = channel_allocations[i].ca_index;
396 break;
397 }
398 }
399
400 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
401 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
402 ai->CA, channels, buf);
403
404 return ai->CA;
405}
406
407static void hdmi_debug_channel_mapping(struct hda_codec *codec,
408 hda_nid_t pin_nid)
409{
410#ifdef CONFIG_SND_DEBUG_VERBOSE
411 int i;
412 int slot;
413
414 for (i = 0; i < 8; i++) {
415 slot = snd_hda_codec_read(codec, pin_nid, 0,
416 AC_VERB_GET_HDMI_CHAN_SLOT, i);
417 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
418 slot >> 4, slot & 0xf);
419 }
420#endif
421}
422
423
424static void hdmi_setup_channel_mapping(struct hda_codec *codec,
425 hda_nid_t pin_nid,
426 struct hdmi_audio_infoframe *ai)
427{
428 int i;
429 int ca = ai->CA;
430 int err;
431
432 if (hdmi_channel_mapping[ca][1] == 0) {
433 for (i = 0; i < channel_allocations[ca].channels; i++)
434 hdmi_channel_mapping[ca][i] = i | (i << 4);
435 for (; i < 8; i++)
436 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
437 }
438
439 for (i = 0; i < 8; i++) {
440 err = snd_hda_codec_write(codec, pin_nid, 0,
441 AC_VERB_SET_HDMI_CHAN_SLOT,
442 hdmi_channel_mapping[ca][i]);
443 if (err) {
444 snd_printdd(KERN_NOTICE
445 "HDMI: channel mapping failed\n");
446 break;
447 }
448 }
449
450 hdmi_debug_channel_mapping(codec, pin_nid);
451}
452
453
454/*
455 * Audio InfoFrame routines
456 */
457
458/*
459 * Enable Audio InfoFrame Transmission
460 */
461static void hdmi_start_infoframe_trans(struct hda_codec *codec,
462 hda_nid_t pin_nid)
463{
464 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
465 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
466 AC_DIPXMIT_BEST);
467}
468
469/*
470 * Disable Audio InfoFrame Transmission
471 */
472static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
473 hda_nid_t pin_nid)
474{
475 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
476 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
477 AC_DIPXMIT_DISABLE);
478}
479
480static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
481{
482#ifdef CONFIG_SND_DEBUG_VERBOSE
483 int i;
484 int size;
485
486 size = snd_hdmi_get_eld_size(codec, pin_nid);
487 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
488
489 for (i = 0; i < 8; i++) {
490 size = snd_hda_codec_read(codec, pin_nid, 0,
491 AC_VERB_GET_HDMI_DIP_SIZE, i);
492 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
493 }
494#endif
495}
496
497static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
498{
499#ifdef BE_PARANOID
500 int i, j;
501 int size;
502 int pi, bi;
503 for (i = 0; i < 8; i++) {
504 size = snd_hda_codec_read(codec, pin_nid, 0,
505 AC_VERB_GET_HDMI_DIP_SIZE, i);
506 if (size == 0)
507 continue;
508
509 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
510 for (j = 1; j < 1000; j++) {
511 hdmi_write_dip_byte(codec, pin_nid, 0x0);
512 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
513 if (pi != i)
514 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
515 bi, pi, i);
516 if (bi == 0) /* byte index wrapped around */
517 break;
518 }
519 snd_printd(KERN_INFO
520 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
521 i, size, j);
522 }
523#endif
524}
525
526static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
527{
528 u8 *bytes = (u8 *)ai;
529 u8 sum = 0;
530 int i;
531
532 ai->checksum = 0;
533
534 for (i = 0; i < sizeof(*ai); i++)
535 sum += bytes[i];
536
537 ai->checksum = -sum;
538}
539
540static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
541 hda_nid_t pin_nid,
542 struct hdmi_audio_infoframe *ai)
543{
544 u8 *bytes = (u8 *)ai;
545 int i;
546
547 hdmi_debug_dip_size(codec, pin_nid);
548 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
549
550 hdmi_checksum_audio_infoframe(ai);
551
552 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
553 for (i = 0; i < sizeof(*ai); i++)
554 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
555}
556
557static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
558 struct hdmi_audio_infoframe *ai)
559{
560 u8 *bytes = (u8 *)ai;
561 u8 val;
562 int i;
563
564 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
565 != AC_DIPXMIT_BEST)
566 return false;
567
568 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
569 for (i = 0; i < sizeof(*ai); i++) {
570 val = snd_hda_codec_read(codec, pin_nid, 0,
571 AC_VERB_GET_HDMI_DIP_DATA, 0);
572 if (val != bytes[i])
573 return false;
574 }
575
576 return true;
577}
578
579static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
580 struct snd_pcm_substream *substream)
581{
582 struct hdmi_spec *spec = codec->spec;
583 hda_nid_t pin_nid;
584 int i;
585 struct hdmi_audio_infoframe ai = {
586 .type = 0x84,
587 .ver = 0x01,
588 .len = 0x0a,
589 .CC02_CT47 = substream->runtime->channels - 1,
590 };
591
592 hdmi_setup_channel_allocation(codec, nid, &ai);
593
594 for (i = 0; i < spec->num_pins; i++) {
595 if (spec->pin_cvt[i] != nid)
596 continue;
597 if (!spec->sink_eld[i].monitor_present)
598 continue;
599
600 pin_nid = spec->pin[i];
601 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
602 snd_printdd("hdmi_setup_audio_infoframe: "
603 "cvt=%d pin=%d channels=%d\n",
604 nid, pin_nid,
605 substream->runtime->channels);
606 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
607 hdmi_stop_infoframe_trans(codec, pin_nid);
608 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
609 hdmi_start_infoframe_trans(codec, pin_nid);
610 }
611 }
612}
613
614
615/*
616 * Unsolicited events
617 */
618
619static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
620{
621 struct hdmi_spec *spec = codec->spec;
622 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
623 int pind = !!(res & AC_UNSOL_RES_PD);
624 int eldv = !!(res & AC_UNSOL_RES_ELDV);
625 int index;
626
627 printk(KERN_INFO
628 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
629 tag, pind, eldv);
630
631 index = hda_node_index(spec->pin, tag);
632 if (index < 0)
633 return;
634
635 spec->sink_eld[index].monitor_present = pind;
636 spec->sink_eld[index].eld_valid = eldv;
637
638 if (pind && eldv) {
639 hdmi_get_show_eld(codec, spec->pin[index],
640 &spec->sink_eld[index]);
641 /* TODO: do real things about ELD */
642 }
643}
644
645static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
646{
647 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
648 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
649 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
650 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
651
652 printk(KERN_INFO
653 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
654 tag,
655 subtag,
656 cp_state,
657 cp_ready);
658
659 /* TODO */
660 if (cp_state)
661 ;
662 if (cp_ready)
663 ;
664}
665
666
667static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
668{
669 struct hdmi_spec *spec = codec->spec;
670 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
671 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
672
673 if (hda_node_index(spec->pin, tag) < 0) {
674 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
675 return;
676 }
677
678 if (subtag == 0)
679 hdmi_intrinsic_event(codec, res);
680 else
681 hdmi_non_intrinsic_event(codec, res);
682}
683
684/*
685 * Callbacks
686 */
687
688static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
689 u32 stream_tag, int format)
690{
691 int tag;
692 int fmt;
693
694 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
695 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
696
697 snd_printdd("hdmi_setup_stream: "
698 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
699 nid,
700 tag == stream_tag ? "" : "new-",
701 stream_tag,
702 fmt == format ? "" : "new-",
703 format);
704
705 if (tag != stream_tag)
706 snd_hda_codec_write(codec, nid, 0,
707 AC_VERB_SET_CHANNEL_STREAMID,
708 stream_tag << 4);
709 if (fmt != format)
710 snd_hda_codec_write(codec, nid, 0,
711 AC_VERB_SET_STREAM_FORMAT, format);
712}
713
714/*
715 * HDA/HDMI auto parsing
716 */
717
718static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
719{
720 struct hdmi_spec *spec = codec->spec;
721 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
722 int conn_len, curr;
723 int index;
724
725 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
726 snd_printk(KERN_WARNING
727 "HDMI: pin %d wcaps %#x "
728 "does not support connection list\n",
729 pin_nid, get_wcaps(codec, pin_nid));
730 return -EINVAL;
731 }
732
733 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
734 HDA_MAX_CONNECTIONS);
735 if (conn_len > 1)
736 curr = snd_hda_codec_read(codec, pin_nid, 0,
737 AC_VERB_GET_CONNECT_SEL, 0);
738 else
739 curr = 0;
740
741 index = hda_node_index(spec->pin, pin_nid);
742 if (index < 0)
743 return -EINVAL;
744
745 spec->pin_cvt[index] = conn_list[curr];
746
747 return 0;
748}
749
750static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
751 struct hdmi_eld *eld)
752{
753 int present = snd_hda_pin_sense(codec, pin_nid);
754
755 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
756 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
757
758 if (present & AC_PINSENSE_ELDV)
759 hdmi_get_show_eld(codec, pin_nid, eld);
760}
761
762static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
763{
764 struct hdmi_spec *spec = codec->spec;
765
766 if (spec->num_pins >= MAX_HDMI_PINS) {
767 snd_printk(KERN_WARNING
768 "HDMI: no space for pin %d\n", pin_nid);
769 return -EINVAL;
770 }
771
772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
773
774 spec->pin[spec->num_pins] = pin_nid;
775 spec->num_pins++;
776
777 /*
778 * It is assumed that converter nodes come first in the node list and
779 * hence have been registered and usable now.
780 */
781 return hdmi_read_pin_conn(codec, pin_nid);
782}
783
784static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
785{
786 struct hdmi_spec *spec = codec->spec;
787
788 if (spec->num_cvts >= MAX_HDMI_CVTS) {
789 snd_printk(KERN_WARNING
790 "HDMI: no space for converter %d\n", nid);
791 return -EINVAL;
792 }
793
794 spec->cvt[spec->num_cvts] = nid;
795 spec->num_cvts++;
796
797 return 0;
798}
799
800static int hdmi_parse_codec(struct hda_codec *codec)
801{
802 hda_nid_t nid;
803 int i, nodes;
804
805 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
806 if (!nid || nodes < 0) {
807 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
808 return -EINVAL;
809 }
810
811 for (i = 0; i < nodes; i++, nid++) {
812 unsigned int caps;
813 unsigned int type;
814
815 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
816 type = get_wcaps_type(caps);
817
818 if (!(caps & AC_WCAP_DIGITAL))
819 continue;
820
821 switch (type) {
822 case AC_WID_AUD_OUT:
823 if (hdmi_add_cvt(codec, nid) < 0)
824 return -EINVAL;
825 break;
826 case AC_WID_PIN:
827 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
828 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
829 continue;
830 if (hdmi_add_pin(codec, nid) < 0)
831 return -EINVAL;
832 break;
833 }
834 }
835
836 /*
837 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
838 * can be lost and presence sense verb will become inaccurate if the
839 * HDA link is powered off at hot plug or hw initialization time.
840 */
841#ifdef CONFIG_SND_HDA_POWER_SAVE
842 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
843 AC_PWRST_EPSS))
844 codec->bus->power_keep_link_on = 1;
845#endif
846
847 return 0;
848}
849
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 918f40378d52..88d035104cc5 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -40,815 +40,20 @@
40 * 40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes. 41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */ 42 */
43#define INTEL_HDMI_CVTS 2 43#define MAX_HDMI_CVTS 2
44#define INTEL_HDMI_PINS 3 44#define MAX_HDMI_PINS 3
45 45
46static char *intel_hdmi_pcm_names[INTEL_HDMI_CVTS] = { 46#include "patch_hdmi.c"
47
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
47 "INTEL HDMI 0", 49 "INTEL HDMI 0",
48 "INTEL HDMI 1", 50 "INTEL HDMI 1",
49}; 51};
50 52
51struct intel_hdmi_spec {
52 int num_cvts;
53 int num_pins;
54 hda_nid_t cvt[INTEL_HDMI_CVTS+1]; /* audio sources */
55 hda_nid_t pin[INTEL_HDMI_PINS+1]; /* audio sinks */
56
57 /*
58 * source connection for each pin
59 */
60 hda_nid_t pin_cvt[INTEL_HDMI_PINS+1];
61
62 /*
63 * HDMI sink attached to each pin
64 */
65 struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
66
67 /*
68 * export one pcm per pipe
69 */
70 struct hda_pcm pcm_rec[INTEL_HDMI_CVTS];
71};
72
73struct hdmi_audio_infoframe {
74 u8 type; /* 0x84 */
75 u8 ver; /* 0x01 */
76 u8 len; /* 0x0a */
77
78 u8 checksum; /* PB0 */
79 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
80 u8 SS01_SF24;
81 u8 CXT04;
82 u8 CA;
83 u8 LFEPBL01_LSV36_DM_INH7;
84 u8 reserved[5]; /* PB6 - PB10 */
85};
86
87/*
88 * CEA speaker placement:
89 *
90 * FLH FCH FRH
91 * FLW FL FLC FC FRC FR FRW
92 *
93 * LFE
94 * TC
95 *
96 * RL RLC RC RRC RR
97 *
98 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
99 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
100 */
101enum cea_speaker_placement {
102 FL = (1 << 0), /* Front Left */
103 FC = (1 << 1), /* Front Center */
104 FR = (1 << 2), /* Front Right */
105 FLC = (1 << 3), /* Front Left Center */
106 FRC = (1 << 4), /* Front Right Center */
107 RL = (1 << 5), /* Rear Left */
108 RC = (1 << 6), /* Rear Center */
109 RR = (1 << 7), /* Rear Right */
110 RLC = (1 << 8), /* Rear Left Center */
111 RRC = (1 << 9), /* Rear Right Center */
112 LFE = (1 << 10), /* Low Frequency Effect */
113 FLW = (1 << 11), /* Front Left Wide */
114 FRW = (1 << 12), /* Front Right Wide */
115 FLH = (1 << 13), /* Front Left High */
116 FCH = (1 << 14), /* Front Center High */
117 FRH = (1 << 15), /* Front Right High */
118 TC = (1 << 16), /* Top Center */
119};
120
121/*
122 * ELD SA bits in the CEA Speaker Allocation data block
123 */
124static int eld_speaker_allocation_bits[] = {
125 [0] = FL | FR,
126 [1] = LFE,
127 [2] = FC,
128 [3] = RL | RR,
129 [4] = RC,
130 [5] = FLC | FRC,
131 [6] = RLC | RRC,
132 /* the following are not defined in ELD yet */
133 [7] = FLW | FRW,
134 [8] = FLH | FRH,
135 [9] = TC,
136 [10] = FCH,
137};
138
139struct cea_channel_speaker_allocation {
140 int ca_index;
141 int speakers[8];
142
143 /* derived values, just for convenience */
144 int channels;
145 int spk_mask;
146};
147
148/*
149 * ALSA sequence is:
150 *
151 * surround40 surround41 surround50 surround51 surround71
152 * ch0 front left = = = =
153 * ch1 front right = = = =
154 * ch2 rear left = = = =
155 * ch3 rear right = = = =
156 * ch4 LFE center center center
157 * ch5 LFE LFE
158 * ch6 side left
159 * ch7 side right
160 *
161 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
162 */
163static int hdmi_channel_mapping[0x32][8] = {
164 /* stereo */
165 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
166 /* 2.1 */
167 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
168 /* Dolby Surround */
169 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
170 /* surround40 */
171 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
172 /* 4ch */
173 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
174 /* surround41 */
175 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
176 /* surround50 */
177 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
178 /* surround51 */
179 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
180 /* 7.1 */
181 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
182};
183
184/*
185 * This is an ordered list!
186 *
187 * The preceding ones have better chances to be selected by
188 * hdmi_setup_channel_allocation().
189 */
190static struct cea_channel_speaker_allocation channel_allocations[] = {
191/* channel: 7 6 5 4 3 2 1 0 */
192{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
193 /* 2.1 */
194{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
195 /* Dolby Surround */
196{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
197 /* surround40 */
198{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
199 /* surround41 */
200{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
201 /* surround50 */
202{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
203 /* surround51 */
204{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
205 /* 6.1 */
206{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
207 /* surround71 */
208{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
209
210{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
211{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
212{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
213{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
214{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
215{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
216{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
217{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
218{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
219{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
220{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
222{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
223{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
224{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
225{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
226{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
227{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
228{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
229{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
230{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
231{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
232{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
233{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
234{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
235{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
236{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
237{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
238{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
239{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
240{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
241{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
242{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
243{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
244{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
245{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
246{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
247{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
248{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
249{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
250{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
251};
252
253/*
254 * HDA/HDMI auto parsing
255 */
256
257static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
258{
259 int i;
260
261 for (i = 0; nids[i]; i++)
262 if (nids[i] == nid)
263 return i;
264
265 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
266 return -EINVAL;
267}
268
269static int intel_hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
270{
271 struct intel_hdmi_spec *spec = codec->spec;
272 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
273 int conn_len, curr;
274 int index;
275
276 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
277 snd_printk(KERN_WARNING
278 "HDMI: pin %d wcaps %#x "
279 "does not support connection list\n",
280 pin_nid, get_wcaps(codec, pin_nid));
281 return -EINVAL;
282 }
283
284 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
285 HDA_MAX_CONNECTIONS);
286 if (conn_len > 1)
287 curr = snd_hda_codec_read(codec, pin_nid, 0,
288 AC_VERB_GET_CONNECT_SEL, 0);
289 else
290 curr = 0;
291
292 index = hda_node_index(spec->pin, pin_nid);
293 if (index < 0)
294 return -EINVAL;
295
296 spec->pin_cvt[index] = conn_list[curr];
297
298 return 0;
299}
300
301static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
302 struct hdmi_eld *eld)
303{
304 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
305 snd_hdmi_show_eld(eld);
306}
307
308static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
309 struct hdmi_eld *eld)
310{
311 int present = snd_hda_pin_sense(codec, pin_nid);
312
313 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
314 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
315
316 if (present & AC_PINSENSE_ELDV)
317 hdmi_get_show_eld(codec, pin_nid, eld);
318}
319
320static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
321{
322 struct intel_hdmi_spec *spec = codec->spec;
323
324 if (spec->num_pins >= INTEL_HDMI_PINS) {
325 snd_printk(KERN_WARNING
326 "HDMI: no space for pin %d \n", pin_nid);
327 return -EINVAL;
328 }
329
330 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
331
332 spec->pin[spec->num_pins] = pin_nid;
333 spec->num_pins++;
334
335 /*
336 * It is assumed that converter nodes come first in the node list and
337 * hence have been registered and usable now.
338 */
339 return intel_hdmi_read_pin_conn(codec, pin_nid);
340}
341
342static int intel_hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
343{
344 struct intel_hdmi_spec *spec = codec->spec;
345
346 if (spec->num_cvts >= INTEL_HDMI_CVTS) {
347 snd_printk(KERN_WARNING
348 "HDMI: no space for converter %d \n", nid);
349 return -EINVAL;
350 }
351
352 spec->cvt[spec->num_cvts] = nid;
353 spec->num_cvts++;
354
355 return 0;
356}
357
358static int intel_hdmi_parse_codec(struct hda_codec *codec)
359{
360 hda_nid_t nid;
361 int i, nodes;
362
363 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
364 if (!nid || nodes < 0) {
365 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
366 return -EINVAL;
367 }
368
369 for (i = 0; i < nodes; i++, nid++) {
370 unsigned int caps;
371 unsigned int type;
372
373 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
374 type = get_wcaps_type(caps);
375
376 if (!(caps & AC_WCAP_DIGITAL))
377 continue;
378
379 switch (type) {
380 case AC_WID_AUD_OUT:
381 if (intel_hdmi_add_cvt(codec, nid) < 0)
382 return -EINVAL;
383 break;
384 case AC_WID_PIN:
385 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
386 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
387 continue;
388 if (intel_hdmi_add_pin(codec, nid) < 0)
389 return -EINVAL;
390 break;
391 }
392 }
393
394 /*
395 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
396 * can be lost and presence sense verb will become inaccurate if the
397 * HDA link is powered off at hot plug or hw initialization time.
398 */
399#ifdef CONFIG_SND_HDA_POWER_SAVE
400 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
401 AC_PWRST_EPSS))
402 codec->bus->power_keep_link_on = 1;
403#endif
404
405 return 0;
406}
407
408/*
409 * HDMI routines
410 */
411
412#ifdef BE_PARANOID
413static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
414 int *packet_index, int *byte_index)
415{
416 int val;
417
418 val = snd_hda_codec_read(codec, pin_nid, 0,
419 AC_VERB_GET_HDMI_DIP_INDEX, 0);
420
421 *packet_index = val >> 5;
422 *byte_index = val & 0x1f;
423}
424#endif
425
426static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
427 int packet_index, int byte_index)
428{
429 int val;
430
431 val = (packet_index << 5) | (byte_index & 0x1f);
432
433 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
434}
435
436static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
437 unsigned char val)
438{
439 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
440}
441
442static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
443{
444 /* Unmute */
445 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
446 snd_hda_codec_write(codec, pin_nid, 0,
447 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
448 /* Enable pin out */
449 snd_hda_codec_write(codec, pin_nid, 0,
450 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
451}
452
453/*
454 * Enable Audio InfoFrame Transmission
455 */
456static void hdmi_start_infoframe_trans(struct hda_codec *codec,
457 hda_nid_t pin_nid)
458{
459 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
460 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
461 AC_DIPXMIT_BEST);
462}
463
464/*
465 * Disable Audio InfoFrame Transmission
466 */
467static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
468 hda_nid_t pin_nid)
469{
470 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
471 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
472 AC_DIPXMIT_DISABLE);
473}
474
475static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
476{
477 return 1 + snd_hda_codec_read(codec, nid, 0,
478 AC_VERB_GET_CVT_CHAN_COUNT, 0);
479}
480
481static void hdmi_set_channel_count(struct hda_codec *codec,
482 hda_nid_t nid, int chs)
483{
484 if (chs != hdmi_get_channel_count(codec, nid))
485 snd_hda_codec_write(codec, nid, 0,
486 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
487}
488
489static void hdmi_debug_channel_mapping(struct hda_codec *codec,
490 hda_nid_t pin_nid)
491{
492#ifdef CONFIG_SND_DEBUG_VERBOSE
493 int i;
494 int slot;
495
496 for (i = 0; i < 8; i++) {
497 slot = snd_hda_codec_read(codec, pin_nid, 0,
498 AC_VERB_GET_HDMI_CHAN_SLOT, i);
499 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
500 slot >> 4, slot & 0xf);
501 }
502#endif
503}
504
505
506/*
507 * Audio InfoFrame routines
508 */
509
510static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
511{
512#ifdef CONFIG_SND_DEBUG_VERBOSE
513 int i;
514 int size;
515
516 size = snd_hdmi_get_eld_size(codec, pin_nid);
517 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
518
519 for (i = 0; i < 8; i++) {
520 size = snd_hda_codec_read(codec, pin_nid, 0,
521 AC_VERB_GET_HDMI_DIP_SIZE, i);
522 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
523 }
524#endif
525}
526
527static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
528{
529#ifdef BE_PARANOID
530 int i, j;
531 int size;
532 int pi, bi;
533 for (i = 0; i < 8; i++) {
534 size = snd_hda_codec_read(codec, pin_nid, 0,
535 AC_VERB_GET_HDMI_DIP_SIZE, i);
536 if (size == 0)
537 continue;
538
539 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
540 for (j = 1; j < 1000; j++) {
541 hdmi_write_dip_byte(codec, pin_nid, 0x0);
542 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
543 if (pi != i)
544 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
545 bi, pi, i);
546 if (bi == 0) /* byte index wrapped around */
547 break;
548 }
549 snd_printd(KERN_INFO
550 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
551 i, size, j);
552 }
553#endif
554}
555
556static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
557{
558 u8 *bytes = (u8 *)ai;
559 u8 sum = 0;
560 int i;
561
562 ai->checksum = 0;
563
564 for (i = 0; i < sizeof(*ai); i++)
565 sum += bytes[i];
566
567 ai->checksum = - sum;
568}
569
570static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
571 hda_nid_t pin_nid,
572 struct hdmi_audio_infoframe *ai)
573{
574 u8 *bytes = (u8 *)ai;
575 int i;
576
577 hdmi_debug_dip_size(codec, pin_nid);
578 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
579
580 hdmi_checksum_audio_infoframe(ai);
581
582 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
583 for (i = 0; i < sizeof(*ai); i++)
584 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
585}
586
587/*
588 * Compute derived values in channel_allocations[].
589 */
590static void init_channel_allocations(void)
591{
592 int i, j;
593 struct cea_channel_speaker_allocation *p;
594
595 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
596 p = channel_allocations + i;
597 p->channels = 0;
598 p->spk_mask = 0;
599 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
600 if (p->speakers[j]) {
601 p->channels++;
602 p->spk_mask |= p->speakers[j];
603 }
604 }
605}
606
607/*
608 * The transformation takes two steps:
609 *
610 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
611 * spk_mask => (channel_allocations[]) => ai->CA
612 *
613 * TODO: it could select the wrong CA from multiple candidates.
614*/
615static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
616 struct hdmi_audio_infoframe *ai)
617{
618 struct intel_hdmi_spec *spec = codec->spec;
619 struct hdmi_eld *eld;
620 int i;
621 int spk_mask = 0;
622 int channels = 1 + (ai->CC02_CT47 & 0x7);
623 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
624
625 /*
626 * CA defaults to 0 for basic stereo audio
627 */
628 if (channels <= 2)
629 return 0;
630
631 i = hda_node_index(spec->pin_cvt, nid);
632 if (i < 0)
633 return 0;
634 eld = &spec->sink_eld[i];
635
636 /*
637 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
638 * in console or for audio devices. Assume the highest speakers
639 * configuration, to _not_ prohibit multi-channel audio playback.
640 */
641 if (!eld->spk_alloc)
642 eld->spk_alloc = 0xffff;
643
644 /*
645 * expand ELD's speaker allocation mask
646 *
647 * ELD tells the speaker mask in a compact(paired) form,
648 * expand ELD's notions to match the ones used by Audio InfoFrame.
649 */
650 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
651 if (eld->spk_alloc & (1 << i))
652 spk_mask |= eld_speaker_allocation_bits[i];
653 }
654
655 /* search for the first working match in the CA table */
656 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
657 if (channels == channel_allocations[i].channels &&
658 (spk_mask & channel_allocations[i].spk_mask) ==
659 channel_allocations[i].spk_mask) {
660 ai->CA = channel_allocations[i].ca_index;
661 break;
662 }
663 }
664
665 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
666 snd_printdd(KERN_INFO
667 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
668 ai->CA, channels, buf);
669
670 return ai->CA;
671}
672
673static void hdmi_setup_channel_mapping(struct hda_codec *codec,
674 hda_nid_t pin_nid,
675 struct hdmi_audio_infoframe *ai)
676{
677 int i;
678 int ca = ai->CA;
679 int err;
680
681 if (hdmi_channel_mapping[ca][1] == 0) {
682 for (i = 0; i < channel_allocations[ca].channels; i++)
683 hdmi_channel_mapping[ca][i] = i | (i << 4);
684 for (; i < 8; i++)
685 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
686 }
687
688 for (i = 0; i < 8; i++) {
689 err = snd_hda_codec_write(codec, pin_nid, 0,
690 AC_VERB_SET_HDMI_CHAN_SLOT,
691 hdmi_channel_mapping[ca][i]);
692 if (err) {
693 snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
694 break;
695 }
696 }
697
698 hdmi_debug_channel_mapping(codec, pin_nid);
699}
700
701static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
702 struct hdmi_audio_infoframe *ai)
703{
704 u8 *bytes = (u8 *)ai;
705 u8 val;
706 int i;
707
708 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
709 != AC_DIPXMIT_BEST)
710 return false;
711
712 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
713 for (i = 0; i < sizeof(*ai); i++) {
714 val = snd_hda_codec_read(codec, pin_nid, 0,
715 AC_VERB_GET_HDMI_DIP_DATA, 0);
716 if (val != bytes[i])
717 return false;
718 }
719
720 return true;
721}
722
723static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
724 struct snd_pcm_substream *substream)
725{
726 struct intel_hdmi_spec *spec = codec->spec;
727 hda_nid_t pin_nid;
728 int i;
729 struct hdmi_audio_infoframe ai = {
730 .type = 0x84,
731 .ver = 0x01,
732 .len = 0x0a,
733 .CC02_CT47 = substream->runtime->channels - 1,
734 };
735
736 hdmi_setup_channel_allocation(codec, nid, &ai);
737
738 for (i = 0; i < spec->num_pins; i++) {
739 if (spec->pin_cvt[i] != nid)
740 continue;
741 if (!spec->sink_eld[i].monitor_present)
742 continue;
743
744 pin_nid = spec->pin[i];
745 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
746 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
747 hdmi_stop_infoframe_trans(codec, pin_nid);
748 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
749 hdmi_start_infoframe_trans(codec, pin_nid);
750 }
751 }
752}
753
754
755/* 53/*
756 * Unsolicited events 54 * HDMI callbacks
757 */ 55 */
758 56
759static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
760{
761 struct intel_hdmi_spec *spec = codec->spec;
762 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
763 int pind = !!(res & AC_UNSOL_RES_PD);
764 int eldv = !!(res & AC_UNSOL_RES_ELDV);
765 int index;
766
767 printk(KERN_INFO
768 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
769 tag, pind, eldv);
770
771 index = hda_node_index(spec->pin, tag);
772 if (index < 0)
773 return;
774
775 spec->sink_eld[index].monitor_present = pind;
776 spec->sink_eld[index].eld_valid = eldv;
777
778 if (pind && eldv) {
779 hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]);
780 /* TODO: do real things about ELD */
781 }
782}
783
784static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
785{
786 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
787 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
788 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
789 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
790
791 printk(KERN_INFO
792 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
793 tag,
794 subtag,
795 cp_state,
796 cp_ready);
797
798 /* TODO */
799 if (cp_state)
800 ;
801 if (cp_ready)
802 ;
803}
804
805
806static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
807{
808 struct intel_hdmi_spec *spec = codec->spec;
809 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
810 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
811
812 if (hda_node_index(spec->pin, tag) < 0) {
813 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
814 return;
815 }
816
817 if (subtag == 0)
818 hdmi_intrinsic_event(codec, res);
819 else
820 hdmi_non_intrinsic_event(codec, res);
821}
822
823/*
824 * Callbacks
825 */
826
827static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
828 u32 stream_tag, int format)
829{
830 int tag;
831 int fmt;
832
833 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
834 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
835
836 snd_printdd("hdmi_setup_stream: "
837 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
838 nid,
839 tag == stream_tag ? "" : "new-",
840 stream_tag,
841 fmt == format ? "" : "new-",
842 format);
843
844 if (tag != stream_tag)
845 snd_hda_codec_write(codec, nid, 0,
846 AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4);
847 if (fmt != format)
848 snd_hda_codec_write(codec, nid, 0,
849 AC_VERB_SET_STREAM_FORMAT, format);
850}
851
852static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 57static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
853 struct hda_codec *codec, 58 struct hda_codec *codec,
854 unsigned int stream_tag, 59 unsigned int stream_tag,
@@ -882,7 +87,7 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = {
882 87
883static int intel_hdmi_build_pcms(struct hda_codec *codec) 88static int intel_hdmi_build_pcms(struct hda_codec *codec)
884{ 89{
885 struct intel_hdmi_spec *spec = codec->spec; 90 struct hdmi_spec *spec = codec->spec;
886 struct hda_pcm *info = spec->pcm_rec; 91 struct hda_pcm *info = spec->pcm_rec;
887 int i; 92 int i;
888 93
@@ -908,7 +113,7 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec)
908 113
909static int intel_hdmi_build_controls(struct hda_codec *codec) 114static int intel_hdmi_build_controls(struct hda_codec *codec)
910{ 115{
911 struct intel_hdmi_spec *spec = codec->spec; 116 struct hdmi_spec *spec = codec->spec;
912 int err; 117 int err;
913 int i; 118 int i;
914 119
@@ -923,7 +128,7 @@ static int intel_hdmi_build_controls(struct hda_codec *codec)
923 128
924static int intel_hdmi_init(struct hda_codec *codec) 129static int intel_hdmi_init(struct hda_codec *codec)
925{ 130{
926 struct intel_hdmi_spec *spec = codec->spec; 131 struct hdmi_spec *spec = codec->spec;
927 int i; 132 int i;
928 133
929 for (i = 0; spec->pin[i]; i++) { 134 for (i = 0; spec->pin[i]; i++) {
@@ -937,7 +142,7 @@ static int intel_hdmi_init(struct hda_codec *codec)
937 142
938static void intel_hdmi_free(struct hda_codec *codec) 143static void intel_hdmi_free(struct hda_codec *codec)
939{ 144{
940 struct intel_hdmi_spec *spec = codec->spec; 145 struct hdmi_spec *spec = codec->spec;
941 int i; 146 int i;
942 147
943 for (i = 0; i < spec->num_pins; i++) 148 for (i = 0; i < spec->num_pins; i++)
@@ -951,12 +156,12 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
951 .free = intel_hdmi_free, 156 .free = intel_hdmi_free,
952 .build_pcms = intel_hdmi_build_pcms, 157 .build_pcms = intel_hdmi_build_pcms,
953 .build_controls = intel_hdmi_build_controls, 158 .build_controls = intel_hdmi_build_controls,
954 .unsol_event = intel_hdmi_unsol_event, 159 .unsol_event = hdmi_unsol_event,
955}; 160};
956 161
957static int patch_intel_hdmi(struct hda_codec *codec) 162static int patch_intel_hdmi(struct hda_codec *codec)
958{ 163{
959 struct intel_hdmi_spec *spec; 164 struct hdmi_spec *spec;
960 int i; 165 int i;
961 166
962 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -964,7 +169,7 @@ static int patch_intel_hdmi(struct hda_codec *codec)
964 return -ENOMEM; 169 return -ENOMEM;
965 170
966 codec->spec = spec; 171 codec->spec = spec;
967 if (intel_hdmi_parse_codec(codec) < 0) { 172 if (hdmi_parse_codec(codec) < 0) {
968 codec->spec = NULL; 173 codec->spec = NULL;
969 kfree(spec); 174 kfree(spec);
970 return -EINVAL; 175 return -EINVAL;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 6afdab09bab7..70669a246902 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,13 +29,23 @@
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31 31
32#define MAX_HDMI_CVTS 1
33#define MAX_HDMI_PINS 1
34
35#include "patch_hdmi.c"
36
37static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
38 "NVIDIA HDMI",
39};
40
32/* define below to restrict the supported rates and formats */ 41/* define below to restrict the supported rates and formats */
33/* #define LIMITED_RATE_FMT_SUPPORT */ 42/* #define LIMITED_RATE_FMT_SUPPORT */
34 43
35struct nvhdmi_spec { 44enum HDACodec {
36 struct hda_multi_out multiout; 45 HDA_CODEC_NVIDIA_MCP7X,
37 46 HDA_CODEC_NVIDIA_MCP89,
38 struct hda_pcm pcm_rec; 47 HDA_CODEC_NVIDIA_GT21X,
48 HDA_CODEC_INVALID
39}; 49};
40 50
41#define Nv_VERB_SET_Channel_Allocation 0xF79 51#define Nv_VERB_SET_Channel_Allocation 0xF79
@@ -43,15 +53,18 @@ struct nvhdmi_spec {
43#define Nv_VERB_SET_Audio_Protection_On 0xF98 53#define Nv_VERB_SET_Audio_Protection_On 0xF98
44#define Nv_VERB_SET_Audio_Protection_Off 0xF99 54#define Nv_VERB_SET_Audio_Protection_Off 0xF99
45 55
46#define Nv_Master_Convert_nid 0x04 56#define nvhdmi_master_con_nid_7x 0x04
47#define Nv_Master_Pin_nid 0x05 57#define nvhdmi_master_pin_nid_7x 0x05
48 58
49static hda_nid_t nvhdmi_convert_nids[4] = { 59#define nvhdmi_master_con_nid_89 0x04
60#define nvhdmi_master_pin_nid_89 0x05
61
62static hda_nid_t nvhdmi_con_nids_7x[4] = {
50 /*front, rear, clfe, rear_surr */ 63 /*front, rear, clfe, rear_surr */
51 0x6, 0x8, 0xa, 0xc, 64 0x6, 0x8, 0xa, 0xc,
52}; 65};
53 66
54static struct hda_verb nvhdmi_basic_init[] = { 67static struct hda_verb nvhdmi_basic_init_7x[] = {
55 /* set audio protect on */ 68 /* set audio protect on */
56 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 69 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
57 /* enable digital output on pin widget */ 70 /* enable digital output on pin widget */
@@ -84,22 +97,60 @@ static struct hda_verb nvhdmi_basic_init[] = {
84 */ 97 */
85static int nvhdmi_build_controls(struct hda_codec *codec) 98static int nvhdmi_build_controls(struct hda_codec *codec)
86{ 99{
87 struct nvhdmi_spec *spec = codec->spec; 100 struct hdmi_spec *spec = codec->spec;
88 int err; 101 int err;
102 int i;
89 103
90 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 104 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
91 if (err < 0) 105 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
92 return err; 106 for (i = 0; i < codec->num_pcms; i++) {
107 err = snd_hda_create_spdif_out_ctls(codec,
108 spec->cvt[i]);
109 if (err < 0)
110 return err;
111 }
112 } else {
113 err = snd_hda_create_spdif_out_ctls(codec,
114 spec->multiout.dig_out_nid);
115 if (err < 0)
116 return err;
117 }
93 118
94 return 0; 119 return 0;
95} 120}
96 121
97static int nvhdmi_init(struct hda_codec *codec) 122static int nvhdmi_init(struct hda_codec *codec)
98{ 123{
99 snd_hda_sequence_write(codec, nvhdmi_basic_init); 124 struct hdmi_spec *spec = codec->spec;
125 int i;
126 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
127 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
128 for (i = 0; spec->pin[i]; i++) {
129 hdmi_enable_output(codec, spec->pin[i]);
130 snd_hda_codec_write(codec, spec->pin[i], 0,
131 AC_VERB_SET_UNSOLICITED_ENABLE,
132 AC_USRSP_EN | spec->pin[i]);
133 }
134 } else {
135 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
136 }
100 return 0; 137 return 0;
101} 138}
102 139
140static void nvhdmi_free(struct hda_codec *codec)
141{
142 struct hdmi_spec *spec = codec->spec;
143 int i;
144
145 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
146 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
147 for (i = 0; i < spec->num_pins; i++)
148 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
149 }
150
151 kfree(spec);
152}
153
103/* 154/*
104 * Digital out 155 * Digital out
105 */ 156 */
@@ -107,25 +158,25 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
107 struct hda_codec *codec, 158 struct hda_codec *codec,
108 struct snd_pcm_substream *substream) 159 struct snd_pcm_substream *substream)
109{ 160{
110 struct nvhdmi_spec *spec = codec->spec; 161 struct hdmi_spec *spec = codec->spec;
111 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 162 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
112} 163}
113 164
114static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo, 165static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
115 struct hda_codec *codec, 166 struct hda_codec *codec,
116 struct snd_pcm_substream *substream) 167 struct snd_pcm_substream *substream)
117{ 168{
118 struct nvhdmi_spec *spec = codec->spec; 169 struct hdmi_spec *spec = codec->spec;
119 int i; 170 int i;
120 171
121 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 172 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
122 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 173 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
123 for (i = 0; i < 4; i++) { 174 for (i = 0; i < 4; i++) {
124 /* set the stream id */ 175 /* set the stream id */
125 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 176 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
126 AC_VERB_SET_CHANNEL_STREAMID, 0); 177 AC_VERB_SET_CHANNEL_STREAMID, 0);
127 /* set the stream format */ 178 /* set the stream format */
128 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 179 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
129 AC_VERB_SET_STREAM_FORMAT, 0); 180 AC_VERB_SET_STREAM_FORMAT, 0);
130 } 181 }
131 182
@@ -136,10 +187,25 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
136 struct hda_codec *codec, 187 struct hda_codec *codec,
137 struct snd_pcm_substream *substream) 188 struct snd_pcm_substream *substream)
138{ 189{
139 struct nvhdmi_spec *spec = codec->spec; 190 struct hdmi_spec *spec = codec->spec;
140 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 191 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
141} 192}
142 193
194static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
195 struct hda_codec *codec,
196 unsigned int stream_tag,
197 unsigned int format,
198 struct snd_pcm_substream *substream)
199{
200 hdmi_set_channel_count(codec, hinfo->nid,
201 substream->runtime->channels);
202
203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
204
205 hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
206 return 0;
207}
208
143static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, 209static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
144 struct hda_codec *codec, 210 struct hda_codec *codec,
145 unsigned int stream_tag, 211 unsigned int stream_tag,
@@ -181,29 +247,29 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
181 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 247 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
182 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 248 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
183 snd_hda_codec_write(codec, 249 snd_hda_codec_write(codec,
184 Nv_Master_Convert_nid, 250 nvhdmi_master_con_nid_7x,
185 0, 251 0,
186 AC_VERB_SET_DIGI_CONVERT_1, 252 AC_VERB_SET_DIGI_CONVERT_1,
187 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 253 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
188 254
189 /* set the stream id */ 255 /* set the stream id */
190 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 256 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
191 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); 257 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
192 258
193 /* set the stream format */ 259 /* set the stream format */
194 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 260 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
195 AC_VERB_SET_STREAM_FORMAT, format); 261 AC_VERB_SET_STREAM_FORMAT, format);
196 262
197 /* turn on again (if needed) */ 263 /* turn on again (if needed) */
198 /* enable and set the channel status audio/data flag */ 264 /* enable and set the channel status audio/data flag */
199 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 265 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
200 snd_hda_codec_write(codec, 266 snd_hda_codec_write(codec,
201 Nv_Master_Convert_nid, 267 nvhdmi_master_con_nid_7x,
202 0, 268 0,
203 AC_VERB_SET_DIGI_CONVERT_1, 269 AC_VERB_SET_DIGI_CONVERT_1,
204 codec->spdif_ctls & 0xff); 270 codec->spdif_ctls & 0xff);
205 snd_hda_codec_write(codec, 271 snd_hda_codec_write(codec,
206 Nv_Master_Convert_nid, 272 nvhdmi_master_con_nid_7x,
207 0, 273 0,
208 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 274 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
209 } 275 }
@@ -220,19 +286,19 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
220 if (codec->spdif_status_reset && 286 if (codec->spdif_status_reset &&
221 (codec->spdif_ctls & AC_DIG1_ENABLE)) 287 (codec->spdif_ctls & AC_DIG1_ENABLE))
222 snd_hda_codec_write(codec, 288 snd_hda_codec_write(codec,
223 nvhdmi_convert_nids[i], 289 nvhdmi_con_nids_7x[i],
224 0, 290 0,
225 AC_VERB_SET_DIGI_CONVERT_1, 291 AC_VERB_SET_DIGI_CONVERT_1,
226 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 292 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
227 /* set the stream id */ 293 /* set the stream id */
228 snd_hda_codec_write(codec, 294 snd_hda_codec_write(codec,
229 nvhdmi_convert_nids[i], 295 nvhdmi_con_nids_7x[i],
230 0, 296 0,
231 AC_VERB_SET_CHANNEL_STREAMID, 297 AC_VERB_SET_CHANNEL_STREAMID,
232 (stream_tag << 4) | channel_id); 298 (stream_tag << 4) | channel_id);
233 /* set the stream format */ 299 /* set the stream format */
234 snd_hda_codec_write(codec, 300 snd_hda_codec_write(codec,
235 nvhdmi_convert_nids[i], 301 nvhdmi_con_nids_7x[i],
236 0, 302 0,
237 AC_VERB_SET_STREAM_FORMAT, 303 AC_VERB_SET_STREAM_FORMAT,
238 format); 304 format);
@@ -241,12 +307,12 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
241 if (codec->spdif_status_reset && 307 if (codec->spdif_status_reset &&
242 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 308 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
243 snd_hda_codec_write(codec, 309 snd_hda_codec_write(codec,
244 nvhdmi_convert_nids[i], 310 nvhdmi_con_nids_7x[i],
245 0, 311 0,
246 AC_VERB_SET_DIGI_CONVERT_1, 312 AC_VERB_SET_DIGI_CONVERT_1,
247 codec->spdif_ctls & 0xff); 313 codec->spdif_ctls & 0xff);
248 snd_hda_codec_write(codec, 314 snd_hda_codec_write(codec,
249 nvhdmi_convert_nids[i], 315 nvhdmi_con_nids_7x[i],
250 0, 316 0,
251 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 317 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
252 } 318 }
@@ -261,28 +327,47 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
261 return 0; 327 return 0;
262} 328}
263 329
330static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
331 struct hda_codec *codec,
332 struct snd_pcm_substream *substream)
333{
334 return 0;
335}
336
264static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, 337static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
265 struct hda_codec *codec, 338 struct hda_codec *codec,
266 unsigned int stream_tag, 339 unsigned int stream_tag,
267 unsigned int format, 340 unsigned int format,
268 struct snd_pcm_substream *substream) 341 struct snd_pcm_substream *substream)
269{ 342{
270 struct nvhdmi_spec *spec = codec->spec; 343 struct hdmi_spec *spec = codec->spec;
271 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 344 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
272 format, substream); 345 format, substream);
273} 346}
274 347
275static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = { 348static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
349 .substreams = 1,
350 .channels_min = 2,
351 .rates = SUPPORTED_RATES,
352 .maxbps = SUPPORTED_MAXBPS,
353 .formats = SUPPORTED_FORMATS,
354 .ops = {
355 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
356 .cleanup = nvhdmi_playback_pcm_cleanup,
357 },
358};
359
360static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
276 .substreams = 1, 361 .substreams = 1,
277 .channels_min = 2, 362 .channels_min = 2,
278 .channels_max = 8, 363 .channels_max = 8,
279 .nid = Nv_Master_Convert_nid, 364 .nid = nvhdmi_master_con_nid_7x,
280 .rates = SUPPORTED_RATES, 365 .rates = SUPPORTED_RATES,
281 .maxbps = SUPPORTED_MAXBPS, 366 .maxbps = SUPPORTED_MAXBPS,
282 .formats = SUPPORTED_FORMATS, 367 .formats = SUPPORTED_FORMATS,
283 .ops = { 368 .ops = {
284 .open = nvhdmi_dig_playback_pcm_open, 369 .open = nvhdmi_dig_playback_pcm_open,
285 .close = nvhdmi_dig_playback_pcm_close_8ch, 370 .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
286 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch 371 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
287 }, 372 },
288}; 373};
@@ -291,7 +376,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
291 .substreams = 1, 376 .substreams = 1,
292 .channels_min = 2, 377 .channels_min = 2,
293 .channels_max = 2, 378 .channels_max = 2,
294 .nid = Nv_Master_Convert_nid, 379 .nid = nvhdmi_master_con_nid_7x,
295 .rates = SUPPORTED_RATES, 380 .rates = SUPPORTED_RATES,
296 .maxbps = SUPPORTED_MAXBPS, 381 .maxbps = SUPPORTED_MAXBPS,
297 .formats = SUPPORTED_FORMATS, 382 .formats = SUPPORTED_FORMATS,
@@ -302,10 +387,36 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
302 }, 387 },
303}; 388};
304 389
305static int nvhdmi_build_pcms_8ch(struct hda_codec *codec) 390static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
391{
392 struct hdmi_spec *spec = codec->spec;
393 struct hda_pcm *info = spec->pcm_rec;
394 int i;
395
396 codec->num_pcms = spec->num_cvts;
397 codec->pcm_info = info;
398
399 for (i = 0; i < codec->num_pcms; i++, info++) {
400 unsigned int chans;
401
402 chans = get_wcaps(codec, spec->cvt[i]);
403 chans = get_wcaps_channels(chans);
404
405 info->name = nvhdmi_pcm_names[i];
406 info->pcm_type = HDA_PCM_TYPE_HDMI;
407 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
408 = nvhdmi_pcm_digital_playback_8ch_89;
409 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
410 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
411 }
412
413 return 0;
414}
415
416static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
306{ 417{
307 struct nvhdmi_spec *spec = codec->spec; 418 struct hdmi_spec *spec = codec->spec;
308 struct hda_pcm *info = &spec->pcm_rec; 419 struct hda_pcm *info = spec->pcm_rec;
309 420
310 codec->num_pcms = 1; 421 codec->num_pcms = 1;
311 codec->pcm_info = info; 422 codec->pcm_info = info;
@@ -313,15 +424,15 @@ static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
313 info->name = "NVIDIA HDMI"; 424 info->name = "NVIDIA HDMI";
314 info->pcm_type = HDA_PCM_TYPE_HDMI; 425 info->pcm_type = HDA_PCM_TYPE_HDMI;
315 info->stream[SNDRV_PCM_STREAM_PLAYBACK] 426 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
316 = nvhdmi_pcm_digital_playback_8ch; 427 = nvhdmi_pcm_digital_playback_8ch_7x;
317 428
318 return 0; 429 return 0;
319} 430}
320 431
321static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) 432static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
322{ 433{
323 struct nvhdmi_spec *spec = codec->spec; 434 struct hdmi_spec *spec = codec->spec;
324 struct hda_pcm *info = &spec->pcm_rec; 435 struct hda_pcm *info = spec->pcm_rec;
325 436
326 codec->num_pcms = 1; 437 codec->num_pcms = 1;
327 codec->pcm_info = info; 438 codec->pcm_info = info;
@@ -334,14 +445,17 @@ static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
334 return 0; 445 return 0;
335} 446}
336 447
337static void nvhdmi_free(struct hda_codec *codec) 448static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
338{ 449 .build_controls = nvhdmi_build_controls,
339 kfree(codec->spec); 450 .build_pcms = nvhdmi_build_pcms_8ch_89,
340} 451 .init = nvhdmi_init,
452 .free = nvhdmi_free,
453 .unsol_event = hdmi_unsol_event,
454};
341 455
342static struct hda_codec_ops nvhdmi_patch_ops_8ch = { 456static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
343 .build_controls = nvhdmi_build_controls, 457 .build_controls = nvhdmi_build_controls,
344 .build_pcms = nvhdmi_build_pcms_8ch, 458 .build_pcms = nvhdmi_build_pcms_8ch_7x,
345 .init = nvhdmi_init, 459 .init = nvhdmi_init,
346 .free = nvhdmi_free, 460 .free = nvhdmi_free,
347}; 461};
@@ -353,9 +467,36 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
353 .free = nvhdmi_free, 467 .free = nvhdmi_free,
354}; 468};
355 469
356static int patch_nvhdmi_8ch(struct hda_codec *codec) 470static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
471{
472 struct hdmi_spec *spec;
473 int i;
474
475 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
476 if (spec == NULL)
477 return -ENOMEM;
478
479 codec->spec = spec;
480 spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
481
482 if (hdmi_parse_codec(codec) < 0) {
483 codec->spec = NULL;
484 kfree(spec);
485 return -EINVAL;
486 }
487 codec->patch_ops = nvhdmi_patch_ops_8ch_89;
488
489 for (i = 0; i < spec->num_pins; i++)
490 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
491
492 init_channel_allocations();
493
494 return 0;
495}
496
497static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
357{ 498{
358 struct nvhdmi_spec *spec; 499 struct hdmi_spec *spec;
359 500
360 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 501 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
361 if (spec == NULL) 502 if (spec == NULL)
@@ -365,16 +506,17 @@ static int patch_nvhdmi_8ch(struct hda_codec *codec)
365 506
366 spec->multiout.num_dacs = 0; /* no analog */ 507 spec->multiout.num_dacs = 0; /* no analog */
367 spec->multiout.max_channels = 8; 508 spec->multiout.max_channels = 8;
368 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 509 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
510 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
369 511
370 codec->patch_ops = nvhdmi_patch_ops_8ch; 512 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
371 513
372 return 0; 514 return 0;
373} 515}
374 516
375static int patch_nvhdmi_2ch(struct hda_codec *codec) 517static int patch_nvhdmi_2ch(struct hda_codec *codec)
376{ 518{
377 struct nvhdmi_spec *spec; 519 struct hdmi_spec *spec;
378 520
379 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 521 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
380 if (spec == NULL) 522 if (spec == NULL)
@@ -384,7 +526,8 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
384 526
385 spec->multiout.num_dacs = 0; /* no analog */ 527 spec->multiout.num_dacs = 0; /* no analog */
386 spec->multiout.max_channels = 2; 528 spec->multiout.max_channels = 2;
387 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 529 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
530 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
388 531
389 codec->patch_ops = nvhdmi_patch_ops_2ch; 532 codec->patch_ops = nvhdmi_patch_ops_2ch;
390 533
@@ -395,13 +538,24 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
395 * patch entries 538 * patch entries
396 */ 539 */
397static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 540static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
398 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
399 { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
400 { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
401 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
402 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
403 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 541 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
404 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 542 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
543 { .id = 0x10de0002, .name = "MCP77/78 HDMI",
544 .patch = patch_nvhdmi_8ch_7x },
545 { .id = 0x10de0003, .name = "MCP77/78 HDMI",
546 .patch = patch_nvhdmi_8ch_7x },
547 { .id = 0x10de0005, .name = "MCP77/78 HDMI",
548 .patch = patch_nvhdmi_8ch_7x },
549 { .id = 0x10de0006, .name = "MCP77/78 HDMI",
550 .patch = patch_nvhdmi_8ch_7x },
551 { .id = 0x10de0007, .name = "MCP79/7A HDMI",
552 .patch = patch_nvhdmi_8ch_7x },
553 { .id = 0x10de000c, .name = "MCP89 HDMI",
554 .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de000b, .name = "GT21x HDMI",
556 .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de000d, .name = "GT240 HDMI",
558 .patch = patch_nvhdmi_8ch_89 },
405 {} /* terminator */ 559 {} /* terminator */
406}; 560};
407 561
@@ -412,9 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0006");
412MODULE_ALIAS("snd-hda-codec-id:10de0007"); 566MODULE_ALIAS("snd-hda-codec-id:10de0007");
413MODULE_ALIAS("snd-hda-codec-id:10de0067"); 567MODULE_ALIAS("snd-hda-codec-id:10de0067");
414MODULE_ALIAS("snd-hda-codec-id:10de8001"); 568MODULE_ALIAS("snd-hda-codec-id:10de8001");
569MODULE_ALIAS("snd-hda-codec-id:10de000c");
570MODULE_ALIAS("snd-hda-codec-id:10de000b");
571MODULE_ALIAS("snd-hda-codec-id:10de000d");
415 572
416MODULE_LICENSE("GPL"); 573MODULE_LICENSE("GPL");
417MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec"); 574MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
418 575
419static struct hda_codec_preset_list nvhdmi_list = { 576static struct hda_codec_preset_list nvhdmi_list = {
420 .preset = snd_hda_preset_nvhdmi, 577 .preset = snd_hda_preset_nvhdmi,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e8cbe216e912..5d2fbb87b871 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4915,7 +4915,7 @@ static void fixup_automic_adc(struct hda_codec *codec)
4915static void fixup_single_adc(struct hda_codec *codec) 4915static void fixup_single_adc(struct hda_codec *codec)
4916{ 4916{
4917 struct alc_spec *spec = codec->spec; 4917 struct alc_spec *spec = codec->spec;
4918 hda_nid_t pin; 4918 hda_nid_t pin = 0;
4919 int i; 4919 int i;
4920 4920
4921 /* search for the input pin; there must be only one */ 4921 /* search for the input pin; there must be only one */
@@ -13561,6 +13561,8 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13561static void alc269_quanta_fl1_setup(struct hda_codec *codec) 13561static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13562{ 13562{
13563 struct alc_spec *spec = codec->spec; 13563 struct alc_spec *spec = codec->spec;
13564 spec->autocfg.hp_pins[0] = 0x15;
13565 spec->autocfg.speaker_pins[0] = 0x14;
13564 spec->ext_mic.pin = 0x18; 13566 spec->ext_mic.pin = 0x18;
13565 spec->ext_mic.mux_idx = 0; 13567 spec->ext_mic.mux_idx = 0;
13566 spec->int_mic.pin = 0x19; 13568 spec->int_mic.pin = 0x19;
@@ -13656,6 +13658,8 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
13656static void alc269_laptop_dmic_setup(struct hda_codec *codec) 13658static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13657{ 13659{
13658 struct alc_spec *spec = codec->spec; 13660 struct alc_spec *spec = codec->spec;
13661 spec->autocfg.hp_pins[0] = 0x15;
13662 spec->autocfg.speaker_pins[0] = 0x14;
13659 spec->ext_mic.pin = 0x18; 13663 spec->ext_mic.pin = 0x18;
13660 spec->ext_mic.mux_idx = 0; 13664 spec->ext_mic.mux_idx = 0;
13661 spec->int_mic.pin = 0x12; 13665 spec->int_mic.pin = 0x12;
@@ -13666,6 +13670,8 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13666static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 13670static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13667{ 13671{
13668 struct alc_spec *spec = codec->spec; 13672 struct alc_spec *spec = codec->spec;
13673 spec->autocfg.hp_pins[0] = 0x15;
13674 spec->autocfg.speaker_pins[0] = 0x14;
13669 spec->ext_mic.pin = 0x18; 13675 spec->ext_mic.pin = 0x18;
13670 spec->ext_mic.mux_idx = 0; 13676 spec->ext_mic.mux_idx = 0;
13671 spec->int_mic.pin = 0x12; 13677 spec->int_mic.pin = 0x12;
@@ -13676,6 +13682,8 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13676static void alc269_laptop_amic_setup(struct hda_codec *codec) 13682static void alc269_laptop_amic_setup(struct hda_codec *codec)
13677{ 13683{
13678 struct alc_spec *spec = codec->spec; 13684 struct alc_spec *spec = codec->spec;
13685 spec->autocfg.hp_pins[0] = 0x15;
13686 spec->autocfg.speaker_pins[0] = 0x14;
13679 spec->ext_mic.pin = 0x18; 13687 spec->ext_mic.pin = 0x18;
13680 spec->ext_mic.mux_idx = 0; 13688 spec->ext_mic.mux_idx = 0;
13681 spec->int_mic.pin = 0x19; 13689 spec->int_mic.pin = 0x19;
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 7754db166d9e..dbc4b89d74e4 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -68,7 +68,7 @@ static void wm8776_write(struct oxygen *chip,
68 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 68 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
69 (reg << 9) | value); 69 (reg << 9) | value);
70 if (reg < ARRAY_SIZE(data->wm8776_regs)) { 70 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
71 if (reg >= WM8776_HPLVOL || reg <= WM8776_DACMASTER) 71 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
72 value &= ~WM8776_UPDATE; 72 value &= ~WM8776_UPDATE;
73 data->wm8776_regs[reg] = value; 73 data->wm8776_regs[reg] = value;
74 } 74 }
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 960a227eb653..ad4462677615 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1974,9 +1974,9 @@ snd_riptide_proc_read(struct snd_info_entry *entry,
1974 } 1974 }
1975 snd_iprintf(buffer, "Paths:\n"); 1975 snd_iprintf(buffer, "Paths:\n");
1976 i = getpaths(cif, p); 1976 i = getpaths(cif, p);
1977 while (i--) { 1977 while (i >= 2) {
1978 snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]); 1978 i -= 2;
1979 i--; 1979 snd_iprintf(buffer, "%x->%x ", p[i], p[i + 1]);
1980 } 1980 }
1981 snd_iprintf(buffer, "\n"); 1981 snd_iprintf(buffer, "\n");
1982} 1982}
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index b9ef7e45891d..b68d99fb6af0 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -90,12 +90,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
90 if (reg >= codec->reg_cache_size) 90 if (reg >= codec->reg_cache_size)
91 return -EINVAL; 91 return -EINVAL;
92 92
93 reg &= AK4104_REG_MASK;
94 reg |= AK4104_WRITE;
95
96 /* only write to the hardware if value has changed */ 93 /* only write to the hardware if value has changed */
97 if (cache[reg] != value) { 94 if (cache[reg] != value) {
98 u8 tmp[2] = { reg, value }; 95 u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
96
99 if (spi_write(spi, tmp, sizeof(tmp))) { 97 if (spi_write(spi, tmp, sizeof(tmp))) {
100 dev_err(&spi->dev, "SPI write failed\n"); 98 dev_err(&spi->dev, "SPI write failed\n");
101 return -EIO; 99 return -EIO;
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index a2763c2e7348..9cd0a66b7663 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -137,7 +137,7 @@ static void uda1380_flush_work(struct work_struct *work)
137{ 137{
138 int bit, reg; 138 int bit, reg;
139 139
140 for_each_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { 140 for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
141 reg = 0x10 + bit; 141 reg = 0x10 + bit;
142 pr_debug("uda1380: flush reg %x val %x:\n", reg, 142 pr_debug("uda1380: flush reg %x val %x:\n", reg,
143 uda1380_read_reg_cache(uda1380_codec, reg)); 143 uda1380_read_reg_cache(uda1380_codec, reg));
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 718ef912e758..df2c6d9617fb 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1349,7 +1349,7 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1349 int mask; 1349 int mask;
1350 struct wm8350_jack_data *jack = NULL; 1350 struct wm8350_jack_data *jack = NULL;
1351 1351
1352 switch (irq) { 1352 switch (irq - wm8350->irq_base) {
1353 case WM8350_IRQ_CODEC_JCK_DET_L: 1353 case WM8350_IRQ_CODEC_JCK_DET_L:
1354 jack = &priv->hpl; 1354 jack = &priv->hpl;
1355 mask = WM8350_JACK_L_LVL; 1355 mask = WM8350_JACK_L_LVL;
@@ -1424,7 +1424,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1424 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); 1424 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
1425 1425
1426 /* Sync status */ 1426 /* Sync status */
1427 wm8350_hp_jack_handler(irq, priv); 1427 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
1428 1428
1429 return 0; 1429 return 0;
1430} 1430}
@@ -1521,8 +1521,8 @@ static int wm8350_remove(struct platform_device *pdev)
1521 WM8350_JDL_ENA | WM8350_JDR_ENA); 1521 WM8350_JDL_ENA | WM8350_JDR_ENA);
1522 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1522 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1523 1523
1524 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L); 1524 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); 1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
1526 1526
1527 priv->hpl.jack = NULL; 1527 priv->hpl.jack = NULL;
1528 priv->hpr.jack = NULL; 1528 priv->hpr.jack = NULL;
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 9cc04ab2bce7..c0bfab8fed3d 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -72,7 +72,7 @@ struct siu_firmware {
72#include <linux/interrupt.h> 72#include <linux/interrupt.h>
73#include <linux/io.h> 73#include <linux/io.h>
74 74
75#include <asm/dma-sh.h> 75#include <asm/dmaengine.h>
76 76
77#include <sound/core.h> 77#include <sound/core.h>
78#include <sound/pcm.h> 78#include <sound/pcm.h>
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index c5efc30f0136..ba7f8d05d977 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -32,7 +32,7 @@
32#include <sound/pcm_params.h> 32#include <sound/pcm_params.h>
33#include <sound/soc-dai.h> 33#include <sound/soc-dai.h>
34 34
35#include <asm/dma-sh.h> 35#include <asm/dmaengine.h>
36#include <asm/siu.h> 36#include <asm/siu.h>
37 37
38#include "siu.h" 38#include "siu.h"
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a03bac943aaf..c8b0556ef431 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -427,24 +427,24 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
427 if (!runtime->hw.rates) { 427 if (!runtime->hw.rates) {
428 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", 428 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
429 codec_dai->name, cpu_dai->name); 429 codec_dai->name, cpu_dai->name);
430 goto machine_err; 430 goto config_err;
431 } 431 }
432 if (!runtime->hw.formats) { 432 if (!runtime->hw.formats) {
433 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", 433 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
434 codec_dai->name, cpu_dai->name); 434 codec_dai->name, cpu_dai->name);
435 goto machine_err; 435 goto config_err;
436 } 436 }
437 if (!runtime->hw.channels_min || !runtime->hw.channels_max) { 437 if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
438 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", 438 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
439 codec_dai->name, cpu_dai->name); 439 codec_dai->name, cpu_dai->name);
440 goto machine_err; 440 goto config_err;
441 } 441 }
442 442
443 /* Symmetry only applies if we've already got an active stream. */ 443 /* Symmetry only applies if we've already got an active stream. */
444 if (cpu_dai->active || codec_dai->active) { 444 if (cpu_dai->active || codec_dai->active) {
445 ret = soc_pcm_apply_symmetry(substream); 445 ret = soc_pcm_apply_symmetry(substream);
446 if (ret != 0) 446 if (ret != 0)
447 goto machine_err; 447 goto config_err;
448 } 448 }
449 449
450 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 450 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
@@ -464,10 +464,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
464 mutex_unlock(&pcm_mutex); 464 mutex_unlock(&pcm_mutex);
465 return 0; 465 return 0;
466 466
467machine_err: 467config_err:
468 if (machine->ops && machine->ops->shutdown) 468 if (machine->ops && machine->ops->shutdown)
469 machine->ops->shutdown(substream); 469 machine->ops->shutdown(substream);
470 470
471machine_err:
472 if (codec_dai->ops->shutdown)
473 codec_dai->ops->shutdown(substream, codec_dai);
474
471codec_dai_err: 475codec_dai_err:
472 if (platform->pcm_ops->close) 476 if (platform->pcm_ops->close)
473 platform->pcm_ops->close(substream); 477 platform->pcm_ops->close(substream);
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 8c2925814ce4..c570ae3e6d55 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -22,13 +22,13 @@ config SND_USB_AUDIO
22 will be called snd-usb-audio. 22 will be called snd-usb-audio.
23 23
24config SND_USB_UA101 24config SND_USB_UA101
25 tristate "Edirol UA-101 driver (EXPERIMENTAL)" 25 tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)"
26 depends on EXPERIMENTAL 26 depends on EXPERIMENTAL
27 select SND_PCM 27 select SND_PCM
28 select SND_RAWMIDI 28 select SND_RAWMIDI
29 help 29 help
30 Say Y here to include support for the Edirol UA-101 audio/MIDI 30 Say Y here to include support for the Edirol UA-101 and UA-1000
31 interface. 31 audio/MIDI interfaces.
32 32
33 To compile this driver as a module, choose M here: the module 33 To compile this driver as a module, choose M here: the module
34 will be called snd-ua101. 34 will be called snd-ua101.
diff --git a/sound/usb/caiaq/midi.h b/sound/usb/caiaq/midi.h
index 9d16db027fc3..380f984babc9 100644
--- a/sound/usb/caiaq/midi.h
+++ b/sound/usb/caiaq/midi.h
@@ -3,6 +3,6 @@
3 3
4int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev); 4int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
5void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len); 5void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
6void snd_usb_caiaq_midi_output_done(struct urb* urb); 6void snd_usb_caiaq_midi_output_done(struct urb *urb);
7 7
8#endif /* CAIAQ_MIDI_H */ 8#endif /* CAIAQ_MIDI_H */
diff --git a/sound/usb/ua101.c b/sound/usb/ua101.c
index 4f4ccdf70dd0..3d458d3b9962 100644
--- a/sound/usb/ua101.c
+++ b/sound/usb/ua101.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Edirol UA-101 driver 2 * Edirol UA-101/UA-1000 driver
3 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 3 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
4 * 4 *
5 * This driver is free software: you can redistribute it and/or modify 5 * This driver is free software: you can redistribute it and/or modify
@@ -25,13 +25,10 @@
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include "usbaudio.h" 26#include "usbaudio.h"
27 27
28MODULE_DESCRIPTION("Edirol UA-101 driver"); 28MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
30MODULE_LICENSE("GPL v2"); 30MODULE_LICENSE("GPL v2");
31MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101}}"); 31MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
32
33/* I use my UA-1A for testing because I don't have a UA-101 ... */
34#define UA1A_HACK
35 32
36/* 33/*
37 * Should not be lower than the minimum scheduling delay of the host 34 * Should not be lower than the minimum scheduling delay of the host
@@ -132,9 +129,6 @@ struct ua101 {
132 dma_addr_t dma; 129 dma_addr_t dma;
133 } buffers[MAX_MEMORY_BUFFERS]; 130 } buffers[MAX_MEMORY_BUFFERS];
134 } capture, playback; 131 } capture, playback;
135
136 unsigned int fps[10];
137 unsigned int frame_counter;
138}; 132};
139 133
140static DEFINE_MUTEX(devices_mutex); 134static DEFINE_MUTEX(devices_mutex);
@@ -424,16 +418,6 @@ static void capture_urb_complete(struct urb *urb)
424 if (do_period_elapsed) 418 if (do_period_elapsed)
425 snd_pcm_period_elapsed(stream->substream); 419 snd_pcm_period_elapsed(stream->substream);
426 420
427 /* for debugging: measure the sample rate relative to the USB clock */
428 ua->fps[ua->frame_counter++ / ua->packets_per_second] += frames;
429 if (ua->frame_counter >= ARRAY_SIZE(ua->fps) * ua->packets_per_second) {
430 printk(KERN_DEBUG "capture rate:");
431 for (frames = 0; frames < ARRAY_SIZE(ua->fps); ++frames)
432 printk(KERN_CONT " %u", ua->fps[frames]);
433 printk(KERN_CONT "\n");
434 memset(ua->fps, 0, sizeof(ua->fps));
435 ua->frame_counter = 0;
436 }
437 return; 421 return;
438 422
439stream_stopped: 423stream_stopped:
@@ -1200,13 +1184,30 @@ static int ua101_probe(struct usb_interface *interface,
1200 .type = QUIRK_MIDI_FIXED_ENDPOINT, 1184 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1201 .data = &midi_ep 1185 .data = &midi_ep
1202 }; 1186 };
1187 static const int intf_numbers[2][3] = {
1188 { /* UA-101 */
1189 [INTF_PLAYBACK] = 0,
1190 [INTF_CAPTURE] = 1,
1191 [INTF_MIDI] = 2,
1192 },
1193 { /* UA-1000 */
1194 [INTF_CAPTURE] = 1,
1195 [INTF_PLAYBACK] = 2,
1196 [INTF_MIDI] = 3,
1197 },
1198 };
1203 struct snd_card *card; 1199 struct snd_card *card;
1204 struct ua101 *ua; 1200 struct ua101 *ua;
1205 unsigned int card_index, i; 1201 unsigned int card_index, i;
1202 int is_ua1000;
1203 const char *name;
1206 char usb_path[32]; 1204 char usb_path[32];
1207 int err; 1205 int err;
1208 1206
1209 if (interface->altsetting->desc.bInterfaceNumber != 0) 1207 is_ua1000 = usb_id->idProduct == 0x0044;
1208
1209 if (interface->altsetting->desc.bInterfaceNumber !=
1210 intf_numbers[is_ua1000][0])
1210 return -ENODEV; 1211 return -ENODEV;
1211 1212
1212 mutex_lock(&devices_mutex); 1213 mutex_lock(&devices_mutex);
@@ -1239,20 +1240,13 @@ static int ua101_probe(struct usb_interface *interface,
1239 init_waitqueue_head(&ua->rate_feedback_wait); 1240 init_waitqueue_head(&ua->rate_feedback_wait);
1240 init_waitqueue_head(&ua->alsa_playback_wait); 1241 init_waitqueue_head(&ua->alsa_playback_wait);
1241 1242
1242#ifdef UA1A_HACK
1243 if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
1244 ua->intf[2] = interface;
1245 ua->intf[0] = usb_ifnum_to_if(ua->dev, 1);
1246 ua->intf[1] = usb_ifnum_to_if(ua->dev, 2);
1247 usb_driver_claim_interface(&ua101_driver, ua->intf[0], ua);
1248 usb_driver_claim_interface(&ua101_driver, ua->intf[1], ua);
1249 } else {
1250#endif
1251 ua->intf[0] = interface; 1243 ua->intf[0] = interface;
1252 for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) { 1244 for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) {
1253 ua->intf[i] = usb_ifnum_to_if(ua->dev, i); 1245 ua->intf[i] = usb_ifnum_to_if(ua->dev,
1246 intf_numbers[is_ua1000][i]);
1254 if (!ua->intf[i]) { 1247 if (!ua->intf[i]) {
1255 dev_err(&ua->dev->dev, "interface %u not found\n", i); 1248 dev_err(&ua->dev->dev, "interface %u not found\n",
1249 intf_numbers[is_ua1000][i]);
1256 err = -ENXIO; 1250 err = -ENXIO;
1257 goto probe_error; 1251 goto probe_error;
1258 } 1252 }
@@ -1264,39 +1258,19 @@ static int ua101_probe(struct usb_interface *interface,
1264 goto probe_error; 1258 goto probe_error;
1265 } 1259 }
1266 } 1260 }
1267#ifdef UA1A_HACK
1268 }
1269#endif
1270 1261
1271 snd_card_set_dev(card, &interface->dev); 1262 snd_card_set_dev(card, &interface->dev);
1272 1263
1273#ifdef UA1A_HACK
1274 if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
1275 ua->format_bit = SNDRV_PCM_FMTBIT_S16_LE;
1276 ua->rate = 44100;
1277 ua->packets_per_second = 1000;
1278 ua->capture.channels = 2;
1279 ua->playback.channels = 2;
1280 ua->capture.frame_bytes = 4;
1281 ua->playback.frame_bytes = 4;
1282 ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, 2);
1283 ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, 1);
1284 ua->capture.max_packet_bytes = 192;
1285 ua->playback.max_packet_bytes = 192;
1286 } else {
1287#endif
1288 err = detect_usb_format(ua); 1264 err = detect_usb_format(ua);
1289 if (err < 0) 1265 if (err < 0)
1290 goto probe_error; 1266 goto probe_error;
1291#ifdef UA1A_HACK
1292 }
1293#endif
1294 1267
1268 name = usb_id->idProduct == 0x0044 ? "UA-1000" : "UA-101";
1295 strcpy(card->driver, "UA-101"); 1269 strcpy(card->driver, "UA-101");
1296 strcpy(card->shortname, "UA-101"); 1270 strcpy(card->shortname, name);
1297 usb_make_path(ua->dev, usb_path, sizeof(usb_path)); 1271 usb_make_path(ua->dev, usb_path, sizeof(usb_path));
1298 snprintf(ua->card->longname, sizeof(ua->card->longname), 1272 snprintf(ua->card->longname, sizeof(ua->card->longname),
1299 "EDIROL UA-101 (serial %s), %u Hz at %s, %s speed", 1273 "EDIROL %s (serial %s), %u Hz at %s, %s speed", name,
1300 ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path, 1274 ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
1301 ua->dev->speed == USB_SPEED_HIGH ? "high" : "full"); 1275 ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
1302 1276
@@ -1314,24 +1288,18 @@ static int ua101_probe(struct usb_interface *interface,
1314 if (err < 0) 1288 if (err < 0)
1315 goto probe_error; 1289 goto probe_error;
1316 1290
1317 err = snd_pcm_new(card, "UA-101", 0, 1, 1, &ua->pcm); 1291 err = snd_pcm_new(card, name, 0, 1, 1, &ua->pcm);
1318 if (err < 0) 1292 if (err < 0)
1319 goto probe_error; 1293 goto probe_error;
1320 ua->pcm->private_data = ua; 1294 ua->pcm->private_data = ua;
1321 strcpy(ua->pcm->name, "UA-101"); 1295 strcpy(ua->pcm->name, name);
1322 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops); 1296 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops);
1323 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops); 1297 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops);
1324 1298
1325#ifdef UA1A_HACK
1326 if (ua->dev->descriptor.idProduct != cpu_to_le16(0x0018)) {
1327#endif
1328 err = snd_usbmidi_create(card, ua->intf[INTF_MIDI], 1299 err = snd_usbmidi_create(card, ua->intf[INTF_MIDI],
1329 &ua->midi_list, &midi_quirk); 1300 &ua->midi_list, &midi_quirk);
1330 if (err < 0) 1301 if (err < 0)
1331 goto probe_error; 1302 goto probe_error;
1332#ifdef UA1A_HACK
1333 }
1334#endif
1335 1303
1336 err = snd_card_register(card); 1304 err = snd_card_register(card);
1337 if (err < 0) 1305 if (err < 0)
@@ -1386,11 +1354,9 @@ static void ua101_disconnect(struct usb_interface *interface)
1386} 1354}
1387 1355
1388static struct usb_device_id ua101_ids[] = { 1356static struct usb_device_id ua101_ids[] = {
1389#ifdef UA1A_HACK 1357 { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */
1390 { USB_DEVICE(0x0582, 0x0018) }, 1358 { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */
1391#endif 1359 { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */
1392 { USB_DEVICE(0x0582, 0x007d) },
1393 { USB_DEVICE(0x0582, 0x008d) },
1394 { } 1360 { }
1395}; 1361};
1396MODULE_DEVICE_TABLE(usb, ua101_ids); 1362MODULE_DEVICE_TABLE(usb, ua101_ids);
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c539f7fe292f..11b0826b8fe6 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2483,7 +2483,6 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip,
2483 sample_width, sample_bytes); 2483 sample_width, sample_bytes);
2484 } 2484 }
2485 /* check the format byte size */ 2485 /* check the format byte size */
2486 printk(" XXXXX SAMPLE BYTES %d\n", sample_bytes);
2487 switch (sample_bytes) { 2486 switch (sample_bytes) {
2488 case 1: 2487 case 1:
2489 pcm_format = SNDRV_PCM_FORMAT_S8; 2488 pcm_format = SNDRV_PCM_FORMAT_S8;
@@ -2581,6 +2580,9 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
2581 chip->usb_id == USB_ID(0x0d8c, 0x0102)) && 2580 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
2582 fp->altsetting == 5 && fp->maxpacksize == 392) 2581 fp->altsetting == 5 && fp->maxpacksize == 392)
2583 rate = 96000; 2582 rate = 96000;
2583 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
2584 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
2585 rate = 8000;
2584 fp->rate_table[fp->nr_rates] = rate; 2586 fp->rate_table[fp->nr_rates] = rate;
2585 if (!fp->rate_min || rate < fp->rate_min) 2587 if (!fp->rate_min || rate < fp->rate_min)
2586 fp->rate_min = rate; 2588 fp->rate_min = rate;
@@ -3386,58 +3388,6 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
3386 return 0; 3388 return 0;
3387} 3389}
3388 3390
3389/*
3390 * Create a stream for an Edirol UA-1000 interface.
3391 */
3392static int create_ua1000_quirk(struct snd_usb_audio *chip,
3393 struct usb_interface *iface,
3394 const struct snd_usb_audio_quirk *quirk)
3395{
3396 static const struct audioformat ua1000_format = {
3397 .format = SNDRV_PCM_FORMAT_S32_LE,
3398 .fmt_type = UAC_FORMAT_TYPE_I,
3399 .altsetting = 1,
3400 .altset_idx = 1,
3401 .attributes = 0,
3402 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3403 };
3404 struct usb_host_interface *alts;
3405 struct usb_interface_descriptor *altsd;
3406 struct audioformat *fp;
3407 int stream, err;
3408
3409 if (iface->num_altsetting != 2)
3410 return -ENXIO;
3411 alts = &iface->altsetting[1];
3412 altsd = get_iface_desc(alts);
3413 if (alts->extralen != 11 || alts->extra[1] != USB_DT_CS_INTERFACE ||
3414 altsd->bNumEndpoints != 1)
3415 return -ENXIO;
3416
3417 fp = kmemdup(&ua1000_format, sizeof(*fp), GFP_KERNEL);
3418 if (!fp)
3419 return -ENOMEM;
3420
3421 fp->channels = alts->extra[4];
3422 fp->iface = altsd->bInterfaceNumber;
3423 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3424 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3425 fp->datainterval = parse_datainterval(chip, alts);
3426 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3427 fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
3428
3429 stream = (fp->endpoint & USB_DIR_IN)
3430 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3431 err = add_audio_endpoint(chip, stream, fp);
3432 if (err < 0) {
3433 kfree(fp);
3434 return err;
3435 }
3436 /* FIXME: playback must be synchronized to capture */
3437 usb_set_interface(chip->dev, fp->iface, 0);
3438 return 0;
3439}
3440
3441static int snd_usb_create_quirk(struct snd_usb_audio *chip, 3391static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3442 struct usb_interface *iface, 3392 struct usb_interface *iface,
3443 const struct snd_usb_audio_quirk *quirk); 3393 const struct snd_usb_audio_quirk *quirk);
@@ -3686,7 +3636,6 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3686 [QUIRK_MIDI_CME] = create_any_midi_quirk, 3636 [QUIRK_MIDI_CME] = create_any_midi_quirk,
3687 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, 3637 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3688 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 3638 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3689 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
3690 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, 3639 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
3691 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk 3640 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
3692 }; 3641 };
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 6b016d4aac6b..42c299cbf63a 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -75,7 +75,6 @@ enum quirk_type {
75 QUIRK_MIDI_US122L, 75 QUIRK_MIDI_US122L,
76 QUIRK_AUDIO_STANDARD_INTERFACE, 76 QUIRK_AUDIO_STANDARD_INTERFACE,
77 QUIRK_AUDIO_FIXED_ENDPOINT, 77 QUIRK_AUDIO_FIXED_ENDPOINT,
78 QUIRK_AUDIO_EDIROL_UA1000,
79 QUIRK_AUDIO_EDIROL_UAXX, 78 QUIRK_AUDIO_EDIROL_UAXX,
80 QUIRK_AUDIO_ALIGN_TRANSFER, 79 QUIRK_AUDIO_ALIGN_TRANSFER,
81 80
@@ -112,7 +111,7 @@ struct snd_usb_midi_endpoint_info {
112 111
113/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */ 112/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
114 113
115/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */ 114/* for QUIRK_AUDIO_EDIROL_UAXX, data is NULL */
116 115
117/* for QUIRK_IGNORE_INTERFACE, data is NULL */ 116/* for QUIRK_IGNORE_INTERFACE, data is NULL */
118 117
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index f06faf7917b9..2b426c1fd0e8 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1016,36 +1016,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1016 } 1016 }
1017}, 1017},
1018{ 1018{
1019 USB_DEVICE(0x0582, 0x0044),
1020 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1021 .vendor_name = "Roland",
1022 .product_name = "UA-1000",
1023 .ifnum = QUIRK_ANY_INTERFACE,
1024 .type = QUIRK_COMPOSITE,
1025 .data = (const struct snd_usb_audio_quirk[]) {
1026 {
1027 .ifnum = 1,
1028 .type = QUIRK_AUDIO_EDIROL_UA1000
1029 },
1030 {
1031 .ifnum = 2,
1032 .type = QUIRK_AUDIO_EDIROL_UA1000
1033 },
1034 {
1035 .ifnum = 3,
1036 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1037 .data = & (const struct snd_usb_midi_endpoint_info) {
1038 .out_cables = 0x0003,
1039 .in_cables = 0x0003
1040 }
1041 },
1042 {
1043 .ifnum = -1
1044 }
1045 }
1046 }
1047},
1048{
1049 /* has ID 0x0049 when not in "Advanced Driver" mode */ 1019 /* has ID 0x0049 when not in "Advanced Driver" mode */
1050 USB_DEVICE(0x0582, 0x0047), 1020 USB_DEVICE(0x0582, 0x0047),
1051 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1021 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {